#

# Appendix 2 to Chapter 4:

# Using @root Directives, Tangling and Untangling

This appendix discusses @root trees. @root and @file directives have much in common. I recommend that you read and understand Chapter 4 before attempting this chapter. This appendix assumes you are familiar with the terminology used in Chapter 4.

@file vs. @root trees
Sections and section definitions
Tangling @root trees with the Tangle commands
Untangling @root trees with the Untangle commands
@verbose, @terse, @quiet and @silent directives

## @file vs. @root trees

Leo outlines may contain both @root and @file trees, and I strongly recommend using @file trees whenever possible. @file trees are much easier to use than @root trees:

- @file trees require less markup than @root trees; all sections in @root trees must have names, but @file trees usually contain many unnamed sections. Within @file trees, the @others directive acts like a reference to all unnamed sections.
- The user must explicitly tangle and untangle @root trees using the Tangle and Untangle commands. Leo tangles and untangles @file trees automatically, tangling all changed @file trees when writing an outline and untangling all @file trees when reading an outline.

However, @root trees are more flexible than @file trees.

- Within @file trees, sections must be defined in descendents of the node that contains the section reference.
- Within @root trees a section may be defined anywhere within the @root tree, regardless of where the section is referenced. Moreover, the @unit directive expands the scope of section definitions in @root trees so that a section may be referenced in several @root trees.
- The meaning of section definitions in @root trees are independent of their position within the tree.

@root trees differ from @file trees as follows:

- Only @root trees may contain section definition lines (see below.)
- Only @file trees may contain @others directives.
- @c directives require section names in the headline of @root trees.
- @c directives are optional at the start of body text in @file trees only.
- Body text without markup is ignored in @root trees; it creates unnamed code sections in @file trees.

## Sections and section definitions

Just as with @file trees, @root trees may contain kinds of sections: code sections and doc sections. Code sections start with section definition lines (see below) or the @c directive. Doc sections start with an @ directive (an @ followed by whitespace or a newline at the start of a line.) Doc sections continue until the end of body text or until the next @c or @(space) directive.
The term "section" has two related meanings. Sections are syntactic units of text in the body pane. Leo writes the text of section to derived files, so another meaning of "section" is "the text that is written to the derived file." Which meaning is intended should be clear from context.

Body text in @root trees contain zero or more sections in any order. The @c directive starts a named code section if the node's headline starts with <<section name>>. Otherwise, the @c directive is invalid.

Section definition lines of the form

>     << section name>>=

(note the equal sign) also start named code sections. Named code sections in @root trees may be defined in several places. The definition of a named code section is the concatenation of all code sections with the same name. Body text that defines no code section is ignored.

At least one non-blank line must follow the section definition line. That is, empty sections are not allowed.

As in @file trees, paired << and >> characters on the same line always denote a section name, even within comments are strings. That is, << and >> characters that do not delimit a section name must be placed on separate lines. If << and >> are not paired on a line, they are treated as literal << and >> characters.

Here is a typical example of body text within an @root tree:

>     @ This method puts an open node sentinel for node v.
>     <<atFile methods>>=
>     def putOpenNodeSentinel(self,v):
>         if v.isAtFileNode() and v != self.root:
>             << issue an error message >>
>         else:
>             s = self.nodeSentinelText(v)
>             self.putSentinel("@+node:" + s)

Provided that the node's headline starts with <<atFile methods>>, the example above is equivalent to:

>     @ This method puts an open node sentinel for node v.
>     @c
>     def putOpenNodeSentinel(self,v):
>         if v.isAtFileNode() and v != self.root:
>             << issue an error message >>
>         else:
>             s = self.nodeSentinelText(v)
>             self.putSentinel("@+node:" + s)

We may not eliminate @c directives in @root trees. If we convert the doc part to a comment we are left with:

>     @c
>     # This method puts an open node sentinel for node v.
>     def putOpenNodeSentinel(self,v):
>         if v.isAtFileNode() and v != self.root:
>             << issue an error message >>
>         else:
>             s = self.nodeSentinelText(v)
>             self.putSentinel("@+node:" + s)

The following escape convention applies only in @root trees. Within a code parts @@ in the first column (and only in the first column) stands for a single @ sign.

## Tangling @root trees and the Tangle commands

Each @root tree represents a single derived file. Tangling is the process of creating derived files from @file or @root trees. Leo tangles @file trees automatically whenever an outline is saved. The user must tangle @file trees explicitly using one of the Tangle commands.

Leo creates derived files from @root trees by expanding all section references in an @root node. Leo expands a section reference by substituting the code section itself for the section reference. This is a recursive process: the substituted code section may contain other code references which are themselves expanded, and so on.

It is unusual and bad style for the meaning of an @root tree to depend on the position of nodes within it. The meaning of a section definition in an @root tree usually does not depend on is position, and we may place sections wherever we want. The outline provides a natural way of organizing an sections as follows:

> Place the definition of a section S in a child of the node containing the reference to S.

If a section is referenced in more than one node, I usually place its definition in a node containing all the nodes that refer to it. Using this rule of thumb creates an outline whose structure mirrors the intrinsic organization of a program.

The Tangle command creates derived files from @root node. The `@root` directive indicates which sections constitute an output file. The text following a `@root` directive forms the entire content of the file, that is, after section references are expanded. An outline can contain arbitrarily many `@root` directives: Leo's Tangle commands will create one output file for each.

For example, the following `@root` section shows a typical way of specifying a header file xx.h.

>     @root"xx.h"
>     #ifndef xx_defined
>     #define xx_defined
>     << declarations of public constants of the xx class >>
>     << declarations of public types of the xx class >>
>     << declarations of public variables of the xx class >>
>     << public prototypes of the xx class >>
>     #endif

The Tangle commands will create the file xx.h from this body text by expanding all the section references. Incidentally, the introductory documentation will be included in the header file: any text preceding the @root directive is treated just like the documentation part of an section definition.

As another example, the following shows a typical way of specifying the corresponding xx.c file:

>     @root"xx.c"
>     << public variables of the xx class >>
>     << private types of the xx class >>
>     << private variables of the xx class >>
>     << private function prototypes of the xx class >>
>     << methods of the xx class >>

There are three menu commands that tangle an outline: Tangle, Tangle All and Tangle Marked. These commands are identical except for how much of the outline is tangled. The Tangle command tangles only the selected portion of the outline, the Tangle All command tangles the entire outline, and the Tangle Marked command tangles only marked headlines.

The `@root` directive has three forms. All three forms mean exactly the same thing.

>     @root filename
>     @root "filename"
>     @root <filename>

If filename is an absolute filename the location of the derived file is specified only by the filename. Otherwise, if the @root node contains a relative filename, the location of the derived file is relative to:

1. the directory specified the applicable @path directive, or
2. the "Default Tangle Directory" in the Preferences panel if no @path directive is in effect, or
3. the directory in which the .leo resides if the .leo file has ever been saved.

An error occurs if no absolute path can be computed according to these rules, or if the filename or directory does not exist.

The Tangle commands format derived files so they are easy to read. The .c file in the Examples folder shows how derived files are formatted by the Tangle commands.

There is one complication that we haven't discussed yet: the scope of section definitions. The scope of a definition is the tree in which the definition is known.

By default, Tangle commands look for section definitions only in the suboutline of the `@root` node being tangled. That is, all sections are assumed to be defined either in the body text of the headline, say h, containing the `@root` directive, or in the body texts of the descendants of h.

`The @unit` directive explicitly indicates the scope of section definitions. When a Tangle command encounters the `@unit` directive it treats the suboutline containing the `@unit` command as the scope for all enclosed roots. This ensures that the group of roots in the subtree use the same section definitions.

For example, suppose we have a tree organized as follows:

    	+ @unit
    		+ @root A
    		sections in A
    		+ @root B
    		sections in B

The `@unit` directive insures that:

1. only sections defined in the unit can effect files A and B and
2. all sections definitions in A and B are compatible with each other.

Finally, Tangle commands ignore any tree containing an `@ignore` directive. This ensures that trees that contain cloned nodes or other subsidiary information do not cause the tangle commands to issue spurious error messages. It also ensures that a tree can never contribute a section definition to another part of the outline by mistake.

## Untangling @root trees with the Untangle commands

The Untangle, Untangle All and Untangle Marked commands are the reverse of the corresponding Tangle commands. They update one or more @root nodes based on changes made to the corresponding derived files.

For example, suppose you create a new part of the outline and Tangle it for the first time. When you compile derived files for the first you are likely to get many syntax errors. You could fix those errors in the outline and Tangle the outline again, but there is a much easier way: you fix the errors in the derived files using the compiler's editor, then run the untangle command on the part of the outline that created the derived file. The Untangle command updates the selected outline to match the changes in the derived files. It's as simple as that. By the way, the Untangle command marks all the nodes in the outline that it updates, and you can examine all such nodes with the Go To Next Marked command in the Outline menu.

You cannot use Untangle to update doc parts, or leading comments in code parts or "trivial" whitespace in code parts. This is a limitation of the Untangle command that cannot be fixed; Untangle has no way of knowing whether leading comments came from doc parts or are just leading comments.

Untangle never changes the structure of an outline; it never inserts, deletes or moves nodes. Don't attempt to change the structure of an outline by modifying derived files; it won't work. Also, never delete, move or alter the sentinel lines in derived files written by the Tangle command. Such lines start with /// followed by a section name.

If you change the section name in a sentinel line Untangle will not update the code in the outline (with the old name) that generated the renamed section. Untangle now warns about sections that appear in a derived file but not in the outline. Untangle has no trouble with changed section references in derived files; it is only changed sentinel lines that cause problems.

Cloned nodes that generate code in several files may cause problems for Untangle. If Untangle is run separately on these derived files, Untangle will update all cloned nodes each time it is run, so only the code in the last Untangle run will take effect. Therefore, the safe way to update text in cloned nodes is to make the change in the .leo file rather than the derived files.

## The @verbose, @terse, @quiet and @silent directives

The `@verbose`, `@terse`, `@quiet` and `@silent` directives determine how the Tangle command outputs comments in `@root` trees. Comments written by the user in code sections are always output: these directives control only: a) the comments containing doc sections and b) sentinel comments that delimit the beginning and end of code sections.

When `@verbose` is in effect Tangle outputs all comments. When `@terse` is in effect, Tangle outputs only those comments necessary for Untangle to work. When `@silent` is in effect Tangle no additional comments. The `@quiet` directive is like `@silent` except that it does output leading sentinels as comments. Like `@silent`, `@quiet` inhibits untangling.

`@verbose` is the default. If more than one of these directives appear in the same body text the "most verbose" of these options will be in effect.