Leo Article

The following describes Leo as for a magazine article.  It also provides yet another kind of overview of Leo which may be helpful for beginners. Actually, the section called "organizing outlines" below would probably be condensed in a real article, but that section is quite helpful so I'll leave it in its expanded state here.

Leo is a new kind of outlining programmer's editor.  Leo understands a simple markup language that is aware of outline structure, and Leo's outline structure clarifies and organizes programs and projects. Leo is more powerful and flexible than typical class and program browsers.  Moreover, Leo's implementation shows how to extend the capabilities of browsers by embedding outlining information into flat text files.  Finally, Leo is compatible with so-called  literate programming languages such as noweb and CWEB.

Outlines and sections

Leo's main window contains two panes. The upper outline pane shows outlines; the lower body pane shows the body text of the presently selected headline. The user may expand and contract headlines to show or hide child nodes. The user may also insert, delete and move nodes.

Leo generates program text in external files (called derived files) from text in the body pane. Body text may contain section references. For example,

<< scan the file buffer >>

is a reference to a section called << scan the file buffer >>. Sections references represent textual substitution, like macro calls. Sections differ from function calls because a section's variables reside in the context of the section reference.

Directives may appear in body text. Directives start with an @ sign in the left column followed by the directive name. The @c directive starts a section definition. The section definition continues until the next @c directive or until the end of the body text. Section definitions may contain references to other sections. A section is named if the headline of the node containing the definition starts with a section reference.  Otherwise, the section is unnamed. Body text containing no @c directive also creates an unnamed section. The @others directive acts like a reference to unnamed sections; this directive drastically reduces the need for named sections. We often describe nodes by the directives they contain.  @others nodes contain an @others directive, and so forth. 

Leo generates derived files from @file trees, trees whose root node has an headline starting with
@file <filename>. Leo generates a derived file, starting from the body text of the @file node, by replacing all section references by the text of their definitions. This is a recursive process; section definition may contain other section references. Outlines constrain the scope of definitions; all sections must be defined in a descendent of the node containing the reference.

Outlines organize programs

Let's look at typical ways of representing programs using Leo's outlines. We adopt the following notation to discuss outline structure. Lines starting with + denote a node with body text and lines starting with - denote a node without body text. All other lines denote body text associated with the preceding headline. Indentation indicates outline structure; child nodes are indented from their parents. Using this notation, a we would typically organize an outline as follows:

+ @file f.c
<< constants >>
<< declarations >>
@others
	+ << constants >>
	the constants
	+ << declarations >>
	the declarations
	+ function one
	function one
	+ function two
	function two
	...

The @file node generates the file f.c. The body text of the @file node is simply:

<< constants >>
<< declarations >>
@others

This body text ensures that the expansions of << constants >> and << declarations >> precede the expansions of all unnamed sections. It is good style to name those sections that must appear in a particular place in the derived file. All unnamed sections are placed in the derived file where the @others directive appears. Unnamed sections appear in the derived file the order in which they appear in the outline.

The children of the @file node contain the definitions of all sections, both named and unnamed. Unnamed sections usually contain functions or method. It is bad style for the meaning of a derived file to depend on the order of unnamed sections in the outline.

One could define a Python class as follows:

+ @file classX.py
<< imports for classX >>
class classX:
	@others
	+ << imports for classX >>
	+ method1
	+ method2
	...

The body text of the @file node is just:

<< imports for classX >>
class classX:
	@others

Indentation is significant in languages like Python. When Leo expands a section reference (or an @others directive), Leo adds the leading whitespace of the line containing the section reference to all lines of the reference's expansion. The text of body text need not be indented beyond its natural indentation.

When two classes appear in the same file, a single @others directive does not suffice. However, no node may contain more than one @others directive.  To get around this limitation we can organize the outline as follows:

+ @file mainClass.py
<<mainClass imports >>
<<class mainClass>>
<<class helperClass>>
	+ <<mainClass imports>>
	+ <<class mainClass>>
	class mainClass:
        	@others
		+ method1
    		+ method2
    		...
    	+ <<class helperClass>>
	class helperClass:
		@others
    		+ method1
    		+ method2
    		...

The body text of the @file node is:

<<mainClass imports>>
<<class mainClass>>
<<class helperClass>>

the body text of the <<class mainClass>> node is:

class mainClass:
	@others

and the body text of the <<class helperClass>> node is:

class helperClass:
	@others

The @others directive refers only to unnamed nodes in the descendents of the node containing the @others directive, so the two @others directives refer to disjoint sets of unnamed sections.

Organizing nodes (nodes with no body text) do not affect the derived file in any way. In particular, such nodes never change indentation of text within derived files.  Organizing nodes are often useful. For example,

+ @file classX.py
class classX:
	@others
	- xtors
		+ __init__
		+ __del__
	- getters
		+ getter1
		+ getter2
	- setters
		+ setter1
		...

The xtors, getters and setters nodes are organizing nodes. They exist merely to make the outline more easy to understand.  They do not affect the text of the derived file in any way.

Clones and tasks

Any part of an outline may be cloned. A clone is a copy of a tree that changes whenever any part of the original tree changes. For example, adding a node to a tree adds the same node to all cloned trees as well.

We can use clones to represent tasks with a project. We create an ordinary headline to represent the task and we label the headline with the name of the task. Let us call such a headline a task headline. Then, throughout the entire outline, we clone all headlines (sections) that pertain to the task and move the new clones as sub-headlines of the task headline. In effect, the task headline becomes a separate view of the project. The task headline is a natural place to place notes about the task, for example, design documents, test data and logs, etc. The task view remains up-to-date: it will change when any of its cloned headlines changes, and conversely, changes to clones under the task outline are propagated throughout the outline. Moreover, we can make changes in the task view and rather than throughout an outline.

Conclusions

Neither outlines nor sections nor clones are new. Outlines are widespread in browsers. Leo borrows the notion of section from so-called literate programming languages like noweb and CWEB, and Leo borrows clones from the MORE outliner.  However, the combination of outlines, sections and clones is unique. Leo's outlines are a superb way to organize projects, files, classes, methods and sections.

Leo uses outline structure in several ways. The programmer may name a part of the tree and refer to that tree by name in source code. The meaning of the @c and @others directives depend on their position within the outline, as does the scope of section definitions. @file trees represent derived files. Many of Leo's commands also understand outline structure; they act on individual nodes and their descendents. For example, one may limit a Find or Change operation to a specified part of an outline. Clones can create multiple views of projects and tasks within a single outline. Outlines naturally contain all kinds project information, including design documents, user documentation, programming logs, task notes, test suites and scripts, etc.

Leo is more flexible than typical class browsers. Most browsers create outlines by parsing program files. The position of classes and methods within the file completely determines what the browser shows. Leo allows you to reorganize outlines freely by adding, deleting, moving and cloning nodes. You can organize a project as you see fit. Unlike most browsers, Leo has a memory. Leo embeds outline structure into derived files using special comment lines called sentinels. In effect, derived files are simultaneously outlines as well as flat text files. Moreover, Leo opens an outline as it was when you last used it, restoring the selected node, the top visible node, and the expansion state of all nodes. After using Leo, most browsers seem feeble-minded.

This article has discussed only a few of Leo's capabilities. See http://personalpages.tds.net/~edream/front.html for full details. Leo is Open Software. Full source code is available. Leo runs on any platform that supports recent versions of Python and Tk/tcl.

Post Script. Leo clarifies the theory and practice of so-called literate programming languages like noweb and CWEB. A full discussion of this topic is beyond the scope of this article. To state only the conclusions, Leo shows that sections are the heart of literate programming, especially when organized by outlines. There has been lengthy debate within the literate programming community about the role of narrative comments and typeset listing in literate programming. Leo shows that narrative comments and text formatting actually have little expressive power. No program listing--regardless of excellent comments, copious hyperlinks or beautiful typesetting--has the slightest chance of showing a program as clearly as a Leo outline.  For a full discussion of this topic, see: http://personalpages.tds.net/~edream/design.html

Edward K. Ream
May 10, 2002