# 1  Writing Mistie formats

A typical intent of a format file is to cause certain characters in the input document to trigger non-trivial changes in the output document. E.g., if the output is to be HTML, we'd like the characters `<`, `>`, `&`, and `"` in the input to come out as `&lt;`, `&gt;`, `&amp;`, and `&quot;`, respectively. The Mistie procedure `mistie-def-char` can be used for this:

```(mistie-def-char #\<
(lambda ()
(display "&lt;")))

(mistie-def-char #\>
(lambda ()
(display "&gt;")))

(mistie-def-char #\&
(lambda ()
(display "&amp;")))

(mistie-def-char #\"
(lambda ()
(display "&quot;")))
```

`mistie-def-char` takes two arguments: The first is the character that is defined, and the second is the procedure associated with it. Here, the procedure writes the HTML encoded version of the character.

Suppose we want a contiguous sequence of blank lines to be come out as the paragraph separator, `<p>`. We could `mistie-def-char` the newline character as follows:

```(mistie-def-char #\newline
(lambda ()
(newline)
(n (h-number-of-newlines s)))
(if (> n 0)
(begin (display "<p>")
(newline) (newline))
(display s)))))
```

This will cause newline to read up all the following whitespace, and then check to see how many further newlines it picked up. If there was at least one, it outputs the paragraph separator, viz., `<p>` followed by two newlines (added for human readability). Otherwise, it merely prints the picked up whitespace as is. The help procedures `h-read-whitespace` and `h-number-of-newlines` are ordinary Scheme procedures:

```(define h-read-whitespace
(lambda ()
(let loop ((r '()))
(let ((c (peek-char)))
(if (or (eof-object? c) (not (char-whitespace? c)))
(list->string (reverse r))

(define h-number-of-newlines
(lambda (ws)
(let ((n (string-length ws)))
(let loop ((i 0) (k 0))
(if (>= i n) k
(loop (+ i 1)
(if (char=? (string-ref ws i) #\newline)
(+ k 1) k)))))))
```

## 1.1  Control sequences

The Mistie procedure `mistie-def-ctl-seq` defines control sequences. A control sequence is a sequence of letters (alphabetic characters), and is invoked in the input document by prefixing the sequence with an escape character. (The case of the letters is insignificant.) `mistie-def-ctl-seq` associates a procedure with a control sequence -- when the control sequence occurs in the input document, it causes the procedure to be applied. The following defines the control sequence `br`, which emits the HTML tag `<br>`:

```(mistie-def-ctl-seq 'br
(lambda ()
(display "<br>")))
```

Before a control sequence can be used, we must fix the escape character. The following sets it to backslash:

```(set! mistie-escape-char #\\)
```

We can now invoke the `br` control sequence as `\br`.

## 1.2  Frames

However, we can do better and get automatic line breaks with a more powerful control sequence. Let's say text between `\obeylines` and `\endobeylines` should have automatic line breaks. We define the control sequences `obeylines` and `endobeylines` as follows:

```(mistie-def-ctl-seq 'obeylines
(lambda ()
(mistie-push-frame)
(mistie-def-char #\newline
(lambda ()
(display "<br>")
(newline)))
(mistie-def-ctl-seq 'endobeylines
(lambda ()
(mistie-pop-frame)))))
```

The `obeylines` control sequence first pushes a new frame on to the Mistie environment, using the Mistie procedure `mistie-push-frame`. What this means is that any definitions (whether `mistie-def-char` or `mistie-def-ctl-seq`) will shadow existing definitions. The Mistie procedure `mistie-pop-frame` exits the frame, causing the older definitions to take effect again.

In this case, we create a shadowing `mistie-def-char` for newline, so that it will emit `<br>` instead of performing its default action (which, as we described above, was to look for paragraph separation). We also define a control sequence `endobeylines` which will pop the frame pushed by `obeylines`. With this definition in place, any text sandwiched between `\obeylines` and `\endobeylines` (assuming `\` is the escape character) will be output with a `<br>` at the end of each of its lines.

## 1.3  Calling Scheme from within the document

We can define a control sequence `eval` that will allow the input document to explicitly evaluate Scheme expressions, without having to put them all in a format file.

```(mistie-def-ctl-seq 'eval
(lambda ()
This will cause `\eval` followed by a Scheme expression to evaluate that Scheme expression. E.g.,
```\eval (display (+ 21 21))
will cause `42` to be printed at the point where the `\eval` statement is placed. Of course, once you have arbitrary access to Scheme within your document, the amount of kooky intertextual stuff you can do is limited only by your imagination. A mundane use for `\eval` is to reset the escape character at arbitrary locations in the document, should the existing character be needed (temporarily or permanently) for something else.