The TeXmacs content model

All TeXmacs documents or document fragments can be thought of as trees, as explained in more detail in the chapter about the TeXmacs document format. Inside Scheme programs, there are two main ways to represent such trees, depending on whether one manipulates active or passive documents:

Passive documents and Scheme trees

Passive documents, like those which are processed by a conversion tool, are usually represented by scheme trees. For instance, the fraction

a2
b + c

is typically represented by

(frac (concat "a" (rsup "2")) "b+c")

This representation is convenient in the sense that they can be manipulated directly using standard Scheme routines on lists.

Active documents and C++ trees

Active documents, like ones which are visible in one of the editors windows, are rather represented using the internal C++ type tree, which has been exported to Scheme via the glue. When a tree is part of a real document inside the editor, the tree is aware about its position inside the document. Using routines from the tree API, you may then make changes in the document simply by assigning new values to the tree.

For instance, consider the following experiment: open two windows and start a Scheme session in each window. In the second window, enter the lines

scheme]

(use-modules (utils library tree))

scheme]

(define t (buffer-tree))

In the first window, you may now modify the document in the second window using commands like

scheme]

(tree-set! t (tree 'document (string->tree "First line.")

(string->tree "Second line.")))

scheme]

(tree-set t 1 (string->tree "New second line."))

scheme]

(tree-set t 0 (tree 'strong (tree-ref t 0)))

A common framework

From the last three lines in above experiment, it becomes apparent that it is quite cumbersome to manipulate trees using the standard tree constructors. For this reason, TeXmacs provides a hybrid type content for manipulating scheme trees and C++ trees in a common framework. For instance, the last three lines in the above experiment may be replaced by

scheme]

(tree-set! t '(document "First line." "Second line."))

scheme]

(tree-set t 1 "New second line.")

scheme]

(tree-set t 0 ‘(strong ,(tree-ref t 0)))

More precisely, a scheme expression of the type content is either a string, a tree or a list whose first element is a symbol and whose remaining elements are other expressions of type content. TeXmacs provides several routines (usually prefixed by tm-) for basic operations on content, like tm-car, tm-arity, tm->list, tm-equal?, etc. Most higher level routines are built on top of these routines, so as to accept arguments of type content whenever appropriate.

Persistent positions inside trees

Besides the fact that trees remember their positions inside the global edit tree, it is also possible to create cursor positions inside the global edit tree, which are naturally updated when modifications take place. This technique is useful when you want to write and editing routine which does not act locally at the cursor position. For instance, the following routine can be used to insert content at the start of the current buffer in a reliable way:

(define (insert-at-buffer-start t)

(with-cursor (path-start (root-tree) (buffer-path))

(insert t)))

The with-cursor macro temporarily changes the cursor position, while storing the old cursor position in such a way that it will be updated during changes of the document. The user may also use the more explicit routines position-new, position-delete, position-set and position-get to manage persistent positions.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".