Mutator tags |
A mutator tag is of the form <
Mutator tags are a particularly interesting feature of TeXmacs for producing highly interactive documents. For instance, inside computer algebra sessions, the output is retrieved inside a mutator tag (which automatically removes itself when the output is complete). In the future, mutators might be used for live conferencing or in interfaces with proof systems.
Indeed, the current implementation of TeXmacs searches for mutator tags in all documents after a small period of inactivity. Documents which are known not to contain mutator tags are ignored during this research. Of course, this implementation is both quite efficient and incompatible with the macro system. So there is room for future improvements.
A very simple example with two types of mutators is provided in the mutator plug-in. It provides the user with two keyboard shortcuts C-F11 and C-F12, which respectively insert the current time and some blinking text. The plug-in consists of the single file
mutator/progs/init-mutator.scm
The C-F11 key simply inserts the continuously updated time into the main text:
(kbd-map ("C-F11" (insert '(mutator "" "(mutate-date)"))))
The secure
(tm-define (mutate-date)
(:secure #t)
(let* ((p (the-mutator-path))
(date (var-eval-system "date
+\"%H:%M:%S\"")))
(tm-assign-diff p date)))
The tm-assign-diff command is convenient, because it only modifies the document if a real change occurred.
The insertion of blinking content is slightly more complex, since it also takes into account the current content of the mutator tag. The C-F12 key inserts a blinking text into the main text and puts the cursor after the text in the body of the mutator:
(kbd-map ("C-F12" (insert-go-to '(mutator "text" "(mutate-blink)") '(0 4))))
The secure
(tm-define (mutate-blink)
(:secure #t)
(let* ((mod (lambda (x y) (* y (- (/ x y) (floor (/
x y))))))
(p (the-mutator-path))
(t (tm-subtree p))
(s (string->number (var-eval-system
"date +\"%S\"")))
(e (mod s 4)))
(if (and (<= e 1) (not (match? t '(strong
:%1))))
(tm-ins-unary p 'strong))
(if (and (>= e 2) (match? t '(strong :%1)))
(tm-rem-unary p))))