<?xml version="1.0" encoding="UTF-8"?>
<leo_file>
<leo_header file_format="2" tnodes="0" max_tnode_index="11731" clone_windows="0"/>
<globals body_outline_ratio="0.452928870293">
	<global_window_position top="12" left="284" height="860" width="988"/>
	<global_log_window_position top="0" left="0" height="0" width="0"/>
</globals>
<preferences>
</preferences>
<find_panel_settings>
	<find_string></find_string>
	<change_string></change_string>
</find_panel_settings>
<vnodes>
<v t="edream.110203163054"><vh>Short summary</vh></v>
<v t="edream.110203163054.1"><vh>About Leo's panes and icons (for newbies)</vh>
<v t="edream.110203163054.2"><vh>This node contains text</vh></v>
<v t="edream.110203163054.3" a="M"><vh>This headline is marked</vh></v>
<v t="edream.110203163054.4"><vh>This is a cloned headline</vh></v>
<v t="edream.110203163054.4"><vh>This is a cloned headline</vh></v>
<v t="edream.110203163054.5"><vh>This node contains no text</vh></v>
</v>
<v t="edream.110203163054.6"><vh>Please use SourceForge to ask questions and make comments</vh></v>
<v t="edream.110203163054.7"><vh>Acknowledgements</vh></v>
<v t="edream.110203163054.8"><vh>What people are saying about Leo</vh>
<v t="edream.110203163054.15"><vh> Open Software award nominations</vh></v>
<v t="edream.110203163054.14"><vh> Speed Ream's slashdot article (Why Leo is interesting)</vh></v>
<v t="edream.110203163054.16"><vh>Alex Abacus</vh></v>
<v t="edream.110203163054.13"><vh>Annonymous</vh></v>
<v t="edream.110203163054.28"><vh>Austin King</vh></v>
<v t="edream.110203163054.27"><vh>Bob Hustead</vh></v>
<v t="edream.110203163054.41"><vh>Brian Takita</vh></v>
<v t="edream.110203163054.19"><vh>Bruce M. Bolden</vh></v>
<v t="edream.110203163054.37"><vh>Bruce Rafnel</vh></v>
<v t="edream.110203163054.44"><vh>Dan Winkler 1</vh></v>
<v t="edream.110203163054.45"><vh>Dan Winkler 2</vh></v>
<v t="edream.110203163054.25"><vh>Dave Hein</vh></v>
<v t="edream.110203163054.33"><vh>David McNab</vh></v>
<v t="edream.110203163054.22"><vh>F. Geiger</vh></v>
<v t="ekr.20040828084113"><vh>Ian Mulvany</vh></v>
<v t="edream.110203163054.43"><vh>Jim Vickroy</vh></v>
<v t="edream.110203163054.34"><vh>Joe Orr</vh></v>
<v t="edream.110203163054.35"><vh>Joe Orr 2</vh></v>
<v t="edream.121503192354.1"><vh>John Benson</vh></v>
<v t="edream.110203163054.40"><vh>John Sequeira</vh></v>
<v t="edream.110203163054.42"><vh>Kent Tenney</vh></v>
<v t="edream.110203163054.21"><vh>Korakot Chaovavanich </vh></v>
<v t="edream.110203163054.24"><vh>Lyn Adams Headley</vh></v>
<v t="edream.110203163054.32"><vh>Marcus A. Martin</vh></v>
<v t="edream.110203163054.36" a="M"><vh>Marshall Parsons</vh></v>
<v t="edream.110203163054.31"><vh>Michael Manti</vh></v>
<v t="edream.110203163054.29"><vh>Nicola Larosa</vh></v>
<v t="edream.110203163054.9" a="M"><vh>Quotes of the Month</vh>
<v t="ekr.20040129074732"><vh>Anon</vh></v>
<v t="ekr.20040118085921"><vh>Tarvin Rhodes</vh></v>
<v t="ekr.20031219090156"><vh>Anon</vh></v>
<v t="edream.120703081642"><vh>Anon</vh></v>
<v t="edream.120503073304"><vh>From Michael Dawson</vh></v>
<v t="edream.110203163054.10"><vh>From David Nichols</vh></v>
<v t="edream.110203163054.11"><vh>From William A. Stapp</vh></v>
<v t="edream.110203163054.12"><vh>From Dan Winkler</vh></v>
</v>
<v t="edream.110203163054.38"><vh>Rich Reis</vh></v>
<v t="edream.110203163054.20"><vh>Serge Brisson</vh></v>
<v t="edream.110203163054.18"><vh>Shakeeb Alireza</vh></v>
<v t="edream.110203163054.17"><vh>Steve Allen</vh></v>
<v t="edream.110203163054.39"><vh>Steven P. Schaefer</vh></v>
<v t="edream.110203163054.30"><vh>Tom Lee</vh></v>
<v t="edream.110203163054.26"><vh>Travers A. Hough</vh></v>
<v t="edream.110203163054.23"><vh>Zak Greant</vh></v>
</v>
<v t="edream.110203163054.46" a="E"><vh>Release Notes</vh>
<v t="edream.110203163054.47"><vh>Warnings</vh></v>
<v t="edream.110203163054.48"><vh>Installation notes</vh>
<v t="edream.110203163054.49"><vh>System requirements</vh></v>
<v t="edream.110203163054.50"><vh>How to install leo.py on Linux</vh></v>
<v t="edream.110203163054.51"><vh>How to install leo.py on Windows</vh></v>
<v t="ekr.20040219100738"><vh>How to install Leo on MacOS Panther (10.3)</vh></v>
<v t="edream.110203163054.59"><vh>How to install the Borland version of Leo on Windows</vh></v>
<v t="edream.110203163054.60"><vh>How to associate leo.py with .leo files on Windows</vh></v>
<v t="edream.110203163054.61"><vh>Putting the Leo icon in Leo windows</vh></v>
<v t="edream.110203163054.62"><vh>Quick start</vh></v>
</v>
<v t="edream.110203163054.63" a="E"><vh>Latest versions</vh>
<v t="ekr.20040922074200" a="ETV"><vh>4.2 final</vh></v>
</v>
<v t="edream.110203163054.117"><vh>leo.py versions</vh>
<v t="ekr.20040922074200"><vh>4.2 final</vh></v>
<v t="ekr.20040914103359"><vh>4.2 rc1</vh>
<v t="ekr.20040914103743.1"><vh>Added new features</vh>
<v t="ekr.20040914103359.137"><vh>Added c.frame.openDirectory to sys.path when executing scripts</vh></v>
<v t="ekr.20040914103359.37"><vh>Added expanded_click_area option to disable left click logic in outline pane</vh></v>
<v t="ekr.20040914103359.2"><vh>Restored the "iconclick1/2" hooks</vh></v>
<v t="ekr.20040914103359.19"><vh>(Allow longer headlines for to support long url's)</vh>
<v t="ekr.20040914103359.20"><vh>Report</vh></v>
<v t="ekr.20040914103359.21"><vh>idle_head_key</vh>
<v t="ekr.20040914103359.22"><vh>&lt;&lt; set head to vnode text &gt;&gt;</vh></v>
<v t="ekr.20040914103359.23"><vh>&lt;&lt; set the widget text to head &gt;&gt;</vh></v>
<v t="ekr.20040914103359.24"><vh>&lt;&lt; set s to the widget text &gt;&gt;</vh></v>
<v t="ekr.20040914103359.25"><vh>&lt;&lt; update p &gt;&gt;</vh></v>
<v t="ekr.20040914103359.26"><vh>&lt;&lt; reconfigure p and all nodes joined to p &gt;&gt;</vh></v>
<v t="ekr.20040914103359.27"><vh>&lt;&lt; update the screen &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="ekr.20040914103743"><vh>Fixed bugs</vh>
<v t="ekr.20040914103359.47"><vh>Disabled perfect import</vh></v>
<v t="ekr.20040914103359.127"><vh>Fixed bugs in Tangle/Untangle</vh></v>
<v t="ekr.20040914103359.12"><vh>Fixed Import Derived Files command</vh></v>
<v t="ekr.20040914103359.15"><vh>Fixed parsing of minimal &lt;preferences&gt; tag</vh></v>
<v t="ekr.20040914103359.7"><vh>Fixed problem with tabs on MacOs</vh></v>
<v t="ekr.20040914103359.28"><vh>Fixed read errors with @language html</vh></v>
<v t="ekr.20040914103359.4"><vh>Made sure a proper message is given with invalid versions of Python</vh></v>
<v t="ekr.20040914103359.110"><vh>Removed failed assert from colorizer</vh></v>
<v t="ekr.20040914103359.31"><vh>Removed spurious "Warning: updating changed text" messages</vh></v>
<v t="ekr.20040914103359.129"><vh>Shifted all Alt-shortcuts to Ctrl shortcuts on the Mac</vh></v>
</v>
</v>
<v t="ekr.20040713110718"><vh>4.2 beta 3</vh>
<v t="ekr.20040804165258.1"><vh>Bug fixes</vh>
<v t="ekr.20040804164600.16"><vh>Leo gives the user a chance to save read-only files</vh></v>
<v t="ekr.20040804164600.36"><vh>Fixed some unit-test bugs</vh></v>
<v t="ekr.20040804164600.56"><vh>Added 3 .cascading style sheets to the distribution list</vh></v>
<v t="ekr.20040804164600.98"><vh>Fixed some bugs in g.importFromPath</vh></v>
<v t="ekr.20040804164600.102"><vh>Fixed major bug in write logic</vh></v>
<v t="ekr.20040804164600.265"><vh>Fixed bug in p.isAncestorOf</vh></v>
<v t="ekr.20040804164600.275"><vh>Leo now writes only the currently selected tree when pasting to the clipboard</vh></v>
<v t="ekr.20040804164600.377"><vh>Fixed performance bug when reading .leo files</vh></v>
<v t="ekr.20040804170846"><vh>Leo now reports problems with bad directories more clearly</vh></v>
<v t="ekr.20040804164600.394"><vh>Leo reads collapsed xml tags properly in .leo files</vh></v>
<v t="ekr.20040804164600.406"><vh>Leo makes brings the confirm save box to the front</vh></v>
<v t="ekr.20040804164600.419"><vh>Improved how es_exception gets line number of errors</vh></v>
<v t="ekr.20040804164600.421"><vh>Fixed major bug: changing headline now marks subnodes dirty</vh></v>
<v t="ekr.20040804164600.470"><vh>Leo now gives update warning only once per derived file</vh></v>
<v t="ekr.20040804164600.471"><vh>Leo updates tnodeLists properly in all situations</vh></v>
<v t="ekr.20040804164600.515"><vh>Fixed several leaks of positions</vh></v>
<v t="ekr.20040804171818"><vh>Fixed all unit tests so they work with both Python 2.2 and Python 2.3</vh></v>
</v>
<v t="ekr.20040804165258.2"><vh>Features</vh>
<v t="ekr.20040804172113"><vh>@test and @suite greatly aid unit testing</vh></v>
<v t="ekr.20040804172113.1"><vh>New scripts in test.leo make it very easy to use the gc, profile and timeit modules</vh></v>
<v t="ekr.20040804165258.3"><vh>Import dialogs allow multiple selections</vh></v>
<v t="ekr.20040804165258.4"><vh>New Check menu and commands</vh></v>
<v t="ekr.20040804170531"><vh>Perfect Import feature automatically corrects imported files</vh></v>
<v t="ekr.20040804170657"><vh>Improved performance of outline pane</vh></v>
<v t="ekr.20040804164600.424"><vh>The Go To Line Number command ignores all @all nodes</vh></v>
</v>
</v>
<v t="EKR.20040628095213"><vh>4.2 beta 1 &amp; beta 2</vh>
<v t="EKR.20040628095213.311"><vh>New coding conventions</vh></v>
<v t="EKR.20040524104904.242"><vh>Extending the format of .leo files</vh></v>
<v t="ekr.20040705111716"><vh>in 4.2 b2</vh>
<v t="ekr.20040705111716.1"><vh>Savedmarks and expantion state in &lt;v&gt; elements for @thin nodes</vh></v>
<v t="ekr.20040705111716.45"><vh>Marked all related @thin nodes dirty when a node changesd</vh></v>
<v t="ekr.20040705111716.126"><vh>Fixed bug when reading  4.1 files with topology errors</vh></v>
<v t="ekr.20040705150130"><vh>Leo passes all important pychecker tests</vh></v>
</v>
<v t="ekr.20040705112148"><vh>in 4.2 b1</vh>
<v t="EKR.20040628095213.513"><vh>Changed *nix install script</vh></v>
<v t="EKR.20040628100535"><vh>Fixed bugs</vh>
<v t="EKR.20040628095213.3"><vh>Made "end1" and "ilde"events work again</vh></v>
<v t="EKR.20040628095213.23"><vh>Put drawing hooks back in</vh></v>
<v t="EKR.20040628095213.56"><vh>Fixed syntax colouring Bug in html mode</vh></v>
<v t="EKR.20040628095213.60"><vh>Colorizing fixes</vh></v>
<v t="EKR.20040628095213.113"><vh>Fixed Select All bug</vh></v>
<v t="EKR.20040628095213.121"><vh>Fixed bugs in @tab_width: support backspace with negative tab width</vh></v>
<v t="EKR.20040628095213.143"><vh>Fixed bugs in Remove Sentinel command</vh></v>
<v t="EKR.20040628095213.160"><vh>Eliminated spurious error messages in Import Derived File command</vh></v>
<v t="EKR.20040628095213.192"><vh>Removed gnx in headlines when importing thin derived files</vh></v>
<v t="EKR.20040628095213.202"><vh>Fixed bugs reading 4.1 files</vh></v>
<v t="EKR.20040628095213.213"><vh>Fixed Open With bug</vh></v>
<v t="EKR.20040628095213.225"><vh>Fixed Go To Line Number command</vh></v>
<v t="EKR.20040628095213.246"><vh>Fixed crash when importing Borland wstring.cpp</vh></v>
<v t="EKR.20040628095213.279"><vh>Fixed bug in insertBodyTime</vh></v>
<v t="EKR.20040628095213.297"><vh>Fixed bug when pasting large text into headlines</vh></v>
<v t="EKR.20040628095213.308"><vh>Fixed bug in delete command</vh></v>
<v t="EKR.20040628095213.312"><vh>Fixed oops: nullGui setIdleTimeHook</vh></v>
<v t="EKR.20040628095213.324"><vh>Fixed problems with trailing newlines and spurious changed bit</vh></v>
<v t="EKR.20040628095213.346"><vh>Fixed headline key handling</vh></v>
<v t="EKR.20040628095213.348"><vh>Fixed Problems executing script</vh></v>
<v t="EKR.20040628095213.354"><vh>Fixed problem with PHP and @last</vh></v>
<v t="EKR.20040628095213.366"><vh>Fixed bug when writing unknownAttributes</vh></v>
<v t="EKR.20040628095213.368"><vh>Fixed bugs opening a second file</vh></v>
<v t="EKR.20040628095213.404"><vh>Fixed bug: @last silently failed when extra lines exist</vh></v>
<v t="EKR.20040628095213.407"><vh>Fixed hang when dragging from one clone copy to another</vh></v>
<v t="EKR.20040628095213.412"><vh>Fixed crash in Write Missing</vh></v>
<v t="EKR.20040628095213.442"><vh>Fixed bug in getScript</vh></v>
<v t="EKR.20040628095213.444"><vh>Fixed problems with @all</vh></v>
<v t="EKR.20040628095213.499"><vh>Fixed double print in Execute Script command</vh></v>
<v t="EKR.20040628095213.512"><vh>Fixed bug reading leo.nsi</vh></v>
</v>
<v t="EKR.20040628100535.1"><vh>Added new features</vh>
<v t="EKR.20040628095213.52"><vh>Allowed &lt;/leo_header&gt; tag</vh></v>
<v t="EKR.20040628095213.109"><vh>Replaced the word "Leo" with Leo icon in Find/Compare/Prefs windows</vh></v>
<v t="EKR.20040628095213.110"><vh>Improved Import command slightly</vh></v>
<v t="EKR.20040628095213.197"><vh>Added 3 files to distribution lists</vh></v>
<v t="EKR.20040628095213.198"><vh>Supported @tabwidth in indent/dedent</vh></v>
<v t="EKR.20040628095213.264"><vh>Import now creates absolute path</vh></v>
<v t="EKR.20040628095213.269"><vh>Created @killcolor directive</vh></v>
<v t="EKR.20040628095213.282"><vh>Added Paste Retaining Clones command</vh></v>
<v t="EKR.20040628095213.314"><vh>Added readLineGenerator &amp; readLineClass to leoGlobals</vh></v>
<v t="EKR.20040628095213.334"><vh>Much better error handling in executeScript</vh></v>
<v t="EKR.20040628095213.377"><vh>Recovered nodes when reading .leo files containing topology errors</vh></v>
<v t="EKR.20040628095213.391"><vh>Generalized write-to-string logic</vh></v>
<v t="EKR.20040628095213.408"><vh>Added case_sensitiveLanguage to colorizer</vh></v>
<v t="EKR.20040628095213.425"><vh>Write entire @thin tree on write errors</vh></v>
<v t="EKR.20040628095213.485"><vh>Handled inner @language and @comment properly</vh></v>
<v t="EKR.20040628095213.490"><vh>Better reporting of body text conflicts</vh></v>
<v t="EKR.20040628095213.493"><vh>Improved error handling for unknownAttributes</vh></v>
<v t="EKR.20040628095213.501"><vh>Read and write all t.unknownAttributes in top vnode of an @thin tree</vh></v>
</v>
</v>
</v>
<v t="EKR.20040601084317"><vh>4.2 a3</vh>
<v t="EKR.20040601084317.2"><vh>Bug fixes</vh>
<v t="EKR.20040601101118"><vh>Fixed copy/paste operations involving @thin trees</vh></v>
<v t="EKR.20040601101430"><vh>Fixed Change Headline command</vh></v>
<v t="EKR.20040601084317.99"><vh>Eliminated spurious "Not written x.tmp" message after write errors</vh></v>
<v t="EKR.20040601084317.142"><vh>Fixed problems saving unknownAttribute field</vh></v>
<v t="EKR.20040601102115"><vh>Fixed unicode problem in the Dump Outline command</vh></v>
</v>
<v t="EKR.20040601101227"><vh>New Features</vh>
<v t="EKR.20040601101227.1"><vh>Leo ignores all directives in @all trees</vh></v>
<v t="EKR.20040601101430.1"><vh>@+-middle sentinels allow sections to be defined in grandchildren</vh></v>
<v t="EKR.20040601101510"><vh>@clone sentinel allows siblings to be cloned</vh></v>
<v t="EKR.20040601101547"><vh>Created @thin, @nosent, @noref and @asis abbreviations</vh>
<v t="EKR.20040524104904.92"><vh>Appendix 1 to Chapter 4: Using @asis, @noref and @nosent trees</vh></v>
</v>
<v t="EKR.20040601084317.102"><vh>Made undo extensible</vh></v>
<v t="EKR.20040601102703"><vh>Started work on simple new undo scheme</vh></v>
<v t="EKR.20040601084317.161"><vh>Created new c, p, v iterators</vh></v>
</v>
<v t="EKR.20040601102808"><vh>Known bugs</vh></v>
</v>
<v t="EKR.20040518070558"><vh>4.2 a2</vh>
<v t="EKR.20040518070940.5"><vh>Implemented @file-thin</vh></v>
<v t="EKR.20040518070824"><vh>Fixed bugs</vh>
<v t="EKR.20040518071415"><vh>Fixed clone bug that caused parts of outlines to disappear</vh></v>
<v t="EKR.20040518070940.156"><vh>Fixed long-standing problem with the outline-only command</vh></v>
<v t="EKR.20040518070824.1"><vh>Made sure file indices are always assigned when writing files.</vh></v>
<v t="EKR.20040518070940"><vh>Fixed problems with missing tnodeList with @file-noref</vh></v>
<v t="EKR.20040518070940.164"><vh>Added t.writeBit</vh></v>
</v>
<v t="edream.110203163054.890"><vh>Chapter 7: Scripting Leo with Python</vh>
<v t="edream.110203163054.891"><vh>Overview</vh></v>
<v t="edream.110203163054.892"><vh>Basic scripts</vh>
<v t="ekr.20040403051340"><vh>Writing to log window</vh></v>
<v t="edream.110203163054.893"><vh>Getting commanders and frames</vh></v>
<v t="edream.110203163054.894"><vh>Redirecting output from scripts</vh></v>
<v t="edream.110203163054.895"><vh>Getting the headline and body text of the presently selected node</vh></v>
<v t="edream.110203163054.896"><vh>Setting the headline and body text of the presently selected node</vh></v>
<v t="edream.110203163054.897"><vh>Traversing all nodes of an outline</vh></v>
<v t="ekr.20040403103655"><vh>Iterators</vh>
<v t="ekr.20040403121641.1"><vh>allNodes_iter</vh>
<v t="ekr.20040403123631.1"><vh>Example 1</vh></v>
<v t="ekr.20040403123631.2"><vh>Example 2</vh></v>
</v>
<v t="ekr.20040403121641.7"><vh>children_iter</vh></v>
<v t="ekr.20040403121641.10"><vh>parents_iter</vh></v>
<v t="ekr.20040403121641.13"><vh>siblings_iter</vh></v>
<v t="ekr.20040403121641.4"><vh>subtree_iter</vh></v>
</v>
<v t="edream.110203163054.898"><vh>Updating the screen</vh></v>
<v t="edream.110203163054.899"><vh>Invoking commands from scripts</vh></v>
<v t="edream.110203163054.900"><vh>Getting preferences</vh></v>
<v t="edream.110203163054.901"><vh>Setting preferences</vh></v>
<v t="edream.110203163054.902"><vh>Functions for finding and changing text from scripts</vh>
<v t="edream.110203163054.903"><vh>Example 1: the findAll function</vh></v>
<v t="edream.110203163054.904"><vh>Example 2: the reFindAll function</vh></v>
</v>
<v t="edream.112303173638"><vh>Running Leo in batch mode</vh></v>
<v t="edream.110203163054.909"><vh>Functions defined in leoGlobals.py</vh></v>
</v>
<v t="edream.110203163054.905"><vh>Summary of the vnode and position classes</vh>
<v t="ekr.20040403103655"><vh>Iterators</vh>
<v t="ekr.20040403121641.1"><vh>allNodes_iter</vh>
<v t="ekr.20040403123631.1"><vh>Example 1</vh></v>
<v t="ekr.20040403123631.2"><vh>Example 2</vh></v>
</v>
<v t="ekr.20040403121641.7"><vh>children_iter</vh></v>
<v t="ekr.20040403121641.10"><vh>parents_iter</vh></v>
<v t="ekr.20040403121641.13"><vh>siblings_iter</vh></v>
<v t="ekr.20040403121641.4"><vh>subtree_iter</vh></v>
</v>
<v t="edream.110203163054.906"><vh>Getters</vh></v>
<v t="edream.110203163054.907"><vh>Setters</vh></v>
</v>
</v>
<v t="EKR.20040518075457"><vh>Dangers of @file-thin</vh></v>
</v>
<v t="ekr.20040216151748"><vh>4.1 final</vh>
<v t="ekr.20040217085036"><vh>Added several new plugins</vh></v>
<v t="ekr.20040216152948"><vh>Added Toggle Angle Brackets command</vh></v>
<v t="ekr.20040216153725"><vh>Changed Undo/Redo messages</vh></v>
<v t="ekr.20040217075627"><vh>Fixed clone bug when pasting nodes</vh></v>
<v t="ekr.20040217085036.1"><vh>Investigated encoding problem: it's a Python 2.3 bug</vh></v>
</v>
<v t="ekr.20040131040356"><vh>4.1 rc4</vh>
<v t="ekr.20040201114855"><vh>New plugins in 4.1 rc4</vh>
<v t="ekr.20040201114855.42"><vh>mod_http.py plugin: Bernhard Mulder</vh></v>
<v t="ekr.20040201114855.91"><vh>newButtons.py plugin: Paul Paterson</vh></v>
<v t="ekr.20040201114855.29"><vh>nodenavigator.py plugin: Paul Paterson</vh></v>
<v t="ekr.20040201114855.36"><vh>rowcol.py: EKR</vh></v>
<v t="ekr.20040201114855.3"><vh>rst2.py plugin: Steve Zatz</vh></v>
<v t="ekr.20040201114855.13"><vh>searchbox.py plugin: Paul Paterson</vh></v>
<v t="ekr.20040201120903"><vh>status_line.py plugin: EKR</vh></v>
</v>
<v t="ekr.20040131041015"><vh>New features in 4.1 rc4</vh>
<v t="ekr.20040131040544.10"><vh>Leo no longer automatically draws the status area</vh></v>
<v t="ekr.20040131040544.21"><vh>Esc and enter key now work in the find panel</vh></v>
<v t="ekr.20040131040544.55"><vh>Improved message for orphan nodes</vh></v>
<v t="ekr.20040131040544.178"><vh>Eliminated marking nodes dirty unnecessarily</vh></v>
<v t="ekr.20040131040544.222"><vh>Execute Script command now ends all nodes with a newline</vh></v>
<v t="ekr.20040131040544.2"><vh>Added message when plugins are disabled</vh></v>
<v t="ekr.20040201061329"><vh>Created status_line.py plugin</vh></v>
<v t="ekr.20040201114855.105"><vh>Simplified operation of script-find/change &amp; improved documentation</vh>
<v t="edream.110603190322.6"><vh> Script Find and Script Change</vh>
<v t="edream.111803060152.1"><vh>How it works</vh></v>
<v t="ekr.20040201113232"><vh>Using the initScriptFind script</vh></v>
<v t="edream.111803060152.2"><vh>Ideas for using scripts</vh></v>
</v>
</v>
<v t="ekr.20040201114855.106"><vh>Added done message to Mark Changed commands</vh></v>
</v>
<v t="ekr.20040131040356.1"><vh>Bugs fixed in 4.1 rc4</vh>
<v t="ekr.20040131044727"><vh>Fixed several bugs when writing derived files</vh></v>
<v t="ekr.20040131040754"><vh>Fixed several crashers</vh></v>
<v t="ekr.20040131040544.5"><vh>Fixed "bad leo file" when reading some 3.x .leo files</vh></v>
<v t="ekr.20040131040544.18"><vh>Fixed huge performance bug in cut/copy node commands</vh></v>
<v t="ekr.20040131040544.32"><vh>Leo now properly re-enables drawing after exceptions</vh></v>
<v t="ekr.20040201114855.107"><vh>Fixed major bug in tkFind.init</vh></v>
<v t="ekr.20040131040544.73"><vh>Fixed bug in Move Up command</vh></v>
<v t="ekr.20040131040544.81"><vh>Fixed bug in Import Derived File</vh></v>
<v t="ekr.20040131040544.146"><vh>Fixed bugs related to saving read-only files</vh></v>
<v t="ekr.20040131040544.169"><vh>Fixed bug in Import Python Window command when using Python 2.2</vh></v>
<v t="ekr.20040131040544.228"><vh>Fixed bugs in Convert All BlanksTabs commands</vh></v>
<v t="ekr.20040131040544.258"><vh>Fixed crashes in open_shell.py plugin</vh></v>
<v t="ekr.20040131044136"><vh>Fixed several bugs involving cut &amp; paste</vh></v>
<v t="ekr.20040131040544.227"><vh>Fixed whitespace problem in leoTkinterGui.py</vh></v>
<v t="ekr.20040131100557"><vh>Fixed glitches when inserting node in hoisted outline</vh></v>
<v t="ekr.20040203084228"><vh>Fixed bugs in search command</vh></v>
</v>
<v t="ekr.20040131040356.2"><vh>Bug fixed in previous 4.1 releases</vh></v>
<v t="ekr.20040131040356.3"><vh>New code-level features</vh></v>
<v t="ekr.20040131040356.4"><vh>New configuration settings</vh></v>
<v t="ekr.20040131040356.5"><vh>New features</vh></v>
</v>
<v t="edream.121403160546"><vh>4.1 rc3</vh>
<v t="edream.121403165221"><vh>Bugs fixed in this release</vh></v>
<v t="edream.121403161017"><vh>Bug fixed in previous 4.1 releases</vh></v>
<v t="edream.121403161017.1"><vh>New code-level features</vh></v>
<v t="edream.121403161017.2"><vh>New configuration settings</vh></v>
<v t="edream.121403161340"><vh>New features</vh></v>
</v>
<v t="edream.110603185805"><vh>4.1 beta 5</vh>
<v t="edream.120403174147"><vh>Changes made in 4.1 beta 5</vh>
<v t="edream.120403180443"><vh>New and improved features</vh>
<v t="edream.120403174147.105"><vh>Honor outline/body pane ratio when opening files</vh></v>
<v t="edream.120403174147.112"><vh>Leo now adjusts newly opened windows so they fit on the screen</vh></v>
<v t="edream.120403174147.119"><vh>Tested support for Unicode file &amp; directory names</vh></v>
<v t="edream.120403174147.128"><vh>Added code so @url nodes may open .leo files</vh></v>
<v t="edream.120403174147.56"><vh>Fixed problems with @lineending platform</vh></v>
</v>
<v t="edream.120403174241"><vh>Bugs fixed</vh>
<v t="edream.120403174147.30"><vh>Fixed crasher in Apply Settings command</vh></v>
<v t="edream.120403174147.102"><vh>Fixed crasher in Toggle Angle Brackets command</vh></v>
<v t="edream.120403174147.109"><vh>Fixed crasher when setting Icon in Linux)</vh></v>
<v t="edream.120403174147.33"><vh>Fixed Find panel bug on the Mac</vh></v>
<v t="edream.120403174147.36"><vh>Fixed Import backslash-newline bug</vh></v>
<v t="edream.120403174147.61"><vh>Fixed Linux import problem</vh></v>
<v t="edream.120403174147.63"><vh>Fixed Recent files crasher</vh></v>
<v t="edream.120403174147.65"><vh>Fixed Replace Blanks command</vh></v>
<v t="edream.110603190322.8"><vh>Fixed Serious Undo Change All bugs</vh></v>
<v t="edream.120403174147.94"><vh>Fixed several long-standing bugs related to Extract commands</vh></v>
</v>
</v>
<v t="edream.120403180443.1"><vh>Changes made in earlier 4.1 betas</vh>
<v t="edream.110603190234.1"><vh>Code-level features</vh>
<v t="edream.110603190125.3"><vh>Regression tests started</vh></v>
<v t="edream.110603190125.4"><vh>Code reorganized to support other guis</vh></v>
<v t="edream.110303182253.39"><vh>Made app.forceShutdown work in "idle" hook</vh></v>
</v>
<v t="edream.110603190404"><vh>Fixed bugs</vh>
<v t="edream.110603190322.13"><vh>Fixed bug involving 0x1a characters in body text.</vh></v>
<v t="edream.110603190322.11"><vh>Fixed first node-only find bug</vh></v>
<v t="edream.110603190322.3"><vh>Fixed bug in idle_body_key</vh></v>
<v t="edream.111803060643"><vh>Fixed LaTeX syntax coloring bug</vh></v>
</v>
<v t="edream.110603192009"><vh>Improved format of .leo files</vh>
<v t="edream.110603190322.9"><vh>Leo now ignores unknown prefs and find prefs</vh></v>
<v t="edream.110603190322.10"><vh>Leo now writes node_only find prefs</vh></v>
<v t="edream.110603190125.1"><vh>.leo files are now cvs-friendly</vh></v>
</v>
<v t="edream.110603192009.1"><vh>New &amp; improved commands</vh>
<v t="edream.112303173638"><vh>Running Leo in batch mode</vh></v>
<v t="edream.110203163054.833"><vh>Executing Python scripts in body text</vh></v>
<v t="edream.110603190322.14"><vh>Added Check Outline command</vh></v>
<v t="edream.110603190322.15"><vh>Added Hoist/De-Hoist commands</vh></v>
<v t="edream.111803060152"><vh>Added script-based find/change commands</vh>
<v t="edream.110603190322.6"><vh> Script Find and Script Change</vh>
<v t="edream.111803060152.1"><vh>How it works</vh></v>
<v t="ekr.20040201113232"><vh>Using the initScriptFind script</vh></v>
<v t="edream.111803060152.2"><vh>Ideas for using scripts</vh></v>
</v>
</v>
<v t="edream.110303182253.3"><vh>Leo now does an auto-save only if files have actually been changed.</vh></v>
<v t="edream.111803062437"><vh>Shift commands now shift single line if no selection</vh></v>
</v>
<v t="edream.110303182719"><vh>New config settings</vh></v>
</v>
</v>
<v t="edream.110203163054.64"><vh>4.1 alpha 1</vh></v>
<v t="edream.110203163054.66"><vh>4.0.x</vh></v>
<v t="edream.110203163054.67"><vh>4.0 final</vh>
<v t="edream.110203163054.68"><vh>4.0 beta 4</vh></v>
<v t="edream.110203163054.69"><vh>4.0 beta 3</vh>
<v t="edream.110203163054.70"><vh>Fixed bugs</vh>
<v t="edream.110203163054.71"><vh>Fixed bug that caused some clones not to be marked as clones</vh></v>
<v t="edream.110203163054.72"><vh>Corrected problems with setting icons on Linux</vh></v>
<v t="edream.110203163054.73"><vh>Fixed crasher in sentinelName</vh></v>
<v t="edream.110203163054.74"><vh>Reenabled orphans &amp; ignored test in new write logic</vh></v>
</v>
<v t="edream.110203163054.75"><vh>New features</vh>
<v t="edream.110203163054.76"><vh>Added support for unknown tnode and vnode attributes</vh></v>
<v t="edream.110203163054.77"><vh>Added build number to signon</vh></v>
<v t="edream.110203163054.78"><vh>Added better error message in setDefaultIcon</vh></v>
</v>
</v>
<v t="edream.110203163054.79"><vh>4.0 beta 2</vh>
<v t="edream.110203163054.80"><vh>To-do for 4.0 final</vh></v>
<v t="edream.110203163054.81"><vh>Fixed Bugs</vh>
<v t="edream.110203163054.82"><vh>Added crucial defensive checks in v.headString() and v.bodySting()</vh></v>
<v t="edream.110203163054.83"><vh>Ensured newlines before all sentinels in @rawfile</vh></v>
<v t="edream.110203163054.84"><vh>Fixed bugs involving find params</vh></v>
<v t="edream.110203163054.85"><vh>Fixed Python Import bug</vh></v>
<v t="edream.110203163054.86"><vh>Fixed several more unicode bugs</vh></v>
<v t="edream.110203163054.87"><vh>Fixed crasher in Go To Outline command.</vh></v>
<v t="edream.110203163054.88"><vh>Fixed @rawfile write problem</vh></v>
</v>
<v t="edream.110203163054.89"><vh>Improved commands</vh>
<v t="edream.110203163054.90"><vh>Finished Import Derived File command and made it undoable</vh></v>
<v t="edream.110203163054.91"><vh>Moved Clear Recent Files menu item into Recent Files menu</vh></v>
<v t="edream.110203163054.92"><vh>Added better log message for Convert All Tabs/Blanks commands</vh></v>
<v t="edream.110203163054.93"><vh>Marked changed nodes &amp; make the @file node and the outline dirty.</vh></v>
<v t="edream.110203163054.94"><vh>Rewrote icon code so it doesn't use PIL or tkIcon in Python 2.3</vh></v>
<v t="edream.110203163054.95"><vh>Created leoGui base class for tkinterGui class</vh></v>
</v>
<v t="edream.110203163054.96"><vh>New and improved settings</vh>
<v t="edream.110203163054.97"><vh>Added support for two new settings affecting drags</vh></v>
<v t="edream.110203163054.98"><vh>changed default for config.write_old_format_derived_files</vh></v>
</v>
</v>
<v t="edream.110203163054.99"><vh>4.0 beta 1</vh>
<v t="edream.110203163054.100"><vh>4.0 Theory of operation</vh></v>
<v t="edream.110203163054.101"><vh>New commands &amp; options</vh>
<v t="edream.110203163054.102"><vh>New write_old_format_derived_files option</vh></v>
<v t="edream.110203163054.103"><vh>New Clear Recent Files command</vh></v>
<v t="edream.110203163054.104"><vh>New Import Derived File command</vh></v>
<v t="edream.110203163054.105"><vh>New Write 3.x/4.x Derived Files &amp; autosave</vh></v>
</v>
<v t="edream.110203163054.106"><vh>New plugins</vh></v>
<v t="edream.110203163054.107"><vh>New read logic and greatly inproved error recovery</vh>
<v t="edream.110203163054.108"><vh>Added test for unvisited nodes in read logic</vh></v>
<v t="edream.110203163054.109"><vh>Error recovery is _much_ better than before</vh></v>
</v>
<v t="edream.110203163054.110"><vh>Improvements &amp; bug fixes</vh>
<v t="edream.110203163054.111"><vh>Added horizontal scrollbar in body pane when @nowrap in effect</vh></v>
<v t="edream.110203163054.112"><vh>Added support for Python 2.3</vh></v>
<v t="edream.110203163054.113"><vh>Leo recycles window objects only if more than one window open</vh></v>
<v t="edream.110203163054.114"><vh>Removed "not undoable" message from Read @file Nodes command</vh></v>
<v t="edream.110203163054.115"><vh>Removed Open Python Window command</vh></v>
<v t="edream.110203163054.116"><vh>Simplified read and write code</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.118"><vh>3.x releases</vh>
<v t="edream.110203163054.119"><vh>3.12 final</vh>
<v t="edream.110203163054.120"><vh>Bug fixes (major)</vh>
<v t="edream.110203163054.121"><vh>Fixed major undo bug</vh></v>
<v t="edream.110203163054.122"><vh>Fixed huge performance bug when handling read errors</vh></v>
<v t="edream.110203163054.123"><vh>Fixed memory leaks: one minor, one huge</vh></v>
</v>
<v t="edream.110203163054.124"><vh>Bug fixes (minor)</vh>
<v t="edream.110203163054.125"><vh>Fixed bug affecting encoding in headlines</vh></v>
<v t="edream.110203163054.126"><vh>Fixed bug affecting log pane</vh></v>
<v t="edream.110203163054.127"><vh>Fixed bug importing files with upper case extensions</vh></v>
<v t="edream.110203163054.128"><vh>Fixed bug involving log messages during Open commands</vh></v>
<v t="edream.110203163054.129"><vh>Fixed bug that caused some log messages to disappear</vh></v>
<v t="edream.110203163054.130"><vh>Fixed bug that disabled double-clicking when when windows were first opened</vh></v>
<v t="edream.110203163054.131"><vh>Fixed bug that forced body_pane_wraps setting to 1</vh></v>
<v t="edream.110203163054.132"><vh>Fixed bug when deleting trailing newlines in the body pane</vh></v>
<v t="edream.110203163054.133"><vh>Fixed colorizer exception when undoing paste</vh></v>
<v t="edream.110203163054.134"><vh>Fixed Go To Line Number bug</vh></v>
<v t="edream.110203163054.135"><vh>Fixed line-break bug with @nosent files</vh></v>
<v t="edream.110203163054.136"><vh>Fixed new Open With problems</vh></v>
<v t="edream.110203163054.137"><vh>Fixed problems with Convert tabs to blanks preference panel setting</vh></v>
<v t="edream.110203163054.138"><vh>Fixed problems with the code that destroys Leo windows</vh></v>
<v t="edream.110203163054.139"><vh>Fixed recent bug in the Reformat Paragraph command</vh></v>
<v t="edream.110203163054.140"><vh>Fixed refresh problem after Read @file Node command</vh></v>
<v t="edream.110203163054.141"><vh>Fixed several problems with the Open With command</vh></v>
<v t="edream.110203163054.142"><vh>Fixed Sort bug</vh></v>
<v t="edream.110203163054.143"><vh>Leo now updates ow/col numbers when plugins not enabled</vh></v>
<v t="edream.110203163054.144"><vh>Made dragging nodes more robust</vh></v>
<v t="edream.110203163054.145"><vh>Removed improper clones from LeoPy.leo</vh></v>
<v t="edream.110203163054.146"><vh>Removed unused fractional widths from leoFind code</vh></v>
<v t="edream.110203163054.147"><vh>updateRecentFiles now handles Null filenames properly</vh></v>
</v>
<v t="edream.110203163054.148"><vh>Code improvements</vh>
<v t="edream.110203163054.149"><vh>New functions in leoGlobals.py</vh></v>
<v t="edream.110203163054.150"><vh>New scripts</vh></v>
<v t="edream.110203163054.151"><vh>Rewrote dialog code</vh></v>
<v t="edream.110203163054.152"><vh>Reorganized vnodes and tnodes</vh></v>
<v t="edream.110203163054.153"><vh>Simplified startup code</vh></v>
<v t="edream.110203163054.154"><vh>Replaced exec with getattr/setattr throughout the code</vh></v>
</v>
<v t="edream.110203163054.155"><vh>Features</vh>
<v t="edream.110203163054.156"><vh>Added @wrap and @nowrap directives</vh></v>
<v t="edream.110203163054.157"><vh>Added apply button to Font panel</vh></v>
<v t="edream.110203163054.158"><vh>Added Icon &amp; Status areas to Leo window</vh></v>
<v t="edream.110203163054.159"><vh>Added minimal support for Rebol and activescript languages</vh></v>
<v t="edream.110203163054.160"><vh>Added Write Dirty @file Nodes command</vh></v>
<v t="edream.110203163054.161"><vh>Changed OnIconDoubleClick to allow @url url comments</vh></v>
<v t="edream.110203163054.162"><vh>Hyperlinks are now enabled by default</vh></v>
<v t="edream.110203163054.163"><vh>Improved how headlines are highlighted</vh></v>
<v t="edream.110203163054.164"><vh>Improved startup logic so only one frame ever gets opened</vh></v>
<v t="edream.110203163054.165"><vh>Improved the reporting of characters that do not exist in the present encoding</vh></v>
<v t="edream.110203163054.166"><vh>Leo now correctly remembers the sizes of windows</vh></v>
<v t="edream.110203163054.167"><vh>Removed toggle &lt;&lt; &gt;&gt; command</vh></v>
<v t="edream.110203163054.168"><vh>Undo now restores cursor</vh></v>
<v t="edream.110203163054.169"><vh>Updated Marks window in Mark Find and Mark Changes commands</vh></v>
<v t="edream.110203163054.170"><vh>Use "file in directory" format for entries in Recent Files list</vh></v>
</v>
<v t="edream.110203163054.171"><vh>Hooks</vh>
<v t="edream.110203163054.172"><vh>About hooks</vh></v>
<v t="edream.110203163054.173"><vh>Added "clear-mark" and "set-mark" hooks</vh></v>
<v t="edream.110203163054.174"><vh>Added hooks to customize popup menus</vh></v>
<v t="edream.110203163054.175"><vh>Added new hooks so that plugins may extend popup menus </vh></v>
</v>
<v t="edream.110203163054.176"><vh>Plugins</vh>
<v t="edream.110203163054.177"><vh>Added add_directives.py plugin</vh></v>
<v t="edream.110203163054.178"><vh>Added color_markup.py plugin</vh></v>
<v t="edream.110203163054.179"><vh>Added nav_buttons.py plugin</vh></v>
<v t="edream.110203163054.180"><vh>Added plugins_menu.py plugin</vh></v>
<v t="edream.110203163054.181"><vh>Added scripts_menu.py plugin</vh></v>
<v t="edream.110203163054.182"><vh>Improved how Leo loads plugins</vh></v>
</v>
<v t="edream.110203163054.183"><vh>Reorganized Leo folder: big change to cvs</vh>
<v t="edream.110203163054.184"><vh>Added scripts for Linux</vh></v>
</v>
</v>
<v t="edream.110203163054.185"><vh>3.11.1</vh></v>
<v t="edream.110203163054.186"><vh>3.11</vh>
<v t="edream.110203163054.187"><vh>New in 3.11 final</vh>
<v t="edream.110203163054.188"><vh>Bug fixes</vh>
<v t="edream.110203163054.189"><vh>Added call to c.redraw() in fileCommands.readAtFileNodes</vh></v>
<v t="edream.110203163054.190"><vh>Added getpreferredencoding to leoGlobals.py</vh></v>
<v t="edream.110203163054.191"><vh>Eliminated caught exception in frame.setTabWidth</vh></v>
<v t="edream.110203163054.192"><vh>Fixed bug in skip_long</vh></v>
<v t="edream.110203163054.193"><vh>Fixed bug that prevented email line in About Leo from working</vh></v>
<v t="edream.110203163054.194"><vh>Fixed unicode bugs when Tangling and Untangling</vh></v>
<v t="edream.110203163054.195"><vh>Fixed various bugs reported by Pychecker</vh></v>
<v t="edream.110203163054.196"><vh>Removed all __del__ methods</vh></v>
</v>
<v t="edream.110203163054.197"><vh>New and improved features and commands</vh>
<v t="edream.110203163054.198"><vh>Added patch by Davide Salomoni to OnIconDoubleClick</vh></v>
<v t="edream.110203163054.199"><vh>@lineending directive specifies line endings</vh></v>
<v t="edream.110203163054.200"><vh>Added thin_at_file_trees &amp; load_derived_files_immediately options</vh></v>
</v>
</v>
<v t="edream.110203163054.201"><vh>** Leo now uses unicode internally</vh>
<v t="edream.110203163054.202"><vh>Added calls to toEncodedString before all calls to write</vh></v>
<v t="edream.110203163054.203"><vh>Check for valid encoding when setting app().tkEncoding</vh></v>
<v t="edream.110203163054.204"><vh>How Leo handles unicode</vh></v>
<v t="edream.110203163054.205"><vh>Unicode settings</vh></v>
<v t="edream.110203163054.206"><vh>Unicode theory of operation</vh></v>
<v t="edream.110203163054.207"><vh>Use app().tkEncoding when writing to log pane</vh></v>
</v>
<v t="edream.110203163054.208"><vh>** Improved hooks &amp; a new plugin architecture</vh>
<v t="edream.110203163054.209"><vh>New plugin architecture</vh>
<v t="edream.110203163054.210"><vh>@file plugins/mod_open_with.py</vh>
<v t="edream.110203163054.211"><vh>on_idle</vh>
<v t="edream.110203163054.212"><vh>&lt;&lt; update v's body text &gt;&gt;</vh>
<v t="edream.110203163054.213"><vh>&lt;&lt; set s to the new text &gt;&gt;</vh></v>
<v t="edream.110203163054.214"><vh>&lt;&lt; set conflict flag &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203163054.215"><vh>create_open_with_menu</vh>
<v t="edream.110203163054.216"><vh>&lt;&lt; create the Open With menu &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.217"><vh>Major reorganization of hooks</vh>
<v t="edream.110203163054.218"><vh>About hooks</vh></v>
</v>
<v t="edream.110203163054.219"><vh>Added several new plugins</vh></v>
<v t="edream.110203163054.220"><vh>Improved Open With plugin</vh></v>
<v t="edream.110203163054.221"><vh>Added logic to retain log output until a log exists</vh></v>
</v>
<v t="edream.110203163054.222"><vh>New configuration options &amp; plugins</vh>
<v t="edream.110203163054.223"><vh>Plugins</vh></v>
<v t="edream.110203163054.205"><vh>Unicode settings</vh></v>
<v t="edream.110203163054.224"><vh>Colors for Show Invisibibles command</vh></v>
<v t="edream.110203163054.225"><vh>look_for_control_drag_on_mouse_down option</vh></v>
<v t="edream.110203163054.226"><vh>body_insertion_cursor_color setting</vh></v>
<v t="edream.110203163054.227"><vh>time/date settings</vh></v>
</v>
<v t="edream.110203163054.228"><vh>New commands</vh>
<v t="edream.110203163054.229"><vh>Toggle Angle Brackets</vh></v>
<v t="edream.110203163054.230"><vh>Insert Body/Headline Time/Date</vh></v>
<v t="edream.110203163054.231"><vh>Go To First/last Node</vh></v>
<v t="edream.110203163054.232"><vh>Go To Parent</vh></v>
<v t="edream.110203163054.233"><vh>Go To Next/Previous Sibling</vh></v>
<v t="edream.110203163054.234"><vh>Write Missing @file Nodes</vh></v>
</v>
<v t="edream.110203163054.235"><vh>Improved commands</vh>
<v t="edream.110203163054.236"><vh>Added support for body/headline_gmt_time settings</vh></v>
<v t="edream.110203163054.237"><vh>Tangle now supports output_newline option</vh></v>
<v t="edream.110203163054.238"><vh>Major improvements to expand/contract commands</vh></v>
<v t="edream.110203163054.239"><vh>Leo now allows multiple writes of cloned nodes</vh></v>
<v t="edream.110203163054.240"><vh>The Sort Siblings command can now sort top-level nodes</vh></v>
<v t="edream.110203163054.241"><vh>Changed locks on customizeLeo.py</vh></v>
</v>
<v t="edream.110203163054.242"><vh>Other improvements</vh>
<v t="edream.110203163054.243"><vh>Allow color param when queuing messages to log pane</vh></v>
<v t="edream.110203163054.244"><vh>Improved scrolling when moving right</vh></v>
<v t="edream.110203163054.245"><vh>Put file name first in window title</vh></v>
<v t="edream.110203163054.246"><vh>Leo scrolls partially visible headlines into full view</vh></v>
<v t="edream.110203163054.247"><vh>Allowed @comment with @language plain</vh></v>
<v t="edream.110203163054.248"><vh>The Find button is now default button in the Find panel</vh></v>
<v t="edream.110203163054.249"><vh>Improved syntax coloring for html and xml</vh>
<v t="edream.110203163054.250"><vh>example of syntax coloring for html</vh></v>
</v>
<v t="edream.110203163054.251"><vh>Improved Prefs panel</vh></v>
<v t="edream.110203163054.252"><vh>Removed setup.py from distributed files</vh></v>
</v>
<v t="edream.110203163054.253"><vh>Bug fixes</vh>
<v t="edream.110203163054.254"><vh>Eliminated potential hang in Open With command</vh></v>
<v t="edream.110203163054.255"><vh>Fixed 2 line number bugs</vh></v>
<v t="edream.110203163054.256"><vh>Fixed bug involving nested comments in sentinel lines</vh></v>
<v t="edream.110203163054.257"><vh>Fixed bugs in promote/demote</vh></v>
<v t="edream.110203163054.258"><vh>Fixed configuration bug.</vh></v>
<v t="edream.110203163054.259"><vh>Fixed crasher in undo logic</vh></v>
<v t="edream.110203163054.260"><vh>Fixed drag problem</vh></v>
<v t="edream.110203163054.261"><vh>Fixed huge performance bug in v.unjoinNode</vh></v>
<v t="edream.110203163054.262"><vh>Fixed long-standing control-v bug on Linux</vh></v>
<v t="edream.110203163054.263"><vh>Fixed minor import bugs</vh></v>
<v t="edream.110203163054.264"><vh>Fixed problem with block comments</vh></v>
<v t="edream.110203163054.265"><vh>Fixed several problems revealed by French plugin</vh></v>
<v t="edream.110203163054.266"><vh>Fixed several problems with noweb mode</vh></v>
<v t="edream.110203163054.267"><vh>Fixed syntax coloring bugs</vh></v>
<v t="edream.110203163054.268"><vh>Full recolor after paste</vh></v>
<v t="edream.110203163054.269"><vh>Installer now creates plugins directory</vh></v>
<v t="edream.110203163054.270"><vh>Removed duplicate redraws when renaming nodes</vh></v>
<v t="edream.110203163054.271"><vh>Udated recent files menu when saving a new .leo file</vh></v>
<v t="edream.110203163054.272"><vh>Worked around bugs in Python 2.3 a1</vh></v>
</v>
</v>
<v t="edream.110203163054.273"><vh>3.10</vh>
<v t="edream.110203163054.274"><vh>Fixed bugs</vh>
<v t="edream.110203163054.275"><vh>Allowed abbreviated xml tags.</vh></v>
<v t="edream.110203163054.276"><vh>Changed shortcut to Find Previous so Alt - F4 closes Leo</vh></v>
<v t="edream.110203163054.277"><vh>Changed url of help file</vh></v>
<v t="edream.110203163054.278"><vh>Fixed @nsf bug reported by Travers A. Hough</vh></v>
<v t="edream.110203163054.279"><vh>Fixed a bug in Untangle</vh></v>
<v t="edream.110203163054.280"><vh>Fixed bug in Python importer</vh></v>
<v t="edream.110203163054.281"><vh>Fixed bug involving redrawing screen initially</vh></v>
<v t="edream.110203163054.282"><vh>Fixed bugs involving @nosentinelsfile</vh></v>
<v t="edream.110203163054.283"><vh>Fixed crashers in colorizeAnyLanguage</vh></v>
<v t="edream.110203163054.284"><vh>Fixed environment bug in Execute Script command</vh></v>
<v t="edream.110203163054.285"><vh>Fixed major memory leak</vh></v>
<v t="edream.110203163054.286"><vh>Fixed path problem in paths passed to tangle_done.py</vh></v>
<v t="edream.110203163054.287"><vh>Fixed problems with Open With code in customizeLeo.py</vh></v>
<v t="edream.110203163054.288"><vh>Fixed Recent Files command</vh></v>
<v t="edream.110203163054.289"><vh>Fixed reversion involving @comment &amp; @language together</vh></v>
<v t="edream.110203163054.290"><vh>Fixed undo bug</vh></v>
</v>
<v t="edream.110203163054.291"><vh>Added features</vh>
<v t="edream.110203163054.292"><vh>New Mark Clones and Go To Next Clone commands.</vh></v>
<v t="edream.110203163054.293"><vh>New Export Headlines command</vh></v>
<v t="edream.110203163054.294"><vh>Control-dragging a node now clones it</vh></v>
<v t="edream.110203163054.295"><vh>New "Node Only checkbox in the Find/Change panel</vh></v>
<v t="edream.110203163054.296"><vh>@root options</vh></v>
<v t="edream.110203163054.297"><vh>Converted leoConfig.py to use @root-code</vh></v>
<v t="edream.110203163054.298"><vh>Added @file options</vh></v>
<v t="edream.110203163054.299"><vh>Added support for underlined menu items</vh></v>
<v t="edream.110203163054.300"><vh>Improved Leo's window icon</vh></v>
<v t="edream.110203163054.301"><vh>Added easy way of replacing any Leo code</vh></v>
<v t="edream.110203163054.302"><vh>Added convenience routines to redirect stderr and stdout</vh></v>
<v t="edream.110203163054.303"><vh>Added "event1" and "event2" hooks</vh></v>
<v t="edream.110203163054.304"><vh>Added  contributed code to support @read-only nodes</vh></v>
</v>
<v t="edream.110203163054.305"><vh>Known bugs</vh>
<v t="edream.110203163054.306"><vh>Bugs in undoReplace logic</vh></v>
</v>
</v>
<v t="edream.110203163054.307"><vh>leo.py 3.9</vh>
<v t="edream.110203163054.308"><vh>Fixed bugs</vh>
<v t="edream.110203163054.309"><vh>Fixed bug involving @language</vh></v>
<v t="edream.110203163054.310"><vh>Correctly colors Pascal's "private" and "uses" keywords</vh></v>
<v t="edream.110203163054.311"><vh>Fixed a major bug in top()</vh></v>
<v t="edream.110203163054.312"><vh>Fixed bugs when importing Java files.</vh></v>
<v t="edream.110203163054.313"><vh>Convert All Blanks/Tabs  commands honor @tabwidth directives</vh></v>
</v>
<v t="edream.110203163054.314"><vh>New documentation for leo.py 3.9</vh>
<v t="edream.110203163054.315"><vh>Major performance improvements</vh>
<v t="edream.110203163054.316"><vh>Incremental syntax coloring speeds redraws</vh></v>
<v t="edream.110203163054.317"><vh>Incremental undo reduces memory usages significantly</vh></v>
</v>
<v t="edream.110203163054.318"><vh>Major configuration improvements</vh>
<v t="edream.110203163054.319"><vh>Chapter 8: Customizing Leo</vh>
<v t="edream.110203163054.320"><vh>Using leoConfig.leo and leoConfig.txt</vh></v>
<v t="edream.110203163054.321"><vh>Using plugins and hooks</vh>
<v t="edream.110203163054.322"><vh>Overview of plugins and hooks</vh></v>
<v t="edream.110203163054.323"><vh>New plugin architecture</vh>
<v t="edream.110203163054.324"><vh>@file plugins/mod_open_with.py</vh>
<v t="edream.110203163054.325"><vh>on_idle</vh>
<v t="edream.110203163054.326"><vh>&lt;&lt; update v's body text &gt;&gt;</vh>
<v t="edream.110203163054.327"><vh>&lt;&lt; set s to the new text &gt;&gt;</vh></v>
<v t="edream.110203163054.328"><vh>&lt;&lt; set conflict flag &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203163054.329"><vh>create_open_with_menu</vh>
<v t="edream.110203163054.330"><vh>&lt;&lt; create the Open With menu &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.172"><vh>About hooks</vh></v>
<v t="edream.110203163054.331"><vh>SECURITY WARNINGS</vh>
<v t="edream.110203163054.332"><vh>The danger of trusting code in shared .leo files</vh></v>
<v t="edream.110203163054.333"><vh>NEVER use this kind of code in a hook!!</vh></v>
<v t="edream.110203163054.334"><vh>Don't use rexec !!</vh>
<v t="edream.110203163054.335"><vh>&lt;&lt; change all instances of rexec to exec in v's body &gt;&gt;</vh></v>
<v t="edream.110203163054.336"><vh>&lt;&lt; delete thisNode &gt;&gt;</vh></v>
<v t="edream.110203163054.337"><vh>&lt;&lt; clear the undo stack &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203163054.338"><vh>Convenience routines for plugins</vh>
<v t="edream.110203163054.339"><vh>Convenience functions to enable and disable the "idle" hook</vh></v>
<v t="edream.110203163054.340"><vh>Convenience methods to create, destroy and modify menus</vh>
<v t="edream.110203163054.341"><vh>createMenuItemsFromTable</vh></v>
<v t="edream.110203163054.342"><vh>createNewMenu</vh></v>
<v t="edream.110203163054.343"><vh>createOpenWithMenuFromTable</vh></v>
<v t="edream.110203163054.344"><vh>deleteMenu</vh></v>
<v t="edream.110203163054.345"><vh>deleteMenuItem</vh></v>
<v t="edream.110203163054.346"><vh>Example: how to create a menu</vh></v>
</v>
</v>
<v t="edream.110203163054.347"><vh>Translating menus into other languages</vh></v>
<v t="edream.121403162622"><vh>Support for unit testing</vh></v>
</v>
<v t="edream.110203163054.61"><vh>Putting the Leo icon in Leo windows</vh></v>
<v t="edream.110203163054.348"><vh>Extending the format of .leo files</vh></v>
<v t="edream.120703073611"><vh>Attaching temporary attributes to vnodes and tnodes</vh></v>
<v t="edream.120703073611.1"><vh>Recommended conventions for plugins</vh></v>
<v t="edream.110603190322.6"><vh> Script Find and Script Change</vh>
<v t="edream.111803060152.1"><vh>How it works</vh></v>
<v t="ekr.20040201113232"><vh>Using the initScriptFind script</vh></v>
<v t="edream.111803060152.2"><vh>Ideas for using scripts</vh></v>
</v>
</v>
<v t="edream.110203163054.349"><vh>More flexible creation of non-existent directories</vh></v>
</v>
<v t="edream.110203163054.350"><vh>New commands &amp; features</vh>
<v t="edream.110203163054.351"><vh>@url</vh></v>
<v t="edream.110203163054.352"><vh>Execute Script command</vh></v>
<v t="edream.110203163054.353"><vh>Go To Line Number command</vh></v>
<v t="edream.110203163054.349"><vh>More flexible creation of non-existent directories</vh></v>
<v t="edream.110203163054.354"><vh>Much better support for cweb</vh>
<v t="edream.110203163054.355"><vh>About cweb mode </vh></v>
</v>
<v t="edream.110203163054.356"><vh>Open With command</vh>
<v t="edream.110203163054.343"><vh>createOpenWithMenuFromTable</vh></v>
</v>
<v t="edream.110203163054.357"><vh>Optional Emacs-style auto-indent</vh></v>
<v t="edream.110203163054.61"><vh>Putting the Leo icon in Leo windows</vh></v>
<v t="edream.110203163054.358"><vh>Reformat Paragraph command</vh></v>
</v>
<v t="edream.110203163054.359"><vh>Appendix 1 to Chapter 4: Using @rawfile, @silentfile and @nosentinlefile trees</vh></v>
</v>
</v>
<v t="edream.110203163054.360"><vh>leo.py 3.8</vh>
<v t="edream.110203163054.361"><vh>Fixed bugs</vh>
<v t="edream.110203163054.362"><vh>Crashers</vh>
<v t="edream.110203163054.363"><vh>Fixed another crasher in scanAllDirectives</vh></v>
</v>
<v t="edream.110203163054.366"><vh>Bugs involving paths &amp; derived files</vh>
<v t="edream.110203163054.368"><vh>Fixed @delims "round trip" bug</vh></v>
<v t="edream.110203163054.369"><vh>Fixed cweb sentinel bug</vh></v>
<v t="edream.110203163054.370"><vh>Fixed import to @root problems</vh></v>
<v t="edream.110203163054.371"><vh>Leo generates @@ sentinels only for real Leo directives</vh></v>
</v>
<v t="edream.110203163054.372"><vh>Minor syntax coloring bugs</vh>
<v t="edream.110203163054.373"><vh>Colorizer now recognizes comments after preprocessor directives</vh></v>
<v t="edream.110203163054.374"><vh>Syntax color perl's alarm function</vh></v>
<v t="edream.110203163054.375"><vh>Fixed block-comment bug in Java and HTML</vh></v>
</v>
<v t="edream.110203163054.376"><vh>Minor user interface bugs</vh>
<v t="edream.110203163054.377"><vh>Worked around Control-T bug</vh></v>
<v t="edream.110203163054.378"><vh>Fixed bug involving menu pastes in headlines</vh></v>
</v>
<v t="edream.110203163054.379"><vh>fixed Unicode bug in setBodyStringOrPane</vh></v>
</v>
<v t="edream.110203163054.380"><vh>New &amp; changed features</vh>
<v t="edream.110203163054.381"><vh>New @rawfile &amp; @silentfile trees</vh>
<v t="edream.110203163054.359"><vh>Appendix 1 to Chapter 4: Using @rawfile, @silentfile and @nosentinlefile trees</vh></v>
</v>
<v t="edream.110203163054.382"><vh>New @raw, @end_raw and @quiet directives</vh>
<v t="edream.110203163054.383"><vh>@raw and @end_raw directives delimit raw text</vh></v>
<v t="edream.110203163054.384"><vh>@verbose, @terse, @quiet and @silent directives control comments in @root trees</vh></v>
</v>
<v t="edream.110203163054.385"><vh>Much better support for CWEB</vh>
<v t="edream.110203163054.355"><vh>About cweb mode </vh></v>
</v>
<v t="edream.110203163054.386"><vh>Allow @comment and @language to coexist</vh></v>
<v t="edream.110203163054.387"><vh>Configuration settings and commands</vh>
<v t="edream.110203163054.388"><vh>Added stylesheet option to support &lt;?xml-stylesheet...?&gt; line</vh></v>
<v t="edream.110203163054.389"><vh>Added Configuration Commands to help menu</vh></v>
<v t="edream.110203163054.390"><vh>Added output_initial_comment option</vh></v>
<v t="edream.110203163054.391"><vh>Added output_newline option</vh></v>
<v t="edream.110203163054.392"><vh>Changed path_directive_creates_directories to create_nonexistent_directories</vh></v>
</v>
<v t="edream.110203163054.393"><vh>Minor changes</vh>
<v t="edream.110203163054.394"><vh>Added support for forth language comments</vh></v>
<v t="edream.110203163054.395"><vh>All export commands now use output_newline option</vh></v>
<v t="edream.110203163054.396"><vh>Changed names of commands in help menu and corresponding entries in leoConfig.leo</vh></v>
<v t="edream.110203163054.397"><vh>Created es_exception</vh></v>
<v t="edream.110203163054.398"><vh>Created reloadAll in leoGlobals.py</vh></v>
<v t="edream.110203163054.399"><vh>Forced focus to body pane after ending headline edit</vh></v>
<v t="edream.110203163054.400"><vh>Use // as single-line comment in Java</vh></v>
<v t="edream.110203163054.401"><vh>wrote "finished" after write @file nodes command</vh></v>
</v>
</v>
<v t="edream.110203163054.402"><vh>Coming soon: Leo 4.0, a major improvement</vh></v>
</v>
<v t="edream.110203163054.403"><vh>leo.py 3.7</vh>
<v t="edream.110203163054.404"><vh>Fixed Bugs</vh>
<v t="edream.110203163054.405"><vh>Language and syntax coloring bugs</vh>
<v t="edream.110203163054.406"><vh>Fixed @comment bug</vh></v>
<v t="edream.110203163054.407"><vh>Fixed colorizing for "while" in C</vh></v>
<v t="edream.110203163054.408"><vh>Fixed @language plain # bug</vh></v>
<v t="edream.110203163054.409"><vh>Fixed @language plain single-quote bug</vh></v>
</v>
<v t="edream.110203163054.410"><vh>Bugs in Edit body commands</vh></v>
<v t="edream.110203163054.411"><vh>Bugs relating to tangling and derived files</vh>
<v t="edream.110203163054.412"><vh>Fixed major bug in @file read code</vh></v>
<v t="edream.110203163054.413"><vh>Fixed minor read bug</vh></v>
<v t="edream.110203163054.406"><vh>Fixed @comment bug</vh></v>
<v t="edream.110203163054.414"><vh>Fixed a bug that affected wrapping in doc parts</vh></v>
</v>
<v t="edream.110203163054.415"><vh>Other bugs</vh>
<v t="edream.110203163054.416"><vh>Fixed reversion in Tangle/Untangle code</vh></v>
<v t="edream.110203163054.417"><vh>Fixed undo cloned headline bug</vh></v>
<v t="edream.110203163054.418"><vh>Fixed Find previous bug</vh></v>
<v t="edream.110203163054.419"><vh>Fixed tab problems</vh></v>
<v t="edream.110203163054.420"><vh>Leo now remembers insert point always</vh></v>
<v t="edream.110203163054.421"><vh>Removed setup.py from binary distribution</vh></v>
</v>
</v>
<v t="edream.110203163054.422"><vh>Improvements</vh>
<v t="edream.110203163054.423"><vh>Many new user options</vh>
<v t="edream.110203163054.424"><vh>General configuration options</vh>
<v t="edream.110203163054.425"><vh>path_directive_creates_directories</vh></v>
<v t="edream.110203163054.426"><vh>relative_path_base_directory</vh></v>
<v t="edream.110203163054.427"><vh>remove_sentinels_extension</vh></v>
<v t="edream.110203163054.428"><vh>write_clone_indices</vh></v>
</v>
<v t="edream.110203163054.429"><vh>Secondary pane ratios</vh></v>
<v t="edream.110203163054.430"><vh>User-configurable colors</vh></v>
<v t="edream.110203163054.431"><vh>User-configurable shortcuts for commands</vh></v>
</v>
<v t="edream.110203163054.432"><vh>Improved support for Unicode</vh></v>
<v t="edream.110203163054.433"><vh>End of cursed newlines</vh></v>
<v t="edream.110203163054.434"><vh>Code is now compatible with Python 2.1</vh></v>
<v t="edream.110203163054.435"><vh>Better file and path handling</vh></v>
<v t="edream.110203163054.436"><vh>Better support for Perl+pod</vh></v>
<v t="edream.110203163054.437"><vh>New End Edit Headline and Abort Edit Headline commands</vh></v>
<v t="edream.110203163054.438"><vh>Allow reads and writes of cloned @file nodes</vh></v>
<v t="edream.110203163054.439"><vh>Leo now closes an empty window when opening a recent file</vh></v>
<v t="edream.110203163054.440"><vh>Improved derived files</vh></v>
<v t="edream.110203163054.441"><vh>Improved enabling of menu items in popup menus</vh></v>
<v t="edream.110203163054.442"><vh>About Leo dialog is now non-modal</vh></v>
</v>
</v>
<v t="edream.110203163054.443"><vh>leo.py 3.6</vh>
<v t="edream.110203163054.444"><vh>Known bug: problems with Python window</vh></v>
<v t="edream.110203163054.445"><vh>Bug fixes</vh>
<v t="edream.110203163054.446"><vh>Fixed problems with opening and writing leoConfig.txt on Linux</vh></v>
<v t="edream.110203163054.447"><vh>Fixed problems renaming files on Linux</vh></v>
<v t="edream.110203163054.448"><vh>Fixed missing headline bug on startup</vh></v>
<v t="edream.110203163054.449"><vh>Improved call to os.path.join in leoApp.finishCreate</vh></v>
<v t="edream.110203163054.450"><vh>Improved how directories are handled in @root trees</vh></v>
<v t="edream.110203163054.451"><vh>Dave Hein: fixed Tk 8.4 problem in Prefs Panel</vh></v>
<v t="edream.110203163054.452"><vh>Dave Hein: added CheckVersion to leoUtils.py</vh></v>
<v t="edream.110203163054.453"><vh>Dave Hein: the Python window now works on Linux.</vh></v>
<v t="edream.110203163054.454"><vh>Steven P. Schaefer: Improved handling of directives in @root trees</vh></v>
<v t="edream.110203163054.455"><vh>Steven P. Schaefer: Fixed cursed newline bug for Linux</vh></v>
</v>
<v t="edream.110203163054.456"><vh>Improvements to existing features</vh>
<v t="edream.110203163054.457"><vh>Leo now remembers scrollbar position and insert point of previously visited nodes</vh></v>
<v t="edream.110203163054.458"><vh>Body pane now gets focus after Go Back/Next</vh></v>
<v t="edream.110203163054.459"><vh>Improved all commands in Help menu</vh></v>
<v t="edream.110203163054.460"><vh>Removed most error messages in atFile::read logic</vh></v>
<v t="edream.110203163054.461"><vh>Added shortcuts for Read/Write @file Nodes commands</vh></v>
<v t="edream.110203163054.462"><vh>Tomaz Ficko: Added support for MouseWheel (Linux only)</vh></v>
</v>
<v t="edream.110203163054.463"><vh>New features</vh>
<v t="edream.110203163054.464"><vh>Added Match Brackets command</vh></v>
<v t="edream.110203163054.465"><vh>Added PHP support</vh></v>
<v t="edream.110203163054.466"><vh>Added LaTex support</vh></v>
</v>
</v>
<v t="edream.110203163054.467"><vh>leo.py 3.5</vh>
<v t="edream.110203163054.468"><vh>Bug fixes</vh>
<v t="edream.110203163054.469"><vh>Called cf.flush in leoConfig.update</vh></v>
<v t="edream.110203163054.470"><vh>Fixed crasher in leoFileCommands.readOutlineOnly</vh></v>
<v t="edream.110203163054.471"><vh>Fixed crasher when leoConfig.txt did not exist</vh></v>
<v t="edream.110203163054.472"><vh>Fixed cursed newline bug in leoAtFile</vh></v>
<v t="edream.110203163054.473"><vh>Rewrote scanAllDirectives routines to handle relative paths</vh></v>
<v t="edream.110203163054.474"><vh>Suppressed erroneous tangle warning about relative paths</vh></v>
</v>
<v t="edream.110203163054.475"><vh>Improvements</vh>
<v t="edream.110203163054.476"><vh>Added configuration settings for horizontal scrollbars</vh></v>
<v t="edream.110203163054.477"><vh>Added commands to the help menu</vh></v>
<v t="edream.110203163054.478"><vh>Added logic to test for read-only files</vh></v>
<v t="edream.110203163054.479"><vh>Added importFiles script</vh></v>
</v>
</v>
<v t="edream.110203163054.480"><vh>leo.py 3.4</vh>
<v t="edream.110203163054.481"><vh>Configuration settings and leoConfig.leo</vh>
<v t="edream.110203163054.482"><vh>Added comments to leoConfig.txt about split direction and ratio</vh></v>
<v t="edream.110203163054.483"><vh>Added save_clears_undo_buffer config option</vh></v>
<v t="edream.110203163054.484"><vh>Corrected spelling of limit_directory_search_extenstion </vh></v>
<v t="edream.110203163054.485"><vh>Created leoConfig.leo</vh></v>
<v t="edream.110203163054.486"><vh>Fixed a major config bug. This fixes font problems</vh></v>
<v t="edream.110203163054.487"><vh>Improved Recent Files menu</vh></v>
<v t="edream.110203163054.488"><vh>Leo honors pane ratio stored in .leo files</vh></v>
<v t="edream.110203163054.489"><vh>Leo writes prefs if leoConfig.txt is read-only</vh></v>
<v t="edream.110203163054.490"><vh>Made leoConfig.txt be read/write by default</vh></v>
<v t="edream.110203163054.491"><vh>Toggle Split Direction now updates leoConfig.txt</vh></v>
</v>
<v t="edream.110203163054.492"><vh>Documentation for code in leo.py that may be of wider interest</vh>
<v t="edream.110203163054.493"><vh>Code hidden in leo.py</vh>
<v t="edream.110203163054.494"><vh>c2py.py</vh></v>
<v t="edream.110203163054.495"><vh>disStats.py</vh></v>
<v t="edream.110203163054.496"><vh>Tkinter utilities</vh></v>
<v t="edream.110203163054.497"><vh>Font dialog</vh></v>
<v t="edream.110203163054.498"><vh>Syntax coloring code</vh></v>
<v t="edream.110203163054.499"><vh>Tree code</vh></v>
</v>
</v>
<v t="edream.110203163054.500"><vh>Fixed bugs</vh>
<v t="edream.110203163054.501"><vh>Fixed another clone bug: created setAncestorsOfClonedNodesInTreeDirty</vh></v>
<v t="edream.110203163054.502"><vh>Fixed bugs that delayed writing of find and prefs panels</vh></v>
<v t="edream.110203163054.503"><vh>Fixed revert problems in font panel</vh></v>
<v t="edream.110203163054.504"><vh>Fixed several unicode bugs</vh></v>
<v t="edream.110203163054.505"><vh>Fixed wandering insertion point bug</vh></v>
</v>
<v t="edream.110203163054.506"><vh>Minor improvements</vh>
<v t="edream.110203163054.507"><vh>Syntax colorer now honors @comment</vh></v>
<v t="edream.110203163054.508"><vh>Added @ignore to "raw" imported files</vh></v>
<v t="edream.110203163054.509"><vh>Added log message for Remove Sentinels command</vh></v>
<v t="edream.110203163054.510"><vh>Improved highlighting of whitespace</vh></v>
<v t="edream.110203163054.511"><vh>Remove Sentinels command now uses .txt extension instead of .tmp</vh></v>
</v>
</v>
<v t="edream.110203163054.512"><vh>leo.py 3.3</vh>
<v t="edream.110203163054.513"><vh>Added support for Unicode</vh></v>
<v t="edream.110203163054.514"><vh>Improved the Import commands &amp; fixed Javadoc problem</vh></v>
<v t="edream.110203163054.515"><vh>Fixed crasher when Tangling</vh></v>
<v t="edream.110203163054.516"><vh>Fixed problems with negative tab widths</vh></v>
<v t="edream.110203163054.517"><vh>Fixed numerous problems related to configuration settings</vh></v>
</v>
<v t="edream.110203163054.518"><vh>leo.py 3.2</vh>
<v t="edream.110203163054.519"><vh>Nested @others directives now valid</vh>
<v t="edream.110203163054.520"><vh>@file test.txt</vh>
<v t="edream.110203163054.521"><vh>class a</vh>
<v t="edream.110203163054.522"><vh>a::one</vh></v>
<v t="edream.110203163054.523"><vh>a:two</vh></v>
</v>
<v t="edream.110203163054.524"><vh>class b</vh>
<v t="edream.110203163054.525"><vh>b::one</vh></v>
<v t="edream.110203163054.526"><vh>b:two</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.527"><vh>Improved Import command</vh></v>
<v t="edream.110203163054.528"><vh>Reassigned shortcuts in the Outline-Move/Select menu</vh></v>
<v t="edream.110203163054.529"><vh>Fixed crasher in the Preferences Panel</vh></v>
<v t="edream.110203163054.530"><vh>Improved syntax coloring of continued C strings</vh></v>
<v t="edream.110203163054.531"><vh>Made many changes to Color Panel</vh></v>
<v t="edream.110203163054.532"><vh>Added email address &amp; URL to About Leo dialog</vh></v>
<v t="edream.110203163054.533"><vh>added disStats.py</vh></v>
</v>
<v t="edream.110203163054.534"><vh>leo.py 3.1</vh>
<v t="edream.110203163054.535"><vh>Added compare panel</vh></v>
<v t="edream.110203163054.536"><vh>Added new settings to leoConfig.txt</vh></v>
<v t="edream.110203163054.537"><vh>Changed precedence scheme for preferences</vh></v>
<v t="edream.110203163054.538"><vh>Fixed @tabwidth, @pagewidth and @language directives</vh></v>
<v t="edream.110203163054.539"><vh>Flatten Outline now escapes only the first non-blank character of each line.</vh></v>
<v t="edream.110203163054.540"><vh>Open Python Window command adds path to IDLE automatically</vh></v>
<v t="edream.110203163054.541"><vh>Python 2.2 required dialog tells where to download Python 2.2 and Tk 8.3</vh></v>
</v>
<v t="edream.110203163054.542"><vh>leo.py 3.0</vh>
<v t="edream.110203163054.543"><vh>Optional new file format</vh></v>
<v t="edream.110203163054.544"><vh>New features (in approximate order of importance)</vh>
<v t="edream.110203163054.545"><vh>Added many settings to leoConfig.txt file</vh>
<v t="edream.110203163054.546"><vh>New windows now open using config params.</vh></v>
</v>
<v t="edream.110203163054.547"><vh>Added autoscrolling in the outline pane</vh></v>
<v t="edream.110203163054.548"><vh>Color panel</vh></v>
<v t="edream.110203163054.549"><vh>Font panel</vh></v>
<v t="edream.110203163054.550"><vh>Leo now opens windows at the position in which they were saved</vh></v>
<v t="edream.110203163054.551"><vh>Added Toggle Split Direction</vh></v>
<v t="edream.110203163054.552"><vh>Improved syntax coloring for @comment directives</vh></v>
<v t="edream.110203163054.553"><vh>Leo warns and aborts if not Python 2.2 or above</vh></v>
<v t="edream.110203163054.554"><vh>All panels now have labeled frames and grooved borders</vh></v>
<v t="edream.110203163054.555"><vh>Leo directives are now colored green by default</vh></v>
<v t="edream.110203163054.556"><vh>Print a traceback message for all serious exceptions</vh></v>
<v t="edream.110203163054.557"><vh>@comment supports comments starting with REM</vh></v>
</v>
<v t="edream.110203163054.558"><vh>Fixed bugs (one crasher)</vh>
<v t="edream.110203163054.559"><vh>Fixed crasher in atFile.scanAllDirectives</vh></v>
<v t="edream.110203163054.560"><vh>Fixed syntax coloring bug involving Leo directives</vh></v>
<v t="edream.110203163054.561"><vh>Windows now open without visual problems</vh></v>
<v t="edream.110203163054.562"><vh>Made Convert Tabs, Convert All Blanks and Convert All Tabs undoable</vh></v>
<v t="edream.110203163054.563"><vh>Made Prefs panel non-modal</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.564"><vh>2.x releases</vh>
<v t="edream.110203163054.565"><vh>leo.py 2.5.1 Many improvements</vh>
<v t="edream.110203163054.566"><vh>New &amp; improved commands</vh>
<v t="edream.110203163054.567"><vh>Tabs and spaces</vh>
<v t="edream.110203163054.568"><vh>Added Convert All Blanks and Convert All Tabs commands</vh></v>
<v t="edream.110203163054.569"><vh>Added Convert Tabs command</vh></v>
<v t="edream.110203163054.570"><vh>Tab widths work</vh></v>
<v t="edream.110203163054.571"><vh>Negative tab width converts tabs to spaces</vh></v>
</v>
<v t="edream.110203163054.572"><vh>Improved Preferences panel</vh></v>
<v t="edream.110203163054.320"><vh>Using leoConfig.leo and leoConfig.txt</vh></v>
<v t="edream.110203163054.573"><vh>Cut and Paste now works properly in all situations</vh></v>
<v t="edream.110203163054.574"><vh>Added Recent Files menu</vh></v>
<v t="edream.110203163054.575"><vh>All Extract and Import commands are now undoable</vh></v>
<v t="edream.110203163054.576"><vh>Made Cascade and Minimize All commands functional</vh></v>
</v>
<v t="edream.110203163054.577"><vh>Significant bug fixes</vh>
<v t="edream.110203163054.578"><vh>Fixed several bugs in the Import commands</vh></v>
<v t="edream.110203163054.579"><vh>Invalid directories no longer cause read errors</vh></v>
</v>
<v t="edream.110203163054.580"><vh>Fixed crashers</vh>
<v t="edream.110203163054.581"><vh>Fixed crasher when saving a new file</vh></v>
<v t="edream.110203163054.582"><vh>Fixed crashers in Remove Sentinels command</vh></v>
<v t="edream.110203163054.583"><vh>Fixed crasher in Import commands</vh></v>
</v>
<v t="edream.110203163054.584"><vh>Fixed minor bugs &amp; improvements</vh>
<v t="edream.110203163054.585"><vh>Recolored body text after extract commands</vh></v>
<v t="edream.110203163054.586"><vh>Fixed bug involving missing clone mark after Move Right command</vh></v>
<v t="edream.110203163054.587"><vh>Changed defaultextension from "x" to ".x" in dialogs.</vh></v>
<v t="edream.110203163054.588"><vh>Fixed minor bug in Save and Save As commands</vh></v>
<v t="edream.110203163054.589"><vh>Fixed minor problems with documentation</vh></v>
<v t="edream.110203163054.590"><vh>Renamed Font to Set Font... and Syntax Coloring... to Set Colors...</vh></v>
</v>
</v>
<v t="edream.110203163054.591"><vh>leo.py 2.4</vh>
<v t="edream.110203163054.592"><vh>Fixed several bugs</vh></v>
<v t="edream.110203163054.593"><vh>Added better error recovery when writing .leo files</vh></v>
<v t="edream.110203163054.594"><vh>Dragging headlines</vh></v>
<v t="edream.110203163054.60"><vh>How to associate leo.py with .leo files on Windows</vh></v>
</v>
<v t="edream.110203163054.595"><vh>leo.py 2.3</vh></v>
<v t="edream.110203163054.596"><vh>leo.py 2.2 Bug fixes and documentation revised</vh></v>
<v t="edream.110203163054.597"><vh>2.1 Import &amp; Export commands</vh>
<v t="edream.110203163054.598"><vh>Import and Export commands</vh></v>
<v t="edream.110203163054.599"><vh>Fixed moves up to root position</vh></v>
<v t="edream.110203163054.600"><vh>Improved the syntax colorer</vh></v>
</v>
<v t="edream.110203163054.601"><vh>2.0 Untangle, Unlimited Undo/Redo, Syntax Coloring, etc.</vh>
<v t="edream.110203163054.602"><vh>Format change: no blank lines between sentinels in derived files</vh></v>
<v t="edream.110203163054.603"><vh>Unlimited Undo and Redo</vh></v>
<v t="edream.110203163054.604"><vh>Drawing and syntax coloring</vh>
<v t="edream.110203163054.605"><vh>Syntax coloring works for all languages</vh></v>
<v t="edream.110203163054.606"><vh>Fixed minor syntax coloring bugs</vh></v>
<v t="edream.110203163054.607"><vh>Headlines given more space</vh></v>
<v t="edream.110203163054.608"><vh>Suppressed auto-indent for Python in @nocolor mode</vh></v>
</v>
<v t="edream.110203163054.609"><vh>Tangle/Untangle</vh>
<v t="edream.110203163054.610"><vh>Fixed old bugs in Untangle</vh></v>
<v t="edream.110203163054.611"><vh>@c now is the same as @code</vh></v>
<v t="edream.110203163054.612"><vh>Untangle only trims trailing lines from updated nodes</vh></v>
</v>
<v t="edream.110203163054.613"><vh>Fixed Linux-specific bugs</vh></v>
</v>
<v t="edream.110203163054.614"><vh>1.0 New commands and bug fixes</vh>
<v t="edream.110203163054.615"><vh>Unfinished commands</vh></v>
<v t="edream.110203163054.616"><vh>How to copy an outline from Borland Leo to Leo.py</vh></v>
<v t="edream.110203163054.617"><vh>Fixed bugs</vh></v>
<v t="edream.110203163054.618"><vh>Remaining minor problems</vh></v>
</v>
<v t="edream.110203163054.619"><vh>0.08 Find, Change and Tangle commands &amp; major bugs fixed</vh>
<v t="edream.110203163054.620"><vh>About the Find and Change commands</vh></v>
<v t="edream.110203163054.621"><vh>About the Tangle command</vh></v>
<v t="edream.110203163054.622"><vh>About hyperlinking</vh></v>
<v t="edream.110203163054.623"><vh>Fixed significant bugs</vh></v>
<v t="edream.110203163054.624"><vh>Other improvements</vh></v>
<v t="edream.110203163054.625"><vh>Improved memory management</vh></v>
<v t="edream.110203163054.626"><vh>The trace function (Sherlock tracing)</vh></v>
<v t="edream.110203163054.627"><vh>Improved directory and file name handling</vh></v>
<v t="edream.110203163054.628"><vh>Improvements that will be propagated back to LeoCB</vh></v>
</v>
<v t="edream.110203163054.629"><vh>0.07 Stability and scripting</vh>
<v t="edream.110203163054.630"><vh>Thorough testing</vh></v>
<v t="edream.110203163054.631"><vh>Removed many irritations.  Some remain</vh></v>
<v t="edream.110203163054.632"><vh>Fixed bug that can drop data</vh></v>
<v t="edream.110203163054.633"><vh>Added Python window and scripting support</vh></v>
<v t="edream.110203163054.634"><vh>Added Script to convert from Leo 1 to Leo 2</vh></v>
<v t="edream.110203163054.635"><vh>Added Leo Documentation command</vh></v>
<v t="edream.110203163054.636"><vh>Added Auto indent</vh></v>
</v>
<v t="edream.110203163054.637"><vh>0.06 Minor changes for Linux</vh></v>
<v t="edream.110203163054.638"><vh>0.05 The first functional version</vh>
<v t="edream.110203163054.639"><vh>Testing &amp; Performance</vh></v>
<v t="edream.110203163054.640"><vh>Installing and Running leo.py</vh></v>
<v t="edream.110203163054.641"><vh>Files &amp; Folders</vh></v>
<v t="edream.110203163054.642"><vh>Functional Commands and Features</vh></v>
<v t="edream.110203163054.643"><vh>Non-Functional Commands and Features</vh></v>
<v t="edream.110203163054.644"><vh>Bugs, Problems and Code Quality</vh></v>
<v t="edream.110203163054.645"><vh>New Things To Do</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.646"><vh>Borland PC versions</vh>
<v t="edream.110203163054.647"><vh>Borland 2.7 Major bug fix: please upgrade</vh></v>
<v t="edream.110203163054.648"><vh>Borland 2.6 Major changes: please upgrade</vh>
<v t="edream.110203163054.649"><vh>Format change: no blank lines between sentinels in derived files</vh></v>
<v t="edream.110203163054.650"><vh>Eliminated spurious read errors</vh></v>
<v t="edream.110203163054.651"><vh>@c now is the same as @code</vh></v>
<v t="edream.110203163054.652"><vh>Fixed old bugs in Untangle</vh></v>
<v t="edream.110203163054.653"><vh>Compatibility with leo.py v2.0</vh></v>
<v t="edream.110203163054.654"><vh>Changed "Batch" check box to "Show Context"</vh></v>
<v t="edream.110203163054.655"><vh>Can not ensure .leo extension</vh></v>
</v>
<v t="edream.110203163054.656"><vh>version 2.5: Fixed several serious bugs</vh></v>
<v t="edream.110203163054.657"><vh>version 2.4: The new Leo2 (Do not use this version)</vh>
<v t="edream.110203163054.658"><vh>Fixed clone bugs</vh></v>
<v t="edream.110203163054.659"><vh>.leo files now contain all data</vh></v>
<v t="edream.110203163054.660"><vh>Replaced archive command</vh></v>
<v t="edream.110203163054.661"><vh>Automatic update of @file trees</vh></v>
<v t="edream.110203163054.662"><vh>Errors while reading</vh></v>
<v t="edream.110203163054.663"><vh>Errors while writing</vh></v>
<v t="edream.110203163054.664"><vh>Drawbacks of @file trees</vh></v>
</v>
<v t="edream.110203163054.665"><vh>version 2.3: Do not use this version</vh>
<v t="edream.110203163054.666"><vh>@first directive</vh></v>
<v t="edream.110203163054.667"><vh>Archive Entire Outline command</vh></v>
<v t="edream.110203163054.668"><vh>Fixed @c syntax coloring</vh></v>
<v t="edream.110203163054.669"><vh>Fixed bugs in the find command</vh></v>
<v t="edream.110203163054.670"><vh>Fixed bug involving @file dirty bits</vh></v>
<v t="edream.110203163054.671"><vh>The Log window is now part of the Leo window</vh></v>
</v>
<v t="edream.110203163054.672"><vh>version 2.2 (beta)</vh></v>
<v t="edream.110203163054.673"><vh>version 2.1 (beta)</vh></v>
<v t="edream.110203163054.674"><vh>1.x versions</vh>
<v t="edream.110203163054.675"><vh>Changes made in version 1.15</vh></v>
<v t="edream.110203163054.676"><vh>Changes made in version 1.14</vh></v>
<v t="edream.110203163054.677"><vh>Changes made in version 1.13</vh></v>
<v t="edream.110203163054.678"><vh>Changes made in version 1.12</vh></v>
<v t="edream.110203163054.679"><vh>Changes made in version 1.11</vh>
<v t="edream.110203163054.680"><vh>Multiple parts not allowed for &lt;&lt; section name &gt;&gt;</vh></v>
<v t="edream.110203163054.681"><vh>Untangling: updating an outline</vh></v>
</v>
<v t="edream.110203163054.682"><vh>Changes made in version 1.10</vh></v>
<v t="edream.110203163054.683"><vh>Changes made in version 1.9</vh>
<v t="edream.110203163054.684"><vh>New Execute Script command</vh></v>
<v t="edream.110203163054.685"><vh>Python window improved</vh></v>
</v>
<v t="edream.110203163054.686"><vh>Changes made in version 1.8</vh></v>
<v t="edream.110203163054.687"><vh>Changes made in version 1.7</vh></v>
<v t="edream.110203163054.688"><vh>Changes made in version 1.6</vh></v>
<v t="edream.110203163054.689"><vh>Changes made in version 1.5</vh></v>
<v t="edream.110203163054.690"><vh>Changes made in version 1.4</vh>
<v t="edream.110203163054.691"><vh>Outline To Noweb command</vh></v>
<v t="edream.110203163054.692"><vh>find/change Python scripts</vh></v>
<v t="edream.110203163054.693"><vh>v.commands() Python method</vh></v>
</v>
<v t="edream.110203163054.694"><vh>Changes made in version 1.3</vh></v>
<v t="edream.110203163054.695"><vh>Changes made in version 1.2</vh></v>
<v t="edream.110203163054.696"><vh>Changes made in version 1.1</vh></v>
<v t="edream.110203163054.697"><vh>Changes made in version 1.0</vh></v>
<v t="edream.110203163054.698"><vh>Changes made in version 0.19</vh>
<v t="edream.110203163054.699"><vh>Fixed directory bug</vh></v>
<v t="edream.110203163054.700"><vh>Added @language HTML, perl and perlpod</vh></v>
<v t="edream.110203163054.701"><vh>Eliminated @noweb &amp; replaced @cweb with @language cweb</vh></v>
<v t="edream.110203163054.355"><vh>About cweb mode </vh></v>
<v t="edream.110203163054.702"><vh>Improved syntax coloring</vh></v>
<v t="edream.110203163054.703"><vh>Improved Print command</vh></v>
<v t="edream.110203163054.704"><vh>Improved how Untangle handles block comments</vh></v>
<v t="edream.110203163054.705"><vh>Eliminated clone windows (but not clone nodes!)</vh></v>
<v t="edream.110203163054.706"><vh>Eliminated Extended noweb Syntax</vh></v>
</v>
<v t="edream.110203163054.707"><vh>Changes made in version 0.18</vh>
<v t="edream.110203163054.708"><vh>File format extended</vh></v>
<v t="edream.110203163054.709"><vh>Fixed bug in languages without block comments</vh></v>
<v t="edream.110203163054.710"><vh>Added @header and @noheader directives</vh></v>
<v t="edream.110203163054.711"><vh>Added @language fortran90</vh></v>
<v t="edream.110203163054.712"><vh>Added @language perlpod</vh></v>
</v>
<v t="edream.110203163054.713"><vh>Changes made in version 0.17</vh>
<v t="edream.110203163054.714"><vh>Support for noweb &lt;&lt;*&gt;&gt; convention</vh></v>
<v t="edream.110203163054.715"><vh>new @cweb, @noweb, @path, @tabwidth and @pagewidth directives</vh></v>
<v t="edream.110203163054.716"><vh>CWEB mode now has a chance of working</vh></v>
<v t="edream.110203163054.717"><vh>Reduced default screen size</vh></v>
</v>
<v t="edream.110203163054.718"><vh>Changes made in version 0.16</vh>
<v t="edream.110203163054.719"><vh>Bug fixes</vh></v>
<v t="edream.110203163054.720"><vh>Fixed crasher involving switching windows</vh></v>
<v t="edream.110203163054.721"><vh>new @language directive</vh></v>
<v t="edream.110203163054.722"><vh>@language and @comment directives can be inherited</vh></v>
<v t="edream.110203163054.723"><vh>Untangle can now handle non-C files</vh></v>
<v t="edream.110203163054.724"><vh>Untangle now removes trailing blank lines</vh></v>
<v t="edream.110203163054.725"><vh>new @verbose, @terse and @silent directives</vh></v>
<v t="edream.110203163054.726"><vh>Default directories</vh></v>
<v t="edream.110203163054.727"><vh>Import Files command now handles Pascal , Python and Java files.</vh></v>
<v t="edream.110203163054.728"><vh>Toggle Active Pane command</vh></v>
<v t="edream.110203163054.729"><vh>Path delimiters are now '\' instead of '/'</vh></v>
<v t="edream.110203163054.730"><vh>Cleaned up code</vh></v>
<v t="edream.110203163054.731"><vh>Fixed crasher involving empty section names</vh></v>
<v t="edream.110203163054.732"><vh>Untangle warns about sections not in the outline</vh></v>
<v t="edream.110203163054.733"><vh>A limitations involving Untangle</vh></v>
</v>
<v t="edream.110203163054.734"><vh>Known Bugs &amp; Limitations</vh></v>
</v>
</v>
</v>
<v t="EKR.20040524104904"><vh>Users Guide</vh>
<v t="EKR.20040524104904.2"><vh>An overview of Leo</vh></v>
<v t="EKR.20040524104904.3"><vh>Front material</vh>
<v t="EKR.20040524104904.4"><vh>Title Page &amp; Summary</vh></v>
<v t="EKR.20040524104904.5"><vh>Preface</vh></v>
<v t="EKR.20040524104904.6"><vh>Leo's Design Goals</vh></v>
<v t="EKR.20040524104904.7"><vh>Acknowledgements</vh></v>
<v t="EKR.20040524104904.8"><vh>Legal Notices: Leo uses the Python license</vh></v>
</v>
<v t="EKR.20040524104904.9"><vh>Chapter 1: Introducing Leo</vh>
<v t="EKR.20040524104904.10"><vh>Overview</vh></v>
<v t="EKR.20040524104904.11"><vh>Leo's main window</vh></v>
<v t="EKR.20040524104904.12"><vh>Body text and sections</vh></v>
<v t="EKR.20040524104904.13"><vh>Outlines organize sections</vh>
<v t="EKR.20040524104904.14"><vh>removeSentinelsCommand</vh>
<v t="EKR.20040524104904.15"><vh>&lt;&lt; Read file into s &gt;&gt;</vh></v>
<v t="EKR.20040524104904.16"><vh>&lt;&lt; set delims from the header line &gt;&gt;</vh></v>
<v t="EKR.20040524104904.17"><vh>&lt;&lt; Write s into newFileName &gt;&gt;</vh></v>
</v>
</v>
<v t="EKR.20040524104904.18"><vh>Clones manage tasks</vh></v>
<v t="EKR.20040524104904.19"><vh>Outlines generate derived files</vh></v>
<v t="EKR.20040524104904.20"><vh>A recommended workflow for using Leo</vh></v>
</v>
<v t="EKR.20040524104904.21"><vh>Chapter 2: Installing Leo</vh>
<v t="EKR.20040524104904.22"><vh>System requirements</vh></v>
<v t="EKR.20040524104904.23"><vh>How to install leo.py on Windows</vh></v>
<v t="EKR.20040524104904.24"><vh>How to associate leo.py with .leo files on Windows</vh></v>
<v t="EKR.20040524104904.25"><vh>Quick start</vh></v>
</v>
<v t="EKR.20040524104904.26"><vh>Chapter 3: Using Outlines &amp; Body text</vh>
<v t="EKR.20040524104904.27"><vh>Cloning headlines</vh>
<v t="EKR.20040524104904.28"><vh>read me</vh></v>
<v t="EKR.20040524104904.29"><vh>a</vh>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.34"><vh>g</vh></v>
</v>
<v t="EKR.20040524104904.29"><vh>a</vh>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.34"><vh>g</vh></v>
</v>
<v t="EKR.20040524104904.35"><vh>f</vh></v>
</v>
<v t="EKR.20040524104904.36"><vh>Creating and destroying headlines</vh></v>
<v t="EKR.20040524104904.37"><vh>Cutting, pasting and deleting headlines</vh></v>
<v t="EKR.20040524104904.38"><vh>Dragging headlines</vh></v>
<v t="EKR.20040524104904.39"><vh>Editing body text</vh></v>
<v t="EKR.20040524104904.40"><vh>Expanding &amp; contracting headlines</vh></v>
<v t="EKR.20040524104904.41"><vh>Indenting body text automatically</vh>
<v t="EKR.20040524104904.42"><vh>Optional Emacs-style auto-indent</vh></v>
</v>
<v t="EKR.20040524104904.43"><vh>Marking headlines</vh></v>
<v t="EKR.20040524104904.44"><vh>Moving &amp; Reorganizing headlines</vh></v>
<v t="EKR.20040524104904.45"><vh>Opening URL's automatically</vh>
<v t="EKR.20040524104904.46"><vh>@url</vh></v>
</v>
<v t="EKR.20040524104904.47"><vh>Resizing panes</vh></v>
<v t="EKR.20040524104904.48"><vh>Undoing operations</vh></v>
</v>
<v t="EKR.20040524104904.49"><vh>Chapter 4: Writing Programs in Leo</vh>
<v t="EKR.20040524104904.50"><vh>Overview</vh></v>
<v t="EKR.20040524104904.51"><vh>Sections and section references</vh></v>
<v t="EKR.20040524104904.52"><vh>Organizing @file trees.</vh>
<v t="EKR.20040524104904.53"><vh>Examples</vh>
<v t="EKR.20040524104904.54"><vh>@file f.c</vh>
<v t="EKR.20040524104904.55"><vh>&lt;&lt; constants &gt;&gt;</vh></v>
<v t="EKR.20040524104904.56"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
<v t="EKR.20040524104904.57"><vh>function 1</vh></v>
<v t="EKR.20040524104904.58"><vh>function 2</vh></v>
</v>
<v t="EKR.20040524104904.59"><vh>@file classX.py</vh>
<v t="EKR.20040524104904.60"><vh>&lt;&lt; imports for classX &gt;&gt;</vh></v>
<v t="EKR.20040524104904.61"><vh>Getters</vh>
<v t="EKR.20040524104904.62"><vh>getter 1</vh></v>
<v t="EKR.20040524104904.63"><vh>getter 2</vh></v>
</v>
<v t="EKR.20040524104904.64"><vh>Setters</vh>
<v t="EKR.20040524104904.65"><vh>setter 1</vh></v>
<v t="EKR.20040524104904.66"><vh>setter 2</vh></v>
</v>
</v>
<v t="EKR.20040524104904.67"><vh>@file mainClass.py</vh>
<v t="EKR.20040524104904.68"><vh>&lt;&lt;mainClass imports &gt;&gt;</vh></v>
<v t="EKR.20040524104904.69"><vh>&lt;&lt;class mainClass&gt;&gt;</vh>
<v t="EKR.20040524104904.70"><vh>method 1</vh></v>
<v t="EKR.20040524104904.71"><vh>method 2</vh></v>
</v>
<v t="EKR.20040524104904.72"><vh>&lt;&lt;class helperClass&gt;&gt;</vh>
<v t="EKR.20040524104904.73"><vh>method 1</vh></v>
<v t="EKR.20040524104904.74"><vh>method 2</vh></v>
</v>
</v>
<v t="EKR.20040524104904.75"><vh>@file bad</vh>
<v t="EKR.20040524104904.76"><vh>Methods</vh>
<v t="EKR.20040524104904.77"><vh>&lt;&lt; section 1 &gt;&gt;</vh>
<v t="EKR.20040524104904.78"><vh>A</vh></v>
</v>
</v>
</v>
</v>
</v>
<v t="EKR.20040524104904.79"><vh>More about directives</vh>
<v t="EKR.20040608091134"><vh>@all directive copies all nodes in @thin trees</vh></v>
<v t="EKR.20040524104904.80"><vh>@color, @nocolor and @killcolor control syntax coloring</vh></v>
<v t="EKR.20040524104904.81"><vh>@comment sets comment delimiters in @root and @unit trees</vh></v>
<v t="EKR.20040524104904.82"><vh>@delims directive specifies comment delimiters in @file trees</vh></v>
<v t="EKR.20040524104904.83"><vh>@encoding directive specifies encoding of text</vh></v>
<v t="EKR.20040524104904.84"><vh>@first and @last directives allow leading and trailing lines in @file trees</vh></v>
<v t="EKR.20040524104904.85"><vh>@language specifying the target language</vh></v>
<v t="EKR.20040524104904.86"><vh>@lineending directive specifies line endings</vh></v>
<v t="EKR.20040524104904.87"><vh>@path, @pagewidth and @tabwidth directives set preferences</vh></v>
<v t="EKR.20040524104904.88"><vh>@raw and @end_raw directives delimit raw text</vh></v>
<v t="EKR.20040524104904.89"><vh>@root options</vh></v>
<v t="EKR.20040524104904.90"><vh>@wrap and @nowrap directives control line wrapping in the body pane</vh></v>
</v>
<v t="EKR.20040524104904.91"><vh>About cweb mode</vh></v>
<v t="EKR.20040524104904.92"><vh>Appendix 1 to Chapter 4: Using @asis, @noref and @nosent trees</vh></v>
<v t="EKR.20040524104904.93"><vh>Appendix 2 to Chapter 4: Using the @root directive, Tangling and Untangling</vh>
<v t="EKR.20040524104904.94"><vh>@root vs. @file trees</vh></v>
<v t="EKR.20040524104904.95"><vh>Sections and section definitions</vh></v>
<v t="EKR.20040524104904.96"><vh>Tangling @root trees with the Tangle commands</vh></v>
<v t="EKR.20040524104904.97"><vh>Untangling @root trees with the Untangle commands</vh></v>
<v t="EKR.20040524104904.98"><vh>@verbose, @terse, @quiet and @silent directives control comments in @root trees</vh></v>
</v>
<v t="EKR.20040608091134.1"><vh>Appendix 3 to Chapter 4: Using @thin instead of @file</vh></v>
</v>
<v t="EKR.20040524104904.99"><vh>Chapter 5: Using Leo's Commands</vh>
<v t="EKR.20040524104904.100"><vh> The File Menu</vh>
<v t="EKR.20040524104904.101"><vh>Loading, Saving and Reverting Files</vh></v>
<v t="EKR.20040524104904.102"><vh>Communicating with external editors</vh>
<v t="EKR.20040524104904.103"><vh>Open With command</vh>
<v t="EKR.20040524104904.104"><vh>createOpenWithMenuFromTable</vh></v>
</v>
</v>
<v t="EKR.20040524104904.105"><vh>Tangling an outline: Producing Derived Files</vh></v>
<v t="EKR.20040524104904.106"><vh>Untangling: updating an outline</vh></v>
<v t="EKR.20040524104904.107"><vh>Tangling and Untangling: the Interface with the IDE</vh></v>
<v t="EKR.20040524104904.108"><vh>Importing Files into Leo Outlines</vh></v>
<v t="EKR.20040524104904.109"><vh>Exporting Files from Leo Outlines</vh></v>
<v t="EKR.20040524104904.110"><vh>Quitting Leo</vh></v>
</v>
<v t="EKR.20040524104904.111"><vh> The Edit Menu</vh>
<v t="EKR.20040524104904.112"><vh>Undoing changes</vh></v>
<v t="EKR.20040524104904.113"><vh>Cutting, pasting and selecting text</vh></v>
<v t="EKR.20040524104904.114"><vh>Shifting body text</vh></v>
<v t="EKR.20040524104904.115"><vh>Creating nodes from body text</vh></v>
<v t="EKR.20040524104904.116"><vh>Converting leading blanks and tabs in body text</vh></v>
<v t="EKR.20040524104904.117"><vh>Executing Python scripts in body text</vh></v>
<v t="EKR.20040524104904.118"><vh>Finding and changing text</vh>
<v t="EKR.20040524104904.119"><vh> Script Find and Script Change</vh>
<v t="EKR.20040524104904.120"><vh>How it works</vh></v>
<v t="EKR.20040524104904.121"><vh>Using the initScriptFind script</vh></v>
<v t="EKR.20040524104904.122"><vh>Ideas for using scripts</vh></v>
</v>
<v t="EKR.20040524104904.123"><vh>Batch</vh></v>
<v t="EKR.20040524104904.124"><vh>Ignore Case</vh></v>
<v t="EKR.20040524104904.125"><vh>Mark Changes</vh></v>
<v t="EKR.20040524104904.126"><vh>Mark Matches</vh></v>
<v t="EKR.20040524104904.127"><vh>Pattern Match</vh></v>
<v t="EKR.20040524104904.128"><vh>Reverse</vh></v>
<v t="EKR.20040524104904.129"><vh>Search Body Text</vh></v>
<v t="EKR.20040524104904.130"><vh>Search Headline Text</vh></v>
<v t="EKR.20040524104904.131"><vh>Suboutline Only</vh></v>
<v t="EKR.20040524104904.132"><vh>Whole Word</vh></v>
<v t="EKR.20040524104904.133"><vh>Wrap Around</vh></v>
</v>
<v t="EKR.20040524104904.134"><vh>Finding locations in outlines corresponding to line in derived files</vh>
<v t="EKR.20040524104904.135"><vh>Go To Line Number command</vh></v>
</v>
<v t="EKR.20040524104904.136"><vh>Inserting the date and time</vh></v>
<v t="EKR.20040524104904.137"><vh>Reformatting paragraphs in body text</vh>
<v t="EKR.20040524104904.138"><vh>Reformat Paragraph command</vh></v>
</v>
<v t="EKR.20040524104904.139"><vh>Matching brackets and parenthesis</vh></v>
<v t="EKR.20040524104904.140"><vh>Setting Preferences</vh>
<v t="EKR.20040524104904.141"><vh>PHP keywords</vh></v>
<v t="EKR.20040524104904.142"><vh>LaTex keywords</vh></v>
</v>
</v>
<v t="EKR.20040524104904.143"><vh> The Outline Menu</vh>
<v t="EKR.20040524104904.144"><vh> Checking outlines</vh></v>
<v t="EKR.20040524104904.145"><vh> Creating and deleting headlines</vh></v>
<v t="EKR.20040524104904.146"><vh> Cutting, pasting and deleting headlines</vh></v>
<v t="EKR.20040524104904.147"><vh> Expanding and contracting headlines</vh></v>
<v t="EKR.20040524104904.148"><vh> Hoisting &amp; De-hoisting headlines</vh></v>
<v t="EKR.20040524104904.149"><vh> Marking headlines</vh></v>
<v t="EKR.20040524104904.150"><vh> Moving, sorting and reorganizing headlines</vh></v>
<v t="EKR.20040524104904.27"><vh>Cloning headlines</vh>
<v t="EKR.20040524104904.28"><vh>read me</vh></v>
<v t="EKR.20040524104904.29"><vh>a</vh>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.34"><vh>g</vh></v>
</v>
<v t="EKR.20040524104904.29"><vh>a</vh>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.30"><vh>b</vh>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
<v t="EKR.20040524104904.31"><vh>c</vh>
<v t="EKR.20040524104904.32"><vh>d</vh></v>
<v t="EKR.20040524104904.33"><vh>e</vh></v>
</v>
</v>
<v t="EKR.20040524104904.34"><vh>g</vh></v>
</v>
<v t="EKR.20040524104904.35"><vh>f</vh></v>
</v>
</v>
<v t="EKR.20040524104904.151"><vh> The Window Menu</vh>
<v t="EKR.20040524104904.152"><vh> Resizing panes</vh></v>
<v t="EKR.20040524104904.153"><vh> Cascading &amp; minimizing windows</vh></v>
<v t="EKR.20040524104904.154"><vh>Toggling the active pane</vh></v>
<v t="EKR.20040524104904.155"><vh>Toggling the orientation of the Leo window</vh></v>
<v t="EKR.20040524104904.156"><vh>Comparing files</vh></v>
</v>
<v t="EKR.20040524104904.157"><vh>The Help Menu</vh>
<v t="EKR.20040524104904.158"><vh>Getting Leo's version</vh></v>
<v t="EKR.20040524104904.159"><vh>Reading documentation</vh></v>
<v t="EKR.20040524104904.160"><vh>Configuring Leo</vh></v>
</v>
</v>
<v t="EKR.20040524104904.161"><vh>Chapter 6: Leo and Literate Programming</vh>
<v t="EKR.20040524104904.162"><vh>Why I like Literate Programming</vh>
<v t="EKR.20040524104904.163"><vh>Literate programming creates a new design dimension</vh></v>
<v t="EKR.20040524104904.164"><vh>Design and coding happen at the highest possible level</vh></v>
<v t="EKR.20040524104904.165"><vh>The visual weight of code is separate from its actual length</vh></v>
<v t="EKR.20040524104904.166"><vh>Sections show relations between snippets of code</vh></v>
<v t="EKR.20040524104904.167"><vh>Complex section names invite improvements</vh></v>
<v t="EKR.20040524104904.168"><vh>Sections create a place for extensive comments</vh></v>
<v t="EKR.20040524104904.169"><vh>Section names eliminate mundane comments</vh></v>
<v t="EKR.20040524104904.170"><vh>Sections create comments automatically</vh></v>
<v t="EKR.20040524104904.171"><vh>Literate programming clarifies the shape of functions</vh></v>
<v t="EKR.20040524104904.172"><vh>I spend less time formatting code</vh></v>
</v>
<v t="EKR.20040524104904.173"><vh>How Leo Improves Literate Programming</vh>
<v t="EKR.20040524104904.174"><vh>Outlines add context</vh></v>
<v t="EKR.20040524104904.175"><vh>Outlines provide scope for commands</vh></v>
<v t="EKR.20040524104904.176"><vh>Clones create different views and focus attention</vh></v>
<v t="EKR.20040524104904.177"><vh>Outlines increase flexibility</vh></v>
<v t="EKR.20040524104904.178"><vh>Outlines express hierarchy directly</vh></v>
<v t="EKR.20040524104904.179"><vh>Outlines create new design dimensions</vh></v>
<v t="EKR.20040524104904.180"><vh>Leo improves tangling and adds untangling</vh></v>
</v>
<v t="EKR.20040524104904.181"><vh>How Leo Changes the Notion of Literate Programming</vh></v>
</v>
<v t="EKR.20040524104904.182"><vh>Chapter 7: Scripting Leo with Python</vh>
<v t="EKR.20040524104904.183"><vh>Overview</vh></v>
<v t="EKR.20040524104904.184"><vh>Basic scripts</vh>
<v t="EKR.20040524104904.185"><vh>Writing to log window</vh></v>
<v t="EKR.20040524104904.186"><vh>Getting commanders and frames</vh></v>
<v t="EKR.20040524104904.187"><vh>Redirecting output from scripts</vh></v>
<v t="EKR.20040524104904.188"><vh>Getting the headline and body text of the presently selected node</vh></v>
<v t="EKR.20040524104904.189"><vh>Setting the headline and body text of the presently selected node</vh></v>
<v t="ekr.20040903095817"><vh>Testing whether a position is valid</vh></v>
<v t="EKR.20040524104904.190"><vh>Traversing all nodes of an outline</vh></v>
<v t="EKR.20040524104904.191"><vh>Iterators</vh>
<v t="EKR.20040524104904.192"><vh>allNodes_iter</vh>
<v t="EKR.20040524104904.193"><vh>Example 1</vh></v>
<v t="EKR.20040524104904.194"><vh>Example 2</vh></v>
</v>
<v t="EKR.20040524104904.195"><vh>children_iter</vh></v>
<v t="EKR.20040524104904.196"><vh>parents_iter</vh></v>
<v t="EKR.20040524104904.197"><vh>siblings_iter</vh></v>
<v t="EKR.20040524104904.198"><vh>subtree_iter</vh></v>
</v>
<v t="EKR.20040524104904.199"><vh>Updating the screen</vh></v>
<v t="EKR.20040524104904.200"><vh>Invoking commands from scripts</vh></v>
<v t="EKR.20040524104904.201"><vh>Getting preferences</vh></v>
<v t="EKR.20040524104904.202"><vh>Setting preferences</vh></v>
<v t="EKR.20040524104904.203"><vh>Functions for finding and changing text from scripts</vh>
<v t="EKR.20040524104904.204"><vh>Example 1: the findAll function</vh></v>
<v t="EKR.20040524104904.205"><vh>Example 2: the reFindAll function</vh></v>
</v>
<v t="EKR.20040524104904.206"><vh>Running Leo in batch mode</vh></v>
<v t="EKR.20040524104904.207"><vh>Functions defined in leoGlobals.py</vh></v>
</v>
<v t="EKR.20040524104904.208"><vh>Summary of the vnode and position classes</vh>
<v t="EKR.20040524104904.191"><vh>Iterators</vh>
<v t="EKR.20040524104904.192"><vh>allNodes_iter</vh>
<v t="EKR.20040524104904.193"><vh>Example 1</vh></v>
<v t="EKR.20040524104904.194"><vh>Example 2</vh></v>
</v>
<v t="EKR.20040524104904.195"><vh>children_iter</vh></v>
<v t="EKR.20040524104904.196"><vh>parents_iter</vh></v>
<v t="EKR.20040524104904.197"><vh>siblings_iter</vh></v>
<v t="EKR.20040524104904.198"><vh>subtree_iter</vh></v>
</v>
<v t="EKR.20040524104904.209"><vh>Getters</vh></v>
<v t="EKR.20040524104904.210"><vh>Setters</vh></v>
</v>
<v t="ekr.20040906100024"><vh>Unit testing with @test, @suite</vh></v>
</v>
<v t="EKR.20040524104904.211"><vh>Chapter 8: Customizing Leo</vh>
<v t="EKR.20040524104904.212"><vh>Using leoConfig.leo and leoConfig.txt</vh></v>
<v t="EKR.20040524104904.213"><vh>Using plugins and hooks</vh>
<v t="EKR.20040524104904.214"><vh>Overview of plugins and hooks</vh></v>
<v t="EKR.20040524104904.215"><vh>New plugin architecture</vh>
<v t="EKR.20040524104904.216"><vh>@file plugins/mod_open_with.py</vh>
<v t="EKR.20040524104904.217"><vh>on_idle</vh>
<v t="EKR.20040524104904.218"><vh>&lt;&lt; update v's body text &gt;&gt;</vh>
<v t="EKR.20040524104904.219"><vh>&lt;&lt; set s to the new text &gt;&gt;</vh></v>
<v t="EKR.20040524104904.220"><vh>&lt;&lt; set conflict flag &gt;&gt;</vh></v>
</v>
</v>
<v t="EKR.20040524104904.221"><vh>create_open_with_menu</vh>
<v t="EKR.20040524104904.222"><vh>&lt;&lt; create the Open With menu &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="EKR.20040524104904.223"><vh>About hooks</vh></v>
<v t="EKR.20040524104904.224"><vh>SECURITY WARNINGS</vh>
<v t="EKR.20040524104904.225"><vh>The danger of trusting code in shared .leo files</vh></v>
<v t="EKR.20040524104904.226"><vh>NEVER use this kind of code in a hook!!</vh></v>
<v t="EKR.20040524104904.227"><vh>Don't use rexec !!</vh>
<v t="EKR.20040524104904.228"><vh>&lt;&lt; change all instances of rexec to exec in v's body &gt;&gt;</vh></v>
<v t="EKR.20040524104904.229"><vh>&lt;&lt; delete thisNode &gt;&gt;</vh></v>
<v t="EKR.20040524104904.230"><vh>&lt;&lt; clear the undo stack &gt;&gt;</vh></v>
</v>
</v>
<v t="EKR.20040524104904.231"><vh>Convenience routines for plugins</vh>
<v t="EKR.20040524104904.232"><vh>Convenience functions to enable and disable the "idle" hook</vh></v>
<v t="EKR.20040524104904.233"><vh>Convenience methods to create, destroy and modify menus</vh>
<v t="EKR.20040524104904.234"><vh>createMenuItemsFromTable</vh></v>
<v t="EKR.20040524104904.235"><vh>createNewMenu</vh></v>
<v t="EKR.20040524104904.104"><vh>createOpenWithMenuFromTable</vh></v>
<v t="EKR.20040524104904.236"><vh>deleteMenu</vh></v>
<v t="EKR.20040524104904.237"><vh>deleteMenuItem</vh></v>
<v t="EKR.20040524104904.238"><vh>Example: how to create a menu</vh></v>
</v>
</v>
<v t="EKR.20040524104904.239"><vh>Translating menus into other languages</vh></v>
<v t="EKR.20040524104904.240"><vh>Support for unit testing</vh></v>
</v>
<v t="EKR.20040524104904.241"><vh>Putting the Leo icon in Leo windows</vh></v>
<v t="EKR.20040524104904.242"><vh>Extending the format of .leo files</vh></v>
<v t="EKR.20040524104904.243"><vh>Attaching temporary attributes to vnodes and tnodes</vh></v>
<v t="EKR.20040524104904.244"><vh>Recommended conventions for plugins</vh></v>
<v t="EKR.20040524104904.119"><vh> Script Find and Script Change</vh>
<v t="EKR.20040524104904.120"><vh>How it works</vh></v>
<v t="EKR.20040524104904.121"><vh>Using the initScriptFind script</vh></v>
<v t="EKR.20040524104904.122"><vh>Ideas for using scripts</vh></v>
</v>
</v>
<v t="EKR.20040524104904.245"><vh>Chapter 9: History of Leo</vh>
<v t="EKR.20040524104904.246"><vh>Beginnings</vh></v>
<v t="EKR.20040524104904.247"><vh>Versions, and more versions</vh></v>
<v t="EKR.20040524104904.248"><vh>Designing @file trees</vh>
<v t="EKR.20040524104904.249"><vh>Deciding to do Leo2</vh></v>
<v t="EKR.20040524104904.250"><vh>A prototype</vh></v>
<v t="EKR.20040524104904.251"><vh>User interaction</vh></v>
<v t="EKR.20040524104904.252"><vh>The write code</vh></v>
<v t="EKR.20040524104904.253"><vh>The read code</vh></v>
<v t="EKR.20040524104904.254"><vh>The load/save code</vh></v>
<v t="EKR.20040524104904.255"><vh>Attributes, mirroring and dummy nodes</vh></v>
<v t="EKR.20040524104904.256"><vh>Clones</vh></v>
<v t="EKR.20040524104904.257"><vh>Error recovery, at last</vh></v>
</v>
<v t="EKR.20040524104904.258"><vh>White papers</vh>
<v t="EKR.20040524104904.259"><vh>tk is the future of Leo</vh></v>
<v t="EKR.20040524104904.260"><vh>Why I like Python</vh></v>
</v>
</v>
<v t="EKR.20040524104904.261"><vh>Chapter 10: Theory of Operation</vh>
<v t="EKR.20040524104904.262"><vh>Overview</vh></v>
<v t="EKR.20040524104904.263"><vh>Nodes</vh></v>
<v t="EKR.20040524104904.264"><vh>Drawing and events</vh></v>
<v t="EKR.20040524104904.265"><vh>Clones</vh></v>
<v t="EKR.20040524104904.266"><vh>Find and change commands</vh></v>
<v t="EKR.20040524104904.267"><vh>Tangle and Untangle commands</vh></v>
<v t="EKR.20040524104904.268"><vh>Unicode theory of operation</vh></v>
<v t="EKR.20040524104904.269"><vh>Unlimited undo</vh></v>
<v t="EKR.20040524104904.273"><vh>4.0 Theory of operation</vh></v>
</v>
<v t="EKR.20040524104904.274"><vh>Appendices</vh>
<v t="EKR.20040524104904.275"><vh>Code hidden in leo.py</vh>
<v t="EKR.20040524104904.276"><vh>c2py.py</vh></v>
<v t="EKR.20040524104904.277"><vh>disStats.py</vh></v>
<v t="EKR.20040524104904.278"><vh>Tkinter utilities</vh></v>
<v t="EKR.20040524104904.279"><vh>Font dialog</vh></v>
<v t="EKR.20040524104904.280"><vh>Syntax coloring code</vh></v>
<v t="EKR.20040524104904.281"><vh>Tree code</vh></v>
</v>
<v t="EKR.20040524104904.282"><vh>Converting @root trees to @file trees</vh></v>
<v t="EKR.20040524104904.283"><vh>Directives</vh>
<v t="EKR.20040524104904.284"><vh>@c and @code</vh></v>
<v t="EKR.20040524104904.285"><vh>@chapter (Macintosh only)</vh></v>
<v t="EKR.20040524104904.286"><vh>@color</vh></v>
<v t="EKR.20040524104904.287"><vh>@comment</vh></v>
<v t="EKR.20040524104904.288"><vh>@delims (not valid in @root or @unit trees)</vh></v>
<v t="EKR.20040524104904.289"><vh>@doc and @(space)</vh></v>
<v t="EKR.20040524104904.290"><vh>@encoding</vh></v>
<v t="EKR.20040524104904.291"><vh>@file (not valid in @root or @unit trees)</vh></v>
<v t="EKR.20040524104904.292"><vh>@first (not valid in @root or @unit trees)</vh></v>
<v t="EKR.20040524104904.293"><vh>@ignore  (not valid in @file trees)</vh></v>
<v t="EKR.20040524104904.294"><vh>@language</vh></v>
<v t="EKR.20040524104904.295"><vh>@nocolor</vh></v>
<v t="EKR.20040524104904.296"><vh>@others (valid only in @file trees)</vh></v>
<v t="EKR.20040524104904.297"><vh>@pagewidth</vh></v>
<v t="EKR.20040524104904.298"><vh>@path</vh></v>
<v t="EKR.20040524104904.299"><vh>@root  (not valid in @file trees)</vh></v>
<v t="EKR.20040524104904.300"><vh>@section (Macintosh only)</vh></v>
<v t="EKR.20040524104904.301"><vh>@silent (not valid in @file trees)</vh></v>
<v t="EKR.20040524104904.302"><vh>@tabwidth</vh></v>
<v t="EKR.20040524104904.303"><vh>@terse  (not valid in @file trees)</vh></v>
<v t="EKR.20040524104904.304"><vh>@unit   (not valid in @file trees)</vh></v>
<v t="EKR.20040524104904.305"><vh>@verbose, @terse and @silent directives</vh></v>
</v>
<v t="EKR.20040524104904.306"><vh>Error Messages</vh>
<v t="EKR.20040524104904.307"><vh>Errors while tangling</vh>
<v t="EKR.20040524104904.308"><vh>Can not re-open temp file</vh></v>
<v t="EKR.20040524104904.309"><vh>Can not rename temporary file name</vh></v>
<v t="EKR.20040524104904.310"><vh>@code expects the header: [text of header] to contain a section name</vh></v>
<v t="EKR.20040524104904.311"><vh>@directive not valid here</vh></v>
<v t="EKR.20040524104904.312"><vh>Halting Tangle: too many errors</vh></v>
<v t="EKR.20040524104904.313"><vh>Invalid recursive reference of &lt;&lt; section name &gt;&gt;</vh></v>
<v t="EKR.20040524104904.314"><vh>Multiple parts not allowed for &lt;&lt; section name &gt;&gt;</vh></v>
<v t="EKR.20040524104904.315"><vh>No file written because of errors</vh></v>
<v t="EKR.20040524104904.316"><vh>Run on comment</vh></v>
<v t="EKR.20040524104904.317"><vh>Run on file name in @root directive</vh></v>
<v t="EKR.20040524104904.318"><vh>Run on section name</vh></v>
<v t="EKR.20040524104904.319"><vh>Run on string</vh></v>
<v t="EKR.20040524104904.320"><vh>Section definition not valid here.</vh></v>
<v t="EKR.20040524104904.321"><vh>Sections nested too deeply</vh></v>
<v t="EKR.20040524104904.322"><vh>The outline contains no roots</vh></v>
<v t="EKR.20040524104904.323"><vh>Undefined section:  &lt;&lt;&lt; section name &gt;&gt;&gt;</vh></v>
<v t="EKR.20040524104904.324"><vh>Unexpected @directive while putting code</vh></v>
<v t="EKR.20040524104904.325"><vh>Warning: possible duplicate definition of: &lt;&lt;&lt; section name &gt;&gt;&gt;</vh></v>
<v t="EKR.20040524104904.326"><vh>Warning: &lt;&lt;&lt; section name &gt;&gt;&gt; has been defined but not used</vh></v>
</v>
<v t="EKR.20040524104904.327"><vh>Errors while untangling</vh>
<v t="EKR.20040524104904.328"><vh>Incompatible definitions of &lt;&lt;&lt; section name &gt;&gt;&gt;</vh></v>
<v t="EKR.20040524104904.329"><vh>Missing root part</vh></v>
<v t="EKR.20040524104904.330"><vh>Missing root section</vh></v>
<v t="EKR.20040524104904.331"><vh>Missing sentinel line for &lt;&lt;&lt; section name &gt;&gt;&gt;</vh></v>
<v t="EKR.20040524104904.332"><vh>Unterminated section: &lt;&lt;&lt; section name &gt;&gt;&gt;</vh></v>
</v>
<v t="EKR.20040524104904.333"><vh>Errors while reading @file nodes</vh>
<v t="EKR.20040524104904.334"><vh>Minor errors</vh></v>
<v t="EKR.20040524104904.335"><vh>Serious errors</vh></v>
</v>
<v t="EKR.20040524104904.336"><vh>Errors while writing @file nodes</vh></v>
</v>
<v t="EKR.20040524104904.337"><vh>Format of derived files (3.x)</vh>
<v t="EKR.20040524104904.338"><vh>Sentinels in derived files</vh>
<v t="EKR.20040524104904.339"><vh>The @delims directive</vh></v>
<v t="EKR.20040524104904.340"><vh>@leo &amp; comment delimiters</vh></v>
<v t="EKR.20040524104904.341"><vh>@node</vh></v>
<v t="EKR.20040524104904.342"><vh>@body</vh></v>
<v t="EKR.20040524104904.343"><vh>@at and @doc &amp; the trailing whitespace convention</vh></v>
<v t="EKR.20040524104904.344"><vh>@others</vh></v>
<v t="EKR.20040524104904.345"><vh>@@delims</vh></v>
<v t="EKR.20040524104904.346"><vh>@@&lt;text&gt;</vh></v>
<v t="EKR.20040524104904.347"><vh>@verbatim and @verbatimAfterRef</vh></v>
<v t="EKR.20040524104904.348"><vh>@&lt;&lt;section name&gt;&gt;</vh></v>
</v>
</v>
<v t="EKR.20040524104904.349"><vh>Format of derived files (4.x)</vh></v>
<v t="EKR.20040524104904.350"><vh>Future Features</vh></v>
<v t="EKR.20040524104904.351"><vh>Known Bugs &amp; Limitations</vh></v>
<v t="EKR.20040524104904.352"><vh>Reference for @file trees</vh></v>
<v t="EKR.20040524104904.354"><vh>Unicode</vh>
<v t="EKR.20040524104904.355"><vh>How Leo handles unicode</vh></v>
<v t="EKR.20040524104904.356"><vh>Unicode settings</vh></v>
</v>
<v t="EKR.20040524104904.357"><vh>XML file format</vh>
<v t="EKR.20040524104904.358"><vh>Summary of the file format</vh></v>
<v t="EKR.20040524104904.359"><vh>&lt;?xml ... ?&gt;</vh></v>
<v t="EKR.20040524104904.360"><vh>&lt;leo_file&gt; ... &lt;/leo_file&gt;</vh>
<v t="EKR.20040524104904.361"><vh>&lt;leo_header ... /&gt;</vh></v>
<v t="EKR.20040524104904.362"><vh>&lt;globals ... &gt; ... &lt;/globals&gt;</vh></v>
<v t="EKR.20040524104904.363"><vh>&lt;preferences ... &gt; ... &lt;/preferences&gt;</vh></v>
<v t="EKR.20040524104904.364"><vh>&lt;find_panel_settings ... &gt; ... &lt;/find_panel_settings&gt;</vh></v>
<v t="EKR.20040524104904.365"><vh>&lt;vnodes&gt;...&lt;/vnodes&gt;</vh>
<v t="EKR.20040524104904.366"><vh>&lt;v...&gt; ... &lt;/v&gt;</vh></v>
</v>
<v t="EKR.20040524104904.367"><vh>&lt;tnodes&gt; ... &lt;/tnodes&gt;</vh>
<v t="EKR.20040524104904.368"><vh>&lt;t...&gt; ... &lt;/t&gt;</vh></v>
</v>
<v t="EKR.20040524104904.369"><vh>&lt;clone_windows&gt; ... &lt;/clone_windows&gt;</vh>
<v t="EKR.20040524104904.370"><vh>&lt;clone_window ...&gt; ... &lt;/clone_window&gt;</vh></v>
</v>
</v>
<v t="EKR.20040524104904.371"><vh>DTD for Leo's File Format</vh></v>
<v t="EKR.20040524104904.372"><vh>An example file</vh>
<v t="EKR.20040524104904.373"><vh>The file itself</vh></v>
<v t="EKR.20040524104904.374"><vh>The outline  from which the example file was created</vh>
<v t="EKR.20040524104904.375"><vh>Headline 1</vh>
<v t="EKR.20040524104904.376"><vh>Headline 2</vh>
<v t="EKR.20040524104904.377"><vh>Headline 3 ( No body text)</vh></v>
</v>
</v>
<v t="EKR.20040524104904.378"><vh>Headline 4 ( a clone )</vh>
<v t="EKR.20040524104904.379"><vh>Headline 5</vh></v>
</v>
<v t="EKR.20040524104904.378"><vh>Headline 4 ( a clone )</vh>
<v t="EKR.20040524104904.379"><vh>Headline 5</vh></v>
</v>
</v>
</v>
</v>
</v>
<v t="EKR.20040524104904.380"><vh>Glossary</vh>
<v t="EKR.20040524104904.381"><vh>@file node, @others node, @root node, etc.</vh></v>
<v t="EKR.20040524104904.382"><vh>@file tree, @others tree, @root tree, etc.</vh></v>
<v t="EKR.20040524104904.383"><vh>Body pane</vh></v>
<v t="EKR.20040524104904.384"><vh>Body text</vh></v>
<v t="EKR.20040524104904.385"><vh>Body text box</vh></v>
<v t="EKR.20040524104904.386"><vh>Child</vh></v>
<v t="EKR.20040524104904.387"><vh>Chunk</vh></v>
<v t="EKR.20040524104904.388"><vh>Clone</vh></v>
<v t="EKR.20040524104904.389"><vh>Clone Arrow</vh></v>
<v t="EKR.20040524104904.390"><vh>Code section</vh></v>
<v t="EKR.20040524104904.391"><vh>CWEB</vh></v>
<v t="EKR.20040524104904.392"><vh>Demote</vh></v>
<v t="EKR.20040524104904.393"><vh>Derived file</vh></v>
<v t="EKR.20040524104904.394"><vh>Descendent</vh></v>
<v t="EKR.20040524104904.395"><vh>Directive</vh></v>
<v t="EKR.20040524104904.396"><vh>Doc section</vh></v>
<v t="EKR.20040524104904.397"><vh>Escape convention</vh></v>
<v t="EKR.20040524104904.398"><vh>Grandchild</vh></v>
<v t="EKR.20040524104904.399"><vh>Headline</vh></v>
<v t="EKR.20040524104904.400"><vh>Hoist &amp; dehoist</vh></v>
<v t="EKR.20040524104904.401"><vh>Leo, Leo1 and Leo2</vh></v>
<v t="EKR.20040524104904.402"><vh>Literate programming</vh></v>
<v t="EKR.20040524104904.403"><vh>Marking</vh></v>
<v t="EKR.20040524104904.404"><vh>Named nodes</vh></v>
<v t="EKR.20040524104904.405"><vh>Node</vh></v>
<v t="EKR.20040524104904.406"><vh>noweb</vh></v>
<v t="EKR.20040524104904.407"><vh>Offspring</vh></v>
<v t="EKR.20040524104904.408"><vh>Organizing node</vh></v>
<v t="EKR.20040524104904.409"><vh>Orphan node</vh></v>
<v t="EKR.20040524104904.410"><vh>Outline</vh></v>
<v t="EKR.20040524104904.411"><vh>Outline pane</vh></v>
<v t="EKR.20040524104904.412"><vh>Parent</vh></v>
<v t="EKR.20040524104904.413"><vh>Part</vh></v>
<v t="EKR.20040524104904.414"><vh>pdf file</vh></v>
<v t="EKR.20040524104904.415"><vh>Promote</vh></v>
<v t="EKR.20040524104904.416"><vh>Root</vh></v>
<v t="EKR.20040524104904.417"><vh>Scope</vh></v>
<v t="EKR.20040524104904.418"><vh>Section</vh></v>
<v t="EKR.20040524104904.419"><vh>Section name</vh></v>
<v t="EKR.20040524104904.420"><vh>Section reference</vh></v>
<v t="EKR.20040524104904.421"><vh>Sentinels, sentinel lines</vh></v>
<v t="EKR.20040524104904.422"><vh>Sibling</vh></v>
<v t="EKR.20040524104904.423"><vh>Status Icon</vh></v>
<v t="EKR.20040524104904.424"><vh>Tangling</vh></v>
<v t="EKR.20040524104904.425"><vh>Target language</vh></v>
<v t="EKR.20040524104904.426"><vh>Tree</vh></v>
<v t="EKR.20040524104904.427"><vh>Unnamed node</vh></v>
<v t="EKR.20040524104904.428"><vh>Untangling</vh></v>
<v t="EKR.20040524104904.429"><vh>Weaving</vh></v>
</v>
</v>
<v t="edream.110203163054.1050"><vh>FAQ</vh>
<v t="edream.110203163054.1051"><vh>Learning about Leo</vh>
<v t="edream.110203163054.1052"><vh>What's the best way to learn to use Leo?</vh></v>
<v t="edream.110203163054.1053"><vh>Where are the simple examples?</vh></v>
<v t="edream.110203163054.1054"><vh>Why should I use clones?</vh></v>
<v t="edream.110203163054.1055"><vh>Which should I use: @root trees or @file trees?</vh></v>
<v t="ekr.20040411074926"><vh>How can I use Leo to develop Leo itself?</vh></v>
</v>
<v t="edream.110203163054.1056"><vh>Unicode and special characters</vh>
<v t="edream.110203163054.1057"><vh>Some characters in derived files look funny. What can I do?</vh></v>
<v t="edream.110203163054.1058"><vh>Some characters are garbled when importing files. What can I do?</vh></v>
</v>
<v t="edream.110203163054.1059"><vh>Using derived files</vh>
<v t="edream.110203163054.1060"><vh>How do I prevent Leo from inserting sentinels in derived files?</vh>
<v t="edream.110203163054.359"><vh>Appendix 1 to Chapter 4: Using @rawfile, @silentfile and @nosentinlefile trees</vh></v>
</v>
<v t="edream.110203163054.1061"><vh>How do I prevent Leo from expanding sections?</vh>
<v t="edream.110203163054.359"><vh>Appendix 1 to Chapter 4: Using @rawfile, @silentfile and @nosentinlefile trees</vh></v>
</v>
<v t="edream.110203163054.1062"><vh>How do I generate files after using the Import commands?</vh></v>
<v t="edream.110203163054.1063"><vh>How can I create Javascript comments?</vh></v>
<v t="edream.110203163054.1064"><vh>How can I disable PHP comments?</vh></v>
<v t="ekr.20040201114855.108"><vh>How can I use Leo with unsuppoorted languages?</vh></v>
<v t="edream.110203163054.1065"><vh>How do I make derived files start with a shebang line?</vh></v>
<v t="edream.110203163054.1066"><vh>How do I use Leo to create cweb files?</vh>
<v t="edream.110203163054.355"><vh>About cweb mode </vh></v>
</v>
<v t="edream.110203163054.1067"><vh>Can @file trees contain material not in the derived file?</vh></v>
<v t="EKR.20040521090400"><vh>How can I use Leo with older C compilers</vh></v>
<v t="ekr.20040804173200.6"><vh>How does @thin make Leo more friendly to CVS?</vh></v>
</v>
<v t="edream.110203163054.1068"><vh>Customizing Leo</vh>
<v t="edream.110203163054.322"><vh>Overview of plugins and hooks</vh></v>
<v t="edream.110203163054.1069"><vh>I'm having trouble getting plugins to work.  What should I do?</vh></v>
<v t="edream.110203163054.1070"><vh>How can I add support for a new language?</vh></v>
<v t="edream.110203163054.319"><vh>Chapter 8: Customizing Leo</vh>
<v t="edream.110203163054.320"><vh>Using leoConfig.leo and leoConfig.txt</vh></v>
<v t="edream.110203163054.321"><vh>Using plugins and hooks</vh>
<v t="edream.110203163054.322"><vh>Overview of plugins and hooks</vh></v>
<v t="edream.110203163054.323"><vh>New plugin architecture</vh>
<v t="edream.110203163054.324"><vh>@file plugins/mod_open_with.py</vh>
<v t="edream.110203163054.325"><vh>on_idle</vh>
<v t="edream.110203163054.326"><vh>&lt;&lt; update v's body text &gt;&gt;</vh>
<v t="edream.110203163054.327"><vh>&lt;&lt; set s to the new text &gt;&gt;</vh></v>
<v t="edream.110203163054.328"><vh>&lt;&lt; set conflict flag &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203163054.329"><vh>create_open_with_menu</vh>
<v t="edream.110203163054.330"><vh>&lt;&lt; create the Open With menu &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.172"><vh>About hooks</vh></v>
<v t="edream.110203163054.331"><vh>SECURITY WARNINGS</vh>
<v t="edream.110203163054.332"><vh>The danger of trusting code in shared .leo files</vh></v>
<v t="edream.110203163054.333"><vh>NEVER use this kind of code in a hook!!</vh></v>
<v t="edream.110203163054.334"><vh>Don't use rexec !!</vh>
<v t="edream.110203163054.335"><vh>&lt;&lt; change all instances of rexec to exec in v's body &gt;&gt;</vh></v>
<v t="edream.110203163054.336"><vh>&lt;&lt; delete thisNode &gt;&gt;</vh></v>
<v t="edream.110203163054.337"><vh>&lt;&lt; clear the undo stack &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203163054.338"><vh>Convenience routines for plugins</vh>
<v t="edream.110203163054.339"><vh>Convenience functions to enable and disable the "idle" hook</vh></v>
<v t="edream.110203163054.340"><vh>Convenience methods to create, destroy and modify menus</vh>
<v t="edream.110203163054.341"><vh>createMenuItemsFromTable</vh></v>
<v t="edream.110203163054.342"><vh>createNewMenu</vh></v>
<v t="edream.110203163054.343"><vh>createOpenWithMenuFromTable</vh></v>
<v t="edream.110203163054.344"><vh>deleteMenu</vh></v>
<v t="edream.110203163054.345"><vh>deleteMenuItem</vh></v>
<v t="edream.110203163054.346"><vh>Example: how to create a menu</vh></v>
</v>
</v>
<v t="edream.110203163054.347"><vh>Translating menus into other languages</vh></v>
<v t="edream.121403162622"><vh>Support for unit testing</vh></v>
</v>
<v t="edream.110203163054.61"><vh>Putting the Leo icon in Leo windows</vh></v>
<v t="edream.110203163054.348"><vh>Extending the format of .leo files</vh></v>
<v t="edream.120703073611"><vh>Attaching temporary attributes to vnodes and tnodes</vh></v>
<v t="edream.120703073611.1"><vh>Recommended conventions for plugins</vh></v>
<v t="edream.110603190322.6"><vh> Script Find and Script Change</vh>
<v t="edream.111803060152.1"><vh>How it works</vh></v>
<v t="ekr.20040201113232"><vh>Using the initScriptFind script</vh></v>
<v t="edream.111803060152.2"><vh>Ideas for using scripts</vh></v>
</v>
</v>
</v>
<v t="edream.120903151103"><vh>Importing files</vh>
<v t="edream.120903151103.1"><vh>How can I import many files at once?</vh></v>
</v>
<v t="edream.110203163054.1071"><vh>Other topics</vh>
<v t="ekr.20040805102623"><vh>How can I use Python's pdb debugger with Leo?</vh></v>
<v t="edream.110203163054.1073"><vh>How can I add support in Leo for a new language?</vh>
<v t="edream.110203163054.1074"><vh>code</vh>
<v t="edream.110203163054.1075"><vh>&lt;&lt; define global constants &gt;&gt;</vh></v>
<v t="edream.110203163054.1076"><vh>&lt;&lt; Create the Target Language frame &gt;&gt;</vh></v>
<v t="edream.110203163054.1077"><vh>&lt;&lt; define colorizer keywords &gt;&gt;</vh></v>
<v t="edream.110203163054.1078"><vh>&lt;&lt; configure language-specific settings &gt;&gt;</vh></v>
<v t="edream.110203163054.1079"><vh>&lt;&lt; check for syntax coloring prefs &gt;&gt;</vh></v>
<v t="edream.110203163054.1080"><vh>&lt;&lt; initialize constant ivars &gt;&gt;</vh></v>
<v t="edream.110203163054.1081"><vh>set_delims_from_language</vh></v>
<v t="edream.110203163054.1082"><vh>set_language</vh></v>
<v t="edream.110203163054.1083"><vh>colorizeAnyLanguage</vh>
<v t="edream.110203163054.1084"><vh>&lt;&lt; configure tags &gt;&gt;</vh></v>
<v t="edream.110203163054.1078"><vh>&lt;&lt; configure language-specific settings &gt;&gt;</vh></v>
<v t="edream.110203163054.1085"><vh>Multiline State Handlers</vh>
<v t="edream.110203163054.1086"><vh>&lt;&lt; continue doc part &gt;&gt;</vh>
<v t="edream.110203163054.1087"><vh>&lt;&lt; handle cweb doc part &gt;&gt;</vh></v>
<v t="edream.110203163054.1088"><vh>&lt;&lt; handle noweb doc part &gt;&gt;</vh></v>
</v>
<v t="edream.110203163054.1089"><vh>&lt;&lt; continue python triple string &gt;&gt;</vh></v>
<v t="edream.110203163054.1090"><vh>&lt;&lt; continue block comment &gt;&gt;</vh></v>
<v t="edream.110203163054.1091"><vh>&lt;&lt; continue nocolor state &gt;&gt;</vh></v>
</v>
<v t="edream.110203163054.1092"><vh>&lt;&lt; handle string &gt;&gt;</vh></v>
<v t="edream.110203163054.1093"><vh>&lt;&lt; start block comment &gt;&gt;</vh></v>
<v t="edream.110203163054.1094"><vh>&lt;&lt; handle single-line comment &gt;&gt;</vh></v>
<v t="edream.110203163054.1095"><vh>&lt;&lt; handle C preprocessor line &gt;&gt;</vh></v>
<v t="edream.110203163054.1096"><vh>&lt;&lt; handle possible section ref or def &gt;&gt;</vh>
<v t="edream.110203163054.1097"><vh>&lt;&lt; set the hyperlink &gt;&gt;</vh></v>
</v>
<v t="edream.110203163054.1098"><vh>&lt;&lt; handle possible @keyword &gt;&gt;</vh>
<v t="edream.110203163054.1099"><vh>&lt;&lt; Handle all cweb control codes &gt;&gt;</vh></v>
<v t="edream.110203163054.1100"><vh>&lt;&lt; Handle non-cweb @keywords &gt;&gt;</vh></v>
</v>
<v t="edream.110203163054.1101"><vh>&lt;&lt; handle possible  keyword &gt;&gt;</vh></v>
<v t="edream.110203163054.1102"><vh>&lt;&lt; handle blank &gt;&gt;</vh></v>
<v t="edream.110203163054.1103"><vh>&lt;&lt; handle tab &gt;&gt;</vh></v>
<v t="edream.110203163054.1104"><vh>&lt;&lt; handle normal character &gt;&gt;</vh></v>
</v>
<v t="edream.110203163054.1105"><vh>getPrefs</vh>
<v t="edream.110203163054.1079"><vh>&lt;&lt; check for syntax coloring prefs &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203163054.1106"><vh>@root tcl/tk test</vh>
<v t="edream.110203163054.1107"><vh>&lt;&lt; stuff &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203163054.1108"><vh>How can I create a template .leo file?</vh></v>
<v t="ekr.20040411074926"><vh>How can I use Leo to develop Leo itself?</vh></v>
<v t="ekr.20040908100113"><vh>Control-Shift backspace doesn't work.  What should I do?</vh></v>
</v>
</v>
<v t="edream.110203163054.1158"><vh>Sample Code</vh>
<v t="edream.112303173638"><vh>Running Leo in batch mode</vh></v>
<v t="edream.110203163054.1162"><vh>Hello World using @file</vh>
<v t="edream.110203163054.1163"><vh>@file sampleHello.c</vh>
<v t="edream.110203163054.1164"><vh>&lt;&lt; includes &gt;&gt;</vh></v>
<v t="edream.110203163054.1165"><vh>main</vh></v>
</v>
</v>
</v>
<v t="edream.110203163054.1653"><vh>Leaps (Leo Enhancement and Advancement Proposals)</vh>
<v t="edream.110203163054.1654"><vh>100's administering Leaps (and LeoCon)</vh>
<v t="edream.110203163054.1655"><vh>Leap 102: LeoCon 1</vh></v>
</v>
<v t="edream.110203163054.1656"><vh>200's single-user Leo</vh>
<v t="edream.110203163054.1657"><vh>Leap 201. (Finished)  Represent clones as shared trees of vnodes</vh></v>
<v t="edream.110203163054.1658"><vh>Leap 202. (Finished) Create cvs-friendly file format for derived files</vh></v>
<v t="edream.110203163054.1659"><vh>Leap 203. (Open) Use Python Mega Widgets</vh></v>
</v>
<v t="edream.110203163054.1661"><vh>300's LeoN and beyond</vh>
<v t="edream.110203163054.1662"><vh>Leap 301: Use central server</vh></v>
<v t="edream.110203163054.1663"><vh>Leap 302: Produce a plugin for a Resolve CVS Conflicts command</vh>
<v t="edream.110203163054.1664"><vh>Comments by Josef</vh></v>
</v>
</v>
</v>
<v t="ekr.20040414161647"><vh>Leo's HTML Users Guide (Created using the rst2 plugin)</vh>
<v t="ekr.20040414162124"><vh>@rst leo_TOC.html</vh>
<v t="ekr.20040414163815"><vh>Table of Contents</vh>
<v t="ekr.20040414163815.1"><vh>@rst</vh></v>
</v>
</v>
<v t="ekr.20040414172212"><vh>@rst frontMatter.html</vh>
<v t="ekr.20040414172218.2"><vh>Preface</vh>
<v t="ekr.20040414172336"><vh>@rst</vh></v>
<v t="ekr.20040416070800"><vh>@rst</vh></v>
<v t="ekr.20040416070800.1"><vh>@rst</vh></v>
</v>
<v t="ekr.20040414172218.4"><vh>Acknowledgements</vh>
<v t="ekr.20040414172617"><vh>@rst</vh></v>
<v t="ekr.20040416075437"><vh>@rst</vh></v>
<v t="ekr.20040416080538"><vh>@rst</vh></v>
</v>
<v t="ekr.20040414172218.5"><vh>Copyright</vh>
<v t="ekr.20040414172617.1"><vh>@rst</vh></v>
</v>
<v t="ekr.20040414174439"><vh>DISCLAIMER OF LIABILITY</vh>
<v t="ekr.20040414174439.1"><vh>@rst</vh></v>
</v>
</v>
<v t="ekr.20040403171740"><vh>@rst scripting.html</vh>
<v t="ekr.20040403183229"><vh>Overview</vh>
<v t="ekr.20040403183229.1"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403175011"><vh>g.top(): the commander of the top window</vh>
<v t="ekr.20040403175011.1"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.3"><vh>g.es(): write to the log pane</vh>
<v t="ekr.20040403175257"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403175157.1"><vh>app.windowList: the list of all open frames</vh>
<v t="ekr.20040403175157.2"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.6"><vh>Getting and setting headline and body text</vh>
<v t="ekr.20040403180217"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.9"><vh>Traversing outlines</vh>
<v t="ekr.20040403183934"><vh>@rst</vh>
<v t="ekr.20040403173920.10"><vh>c.allNodes_iter</vh>
<v t="ekr.20040403185643"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.13"><vh>p.children_iter</vh>
<v t="ekr.20040403185803"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.14"><vh>p.parents_iter and p.self_and_parents_iter</vh>
<v t="ekr.20040403185803.1"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.15"><vh>p.siblings_iter and p.following_siblings_iter</vh>
<v t="ekr.20040403185803.2"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.16"><vh>p.subtree_iter and p.self_and_subtree_iter</vh>
<v t="ekr.20040403185803.3"><vh>@rst</vh></v>
</v>
<v t="ekr.20040903100514"><vh>Testing whether a position is valid</vh>
<v t="ekr.20040903100514.1"><vh>@rst</vh></v>
</v>
</v>
</v>
<v t="ekr.20040403173920.17"><vh>Updating the screen</vh>
<v t="ekr.20040403183934.1"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.18"><vh>Invoking commands from scripts</vh>
<v t="ekr.20040403183934.2"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.19"><vh>Getting and setting preferences</vh>
<v t="ekr.20040403183934.3"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.21"><vh>Functions for finding and changing text from scripts</vh>
<v t="ekr.20040403184306.1"><vh>@rst</vh>
<v t="ekr.20040403191729"><vh>g.findAll</vh>
<v t="ekr.20040403173920.22"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403191729.1"><vh>g.reFindall</vh>
<v t="ekr.20040403173920.23"><vh>@rst</vh></v>
</v>
</v>
</v>
<v t="ekr.20040403173920.24"><vh>Running Leo in batch mode</vh>
<v t="ekr.20040403184306.2"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.25"><vh>Functions defined in leoGlobals.py</vh>
<v t="ekr.20040403184306.3"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.5"><vh>Redirecting output from scripts</vh>
<v t="ekr.20040403183718"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.26"><vh>Summary of the vnode and position classes</vh>
<v t="ekr.20040403184306.4"><vh>@rst</vh>
<v t="ekr.20040411151245"><vh>Iterators</vh>
<v t="ekr.20040411151245.1"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.27"><vh>Getters</vh>
<v t="ekr.20040403192653"><vh>@rst</vh></v>
</v>
<v t="ekr.20040403173920.28"><vh>Setters</vh>
<v t="ekr.20040403192653.1"><vh>@rst</vh></v>
</v>
</v>
</v>
<v t="ekr.20040906100201"><vh>Unit testing with @test and @suite</vh>
<v t="ekr.20040906100201.1"><vh>@rst</vh></v>
</v>
</v>
</v>
</vnodes>
<tnodes>
<t tx="EKR.20040518070558">Leo 4.2 alpha 2           May 18, 2004

This is an important milestone in Leo's history; the two defining features of the 4.2 code base are complete:

1. This is the first stable version using the "shared nodes" code base.

Shared nodes dramatically improve the time needed to insert, delete, and move nodes.  Moreover, the new code base is code compatible with the old.  Indeed, much of Leo still uses the old code base.  See Chapter 7 for full details of how to script Leo with the 4.2 code base.

2. This is the first version to use @file-thin for most derived files.

@file-thin makes it possible to use Leo effectively in a cvs environment.  Indeed, cvs now contains only a "dummy" version of LeoPy.leo.  The idea is that:

- LeoPyRef.leo hardly ever changes.  Developers will download LeoPyRef.leo once from cvs, then rename LeoPyRef.leo to be LeoPy.leo.  LeoPy.leo is private to each developer.

- Developers will commit and update to cvs only thin derived files.  There is no longer any need to keep .leo files and the files derived from them "in synch".

- Similar remarks apply to LeoPlugins.leo.  Cvs contains only LeoPluginsRef.leo, and contributors will need only to submit thin derived files.

I have been using the new code base without incident for weeks now, and I am fairly confident that it is safe to use.  Nevertheless, I would suggest routine caution when dealing with this version until more people have tested it.

Known bugs

- Cutting and pasting an @file-thin node does not work properly.  This will be easy to fix, I think.

- The present algorithm for reading thin derived files probably does not handle properly the situation in which a named node is some kind of grand child of the referencing node rather than being an immediate child of the referencing node.  This is a rare situation, easily avoided, and it doesn't happen at all in LeoPy.leo.  Nevertheless, something must be done.

Other improvements:

- Fixed a number of problems with using Leo on MacOS X.  In particular, Leo now uses the clover key as is usual on the Mac.  More Mac and *nix specific improvements are coming.

Still to do:

- Perfect import and @import.
- Make the Go To Line Number command work with @file-thin files.
- Fix minor bugs and add new features
  See the "To Do: 4.2" node in the leoToDo.txt node in LeoPy.leo.</t>
<t tx="EKR.20040518070824"></t>
<t tx="EKR.20040518070824.1">- Moved call to assignFileIndices into write_Leo_file.
- Called assignFileIndices in writeAtFileNodes, writeDirtyAtFileNodes, writeMissingAtFileNodes</t>
<t tx="EKR.20040518070940"></t>
<t tx="EKR.20040518070940.5">What I did:

File format

Added -thin field to @+leo sentinel

Recognizers

- Added vnode recognizers for @file-thin option.
- Added position proxies for vnode recognizers.

Directives &amp; sentinels
- Added support for @all.

Writing

- Added top-level atFile code to write @file-thin tree.
- DO write @file-thin vnodes if there was an error writing the derived file.
	- No autosave for @file-thin.
 	- Leo writes @file nodes first, so this is not a problem.
	- putVnode checks orphan bit, which gets set if there was an error.
- Don't write vnodes (or related tnodes) for @file-thin trees. (fileCommands).
- Do write empty nodes in @thin trees.
- Don't generate close node sentinels until all children have been generated.

Reading

- Set at.thinFile when reading thin files.
- Suppressed changed message and related items for thin files.
- Modified scanText4 and allies to read thin derived files.
	- Don't look for tnodeList for thin files.
	- Initially, at.lastThinNode is at.root.v
	- readStartNode calls createThinChild
	- createThinChild makes a child of at.lastThinNode if needed and sets at.lastThinNode.
- Updated fc.tnodesDict in at.createThinChild.
	Otherwise clones existing only in two thin files won't be linked properly.</t>
<t tx="EKR.20040518070940.156">After a match, the find-next command searched only in the suboutline where the first match occurred.
To fix this, we call g.app.findFrame.handleUserClick in various Tk event handlers.</t>
<t tx="EKR.20040518070940.164">@nocolor


p.v.t.visitedBit was used for two purposes:

- To mark the nodes to be written.
- To mark nodes that are not orphan.

What I did:

- Added t.is/set/clearWriteBit.
- Call t.setWriteBit in putVnode unless we are in a thin node.
- putTnodes tests for t.writeBit rather than t.visitedBit.</t>
<t tx="EKR.20040518071415">Leo did not handle moving a node to the root position of the outline correctly.</t>
<t tx="EKR.20040518075457">Using @ignore with @file-thin is asking for trouble.
If you remove the @ignore and then save, you will lose data.

How to recover the data:
	- Read Outline.
	- Remove @ignore
	- Import derived file... </t>
<t tx="EKR.20040521090400">Some older C compilers don't understand the "//" comment symbol, so using @language C won't work.

Moreover, the following does not always work either:

@comment /* */

This generates the following sentinel line:

/*@@comment /* */*/"

in the output file, and not all C compilers allow nested comments, so the last "*/" generates an error.

The solution is to use:

#if 0
@comment /* */
#endif

Leo is happy: it recognizes the @comment directive.

The C compiler is happy: the C preprocessor strips out the offending line before the C
compiler gets it.

Thanks to Rich Ries for this tip.</t>
<t tx="EKR.20040524104904">@nocolor

This outline contains the latest documentation available for Leo.</t>
<t tx="EKR.20040524104904.2">@nocolor

The following was written by Joe Orr, a user of Leo.  For more details, see http://www.jserv.com/jk_orr/xml/leo.htm

Leo is a powerful tool for organizing text into tree structures, and for just generally attacking a number of problems from a tree-based perspective. 

&lt;opinion&gt;
There has been a lot of hype about XML and all the uses to which it can be put. But, to my mind, the greatest benefit of XML is that it allows people to easily work with tree structures. All the benefits of XML really flow from that. Leo is the best application I've seen for conceiving and planning the trees that are then put into action via various XML technologies.
&lt;/opinion&gt;

Outlining Editors have existed for a while (e.g. PC-Outline, MORE) but Leo takes a major leap beyond previous tools for three reasons:

You can embed a simple macro language inside of a Leo document to instruct Leo to assemble pieces of the Leo document into another file. This facilitates, among other things, one type of Literate Programming.

Leo saves its files in XML format. This means that you can easily import and export Leo documents to any number of programs that can understand XML. for example, you can use an XSLT stylesheet to export a Leo file to HTML. And you can import any XML file into Leo using another XSLT stylesheet.

Leo is fully scriptable via Python.</t>
<t tx="EKR.20040524104904.3">@nocolor</t>
<t tx="EKR.20040524104904.4">Leo Users Manual
June 15, 2002

Leo is a programmer's editor and a flexible browser for projects, programs, classes or data. Leo clarifies design, coding, debugging, testing and maintenance.

Leo is a literate programming tool, compatible with noweb and CWEB. Leo enhances any text-based programming language, from assembly language and C to Java and Python to XML and English.

Leo is an outlining editor. Outlines clarify the big picture while providing unlimited space for details.

Leo is also a data organizer. A single Leo outline can generate complex data spanning many different files.  Leo has been used to manage web sites.

Leo is a project manager. Leo provides multiple views of a project within a single outline. Leo naturally represents tasks that remain up-to-date.

Leo is fully scriptable using Python and saves its files in XML format.

Leo is portable.  Leo.py is 100% pure Python and will run on any platform supporting Python and Tk/tcl, including Windows, Linux and MacOS X.  Leo.exe runs on any Windows platform.

Leo is Open Software, distributed under the Python License.

Leo was designed and built by:

Edward K. Ream
email:  edream@tds.net
voice: (608) 231-0766</t>
<t tx="EKR.20040524104904.5">Using Leo quickly becomes completely addicting.  I would never again willingly program without Leo; many of Leo's users say the same.

What makes Leo special?

Leo creates a powerful new world: a new way of programming, a new way of organizing data, and a new way of managing projects.  The following paragraphs discuss specific reasons why Leo works so well.

1. Outlines clarify and make explicit the relationships between parts of a project, regardless of whether those parts are computer programs, pages in a web site, pages in a document or tasks of a project.   Leo excels in handling complex projects: it shows you the big pictures at all times, while providing unlimited places to hide details.  Once you experience this way of seeing, you will never be satisfied with anything less.
   
2. A single outline can contain multiple kinds of data: programs, documentation, project management tasks, test data, whatever.  This means, for example, that the relationships between a program, its documentation and its tests suites can be shown directly within the same outline. Clones provide a way of relating and organizing all these kinds of data, and clones can create multiple views of these data within the _same_ outline.

3. Leo's users can use plugins to add literally any conceivable feature to Leo.  Several significant improvements to Leo started out as started out as plugins and later migrated into Leo's core.

4. Leo unifies outline structure, code and data:  

- Outlines organize the code and data within them.
- Leo's markup language (noweb) understands and uses outline structure.
- Leo's Execute script command understands outline structure, section references and Leo's directives.
- Scripts have full access to the outline structure of the outlines in which the are embedded.

The outline structure _is_ data, scripts are data _within_ this structure, and scripts may _use_ this structure to access their own data.

The unification of code, data and outline structure has great practical significance.  For example, a Leo outline is a natural way to organize the unit testing code and test cases.  Moreover,  test cases can access data using the outline structure.  The possibilities are endless.  For example, some unit tests create, test and then destroy other parts of the outline.  Finally, Leo's Execute Script command is a most convenient way of executing and debugging test code.

The history of Leo

Inventing and reinventing Leo has been the happiest and most creative part of my professional life.  Work on Leo accelerated significantly when a community of Leo's users became established on SourceForge.  For that I am truly grateful.  Suggestions (and plugins!) from users continue to drive Leo in excellent new directions.  Leo has come a long way since the early prototypes more than 9 years ago.  But in all that time, Leo's look and feel have remained almost completely unchanged--there has been no need to do so.

Leo grew out of my attempts to understand and use Donald Knuth's CWEB system of "literate programming".  I had great difficulty the original CWEB. The design and organization of my own literate programs were a mystery to me. I couldn't keep the parts of a literate program clear in my mind.  I easily became confused about what I had done or what remained to do.  It was too difficult to remember the names of sections or where I had defined functions and variables.  Leo eliminates all these problems and makes Knuth's original idea truly useful.  Chapter 6 discusses these ideas in much greater detail.

March 5, 1996 is Leo's true birthday.  On that day I started using the MORE outlining program to organize literate programs.  I had been lead to do this by the (gradual!) realization that webs are "outlines in disguise".  Within an hour of writing code in MORE, I knew that using outlines to organize literate programs would work spectacularly well.  March 5, 1996 was the day that changed my programming life forever.

There have been many changes and improvements to Leo since that first prototype, and Leo continues to evolve and grow.  Leo's plugins provide excellent test beds for experimentation and development.  Who knows what the next spectacular plugin will bring?

Edward K. Ream
June, 2004
</t>
<t tx="EKR.20040524104904.6">This is what I wanted when I started this project.

1. A tool that I could use successfully. I had tried flat literate programming and failed to produce a program that I could understand. The design of my own literate programs were a mystery to me. With the insight gained with two years experience with literate outlines, I believe I could now probably create flat literate outlines with some success. But how would I do that? By mentally simulating a literate outline! So although it would be possible for me to use flat literate programming tools, it would never be easy or natural.

Using literate outlines instantly transformed how I program. No longer was I confused about what I had done or what remained to do. No longer did I need to remember section names. No longer did I have to search for where functions and variables were defined. March 5, 1996, the day I started using MORE as a prototype of a literate outliner, changed my programming life forever. Within an hour of writing code in MORE, I knew that literate outlines would work, and work spectacularly well.

2. A way to ignore formatting. Printed listings, no matter how "beautiful", simply do not convey the structure of complex programs as well as an on-screen outline. What matters is how a program is represented on screen. I have been using Leo since early 1996. Not once have I had any inclination to look at a printed listing in order to understand my program better.

3. An outliner as good as MORE. I accomplished this by borrowing a large part of MORE's screen design. Consider this the sincerest form of flattery.

I did make one real change to MORE's design. MORE shows body text in multiple separate windows within the main outline pane; Leo shows body text in a single body pane. Leo's approach simplifies switching between nodes: one simply selects a new headline and the body text appears in the body pane. With MORE, one has to explicitly open the body pane for each individual headline, which can be clumsy.
However, MORE's approach does have some advantages. First, when opening body text in MORE, the subsidiary window becomes as large as necessary to show the entire body text, up to the limit of the size of the containing window. With Leo, the body pane stays fixed unless one resizes it. This is the reason Leo has several shortcuts for resizing the body pane.

MORE leaves lots of open windows around when doing a search or change command; MORE could be called a slob in this regard. However, MORE's way does have one benefit: one can see all the places where the search command found a match just be looking at all the open windows. With Leo this can not be done so directly; one must mark headlines to see where one has been. This is the main reason why Leo has a Find Next Marked Headline command. Without this command one must resort to something like expanding all headlines.
Leo and MORE have superb outlining facilities; each provides true outline objects and a full range of outline operations. Leo attempts to fix the one clumsy feature of MORE, the need to explicitly open body text. On the whole, I believe that Leo is slightly easier to use than MORE, especially for programming.

4. A self-contained programming system.  Leo's Tangle command provides basic support for literate programming.  Leo's Untangle command is a novel addition to literate programming.  The automatic tangling and untangling of @file trees is another major step forward.  Finally, Leo's many import and export commands ensure that Leo is compatible with noweb and CWEB.

5. A fun tool.  In Chapter 6 I list several highbrow reasons for liking literate programming. I know somebody gets what literate programming is all about when he or she says how much fun literate programming is. Clearly, Leo has succeeded admirably in this regard. I would never again willingly program without a literate outliner.</t>
<t tx="EKR.20040524104904.7">@nocolor

Leo owes much of its visual design to MORE, possibly the most elegant computer program ever written. Leo's clone nodes are inspired by MORE.

The following people have made generous donations to the Leo project: Robert Low, Nic Cave-Lynch.

The following people reported bugs, answered questions, and made suggestions for improving Leo: Alex Abacus, Shakeeb Alireze, Bruce Arnold, Chris Barker, Eric Brown, Darius Clarke, Bill Drissel, Wenshan Du, Allen Edwards, Chris Elliot, Mark Engleberg, Dethe Elza, Stephen Ferg, Tom Fetherston, Tomaz Ficko, Niklas Frykholm, Fred Gansevles, Jonathan M. Gilligan, Thomas Guettler, Zak Greant, Thomas Guettler, Romain Guy, Dave Hein, Tiago Castro Henriques, Gary Herron, Steve Holden, Klass Holwerda, Matthias Huening, Robert Hustead, John Jacob, Christopher P. Jobling, Eric S. Johansson, Garold Johnson, James Kerwin, Nicola Larosa, David LeBlanc, Chris Liechti, Steve Litt, Martin v. Loewis, Robert Low, Fredrik Lundh, Alex Martelli,  Marcus A. Martin, Gidion May, David McNab, Chad Netzer, Naud Olivier, Joe Orr, Marc-Antoine Parent, Paul Paterson, Davide Salomoni, Sean Shaleh Perry, Tim Peters, Scott Powell, Bruce Rafnel, Walter H. Rauser, David Speed Ream, Rich Ries, Aharon Robbins, Guido van Rossum, David Rowe, Steven Schaefer, Wolfram Schwenzer, Gil Shwartz, Paul Snively, Phil Straus, Jurjen Stellingwerff,  Jeffrey Thompson, Gabriel Valiente, Tom van Vleck, Jim Vickroy, Tony Vignaux, Ying-Chao Wang, Cliff Wells, Dan Wharton, Wim Wijnders, Vadim Zeitlin.

The following people have written code for Leo: Dave Hein wrote code to support PHP, to handle Tk version numbers properly and to open the Python window properly on Linux.  Marcus A. Martin wrote code to support LaTex. Bernhard Mulder proposed a new way of untangling derived files.  Paul Paterson wrote the first implementation of plugins and the spell checking plugin.  Steven P. Schaefer eliminated problems with end-of-line on Linux and fixed bugs in how directives were handled in @root trees.

The following deserve special mention: David Brock wrote TSyntaxMemo.  The late Bob Fitzwater kept me focused on design. Donald Knuth invented literate programming and the CWEB language. Joe Orr created Leo stylesheets for Leo; see http://www.jserv.com/jk_orr/xml/leo.htm. Joe Orr also created an outstanding set of tutorials for Leo; see http://www.evisa.com/e/sb.htm. John K. Ousterhout created tcl/Tk. Neal Norwitz wrote PyChecker.  Marc-Antoine Parent urged me to use XML for Leo's file format and helped improve it. Paul Paterson suggested the plugin architecture and suggested an approach to spell checking.  Norman Ramsey created noweb and gave permission to quote from the noweb web documentation. Rich Ries has contributed a huge number of suggestions. Steven P. Schaefer pointed out major security problems lurking in hooks.  Gil Shwartz helped with unicode support.  Phil Straus has been a great friend and constant support. Guido van Rossum created Python, Tkinter and the Python License. Dave Winer created MORE. Dan Winkler helped support Leo on the Mac.

Special thanks to my family. My brother, David Speed Ream, tested Leo and made many useful suggestions. Rebecca, James and Linda make it all worthwhile. It was during a conversation with Rebecca that I realized that MORE could be used as a prototype for Leo. That was a crucial first step.</t>
<t tx="EKR.20040524104904.8">COPYRIGHT

All parts of Leo are distributed under the following copyright.  This is intended to be the same as the Python license, namely that Leo is absolutely free, even for commercial use, including resale.  There is no GNU-like "copyleft" restriction.  This license is compatible with the GPL.

Copyright 1997-2002 by Edward K. Ream.  All Rights Reserved.

Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Edward K. Ream or Leo not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission from Edward K. Ream. 

DISCLAIMER OF WARRANTIES

EDWARD K. REAM (REAM) SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESSED OR IMPLIED, WITH RESPECT TO THIS COMPUTER SOFTWARE, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS RO A PARTICULAR PURPOSE.  IN NO EVENT SHALL REAM BE LIABLE FOR ANY LOSS OF PROFIT OR ANY COMMERCIAL DAMAGE, INCLUDING BUT NOT LIMITED TO SPECIAL, INCIDENTAL, CONSEQUENTIAL OR OTHER DAMAGES.</t>
<t tx="EKR.20040524104904.9"></t>
<t tx="EKR.20040524104904.10">Leo's main window contains an _outline pane_ and a _body pane_. An _outline_ represents an entire project and is stored in a single .leo file.  An outline consists of _headlines_. Headlines may be expanded and contracted.  Each headline has its own _body text_.  The body pane shows the body text of the presently selected headline. A _node_ is a headline and its body text.

_Sections_ group arbitrary text into a meaningful unit. Sections increase the expressive power of any language, from C to Python to XML to English. Outlines may be reorganized freely because the meaning of a section does not usually depend on its position.

_Clones_ are parts of an outline that change in unison.  Any change to a clone's headline, body text or its children is propagated to all other clones.  Clones can represent tasks and clones can create multiple views of a project within a single outline.

_Derived files_ are files generated from parts of an outline. An outline may generate many derived files. Conversely, an outline may be updated using changes to derived files.

In short, sections simplify text, clones represent tasks, outlines organize projects and outlines generate derived files.</t>
<t tx="EKR.20040524104904.11">Leo's main window contains two panes, an outline pane on top and a body pane below.  The outline pane contains a set of headlines.  Headlines fold (expand and contract) like Windows Explorer when you click the + or - icons. Headlines group components (subheadlines) into larger units.

The bottom pane contains the body text associated with the selected headline.  The combination of a headline and its associated body text is called a node. Body text can simply be plain text or text in the noweb or CWEB languages. A Leo program is a collection of all the body text of an outline organized by the headline.

Leo's outline are much more flexible and powerful than typical class browsers:

1. Leo's programming language understands outline structure.  The programmer may name a part of the tree and refer to that tree by name in source code.

2. Leo's commands understand outline structure.  Many of Leo's dozens of commands act on individual nodes and their descendents.  For example, one may limit a Find or Change operation to a specified part of an outline.

3. Leo allows the user to reorganize outlines freely by adding, deleting and moving nodes.

4. Leo opens an outline as it was when the user last used it, restoring the selected node, the top visible node, and the expansion state of all nodes.</t>
<t tx="EKR.20040524104904.12">@nocolor

Text in Leo's body pane is simply plain text that may contain section references.  For example, here is part of Leo's source code.

@color
def removeSentinelsCommand (self,fileName):
	valid = true
	&lt;&lt; Read file into s &gt;&gt;
	&lt;&lt; Set delims from the header line &gt;&gt;
	if valid:
		s = self.removeSentinelLines(s,line_delim,start_delim,end_delim)
		newFileName = fileName + ".tmp"
		&lt;&lt; Write s into newFileName &gt;&gt;
	else:
		es("Invalid @+leo sentinel in " + fileName)
		
@nocolor
Section references have the form &lt;&lt;section name&gt;&gt; and may appear anywhere in code.   Leo replaces a section reference by its definition  when Leo creates a source (derived) file.
Section references clarify code.  In this example, the code that is represented by the three section references does not conceal the overall shape of the removeSentinelsCommand function.  In particular, the role of the valid and s variable are clear.  Section references are often more convenient than functions.  For example, there is no need to return s from

	&lt;&lt;Read file into s&gt;&gt;
	
or to pass s to

	&lt;&lt;Write s into newFileName&gt;&gt;.
	
There are two ways to define sections.  The first way is to use a section definition line,

	&lt;&lt;section name&gt;&gt;=

(notice the equal sign) on a line by itself in body text, followed by the source code that defines the section.   The second way is to create a node with &lt;&lt;section name&gt;&gt; in its headline and the source code that defines the section in its body text.  Either way, the section definition may contain other section references.</t>
<t tx="EKR.20040524104904.13">Outlines can show relationships between sections. In the example above, a natural way of organizing the outline would as shown in the child of this node.  The removeSentinelsCommand method is defined in one node which has three children, one for each section referenced in the definition of removeSentinelsCommand.

Furthermore, Leo uses outline structure to delimit derived files and to control the scope of section definitions.  See Chapter 4 for details.</t>
<t tx="EKR.20040524104904.14">@color
def removeSentinelsCommand (self,fileName):

	path, self.fileName = os.path.split(fileName) # path/fileName
	trace(`self.fileName`)
	&lt;&lt; Read file into s &gt;&gt;
	valid = true
	line_delim = start_delim = end_delim = None
	&lt;&lt; set delims from the header line &gt;&gt;
	if valid == false:
		es("Invalid @+leo sentinel in " + fileName)
	else:
		trace("line:"+`line_delim`+","+
			"start:"+`start_delim`+","+
			"end:"+`end_delim`)
		s = removeSentinelLines(s,line_delim,start_delim,end_delim)
		newFileName = os.path.join(path,fileName+".tmp")
		&lt;&lt; Write s into newFileName &gt;&gt;</t>
<t tx="EKR.20040524104904.15">try:
	file = open(fileName)
	s = file.read()
	file.close()
except:
	es("Can not read " + fileName)
	return</t>
<t tx="EKR.20040524104904.16">@ This code is similar to atFile::scanHeader.
@c

tag = "@+leo"
# Skip any non @+leo lines.
i = 0
while i &lt; len(s) and not find_on_line(s,i,tag):
	i = skip_line(s,i)
# We should be at the @+leo line.
i = j = skip_ws(s,i)
# The opening comment delim is the initial non-whitespace.
while i &lt; len(s) and not match(s,i,tag) and not is_ws(s[i]) and not is_nl(s,i):
	i += 1
if j &lt; i: line_delim = s[j:i]
else: valid = false
# Make sure we have @+leo
i = skip_ws(s,i)
if match(s,i,tag): i += len(tag)
else: valid = false
# The closing comment delim is the trailing non-whitespace.
i = j = skip_ws(s,i)
while i &lt; n and not is_ws(s[i]) and not is_nl(s,i):
	i += 1
if j &lt; i:
	start_delim = line_delim
	end_delim = s[j:i]
	line_delim = None</t>
<t tx="EKR.20040524104904.17">try:
	file = open(newFileName,"w")
	file.write(s)
	file.close()
except:
	es("Can not create " + newFileName)</t>
<t tx="EKR.20040524104904.18">Headlines (and the sections they contain) are the natural building block of tasks. To build tasks from headlines we need another feature of Leo's outlines, namely clones. A clone is a copy of a tree that changes whenever any part of the original tree changes.  Clones are powerful. For example, adding a node to a cloned tree adds the same node to all cloned trees as well.

We can use an ordinary headline to represent any task as follows.  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.  Most importantly, the task view will change when any of its cloned headlines changes, and conversely, changes to clones under the task outline are propagated throughout the outline. This means that,

a) the task headline will remain up-to-date when the project changes, and
b) we can make changes in the task view and rather than throughout an outline.

In short, task headlines focus our attention on only those parts of a project that relate directly to a task and makes it easy to change code scattered throughout a project.</t>
<t tx="EKR.20040524104904.19">Leo outlines are stored in a single .leo file. Leo can create many derived files from a single outline.  You can create derived files explicitly using the Tangle command, or automatically when an outline file is saved.  Conversely, Leo can update outlines based on changes to derived files. Again, you can update an outline explicitly using the Untangle command, or automatically when an outline file is opened.  Outline files contain all information contained in derived files.  This redundancy is useful for backing up data and for error recovery.

This introduction has only sketched Leo's capabilities.  Chapter 3 shows how to create and reorganize Leo's outlines. This chapter covers clones, a powerful outline feature found in few other outliners.  Chapter 4 tells you everything you need to write programs in Leo.  Chapter 5 discusses all of Leo's commands.  Chapter 7 discusses scripting Leo with Python.</t>
<t tx="EKR.20040524104904.20">There is a trick that makes it very easy to develop Leo using Leo itself. The
trick is to create a workflow that separates editing from testing.

Putting test code in LeoPy.leo would waste a lot of time. To run tests I would
have to exit Leo and reload LeoPy. A much quicker way is to put all test code
in a test.leo file. So to change and test code, just do the following:

1. Save LeoPy.leo but do NOT exit Leo. 

2. Quit the copy of Leo running test.leo, then reload test.leo.

3. Run test scripts from test.leo.

That's all. Python will recompile any changed .py files in the new copy of Leo.

BTW, I use a batch file called t.bat that runs test.leo, so my
"edit-reload-test" cycle is just:

1. Control-S (to save the .leo file)
2. t (to run load test.leo)
3. Control-E (to run the test script)

The benefits of the new workflow:

1. test.leo loads _much_ more quickly than LeoPy.leo does. This new approach
can increase the speed of the edit-reload-test cycle by more than a factor of
10. Hitting Control-S, t, Control-E takes about 5 seconds.

2. LeoPy.leo continues to run with the _old_ code, so it is much easier to fix
syntax errors or exceptions in the _new_ code: just fix the problem and save
LeoPy.leo _without_ closing LeoPy.leo., then restart test.leo. Tests are run on
new code; editing is done on old, stable code.

3. test.leo is the perfect place to develop test. I can create and organize
those tests and when I am done, test.leo is a log of my work.

BTW, I have long wondered whether there was a way to recompile Leo's .py files
without leaving Leo. Theoretically this is possible using reload, but in
practice it doesn't work when objects contain state information. The new
workflow neatly solves the problem while sidestepping the problems.</t>
<t tx="EKR.20040524104904.21">@nocolor

This chapter tells how to install Leo.

New in version 4.1:  The first time you start Leo, Leo will ask you for a unique identifier.  If you are using cvs, use your cvs login name.  Otherwise your initials will do.

Leo stores this identifier in leoID.txt, so you can change this identifier at any time by chaning leoID.txt.</t>
<t tx="EKR.20040524104904.22">leo.py is Leo2 written in Python and Tk.  It should work on any platform that supports Python 2.2 or later and Tk 8.3 or later.

Download Python from http://python.org/
Download tcl/Tk from http://tcl.activestate.com/software/tcltk/

See "How to install Leo on MacOS Panther (10.3)" for installation instructions for MacOs X.  Leo will not run on MacOs 9.</t>
<t tx="EKR.20040524104904.23">@nocolor

leo.py requires Python 2.1 and tcl/tk 8.3 or above.

	Download Python from http://python.org/ 
	Download tcl/Tk from http://tcl.activestate.com/software/tcltk/

Leo is distributed as a single compressed folder.  Simply uncompress this folder and run leo.py.  You can run leo.py by double-clicking leo.py.  You can also run leo.py from a Python interpreter as follows:

@color

	import leo
	leo.run() # runs leo.py, opening a new outline.
	leo.go() # runs leo.py after reloading all modules.
	leo.leoOpen(fileName) # runs leo.py, reloads all modules, and opens fileName.
	
@nocolor

Another way to open files would be to create a batch file.  On Windows, I put the following .bat file in c:\Windows

cd c:\prog\LeoCVS\leo
c:\python22\python c:\prog\LeoCVS\leo\leo.py %1

This opens the file specified by the first argument (%1).</t>
<t tx="EKR.20040524104904.24">leo.py 2.4 and above will open .leo files automatically provided that you associate leo.py with .leo files.  Here is how to open leo.py when double-clicking a .leo file on Windows 2K or XP.  I'm not sure it will work for Windows 95/98/Me.

In Windows 2K or XP, Go to Start-&gt;Settings-&gt;Control panel, open the "Folder Options" applet.
Select the "file types" tab from the Folder Options window. Press the "new" button.
Enter LEO into the "Create New Extension" File Extension text field. Press OK.

With LEO still highlighted in the Registered File Types list box, press the Advanced button.
Change the default file type field to something like "Leo Literate Outline".
Press the Icon button and browse to the LeoDoc icon in your [leo install dir]\leo-2.3\Icons folder.
Click OK. This gets the icons right and registers the description of the .leo file.

You now have to tell windows what to do to open the file properly.
Press the new button to open the "New Action" window.
In the Action field type Open.
In the "Action used to perform action" type _one_ of the following lines:

[python install dir]\pythonw.exe   [leo install dir]\leo.py %1
[python install dir]\python.exe -i [leo install dir]\leo.py %1

The first  line opens Leo files with no console window.
The second line opens Leo files with a console window and leaves the window open after Leo exits.

You should now be able to double click on a leo file in explorer with leo.py.</t>
<t tx="EKR.20040524104904.25">@nocolor

Quick start

This is the minimum you need to use Leo effectively.

1. Write body text using the noweb languages. See Using noweb, CWEB and Directives.

2. Create source files (derived files) using the Tangle command. Only @root directives under the currently selected headline are tangled by the Tangle command. Warning: The Tangle command will overwrite files specified in @root directives if they exist.

3. Use the Untangle command to propagate changes made to derived files back into the outline Untangle is useful only for making small syntactic changes. Don't attempt to change the structure of an outline by modifying derived files; it won't work.

4. Many command key abbreviations are specified in the Syntax Coloring panel.

See the Appendices for a concise summary of information about Leo.</t>
<t tx="EKR.20040524104904.26">@nocolor

This chapter tells how to use Leo's outline pane.  It introduces terminology and discusses creating, moving, marking, cloning headlines.

This chapter also discusses the control keys that can be used in the body pane.  This material is excerpted from documentation at http://tcl.activestate.com/man/tcl8.4/TkCmd/text.htm</t>
<t tx="EKR.20040524104904.27">A cloned node is a copy of a node that changes when the original changes. Changes to the children, grandchildren, etc. of a node are simultaneously made to the corresponding nodes contained in all cloned nodes.  Clones are marked by a small arrow  by their leader characters.

There is no real distinction between the "original" node and any of its clones.  This makes it possible to update any of the clones and the original node will change as well.  When the second-to-last cloned node is deleted the last cloned node becomes a regular node again.

Clones are useful for making alternate views of a program.  For example, when I begin to fix a bug I clone all the sections of the code that relate to the bug, and place those cloned sections under a new headline whose name is the name of the bug I am fixing.

The children of this headline show some complex clones.  To see how clones work, try moving the node marked f around with the nodes marked a fully expanded.  Not all moves are allowed:  you can't move a cloned node so it would become a child of another clone of itself.</t>
<t tx="EKR.20040524104904.28">This is a kind of bizarre outline that I use to test clone operations.  Try moving the nodes a through g around and see what happens to the children of the various clones.</t>
<t tx="EKR.20040524104904.29"></t>
<t tx="EKR.20040524104904.30"></t>
<t tx="EKR.20040524104904.31"></t>
<t tx="EKR.20040524104904.32"></t>
<t tx="EKR.20040524104904.33"></t>
<t tx="EKR.20040524104904.34"></t>
<t tx="EKR.20040524104904.35"></t>
<t tx="EKR.20040524104904.36">The Insert Node command inserts a new headline into the outline.

The Delete Node command deletes a headline and all its children.
</t>
<t tx="EKR.20040524104904.37">The Cut Outline, Paste Outline, Copy Outline and Delete Outline commands work on nodes rather than text.  For example, to delete a headline, select the headline and choose the Cut Outline or Delete Outline commands.

The Cut Outline and Copy Outline copy a text representation of the outline to the clipboard.  This representation is the same as the file format with some information deleted.  You may copy this text representation into a body pane (or into any other text editor) using the Paste command in the Edit menu.

Warning:  In practice, it is almost always wiser to move clones rather than cutting or pasting them.  Cutting and pasting outlines preserves clones, but the links between clones only exist within the part of the outline that was pasted.  Therefore, if you are cutting and pasting an outline containing clones it is best to cut and paste the _entire_ outline.  Alternatively, you can paste part of an outline, then delete all clones.</t>
<t tx="EKR.20040524104904.38">New in leo.py v2.4: You may drag an node (including all its descendents) from one place to another in an outline.  To start a drag, press the main (left) mouse button while the cursor is over the icon for a node.  The cursor will change to a hand icon. If you release the mouse button while the hand cursor is above the icon for another node, Leo will move the dragged node after that node.  If you release the mouse button when the hand cursor is not over an icon, Leo will print "not moved" and leave the outline pane as it is.  This can result in the dragged node not being visible on the screen, but it seems less alarming not to force the current node to become visible as that would undo any scrolling that has just been done.

New in leo.py 3.0: If you drag outside the outline pane, the outline pane will scroll automatically.

Leo scrolls the outline pane as the result of mouse-moved events, so to continue scrolling you must keep moving the mouse.  I experimented with scrolling the outline pane whenever the cursor is dragged outside it, but the results were not good.  There was a noticeable delay between releasing the cursors and halting the scrolling.  The present code is simpler and more likely to work on all platforms.

Leo only allows dragging from one icon to another.  In particular, you can't move a node to the first child of another node unless that node is already expanded.   I experimented with automatically open nodes when the cursor moves over an unexpanded node with children.  However, this was confusing and alarming.  It seems best to expand and contract nodes explicitly.</t>
<t tx="EKR.20040524104904.39">Body text in leo.py has the following features:

Leo auto indents when @nocolor is not in effect.  That is, typing a newline automatically inserts the same leading whitespace present on the previous line.  If the present language is Python (set either in the preferences or with an @language Python command), Leo inserts an additional tab if the previous line ends with a colon.

The default features of Leo's body text derive from the Tk Text widget, described at:
http://www.tcl.tk/man/tcl8.3/TkCmd/text.htm
Not all these features are found on all platforms.

The following features are mostly derived from the Tk Text widget.  Some default behaviors have been changed because they conflict with other Leo features.

Clicking mouse button 1 positions the insertion cursor just before the character underneath the mouse cursor, sets the input focus to this widget, and clears any selection in the widget. Dragging with mouse button 1 strokes out a selection between the insertion cursor and the character under the mouse. 

Double-clicking with mouse button 1 selects the word under the mouse and positions the insertion cursor at the beginning of the word.

The ends of the selection can be adjusted by dragging with mouse button 1 while the Shift key is down; this will adjust the end of the selection that was nearest to the mouse cursor when button 1 was pressed. 

Clicking mouse button 1 with the Control key down will reposition the insertion cursor without affecting the selection. 

If any normal printing characters are typed, they are inserted at the point of the insertion cursor. 

If the mouse is dragged out of the body pane while button 1 is pressed, the entry will automatically scroll to make more text visible (if there is more text off-screen on the side where the mouse left the window). 

The Left and Right (arrow) keys move the insertion cursor one character to the left or right; they also clear any selection in the text. If Left or Right is typed with the Shift key down, then the insertion cursor moves and the selection is extended to include the new character. Control-Left and Control-Right move the insertion cursor by words, and Control-Shift-Left and Control-Shift-Right move the insertion cursor by words and also extend the selection.

The Up and Down (arrow) keys move the insertion cursor one line up or down and clear any selection in the text. If Up or Right is typed with the Shift key down, then the insertion cursor moves and the selection is extended to include the new character. Control-Up and Control-Down move the insertion cursor by paragraphs (groups of lines separated by blank lines), and Control-Shift-Up and Control-Shift-Down move the insertion cursor by paragraphs and also extend the selection. Control-p and Control-n behave the same as Up and Down, respectively. 

The Next(Page Down) and Prior(Page Up) keys move the insertion cursor forward or backwards by one screenful and clear any selection in the text. If the Shift key is held down while Next or Prior is typed, then the selection is extended to include the new character.

Line movement is by text lines terminated by hard returns (newlines), not by displayed lines;  if a text line is long and wraps across more than one display line, then the Up and Down movement will skip the extra wrapped display lines.

Home moves the insertion cursor to the beginning of its line and clear any selection in the widget. Shift-Home moves the insertion cursor to the beginning of the line and also extends the selection to that point. 

End moves the insertion cursor to the end of the line and clear any selection in the widget. Shift-End moves the cursor to the end of the line and extends the selection to that point. 

Control-Home moves the insertion cursor to the beginning of the text and clear any selection in the widget. Control-Shift-Home moves the insertion cursor to the beginning of the text and also extends the selection to that point. 

Control-End moves the insertion cursor to the end of the text and clear any selection in the widget. Control-Shift-End moves the cursor to the end of the text and extends the selection to that point. 

The Select key and Control-Space set the selection anchor to the position of the insertion cursor. They don't affect the current selection. Shift-Select and Control-Shift-Space adjust the selection to the current position of the insertion cursor, selecting from the anchor to the insertion cursor if there was not any selection previously. 

Control-/ selects the entire contents of the widget. 

Control-\ clears any selection in the widget. 

The F16 key (labeled Copy on many Sun workstations) or Control-c copies the selection in the widget to the clipboard, if there is a selection. This action is carried out by the command tk_textCopy. 

The F20 key (labeled Cut on many Sun workstations) or Control-x copies the selection in the widget to the clipboard and deletes the selection. This action is carried out by the command tk_textCut. If there is no selection in the widget then these keys have no effect. 

The F18 key (labeled Paste on many Sun workstations) or Control-v inserts the contents of the clipboard at the position of the insertion cursor. This action is carried out by the command tk_textPaste. 

The Delete key deletes the selection, if there is one in the widget. If there is no selection, it deletes the character to the right of the insertion cursor. 

Backspace deletes the selection, if there is one in the widget. If there is no selection, they delete the character to the left of the insertion cursor. </t>
<t tx="EKR.20040524104904.40">You can expand or contract a headline by clicking in the standard Windows Tree View icon to the left of the status icon.

Expanding a node shows its immediate children; contracting a node hides all its children.  The Expand All Subheads command expands all of a nodes offspring (children, grandchildren, etc.)</t>
<t tx="EKR.20040524104904.41">Leo auto indents body text following colons when @language is in effect.

You may use Emacs-style auto-indentation instead.  The child of this node provides full details.</t>
<t tx="EKR.20040524104904.42">Leo now supports optional Emacs-style auto-indent.  This style of auto-indent aligns newly created lines with unmatched ( [ or { brackets in the previous line. This feature is enabled only if smart_auto_indent = 1 in leoConfig.txt.

This code was contributed by David McNab, david@rebirthing.co.nz.</t>
<t tx="EKR.20040524104904.43">You can mark headlines in several ways: with the various Outline:Mark commands, with the Find or Change commands, or with the Untangle command.  The "Go To Next Marked" command will go to the next marked node, if any.

The Mark command will unmark the selected headline if it is already marked.</t>
<t tx="EKR.20040524104904.44">There are a number of ways to move and reorganize headlines.

The Move Up, Move Down, Move Left and Move Right commands move the currently selected outline.  The Promote command makes all the children of a headline siblings of the headline.  The Demote command makes all the siblings of a headline children of the headline.

You can cut and paste any part of a tree.  If a headline contains selected text, the cut, copy, clear or paste operation affects only the selected text. Otherwise, the cut, copy, clear or paste operations acts on the node and all nodes contained by it.  For example, you can move a headline by cutting it, selecting another location in the outline and pasting the headline in the new location.

Warning:  In practice, it is almost always wiser to move clones rather than cutting or pasting them.  Cutting and pasting outlines preserves clones, but the links between clones only exist within the part of the outline that was pasted.  Therefore, if you are cutting and pasting an outline containing clones it is best to cut and paste the _entire_ outline.  Alternatively, you can paste part of an outline, then delete all clones.  
</t>
<t tx="EKR.20040524104904.45">Double-clicking the icon box of a node whose headline has the form:

@url &lt;any url&gt;

executes the url in your default web browser.  See the child of this node for full details.</t>
<t tx="EKR.20040524104904.46">Double-clicking the icon box of a node whose headline has the form:

@url &lt;any url&gt;

executes the url in your default web browser.

Leo checks that the url is valid before doing so. A valid url is:

-- 3 or more lowercase alphas,
-- followed by one ':',
-- followed by one or more of: $%&amp;'()*+,-./0-9:=?@A-Z_a-z{}~
-- followed by one of:         $%&amp;'()*+/0-9:=?@A-Z_a-z}~

Url's should contain no spaces: use %20 to indicate spaces.

You may use any type of url that your browser supports: http,mailto,ftp,file,etc.
</t>
<t tx="EKR.20040524104904.47">You can change the relative sizes of the outline and body panes by dragging the splitter bar.  The Equal Sized Panes command resizes the panes so that each fills half of the main window.</t>
<t tx="EKR.20040524104904.48">The outline pane supports one level of undo.

The body pane supports unlimited undo.  However, you can not undo an operation affecting body text after selecting a new headline.  You can undo or redo the last operation involving the outline itself.  You can not undo operations affecting headline text.</t>
<t tx="EKR.20040524104904.49">@nocolor
@ignore
@language python</t>
<t tx="EKR.20040524104904.50">Important note 1: This chapter tells how to use the noweb markup language.  See the node called About CWEB if you plan to use the CWEB markup language.

Important note 2: This chapter discusses only the @file directive.

-- Appendix 1 to this chapter tells how to use the new @rawfile directive.
-- Appendix 2 to this chapter tells how to use the older @root directive.

This is the most important chapter because it describes everything you need to know to write programs with Leo. Unless otherwise mentioned, this chapter applies to all versions of Leo.  Newcomers to Leo should read Introducing Leo before reading further.

I _strongly recommend_ that you have look at an example of a Leo outline like LeoPy.leo while you read this documentation. It is much easier to use Leo than to describe all the rules in detail.  Looking at a real Leo outline will make many points clear that are difficult to describe succinctly in words.

Terminology: _Directives_ are commands that appear in body text.  Directives start with an @ in the leftmost column followed by a directive name. We often refer to outline nodes by the directives they contain.  For example, an @others node is a node containing an @others directive, an @ignore node is a node containing an @ignore directive, and so on.  Exception: an @file node is a node whose headline starts with @file.  We also speak of @root trees, trees whose is an @root node, @file trees, trees whose root is an @file node, and so on.

The essentials of writing programs in Leo are as follows:

1. A Leo program is composed the all the body text in an outline, or part of an outline.

2. Body text is a sequence of _sections_.  There are two kinds of sections: doc sections and code sections.

3. Sections may contain _section references_ that refer to other sections by their nam.

4. Leo uses outline structure to control the scope of section definitions.

5. Leo creates source files called _derived files_ by expanding all section references in an @file tree.
</t>
<t tx="EKR.20040524104904.51">@nocolor
There are two kinds of sections: code sections and doc sections.  Code sections start with the @c directive.  Within @file trees, the entire body text of a node is a code section by default, so the @c directive can be omitted if there are no doc sections in the body pane.  Doc sections start with @ followed by a space 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.

Code sections may contain section references of the form &lt;&lt;section name&gt;&gt;. That is, a section reference is any sequence of characters except newlines enclosed in &lt;&lt; and &gt;&gt;. Leo ignores whitespace and case inside section names, so the following are equivalent:
@color

	&lt;&lt; Read file into s &gt;&gt;
	&lt;&lt;READ File into S&gt;&gt;

@nocolor
Leo underlines section names whose definitions are not found in any descendent.  Such sections are always invalid in @file trees, and may be valid in @root trees provided that the section is defined somewhere else.

Paired &lt;&lt; and &gt;&gt; characters on the same line always denote a section name, even within comments and strings.  That is, &lt;&lt; and &gt;&gt; characters that do not delimit a section name must be placed on separate lines.  If &lt;&lt; and &gt;&gt; are not paired on a line, they are treated as literal &lt;&lt; and &gt;&gt; characters.

Body text may contain zero or more sections in any order.  A code section is named if the node's headline starts with &lt;&lt;section name&gt;&gt;.  Otherwise, the code section is unnamed.  Body text that contains no @ or @c directive is considered to be a single unnamed code section. @ and @c directives terminate any previous section. For example,

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

@nocolor
An @c directive is optional at the start of body text, so:
@color

@c
def hasChildren(self):
	return self.firstChild() != None

@nocolor
is equivalent to the following text without any markup:
@color

def hasChildren(self):
	return self.firstChild() != None

@nocolor
The @c directive is needed here:
@color

@ Returns true if the receiver has child nodes.
@c
def hasChildren(self):
	return self.firstChild() != None

@nocolor
However, we could replace the doc part with a comment, like this:
@color

# Returns true if the receiver has child nodes.
def hasChildren(self):
	return self.firstChild() != None

@nocolor
The choice of using doc parts or comments is a matter of style.  Doc parts are convenient for longer comments that would be tedious to format by hand.

Minor note 1: For historical reasons, the @code directive is a synonym for the @c directive and the @doc directive is a synonym for @ directive. Only the @c, @code, @ and @doc directives terminate sections.

Minor note 2: A line of the form:
	
@ %def identifiers

terminates the previous code section and indicates that the preceding code section defines the list of identifiers.  This list contains identifiers separated by whitespace; any sequence of non-white characters may be an identifier.  This construction is used in traditional noweb programming to generate indices.</t>
<t tx="EKR.20040524104904.52">Lets see how to organize typical outlines.  The only rules we must follow are:

- All nodes containing body text must be referenced.

- Each named node must descend from the node that refers to it.

- The @ignore directive is not valid in @file trees.

A node that is not referenced is called an _orphan node_.  If an @file tree contains an orphan node or @ignore node, Leo issues a warning and does not write the derived file when saving an outline. Leo saves all the information in the @file tree in the .leo file, so nothing is lost; Leo will recreate the @file tree from the .leo file when reading the outline the next time.

We can avoid having to refer to sections by name by using the @others directive.  This can save a lot of work.

The @others directive refers to _all unnamed_ sections.  An @file tree may contain more than one @others directive.  @others directives that descend from other @other directives refer only to unnamed nodes that descend from them.  The @others directive that occurs highest in the @file tree refers to all other unnamed nodes.

There are two minor restrictions on the @others directive:

- No single node may contain more than one @others directive.

- No named node may "intervene" between an unnamed node containing body text and an @others node. This restriction will be discussed in detail below.  In practice this is never a problem.

When saving an outline, Leo creates derived files from all changed @file trees by expanding references to named and unnamed sections:

- Section references place the body text of a single named section in the derived file.

- @others directives place the body text of all unnamed nodes in the derived file.

- The @others directive places unnamed nodes in outline order, the order in which nodes appear in an outline when all nodes are expanded.

When reading an outline, Leo recreates @file trees from derived files. In particular, you may change derived files outside of Leo, and Leo will update the outline accordingly.  You may change derived files in any way provided that you don't change sentinel lines.  Sentinel lines are comment lines whose first character (after the comment delimiter) is @.  Leo represents outline structure in sentinel lines, so changing sentinel lines will corrupt the outline structure. (The appendix lists the format and meaning of all sentinel lines.)

Some examples should make all this much clearer.  See the children of this node.

The @ignore directive is not valid in @file trees because derived files contain primary data.  The .leo file also contains a copy of the information in the @file tree, but this information is used for backup and error recovery. As a result, everything in an @file trees must correspond to information the derived file and the @ignore directive may not appear in @file trees.</t>
<t tx="EKR.20040524104904.53">@file f.c shows how to create a C file.

@file classX.py shows how to create a single Python class.

@file mainClass.py shows how to define two classes in a single Python file.

The @file bad tree is invalid.  No named node may "intervene" between an unnamed node containing body text and an @others node.
</t>
<t tx="EKR.20040524104904.54">@color
@ This @file node generates the file f.c.

This body text ensures that the expansions of &lt;&lt; constants &gt;&gt; and &lt;&lt; declarations &gt;&gt; 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.
@c

&lt;&lt; constants &gt;&gt;
&lt;&lt; declarations &gt;&gt;
@others</t>
<t tx="EKR.20040524104904.55">the constants</t>
<t tx="EKR.20040524104904.56">the declarations</t>
<t tx="EKR.20040524104904.57">text of function 1</t>
<t tx="EKR.20040524104904.58">text of function 2</t>
<t tx="EKR.20040524104904.59">@color
@ This @file node generates the file classX.py.

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.

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

&lt;&lt; imports for classX &gt;&gt;
class classX:
	@others</t>
<t tx="EKR.20040524104904.60"></t>
<t tx="EKR.20040524104904.61">@ This is an organizing node.  Using this node does not change the indentation in the derived file.</t>
<t tx="EKR.20040524104904.62"></t>
<t tx="EKR.20040524104904.63"></t>
<t tx="EKR.20040524104904.64">@ This is an organizing node.  Using this node does not change the indentation in the derived file.</t>
<t tx="EKR.20040524104904.65"></t>
<t tx="EKR.20040524104904.66"></t>
<t tx="EKR.20040524104904.67">@color
@ This @file node generates the file mainClass.py.

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 shown.

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

&lt;&lt;mainClass imports&gt;&gt;
&lt;&lt;class mainClass&gt;&gt;
&lt;&lt;class helperClass&gt;&gt;</t>
<t tx="EKR.20040524104904.68"></t>
<t tx="EKR.20040524104904.69">class mainClass:
	@others</t>
<t tx="EKR.20040524104904.70"></t>
<t tx="EKR.20040524104904.71"></t>
<t tx="EKR.20040524104904.72">class helperClass:
	@others</t>
<t tx="EKR.20040524104904.73"></t>
<t tx="EKR.20040524104904.74"></t>
<t tx="EKR.20040524104904.75">@color
@language python
@ The following outline is invalid.  Node A is an unnamed node containing body text, and the &lt;&lt;section one&gt;&gt; node intervenes between Node A and the @others node.
@c

class classX:
	@others
</t>
<t tx="EKR.20040524104904.76">def bad():
	&lt;&lt; section 1 &gt;&gt;</t>
<t tx="EKR.20040524104904.77">@ This node is invalid because it intervenes between Node A and the @others node above.
</t>
<t tx="EKR.20040524104904.78">def spam():
	pass</t>
<t tx="EKR.20040524104904.79">The following sections discuss directives that have not been discussed previously.  Unless otherwise noted, these directives are valid anywhere in an outline.</t>
<t tx="EKR.20040524104904.80">Syntax coloring is on by default in all body text. Leo formats comments and documentation parts in red, directives and C keywords in blue, strings and character constants in gray and all other text in code parts in black.

The @nocolor directive disables syntax coloring for the body text in which it appears. No syntax coloring is done until an @color directive re-enables syntax coloring.

If a node contains neither the @color nor the @nocolor directive it may inherit the syntax coloring attribute from an ancestor. The nearest ancestor that contains exactly one of the @color or @nocolor directives will control the syntax coloring. Ambiguous nodes, nodes containing both the @color and @nocolor directives, never affect the coloring of their offspring.

New in 4.2:  The @killcolor directive completely disables the colorizer for that node.  The result is a huge improvement in responsiveness for large body text.  As usual @killcolor may itself be overridden in descendent nodes.

The differences between @killcolor and @nocolor:

- @nocolor suppresses coloring only until the next @color directive.

- @killcolor overrides @nocolor and @color directives.  Any node containing @killcolor is unambiguously a @killcolor node regardless of whether that node also contains @color or @nocolor directives.

Note: the @color, @nocolor and @killcolor directives do not affect the Tangle commands in any way. In particular, the Tangle commands will recognize section definitions as usual even after an @nocolor directive is seen.
</t>
<t tx="EKR.20040524104904.81">Note: the @comment directive is now officially deprecated: you should use the @language directive whenever possible.

Untangle will not process an @root or @unit node if an @comment directive is in effect because Untangle can't be sure of properly parsing a derived file if the language of the derived file isn't known. It might be possible to assume some defaults in this case, but that is not done at present and is not a high priority.

By default, the Tangle Commands produces C-language comments. Single-line comments generated during tangling start with ///, while documentation parts are surrounded by /* and */. The @comment directive allows you to use Tangle to produce shell and make files, as well as source code for other programming languages.

The @comment directive may be followed by zero to three delimiters, separated by whitespace. This directive sets the single-line comment delimiter and the opening and closing block comment delimiters as follows:

@comment
	(no delim) restores the defaults to ///, /* and */
@comment ///
	(one delim) sets the single-line comment and clears the other delimiters.
@comment /* */
	(two delims) sets the opening and closing block comment delimiters and clears the single-line comment.
@comment /// /* */
	(three delims) sets all three delimiters.

If only one delimiter is given, Leo does not write any documentation parts while tangling. If two delimiters are given, block-style comments are used instead of single-line comments.
For example, the @comment { } directive could be used to Tangle Pascal files.

The @comment directive is only recognized in @root, @unit or @file nodes, and the @comment directive must precede the first section name or @code directive. An @comment directive in the body text of an @unit directive specifies the current global defaults. An @comment directive in the body text of an @root directive affects comments generated for one root only. Comments in all other roots are governed by the global defaults.

New in leo.py 3.0: Leo will convert underscores in the @comment directives to significant spaces.  For example,

@comment REM_

causes the comment delimiter to be "REM " (Note the trailing space).</t>
<t tx="EKR.20040524104904.82">@nocolor

The @delims directive changes the comment strings used to mark sentinel lines. This directive is often used to place Javascript text inside XML or HTML files.

The @delims directive contains one or two delimiters, separated by whitespace. If only one delim is present it delimits single-line comments. If two delims are present they delimit block comments. The @delims directive can not be used to change the comment strings at the start of the derived file, that is, the comment strings for the @+leo sentinel and the initial @+body and @+node sentinels. The @delims directive inserts @@delims sentinels into the derived file. The new delimiter strings continue in effect until the next @@delims sentinel in the derived file or the end of the derived file.

Note: Leo can not revert to previous delimiters automatically; you must change back to previous delimiters using another @delims directive. For example:

@color

@delims /* */
Javascript stuff
@delims &lt;-- --&gt;
HTML stuff

@nocolor
Adding, deleting or changing @@delims sentinels will destroy Leo's ability to read the derived file. Mistakes using the @delims directive have no effect on Leo, though such mistakes will thoroughly mess up a derived file as far as compilers, HTML renderers, etc. are concerned.</t>
<t tx="EKR.20040524104904.83">You may use the @encoding directive to specify the encoding used in a derived file.  You can't mix encodings in a single derived file.  For example,

@encoding iso-8859-1

If the encoding used in a derived file is not "utf-8" it is represented in the @+leo sentinel line, like this:

#@+leo-encoding=iso-8859-1.

The "utf-8" encoding is used by default.  The "utf-8" encoding is a "lossless" encoding (it can represent all unicode code points), so encoding and decoding to and from utf-8 plain strings will never cause a problem.  When reading or writing a character not in a "lossy" encoding (such as iso-8859-1), Leo converts such characters to '?' and issues a warning. </t>
<t tx="EKR.20040524104904.84">The @first directive allows you to place lines at the very start of files derived from @file nodes. For example, the body text of @file spam.py might be:

	@first #! /usr/bin/env python

The body text of @file foo.perl might be:

	@first #/usr/bin/perl

@first directives are recognized only at the start of the body text of @file nodes. No text may precede @first directives. More than one @first directive may exist, like this:

	@first #! /usr/bin/env python
	@first # more comments.

Similarly, @last directives are recognized only at the end of body text of @file nodes.  No text may follow @last directives.  More than one @last directive may exist.  For example, here is how a PHP file might be set up:

	@first &lt;?php
	...
	@last ?&gt;</t>
<t tx="EKR.20040524104904.85">@nocolor
The @language directive specifies the comment delimiters and string types used by the Tangle and Untangle commands. This directive over-rides the default specified in the Preferences panel. The form of this directive is:
@color

@language x

@nocolor
where x is one of the following: actionscript, c, c++, cweb, elisp, html, java, latex, objective-c, pascal, perl, perlpod, plain, python, rebol, shell or tcltk. Shell files have comments that start with #. Case is ignored in the language specifiers, but not in the @language itself. Thus, the following are equivalent:
@color

@language html
@language HTML
@language hTmL

but the following is invalid:

@LANGUAGE html</t>
<t tx="EKR.20040524104904.86">New in version 3.11.  The @lineending directive allows you to specify the line endings for individual derived files.  This directive will override the output_newline setting in leoConfig.txt.  Note that @lineending _never_ affects the line endings in .leo files themselves:  we must have consistent line endings in .leo files!  See below for more details.

The valid forms of the new @lineending directive are:

@lineending nl       (the default, Linux)
@lineending cr       (Mac)
@lineending crlf     (Windows)
@lineending lf       (same as nl, not recommended)
@lineending platform (same as platform value for output_newline setting in leoConfig.txt)</t>
<t tx="EKR.20040524104904.87">@nocolor

The @path, @pagewidth and @tabwidth directives allow preferences to be set on a file-by-file basis: they override the corresponding defaults in the Preferences panel.

The form of the @path directive is @path filename, where filename is taken to be everything following @path to the end of the line.

If the filename in @file pathname or @root pathname is an absolute filename the location of the derived file is specified only by the filename.  Otherwise, if the filename is 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 form of the @pagewidth directive is @pagewidth n, where n is a positive integer that indicates the width of tangled pages in columns. This setting only affects how Tangle outputs block comments.

The form of the @tabwidth directive is @tabwidth n, where n is a positive integer that indicates the width of tabs in spaces. This is used by Tangle to output leading whitespace.</t>
<t tx="EKR.20040524104904.88">The @raw and @end_raw directives are valid only within @file trees.  The @raw directive starts a section of "raw" text.  The @end_raw directive ends such a section, as does the end of body text. No section references are recognized within "raw" text, and no additional leading whitespace is generated within "raw" text when writing the derived file.
</t>
<t tx="EKR.20040524104904.89">New in Leo 3.10:  Leo allows you to choose whether body text in @root trees will start in code mode or doc mode by default.

@root-doc filename and @root-code filename specify that body text is assumed to start in doc mode or code mode respectively.  The options (-doc and -code) must follow @root immediately with no intervening whitespace.  In effect, @root-code and @root-doc are two new directives.

These @root options override the new at_root_bodies_start_in_doc_mode option in leoConfig.py.  This option affects only @root trees without options.  Such "plain" @root trees are now deprecated, which only means that it is now better style to use either @root-code or @root-doc.  The reason is simple: the meaning of plain @root trees will depend on the at_root_bodies_start_in_doc_mode option, and that isn't good.

By default, at_root_bodies_start_in_doc_mode = 1 for compatibility for old @root trees.  I actually don't think this option is good for much; I created it before I created @root-doc and @root-code, and I decided it wouldn't hurt to leave it in.  Anyway, you now have complete flexibility about how @root works, and in particular you can make @root work just like @file.</t>
<t tx="EKR.20040524104904.90">New in version 3.12: By default, the body_pane_wraps setting in leoConfig.txt controls whether body text wraps.  You may override this setting for a particular tree using the @wrap and @nowrap directives.
</t>
<t tx="EKR.20040524104904.91">Cweb mode refers to how Leo tangles an outline when @language cweb is in effect or the cweb option in the Preferences Panel is in effect.

Leo treats _all_ cweb code in cweb mode as unevaluated text.  That is, Leo treats cweb control codes, including @&lt;...@&gt;, @&lt;...@&gt;=, @c, @space, @* and @** as "raw" text within cweb mode.  Leo does _not_ expand _cweb_ section references when writing derived files in cweb mode.  However, Leo _does_ expand _noweb_ section references, so you may use noweb sections to organize cweb files! You can create _noweb_ code and doc sections using the @code and @doc directives in place of @c and @space directives.

By default, cweb colors @space, @* and @** sections using the same syntax coloring as for LaTeX.  In addition, cweb colors C // and /*..*/ comments using LaTeX coloring by default.  You may change these defaults using the color_cweb_doc_parts_with_latex and color_cweb_comments_with_latex options in leoConfig.py.</t>
<t tx="EKR.20040524104904.92">An @asis tree is a tree whose root headline starts with @asis &lt;filename&gt;.  Similarly, for @noref and @nosent trees.

New in 4.2:  The following terms are equivalent.  The first form is preferred in each case.

@asis, @file-asis, @silent
@nosent, @file-nosent and @nosentinelsfile
@noref, @file-noref and @rawfile

You can get any combination of sentinels/no sentinels and references/no references using @file, @nosent, @noref and @asis trees:

                 Derived files        Sections and 
Type of tree   contain sentinels?   @others expanded?
------------   ------------------   -----------------
       @file   yes                  yes
     @nosent   no                   yes
      @noref   yes                  no
       @asis   no                   no

Leo can not update the outline from changes made from derived files unless those files contain sentinels.  The primary source for @nosent and @asis trees are the outlines from which those files were derived.

Leo creates files derived from @noref and @asis trees by writing the body text of all nodes of the tree in outline order.  Leo writes the body text _as is_, without recognizing section definitions, without expanding section references, and without treating directives specially in any way.  In particular, Leo copies all directives, including @space or @c directives, to the derived file as text. However, Leo recognizes the @ignore directive in the _ancestors_ of @noref or @asis nodes, so you may use the @ignore directive as usual to prevent Leo from writing @rawfile and @silentfile trees.

Notes:

1. When writing @noref trees, Leo writes only the @+leo, @-leo, @+node, @-node, @+body and @-body sentinels.

2. Within @asis trees only, if a headline starts with @@, Leo writes everything in the headline following the @@ just before the corresponding body text.

3. Files derived from @asis trees contain _nothing_ not contained in body text (or @@ headlines).  In particular, if body text does not end in a newline, the first line from the next node will concatenated to the last line of the preceding node.</t>
<t tx="EKR.20040524104904.93"></t>
<t tx="EKR.20040524104904.94">@file trees are much easier to use than @root trees:

1. @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.

2. 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:

1. Within @file trees, sections must be defined in descendants of the node that contains the section reference.

2. 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.  (See "Tangling @root trees with the Tangle commands for a complete description of the @root directives.)

3. 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.</t>
<t tx="EKR.20040524104904.95">@nocolor
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 @ followed by a space 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 &lt;&lt;section name&gt;&gt;.  Otherwise, the @c directive is invalid.

Section definition lines of the form:

	&lt;&lt; section name&gt;&gt;=

(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.

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

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

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

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

@nocolor
Provided that the node's headline starts with &lt;&lt;atFile methods&gt;&gt;, the example above is equivalent to:
@color

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

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

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

@nocolor
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.</t>
<t tx="EKR.20040524104904.96">@nocolor
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 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. The process of creating derived files is called "tangling" because the code from the outline is rearrange to create the derived files.

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

@root"xx.h"
#ifndef xx_defined
#define xx_defined
&lt;&lt; declarations of public constants of the xx class &gt;&gt;
&lt;&lt; declarations of public types of the xx class &gt;&gt;
&lt;&lt; declarations of public variables of the xx class &gt;&gt;
&lt;&lt; public prototypes of the xx class &gt;&gt;
#endif

@nocolor
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:
@color

@root"xx.c"
&lt;&lt; public variables of the xx class &gt;&gt;
&lt;&lt; private types of the xx class &gt;&gt;
&lt;&lt; private variables of the xx class &gt;&gt;
&lt;&lt; private function prototypes of the xx class &gt;&gt;
&lt;&lt; methods of the xx class &gt;&gt;

@nocolor
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.
@color

@root filename
@root "filename"
@root &lt;filename&gt;

@nocolor

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.</t>
<t tx="EKR.20040524104904.97">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.</t>
<t tx="EKR.20040524104904.98">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 adds 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.</t>
<t tx="EKR.20040524104904.99">@nocolor

This chapter is discusses all of Leo's menu commands.  It is organized by menu, and by function within each menu.

A note about typography:  in this chapter command names and menu names will be capitalized, just as they would be in a menu.  This convention allows us to write, for example, the Save A Copy As command, rather than having to use distracting quotation marks, like the "Save A Copy As" command.</t>
<t tx="EKR.20040524104904.100"></t>
<t tx="EKR.20040524104904.101">The New command creates a new Leo main window.  The Open command opens an existing Leo file and shows it in a main window.  The Close command closes the topmost Leo window, and gives you an opportunity to save your work if you haven't yet done so.

The Save, Save As and Save To commands save the topmost Leo window to a file.  The Save As command changes the name of the outline being edited; the Save To command does not.

The Revert command reloads a file, discarding any changes made to the file since it was last saved.

New in Leo 2.5: The Recent Files... command brings up a submenu containing a list of recently opened files.  Choosing an item in this submenu opens the selected file or brings it to the front. Leo adds files to this submenu even if leoConfig.txt is missing or read-only, but those additions will not be remembered unless leoConfig.txt is present and writable.

New in Leo 4.0: The Clear Recent Files command deletes all entries in the Recent Files submenu except the most recent file.  The files themselves are not affected, just the menu entries.

The following four file commands are located in the File:Read/Write submenu.

Read Outline Only: reads an outline using only the .leo file, not any files derived from @file nodes.  This command is useful for reverting a project to a previously saved state.

Read @file Nodes: updates all @file nodes in an outline.  This ensures that the state of an outline matches all files derived from @file nodes.  Included for completeness.  This happens automatically when a .leo file is first read, and it also happens automatically when Leo2 is reactivated.

Write Outline Only: saves an outline without writing any @file trees.  Useful for inserting an @file node into an outline without modifying a derived file with the same name.

Write @file Nodes: forces an update of all @file trees.  Surprisingly useful.

New in Leo 3.12:  The Write Dirty @file Nodes command writes all @file trees that have been changed.

New in Leo 4.0: The Write 4.x Derived Files command and Write 3.x Derived Files command work just like the Write @file Nodes command, except that they write the indicated format off derived file.  In contrast, the Write @file Nodes command writes 3.x format derived files if and only if the write_old_format_derived_files = 1 in leoConfig.txt.  Auto Save: all three of these commands automatically save the outline (the .leo file) if any derived file was actually written.  This is necessary so that information in the .leo file always remains in synch with all derived files.</t>
<t tx="EKR.20040524104904.102">The Open With command allows you to communicate with external editor.  See the child of this node for full details.</t>
<t tx="EKR.20040524104904.103">The Open With command allows you to communicate with external editor.  When you select this command Leo creates a temporary file and invokes an external program.  Leo periodically checks whether this temporary file has changed; Leo changes the corresponding node in the outline if so.

You must create the entries in the Open With submenu. This would typically be done in a hook routine, using the createOpenWithMenuFromTable routine described in the child of this node.

The @file mod_open_with.py node in LeoPy.leo gives a complete example of handling the Open With menu.</t>
<t tx="EKR.20040524104904.104">createOpenWithMenuFromTable (self,table)

This method adds items to submenu of the Open With menu item in the File menu.

The table argument describes the entries to be created.  This table is a sequence of items of the form (name,shortcut,data).

- name is the command name
- shortcut is the shortcut, or None to indicate no shortcut.
- data is a tuple of the form (command,arg,ext)
- command is one of "os.system", "os.startfile", "os.spawnl", "os.spawnv" or "exec".
- arg is an argument to be passed to the given command.
- ext is a file extension or None.

When the user selects the Open With item corresponding to the table item Leo executes command(arg).
If ext is not None, the temp file has the given extension.
Otherwise, Leo computes an extension based on what @language directive is in effect.

For example:

table = (
	("Idle",   "Alt+Shift+I",("os.system",idle_arg,".py")),
	("Word",   "Alt+Shift+W",("os.startfile",None,".doc")),
	("Wordpad","Alt+Shift+T",("os.startfile",None,".txt")))

top().frame.createOpenWithMenuFromTable(table)
	</t>
<t tx="EKR.20040524104904.105">The Tangle, Tangle All and Tangle Marked commands create derived files from portions of an outline.  These commands indent and format the derived files so that they are easy to read and so that it is clear what sections produced the code.  The .c file in the Examples folder shows the code produced by the Tangle commands.

The three Tangle 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.

Derived files are usually .h or .c files (C), .cpp files (C++), or .m files (Objective-C) files, and they can also be other files such as "make" or "help" files.

The Tangle commands create a derived file, call it F, from each @root node.  This process is very much like macro expansion.  The contents of F are simply the body text of the @root node, with each section reference replaced by its definition.  Substitution continues until all references to sections are replaced with their definitions.

By default, Tangle commands look for section definitions only in the suboutline containing the @root directive 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 changes the default scope of the tangle command, while the @ignore directive causes the tangle commands to ignore a subtree.  For more details, see the discussion of the @unit and @ignore commands in Chapter called "Using noweb, CWEB and directives". 
</t>
<t tx="EKR.20040524104904.106">The Untangle, Untangle All and Untangle Marked commands are the reverse of the corresponding Tangle commands.  They update an outline based on changes made to one or more derived files.  These are exceptionally useful commands.

For example, suppose you create a new part of the outline and Tangle it for the first time.  When you compile the resulting derived files for the first time, 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 not all the code is changed the same way in derived files.  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 only reliable way to update text in cloned nodes is to make the change in the .leo file rather than the derived files.</t>
<t tx="EKR.20040524104904.107">When using the Tangle and Untangle commands there are several issues to be aware of concerning your IDE (Integrated Development Environment). This section applies particularly to the Borland IDE; similar remarks apply to other IDE's.

Assuming you have added a .cpp file to your project, you update the file with the Tangle command.  When you switch to the IDE you will get a dialog asking whether you want to update the file.  Say yes and rebuild or remake.

You won't get the dialog unless the file is already open in the IDE.  There is a bug in the Borland IDE: the dialog doesn't come to the front, so it can be easy to miss.

Now suppose you compile the file and get 20 errors all over the .cpp file. You fix the errors _in the IDE_, save the file, switch to Leo, and run the Untangle command. All your changes will appear in the outline! Each changed node will be marked by the Untangle command.

If you like you can use the Go To Next Marked command to find each changed node.
</t>
<t tx="EKR.20040524104904.108">Note: the following describe the import and export commands found in leo.py.  This documentation notes differences with the Windows version of Leo.

The Import to @file command creates an @file node from a file.  The Import to @root command creates an @root node from a file.  These commands do not attempt to do perfect translations; they merely automate the bulk of the drudgery.  The Import to @root command is called Import Files in the Borland/Windows version of Leo.  The Import to @file command does not exist in the Borland/Windows version of Leo.

The Import CWEB Files command creates an @file node from a CWEB file.  This command does not exist in the Borland/Windows version of Leo.

The Import noweb Files command creates an @file node from a CWEB file.  The Borland/Windows version of this command creates an @root node.

The Import Flattened Outline command (called Import MORE Text in the Borland/Windows version of Leo) converts plain text written in MORE format to an outline. This command brings up a dialog which will accept at most one file. If that file contains MORE-format text it creates an outline corresponding to that text.

MORE is a now- defunct Macintosh outliner program. MORE represents outlines as follows. Headlines are denoted by a leading + or - character, preceding by zero or more tabs that denote the level of the headline. Body text follows its headline, with no indentation. The original MORE format did not escape lines in the body text that started with + or -. Leo escapes such characters by preceding +, - or backslash with a backslash.

New in Leo 4.0: The Import Derived File command imports all the nodes in a derived file into the outline.  Unlike the read commands, no outline structure is preserved.  This command can import either 3.x or 4.x derived files.  This command is necessary in version 4.0 because there is no other way to read derived files that are out-of-synch with a .leo file.</t>
<t tx="EKR.20040524104904.109">The Outline To CWEB command creates a CWEB file from the selected outline.

The Outline TO noweb command creates a noweb file from the selected outline.

The Flatten Outline command creates a text file in MORE format from the selected outline.  See the previous section for a discussion of the MORE format.

The Remove Sentinels command removes all sentinel lines from a file derived from an @file node.</t>
<t tx="EKR.20040524104904.110">The Quit command causes Leo to exit.   You may also exit Leo by closing the main window.  In either event you will be prompted to save any file that has been altered but not saved. </t>
<t tx="EKR.20040524104904.111"></t>
<t tx="EKR.20040524104904.112">For leo.py version 2.0 and above:

leo.py supports unlimited Undo and Redo.  All outline operations, including the Change All command and all operations and commands that affect body text may be undone and redone.  Only the "Read @file Nodes" command is undoable; it clears the undo state. This command raises a dialog to allow the user to cancel.

Think of actions that may be Undone or Redone as a string of beads.  A "bead pointer" points to the present bead.  Performing an operation creates a new bead after the present bead and removes all following beads.  Undoing an operation moves the bead pointer backwards; redoing an operation moves the bead pointer forwards.  The Undo command is disabled when the bead pointer moves in front of the first bead; the Redo command is disabled when the bead pointer points to the last bead.

For all Borland versions:

The body pane supports unlimited undo.  However, you can not undo an operation affecting body text after selecting a new headline.  You can undo or redo the last operation involving the outline itself.  You can not undo operations affecting headline text.</t>
<t tx="EKR.20040524104904.113">Leo supports the standard editing commands that appear in the edit menu: Undo, Cut, Copy, Paste and Clear. These commands work with either headline (when a headlines text is being edited) or body text. Text may be cut, copied and pasted between headline text and body text.

The Select All command selects all text in the body pane.
</t>
<t tx="EKR.20040524104904.114">The Shift Left and Shift Right commands shift selected lines in the body text left or right one tab position. The entire line is shifted if any characters of the line are selected.</t>
<t tx="EKR.20040524104904.115">The Extract, Extract Section and Extract Section Names commands create child nodes whose headline is the first line of the selected body text.

The Extract command creates a new node whose headline is the first line of selected body text and whose body is all other lines of selected text.  All selected text is deleted from the original body text. 

The Extract Section command creates a new node whose headline is the first line of selected text and whose body is @code followed by all the other lines of selected text.  All selected text lines except the first line are deleted from the original body text. This command is enabled only if the first line contains a section name (enclosed in angle brackets) on a line by itself.

The Extract Section Names command creates one or more child nodes, one for each section name (enclosed in angle brackets) in the selected body text.  The headline of each created node is the section name and the body text of each created node is just @code followed by a newline.</t>
<t tx="EKR.20040524104904.116">New in leo.py v2.5.

The Convert Tabs command converts leading tabs to blanks in a single node.  The Convert Blanks command converts blanks to tabs in a single node.  The Convert All Tabs converts leading tabs to blanks throughout the selected tree.  The Convert All Blanks command converts leading blanks to tabs throughout the selected tree.

All these commands convert between tabs and blanks using the tab width shown in the Preferences panel.</t>
<t tx="EKR.20040524104904.117">The Execute Script command executes body text as a Python script.  Leo execute the selected text, or the entire body text if no text is selected.

Scripts are executed in a "pristine" environment, that is, with __builtins__ as both the local and global environments.

New in version 4.1:  Body text may now contain @directives and section references. This is a major step forward: you can now use all of Leo's features to organize scripts that you execute interactively.

Section definitions must appear in the node containing the script or in descendant nodes.  Leo "preprocesses" all scripts by simulating the writing of a derived file to a string.

The Execute Script command sets app.scriptDict["script1"] to the value of the script before preprocessing, and sets app.scriptDict["script2"] to the value of the script after preprocessing.  Scripts may examine and change app.scriptDict as they please.</t>
<t tx="EKR.20040524104904.118">The Edit menu contains four commands for searching and replacing text.  The Find and Find Again commands search through the outline for text and the Change and Change, Then Find commands change selected text.

New in Leo 4.1:  The Esc key dismisses the dialog.  Pressing the enter key is the same a pressing the Find button.

The following check boxes options appear in the search dialog and control the operations of the find and change commands.
</t>
<t tx="EKR.20040524104904.119">@nocolor

New in 4.1: Leo now supports scripts in Leo's Find/Change dialog.

Leo's find panel now contains the Script Search radio button and the Script
Change checkbox. When the Script Search radio button is selected Leo treats the
contents of the Search Text as a script to execute whenever any kind of Find
command is executed. Similarly, when the Script Change checkbox is selected Leo
treats the context of the Change Text as a script to execute whenever any kind
of Change command is executed. See below for just how this works.

Script-based find-change is extremely powerful. In effect, Leo's Find/Change
panel becomes a new platform for running scripts interactively. Leo now has all
the find/change capability of pattern matching languages like Snobol and Icon,
just by using the capabilities of the plain Python language. Moreover, Leo can
deliver these capabilities interactively or not depending which buttons you push
in Leo's Find/Change panel.

Script-based find/change frees the user from having to control script-based
searches interactively. Rather than forcing find/change scripts to implement
their own interactive controls, it is much easier to use what Leo already has.</t>
<t tx="EKR.20040524104904.120">Leo dedicates a Python dictionary called app.searchDict for communication
between Leo and the search and change scripts. The search and change scripts may
also use app.searchDict for communication between themselves. Leo sets
app.searchDict["type"] to "find", "change", "findAll" or "changeAll" to indicate
the kind of command being executed. Scripts may use all other entries in
app.searchDict as they please.

Leo executes the find script once when you press the Find button (or the Change
then Find button) in Leo's Find/Change dialog. Typically, the find script would
traversing the tree and highlight the found text or otherwise indicate to the
user that the find operation has succeeded. However, the script can do anything
it pleases.

Leo executes the the find script repeatedly when you press the Find All button.
Leo keeps executing the find script until app.searchDict["continue"] evaluates
to false. Initially there is no entry for app.searchDict["continue"], so the
find script must set app.searchDict["continue"] = true if it wants Leo to keep
executing it.

Leo executes the change script once when you press the Change button. Typically,
the change script would change the selected text. Usually the change script will
compute the new value of body text and call v.setBodyStringOrPane(newText) to
make that change permanent. 

The change script also may handle undo, typically by calling
c.frame.onBodyChanged(v,"Change",oldText=oldText). Leo does not handle undo
automatically. Indeed, Leo makes no assumptions whatever about what the change
script really does.

Leo executes the the change script repeatedly when you press the Change All
button. Just as with the Find All command, Leo keeps executing the change script
until app.searchDict["continue"] evaluates to false.

Most find and change scripts will ignore settings in the Find Panel like "whole
word", "pattern match", and "reverse". However, these settings are available to
the scripts via ivars such as c.whole_word_flag, etc. if desired.</t>
<t tx="EKR.20040524104904.121">@nocolor

The Scripts node in LeoPy.leo contains a script called initScriptFind.  This script makes it easy to set up script based searches as follows:

1. Put the following code in the root of a tree that will contain your script search:

@color
# Initialize Leo's find panel using the named children of this node.
from leoGlobals import *
initScriptFind("Find script","Change script") # Second argument is optional.
# Start searching at the top.
top().selectVnode(c.rootVnode())
@nocolor

2. Put the search script in a child node called "Find script" (no quotes).

3. (Optional) Put the change script in a child node called "Change script"

4.  Execute the code above.  Leo does the following:

- Puts the body of the "Find script" into the find text of Leo's Find/Change dialog.
- Puts the body of the "Change script" into the change text of Leo's Find/Change dialog.
- Selects the Script Find radio button.
- Selects the Script Change checkbox if the change script exists.
- Selects the root of the entire outline.

Presto!  Leo is ready for a script search.</t>
<t tx="EKR.20040524104904.122">@nocolor

Some ideas for using scripts:
	
Either the find and change scripts may use Python's re module.  For
example, the find script could set app.searchDict["m"] to the match object
returned by re's match method.  The change script would then compute the
result, change the text and set the undo info as usual.

There is no reason to confine find/change scripts to operate on data only
within a Leo outline. These scripts could as easily traverse your file system
as the Leo outline. But notice: scripts could pull data from the file system
into the outline so that you can see the effects of changes as the scripts
operate. Again, this can all happen interactively if you like.</t>
<t tx="EKR.20040524104904.123">When checked, the Find and Change commands proceed without stopping.  Output is sent to the log window regarding the progress of the command.
</t>
<t tx="EKR.20040524104904.124">When checked, the Find and Change commands ignore the case of alphabetic characters when determining matches.
</t>
<t tx="EKR.20040524104904.125">When checked, the Change command marks all headlines whose headline or body text are changed by the command.
</t>
<t tx="EKR.20040524104904.126">When checked, the Find and Change commands mark all headlines in which a match is found with the pattern.
</t>
<t tx="EKR.20040524104904.127">When checked, the Find and Change commands treat several characters specially in the find pattern.  The '*' character matches any sequence of zero or more characters.  The '.' character matches any single character. The '^' character at the start of a pattern, or a '$' character at the end of a pattern matches a newline.

Examples:
The pattern "^abc$" matches lines that only contain "abc".
The pattern "^a" matches any line starting with "A".
The pattern "a$" matches any line ending with "a".
The pattern "^*$" matches any line at all.</t>
<t tx="EKR.20040524104904.128">When checked, the Find and Change commands search backward through the file.
</t>
<t tx="EKR.20040524104904.129">When checked, the Find and Change commands search body text.
</t>
<t tx="EKR.20040524104904.130">When checked, the Find and Change commands search headline text.
</t>
<t tx="EKR.20040524104904.131">When checked, the Find and Change commands search only the currently selected headline and its offspring.
</t>
<t tx="EKR.20040524104904.132">When checked, the find pattern must match an entire word.  Words consist of an alphabetic character or underscore, followed by zero or more alphabetic characters, numbers or underscores.
</t>
<t tx="EKR.20040524104904.133">When checked, the Find and Change commands continues at the top of the file when the command reaches the bottom of the file.  For reverse searches, the find or change command continues at the bottom of the file when the command reaches the top of the file.
</t>
<t tx="EKR.20040524104904.134">The Go To Line Number command selects the locations in your outlines corresponding to a line in a derived file.  See the child of this node for full details.</t>
<t tx="EKR.20040524104904.135">The present version should be quite usable for its main purpose: tracking
down lines corresponding to error messages. In particular, except for possible
pathological cases, Leo should always put the cursor in the node containing the
referenced line. Possible pathologies involve asking Leo to "go to" a sentinel
line. It won't always be clear what node contains the sentinel.

I am well aware that Leo may not put the cursor on the proper line within
the vnode, but human beings being the excellent pattern matchers that we are,
we should be easily be able to find a line within a node.

Notes in LeoPy.leo, in the node called (Go to line number), discuss a variety
of issues that may cause the cursor not to go to the "proper" line. It also
discusses a better way to position the cursor.

Internally, there are two main versions of this command: one for @silentfile
trees, and one for @rawfile and @file trees. In the first case, there are no
sentinels in the derived file, so Leo just steps through the outline. This is
the easy case, and should work well. In the second case (@rawfile and @file
trees), the derived file contains sentinels, and Leo uses those sentinels to
determine in what vnode the given line occurs.

In this second case, Leo can almost always position the cursor within the
proper node, because Leo just scans back in the derived file looking for the
proper @+node sentinel. However, in order to "count" lines in the derived file
(to place the cursor properly _within_ the body text) Leo must recreate exactly
the logic used by the atFile.read logic, and that isn't easy. Moreover, there
is _no_ guarantee that the derived file is unchanged from when it was written;
after all, if you get syntax errors you tend to want to fix them ;-)

Please do not report bugs in this command, unless the bug involves a
crash, which would be reported both in Leo's log pane and in the console
window. This command will probably be improved in 3.10.</t>
<t tx="EKR.20040524104904.136">New in leo.py 3.11: Insert Body Time/Date and Insert Headline Time/Date
commands. These are in the Edit Body and Edit Headline menus respectively.
These commands insert the formatted time &amp; date into t body or headline text.
You must be editing a headline to be able to insert the time/date into the
headline. If you aren't Leo will say: "Edit headline to append date/time"

Leo allows you to specify your preferred format for time and date using settings
in leoConfig.leo/.txt: body_time_format_string in &lt;&lt; body pane options &gt;&gt; and
headline_time_format_string in &lt;&lt; outline pane options&gt;&gt;

These settings specify the format string passed to time.strftime(format). For a
complete list of the format options see
http://www.python.org/doc/current/lib/module-time.html

If the format specified by either of these two settings is erroneous the
"%m/%d/%Y %H:%M:%S" format is used by default, resulting in a time/date format
like 1/30/2003 8:31:55</t>
<t tx="EKR.20040524104904.137">The Reformat Paragraph command allows you to easily reformat body text.  See the child of this node for full details.</t>
<t tx="EKR.20040524104904.138">New in leo.py v3.9

Whether importing text from an outside source, typing in text, or modifying text, eventually you end up with a block of text in which some lines are too long and some are too short.  The Reformat Paragraph command will rearrange the words in a text paragraph to fill each line as full as possible, up to the @pagewidth setting.

A paragraph is delimited by blank lines, Leo directives, and (of course) start and end of text in a node.  The width of the line used by the reformatting operation is governed by @pagewidth and the indentation that would be applied to the node when tangled (as part of a @root) or written (as part of a @file).

The command operates on the paragraph containing the insert cursor.  If the insert cursor is on a blank line or directive, nothing happens.  If the cursor is on a line containing text, then the paragraph containing that text line is reformatted and the insert cursor is moved to the next paragraph.

Be careful that you don't do this on source code!  Of course, if you do reformat something that should have been left alone, then just Undo.

NOTE: Lines with hanging indentation are handled so that the hanging indentation is preserved.  This is most useful for bulleted or numbered lists, such as:

  1. This is the first paragraph, and
     it has a hanging indentation.

  2. This is the second paragraph, and
     it too has a hanging indentation.</t>
<t tx="EKR.20040524104904.139">The Match Brackets command is enabled if the cursor is next to one of the following characters in the body pane:

( ) [ ] { } &lt; &gt;

This command looks for the matching character, searching backwards through the body text if the cursor is next to ) ] } or &gt; and searching forward through the text otherwise.  If the cursor is between two brackets the search is made for the bracket matching the leftmost bracket.

If a match is found, the entire range of characters delimited by the brackets is highlighted and the cursor is placed just to the left of the matching characters.  Thus, executing this command twice highlights the range of matched characters without changing the cursor.</t>
<t tx="EKR.20040524104904.140">New in leo.py 3.11:  The Preferences Panel now contains a checkbox called "Replace tabs with spaces".  It is no longer necessary to type a negative tab width to indicate that tabs are to be converted to spaces.

New in leo.py 3.0: The Set Colors command brings up a dialog specifying colors for syntax coloring.  You can specify colors for each syntax coloring construct using a color wheel or by choosing one of the standard Tk color names.  When a color becomes active Leo writes its value or color name to the log pane for your reference.  This is useful when setting coloring options in leoConfig.txt.

New in leo.py 3.0:  The Set Font command brings allows you to specify the fonts used in the body pane, the outline pane (in headlines) and in the log pane. A font becomes active when you double-click its name, or check or uncheck any checkbox.  When a font becomes "active", the new font appears in the panes whose check boxes are selected. Font sizes must be greater than 0 and less than 100 for them to become in effect.  When you choose OK or Cancel Leo writes the fonts presently active in each pane to the log pane for your reference.  This is useful when setting font options in leoConfig.txt.

The Preferences command brings up the preferences dialog. The Page Width option determines where Tangle will break lines. The other two global options control whether the Tangle and Untangle commands will execute a batch file when they are finished. The Default Target Language determines the default syntax coloring and the comment delimiters used by default when Tangling.

New in leo.py 2.5, negative tab widths: Leo converts tabs to blanks as you type when a negative tab width is specified.</t>
<t tx="EKR.20040524104904.141">Leo understands the following PHP keywords:

&lt;?php, ?&gt;, __CLASS__, __FILE__, __FUNCTION__, __LINE__, and,	as, break, case, cfunction, class, const, continue, declare, default, do, else, elseif,  enddeclare, endfor, endforeach, endif, endswitch, endwhile, eval,  extends, for, foreach, function, global, if, new, old_function, or, static, switch, unset(), use, var, while, xor,

Leo does not yet color the following keywords containing():

array(), die(), echo(), empty(), exit(), include(), include_once(), isset(), list(), print(), require(), require_once(), return()</t>
<t tx="EKR.20040524104904.142">Leo understands the following LaTex keywords: capitalization is significant.  For example, \vert produces a single vertical line and \Vert produces a double vertical line.

\@, \(, \), \{, \},

\acute, \addcontentsline, \addtocontents, \addtocounter, \address,
\addtolength, \addvspace, \AE, \ae, \aleph, \alph, \angle, \appendix, 
\approx,\arabic, \arccos, \arcsin, \arctan, \ast, \author,

\b, \backmatter, \backslash, \bar, \baselineskip, \baselinestretch,
\begin, \beta, \bezier, \bf, \bfseries, \bibitem, \bigcap, 
\bigcup, \bigodot, \bigoplus, \bigotimes, \bigskip, \biguplus, 
\bigvee, \bigwedge,\bmod, \boldmath, \Box, \breve, \bullet,

\c, \cal, \caption, \cdot, \cdots, \centering, \chapter, 
\check, \chi, \circ, \circle, \cite, \cleardoublepage, \clearpage, 
\cline,\closing, \clubsuit, \coprod, \copywright, \cos, \cosh, 
\cot, \coth,csc,

\d, \dag, \dashbox, \date, \ddag, \ddot, \ddots, \decl, 
\deg, \Delta, \delta, \depthits, \det, 
\DH, \dh, \Diamond, \diamondsuit, \dim, \div, \DJ, \dj, 
\documentclass, \documentstyle, \dot, \dotfil, \downarrow,

\ell, \em, \emph, \end, \enlargethispage, \ensuremath, 
\enumi, \enuii, \enumiii, \enuiv, \epsilon, \equation, \equiv,
\eta, \example, \exists, \exp,

\fbox, \figure, \flat, \flushbottom, \fnsymbol, \footnote, 
\footnotemark, \fotenotesize, 
\footnotetext, \forall, \frac, \frame, \framebox, \frenchspacing, 
\frontmatter,

\Gamma, \gamma, \gcd, \geq, \gg, \grave, \guillemotleft, 
\guillemotright,\guilsinglleft, \guilsinglright,

\H, \hat, \hbar, \heartsuit, \heightits, \hfill, \hline, \hom, \hrulefill,\hspace, \huge,\Huge,\hyphenation

\Im, \imath, \include, includeonly, indent, \index, \inf, \infty, \input, \int, \iota,\it, \item, \itshape,

\jmath, \Join,

\k, \kappa, \ker, \kill,

\label, \Lambda, \lambda, \langle, \large, \Large, \LARGE, 
\LaTeX, \LaTeXe, 
\ldots, \leadsto, \left, \Leftarrow, \leftarrow, \lefteqn, \leq,
\lg, \lhd, \lim, \liminf, \limsup, \line, \linebreak, 
\linethickness, \linewidth,\listfiles,
\ll, \ln, \location, \log, \Longleftarrow, \longleftarrow, 
\Longrightarrow,longrightarrow,

\mainmatter, \makebox, \makeglossary, \makeindex,\maketitle, \markboth, \markright,
\mathbf, \mathcal, \mathit, \mathnormal, \mathop,
\mathrm, \mathsf, \mathtt, \max, \mbox, \mdseries, \medskip,
\mho, \min, \mp, \mpfootnote, \mu, \multicolumn, \multiput,

\nabla, \natural, \nearrow, \neq, \newcommand, \newcounter, 
\newenvironment, \newfont,
\newlength,\newline, \newpage, \newsavebox, \newtheorem, \NG, \ng,
\nocite, \noindent, \nolinbreak, \nopagebreak, \normalsize,
\not, \nu, nwarrow,

\Omega, \omega, \onecolumn, \oint, \opening, \oval, 
\overbrace, \overline,

\P, \page, \pagebreak, \pagenumbering, \pageref, \pagestyle, 
\par, \parbox,\paragraph, \parindent, \parskip, \part, 
\partial, \per, \Phi, \phi,\Pi, \pi, \pm, 
\pmod, \pounds, \prime, \printindex, \prod, \propto, \protext, 
\providecomamnd, \Psi,\psi, \put,

\qbezier, \quoteblbase, \quotesinglbase,

\r, \raggedbottom, \raggedleft, \raggedright, \raisebox, \rangle, 
\Re, \ref, \renewcommand, \renewenvironment, \rhd, \rho, \right, 
\Rightarrow,\rightarrow, \rm, \rmfamily,
\Roman, \roman, \rule, 

\s, \samepage, \savebox, \sbox, \sc, \scriptsize, \scshape, 
\searrow, \sec, \section,
\setcounter, \setlength, \settowidth, \settodepth, \settoheight, 
\settowidth, \sf, \sffamily, \sharp, \shortstack, \Sigma, \sigma, 
\signature, \sim, \simeq, \sin, \sinh, \sl, \SLiTeX,
\slshape, \small, \smallskip, \spadesuit, \sqrt, \sqsubset,
\sqsupset, \SS,
\stackrel, \star, \subsection, \subset, 
\subsubsection, \sum, \sup, \supressfloats, \surd, \swarrow,

\t, \table, \tableofcontents, \tabularnewline, \tan, \tanh, 
\tau, \telephone,\TeX, \textbf,
\textbullet, \textcircled, \textcompworkmark,\textemdash, 
\textendash, \textexclamdown, \textheight, \textquestiondown, 
\textquoteblleft, \textquoteblright, \textquoteleft,
\textperiod, \textquotebl, \textquoteright, \textmd, \textit, \textrm, 
\textsc, \textsl, \textsf, \textsuperscript, \texttt, \textup,
\textvisiblespace, \textwidth, \TH, \th, \thanks, \thebibligraphy,
\Theta, theta, 
\tilde, \thinlines, 
\thispagestyle, \times, \tiny, \title,\today, \totalheightits, 
\triangle, \tt, 
\ttfamily, \twocoloumn, \typeout, \typein,

\u, \underbrace, \underline, \unitlength, \unlhd, \unrhd, \Uparrow,
\uparrow,\updownarrow, \upshape, \Upsilon, \upsilon, \usebox,
\usecounter, \usepackage, 

\v, \value, \varepsilon, \varphi, \varpi, \varrho, \varsigma, 
\vartheta, \vdots, \vec, \vector, \verb, \Vert, \vert, \vfill,
\vline, \vphantom, \vspace,

\widehat, \widetilde, \widthits, \wp,

\Xi, \xi,

\zeta</t>
<t tx="EKR.20040524104904.143"></t>
<t tx="EKR.20040524104904.144">The Check Outline command checks the outline for consistency.

The Check All Python Code and Check Python Code commands report any syntax errors or tabnanny errors.  These commands mark erroneous nodes.  These commands work on the selected Node and its descendants.  These commands ignore any nodes for which a) @ignore is in effect or b) @language python is in not effect.

The Check Python Code and Pretty Print Python Code commands replace nodes with their pretty-printed alternative.

You may implement alternate pretty printers in a plugin merely by overriding the following methods of class prettyPrinter in leoCommands.py:
    
- putOperator:      puts whitespace around operators.
- putNormalToken:   puts whitespace around everything else.</t>
<t tx="EKR.20040524104904.145">The Insert Headline command inserts a new headline after the presently selected headline, either as the next sibling or the first child of the presently selected headline if the presently selected headline has children and is expanded.</t>
<t tx="EKR.20040524104904.146">The Cut Outline, Paste Outline, Copy Outline and Delete Outline commands work on nodes rather than text.  For example, to delete a headline, select the headline and choose the Cut Outline or Delete Outline commands.

The Cut Outline and Copy Outline copy a text representation of the outline to the clipboard.  This representation is the same as the file format with some information deleted.  You may copy this text representation into a body pane (or into any other text editor) using the Paste command in the Edit menu.

New in 4.2:  The Paste Retaining Clone command retains the identity of nodes, so if the pasted node already exists in the outline the newly pasted node will become of a clone of the already-existing node.  In contrast, the Paste Outline creates nodes with new identities (new gnx's).</t>
<t tx="EKR.20040524104904.147">The Expand command expands the currently selected node so that all its children are visible.  The Expand All Subheads command expands the currently selected node so that all its offspring are visible.  The Expand All command expands all the nodes of the entire tree.

New with leo.py version 1.0 and Borland Leo v2.6:

The Contract Parent contracts the parent node of the present node, making the parent the new present node.</t>
<t tx="EKR.20040524104904.148">The Hoist command redraws the screen so presently selected tree becomes the only visible part of the outline.  Leo prevents the you from moving nodes outside the hoisted outline.  The De-hoist command restores the outline.  Hoist commands may be nested.</t>
<t tx="EKR.20040524104904.149">The Mark Headline command marks a headline with a red marker  near the leader characters, while the Unmark Headline command removes such a mark.  Only one of these commands appear in the Outline menu at any time: the Mark Headline command appears if the currently selected headline is unmarked.  Otherwise, the Unmark Headline command appears.  The Mark Subheads command marks all offspring of the currently selected node.  The Unmark All command removes the marks from the entire tree.

The Mark Changed Items command marks all headlines whose headline or body text has been changed since the file was last saved.  The Mark Changed Roots command marks all changed headlines whose body text contains the @root directive.  This command is especially useful with the Tangle Marked command.</t>
<t tx="EKR.20040524104904.150">The Move Up, Move Down, Move Left and Move Right commands move the currently selected node in the indicated direction.  The Promote command makes all the children of a node siblings of the node.  The Demote command makes all the siblings that follow a node children of the node.

The Sort Children command sorts all children of the present node in alphabetical order, based on the headlines of the children.

The Sort Siblings command sorts all siblings of the present node in alphabetical order.

New in version 4.1:  The Hoist command redraws the outline making the present node the root node.  The outline itself is unaffected by the Hoist command.  The De-Hoist command removes one level of hoisting.</t>
<t tx="EKR.20040524104904.151"></t>
<t tx="EKR.20040524104904.152">The Equal Sized Panes command adjusts the sizes of the code and body pane of the topmost window so that they are the same height.
</t>
<t tx="EKR.20040524104904.153">The Cascade command cleans up the screen by cascading all Leo windows.  The Minimize All command minimizes all Leo windows.</t>
<t tx="EKR.20040524104904.154">This command changes the pane that is currently active.  If the outline pane was active, the body pane becomes active, and vice versa.  This command makes it possible to switch between panes without using the mouse.</t>
<t tx="EKR.20040524104904.155">New in leo.py 3.0:  The Toggle Split Direction command switches between vertical and horizontal orientations of the Leo window.  In the vertical orientation, the body pane appears below the pane containing the outline and log panes.  In the horizontal orientation, the body pane appears to the left the pane containing the outline and log panes.

leoConfig.txt specifies the default direction.  If leoConfig.txt does not exist, or does not specify the direction, the "vertical" orientation is used, just as in previous versions.

By default, the ratio of pane outline pane to the body pane is 0.5 in the vertical orientation and 0.3 in the horizontal orientation.  These two ratios may be changed using leoConfig.txt.</t>
<t tx="EKR.20040524104904.156">The Open Compare Window command opens a dialog that allows you to compare two files.

This is not really a general-purpose file-compare dialog.  The purpose of this window is to show what sentinels a derived file contains.  One file is assumed to contain sentinels, the other file is assumed not to contain sentinels.</t>
<t tx="EKR.20040524104904.157"></t>
<t tx="EKR.20040524104904.158">The About Leo command puts up a dialog box showing the version of Leo.
</t>
<t tx="EKR.20040524104904.159">The Online Home Page command opens Leo's home page at http://webpages.charter.net/edreamleo/front.html.

The Open Online Tutorial command opens Joe Orr's excellent ScreenBook tutorial at http://www.evisa.com/e/sbooks/leo/sbframetoc_ie.htm.

The Open Offline Tutorial command opens the file sbooks.chm if it exists in the folder containing leo.py.  If sbooks.chm does not exist, you will be asked whether you want to download it from Leo's SourceForge web site.  If you say yes, the page http://sourceforge.net/project/showfiles.php?group_id=3458 will open.  You should then download sbooks.sbm to the folder containing leo.py.

The Open LeoDocs.leo command opens this file, leoDocs.leo.

</t>
<t tx="EKR.20040524104904.160">The Open LeoConfig.leo command opens the file leoConfig.leo, the primary source file for the derived file leoConfig.txt.  Use the Tangle All command to update leoConfig.txt from changes made to leoConfig.leo.

The Apply Settings command applies the settings in leoConfig.txt.  Leo reads these settings when it begins execution, so the only time you would need to use this command is just after changing leoConfig.txt.</t>
<t tx="EKR.20040524104904.161">@nocolor

This chapter discusses Leo's relationship with traditional literate programming.</t>
<t tx="EKR.20040524104904.162">The following sections discuss the main benefits of traditional literate programming. It's worth noting that none of these benefits derives from being able to produce printed output.</t>
<t tx="EKR.20040524104904.163">Sections add a new dimension to the design and coding process. Choices about what sections do, what they are named, what order they appear in, are choices in a design space different from "normal" programming. This an abstract concept, to be sure. However, the following concrete discussions are really manifestation of working in this new design space.</t>
<t tx="EKR.20040524104904.164">The names of sections are constrained only by one's design skill, not by any rules of language. You say what you mean, and that becomes both the design and the code. You never have to simulate a concept because concepts become section names.</t>
<t tx="EKR.20040524104904.165">The visual weight of a web section is simply the length and complexity of the section's name, regardless of how complex the actual definition of the section is. The results of this separation are spectacular. No longer is one reluctant to do extensive error handling (or any other kind of minutia) for fear that it would obscure the essence of the program. Donald Knuth stresses this aspect of literate programming and I fully agree.</t>
<t tx="EKR.20040524104904.166">Sections can show and enforce relationships between apparently unrelated pieces of code. Comments, macros or functions are other ways to indicate such relationships, but often sections are ideal. Indeed, a natural progression is to create sections as a matter of course. I typically convert a section to a function only when it becomes apparent that a function's greater generality outweighs the inconvenience of having to declare and define the function.</t>
<t tx="EKR.20040524104904.167">A section name is complex when it implies unwholesome dependencies between the caller (user) of the section and the section itself. Such section names tend to be conspicuous, so that the programmer is lead to revise both the section name and its purpose. Many times my attention has been drawn to a poorly conceived section because I didn't like what its name implied. I have always been able to revise the code to improve the design, either by splitting a section into parts or be simplifying its relation to colleagues.</t>
<t tx="EKR.20040524104904.168">One of the most surprising thing about literate programming is how severely traditional programming tends to limit comments. In a conventional program the formatting of code must indicate structure, and comments obscure that formatting. Sections in literate programming provide a place for lengthy comments that do not clutter up the code at the place the section is referenced.</t>
<t tx="EKR.20040524104904.169">The section name often says it all. The reference to the section says everything that the user needs to know, and the section name at the point of definition also eliminates the need for many comments.</t>
<t tx="EKR.20040524104904.170">@nocolor

A typical root starts out with something like.
@color

	&lt;&lt; includes for class x &gt;&gt;
	&lt;&lt; private data for class x &gt;&gt;
	&lt;&lt; private prototypes for class x &gt;&gt;
	&lt;&lt; functions of class x &gt;&gt;

@nocolor
In the derived file there is a comment that looks like this:
@color

	/// &lt;&lt; includes for class x &gt;&gt;

@nocolor
It would be silly to write this comment by hand, though often programmers do just that in order to have a place holder for a mark in the source file. With literate programming the situation is different: the comment indicates that the code came from a particular section; that is, the comment servers a real purpose.
</t>
<t tx="EKR.20040524104904.171">These last several paragraphs have discussed comments in detail because the net effect of "putting comments where they belong" is that comments don't clutter the code. Section references hide irrelevant detail, so larger-scale patterns within functions (or declarations) become more apparent. Often just recasting code into web format has created Ahas about my own code, with no special attention to recoding or redesign! Recasting a function as a web raises the real and apparent level of abstraction.</t>
<t tx="EKR.20040524104904.172">Formatting no longer has to indicate overall design; sections do that. I am less obsessive about formatting code; it simply doesn't matter much whether different sections are formatted consistently because the format of one section has no effect on the look of other sections. Also, I don't worry about most line breaks within documentation parts, or about adding comment delimiters.</t>
<t tx="EKR.20040524104904.173">Outlines add something brand new to traditional literate programming, namely an explicit mechanism for expressing structure at any level of detail, from largest overall view to smallest detail. The following sections elaborate on this theme.</t>
<t tx="EKR.20040524104904.174">By far the biggest drawback of conventional literate programming is that there are so many sections; it becomes difficult to understand the relationships, if any, between sections. Using an outline to express a literate programming instantly solves this problem. The programmer is always aware of how sections are related.</t>
<t tx="EKR.20040524104904.175">Outlines provide a convenient way of expressing the intended scope of commands.  For example, the Tangle command operates only on the presently selected tree. The Extract Section command creates a new section as the last child of the present node.</t>
<t tx="EKR.20040524104904.176">Clones transform a tree into a directed graph without loops. This is a very powerful data structure. Nothing would be gained by cloning an arbitrary directed graph: in general, the clone would simply become the entire tree. Cloning a tree, however, is very effective.

A set of clones becomes essentially a different view of the outline. The set is itself part of the outline, so the outline itself contains an elegant mechanism for representing arbitrarily many views of the same data. It is because of the power of clones that I described MORE in the dedication as possibly the most elegant computer program ever written.

It is easy to create different (and useful) view of a literate outline. For example, I often make clones of all relevant sections of my outline while debugging or adding new features. The clones carry along relevant suboutlines, so essential context is retained, but gathering all the clones together automatically concentrates attention on the problem at hand.</t>
<t tx="EKR.20040524104904.177">The meaning of a well written literate outline is independent on the order in which sections appear, so outlines may be reorganized at will. In addition, headlines without body text do not affect derived files in any way; such headlines can be inserted freely at any time. In fact, such "nonfunctional" headlines often convey the most information about the structure and design of a large system. Decoupling structure from content in this way is precisely what is needed for flexibility: one can reorganize at will without worrying about changing the meaning of the code.</t>
<t tx="EKR.20040524104904.178">Hierarchy is often implicit in programming: for example, the grouping of functions into files, or the organization of a single file as a set of functions, etc. An outline directly expresses hierarchy. For example, Leo's tangle or Find and Change commands may be restricted to a particular suboutline. That's a direct expression of an hierarchical constraint or property: I only want to deal with this part of the outline. With outlines, I can do so effortlessly.

Traditional literate programming often simulates the hierarchy using "bridge" comments. Those comments are far weaker than explicit structure. Experience with the Print command clearly shows that a clear literate outline can easily become unintelligible when printed, no matter how "beautiful" the typeset printout is.

My experience shows that organizational crutches such as printed listings, tables of contents and indices are much less clear than the corresponding outline. You could say the entire outline is a table of contents!</t>
<t tx="EKR.20040524104904.179">There are many ways to express a program as a literate outline. Again, the choices made when doing so are choices in another design space. Such choices are important, and add clarity to the entire program, but can only be expressed when the hierarchy is expressed explicitly.</t>
<t tx="EKR.20040524104904.180">Tangling and untangling are the fundamental operations of literate programming. Any editor that supports literate programming should provide these operations directly. Moreover, Leo automatically untangles @file trees when reading .leo files and tangles @file trees when writing .leo files.  Eliminating the need for explicit tangling and untangling is a huge improvement.</t>
<t tx="EKR.20040524104904.181">Leo changes the theory and practice of literate programming as follows:

1. Leo reduces the need for comments within a program. In particular, bridge or transition phrases are almost always unnecessary in a literate outline. One never needs to say something like, "having just finished with topic x, we turn now to topic y." Literate outlines tend to be far less chatty than flat literate programs.

2. Leo shows that printed listings are not necessary to understand noweb or CWEB programs. No printed listing can be as clear as Leo's outline view. It is possible to make printed listings intelligible by adding "context lines" that show the outline context of a section definition. Without such context lines a literate program must rely on extensive bridge comments.

3. Leo shows that simple, standard, yet flexible outline organizations provide a more natural way to organize large programs than narrative organizations. Indeed, narrative style creates severe maintenance problems. The narrative is soon forgotten, and when that happens it becomes difficult to find anything. The few times I have tried narrative organization I soon regretted it: things just weren't where I expected them to be.

4. Leo shows that traditional literate programming encourages a too creative approach to programming. A dictionary is a better model for programs than a novel. Literate outlines provide a more regular organization, while providing space for the most lengthy discussions when those discussions are required.

In short, Leo shows that the phrase "literate programming" is a misnomer. Indeed, chunks or sections, the atoms of literate programming, have little to do with literature. Outlines eliminate the need for narrative. One can use chunks or sections to write narrative prose, but Leo demonstrates that one is under no obligation to do so.</t>
<t tx="EKR.20040524104904.182">@nocolor
@language python

This chapter documents scripting for Leo using Python.

This chapter describes only the most useful functions, classes and methods in leo.py.  However, keep in mind the following:

	** Your scripts have complete access to _all_ of Leo's source code **

Therefore, the most complete documentation for scripting is Leo's source code itself, that is, the file LeoPy.leo.  In particular, see the node called "Overview of the Code", the first child of the node called "Code".

You can execute all of the scripts in this chapter by selecting the node containing the script and executing the "Execute Script" command.  N.B.  Leo's Execute Script command now understands all aspects of Leo's markup, including @others directives, doc parts and section references.  This means that you don't have to select just the "code" part in the examples below: you can select the entire node!</t>
<t tx="EKR.20040524104904.183">@nocolor
@ Leo's source code is a collection of classes, along with utility functions in leoGlobals.py.  The preferred way of accessing the functions and data in leoGlobals.py is as follows:
@c
@color
	
import leoGlobals as g
from leoGlobals import true,false

@nocolor
@ After these imports you may call function x in leoGlobals as follows: g.x()

g.app refers to the _application object_ representing the entire Leo application.
The ivars (instance variables) of g.app represent Leo's global variables.

A _commander_ (an instance of the Commands class) represents the operations that can be performed on a _particular_ window.  Each open Leo window has its own commander.  g.top() returns the commander of the top window.  By convention, any variable named c refers to a commander.

A _frame_ (an instance of the leoFrame class) contains all the internal data needed to manage a Leo window.  Given a commander c, c.frame refers to the commanders frame.  Given a frame f, f.c refers to the frame's commander.

A _vnode_ represents an outline node.  New in 4.2:  a node may appear several times within the same outline.  You can use vnode methods to get and set headline text, body text and properties such as whether the node is dirty or marked.  By convention, any variable named v,v1 or v2 refers to a vnode.  vnodes have v._parent, v._next and v._back links that "point" to the vnodes parent and siblings.  Leo moves vnodes around by changing these links.

Joined vnodes are updated together.  Cloned nodes are joined, as are corresponding nodes in the subtrees of cloned nodes.

A _tnode_ represents the actual data in a vnode, including headline and body text.  Vnodes that are joined to each other have the same tnode.  For any vnode v, v.t is v's tnode.

New in Leo 4.2:  tnodes contain a t._firstChild link that points to a _vnode_.  Because cloned vnodes share the same tnode, they also share the same v.t._firstChild link.  In other words, cloned vnodes use a _single_ subtree to represent their common descendant trees.  A _shared subtree_ is a tree of vnodes shared by multiple cloned nodes.  The root of a shared subtree is always some v.t._firstChild link.

N.B. The vnodes of a shared subtree will appear multiple times on the screen.  That means that in Leo 4.2 in later vnodes no longer represent a _single_ location on the screen, nor do vnodes represent a particular position in a traversal of a tree.

New in Leo 4.2:  a _position_ object represents the location of a particular node in a tree traversal or on the screen.  By convention, any variable named p or p1 or p2 refers to a position.  For any position p, p.v is the vnode at that position and p.v.t is the tnode at that position.

Leo's code uses position objects very much like vnodes were used in pre-4.2 versions of Leo.  In particular, please note the following extremely important properties of commanders and positions:
	
- In Leo 4.2 the c.currentVnode and c.rootVnode methods return _positions_, not vnodes.
- position objects support all the common vnode methods that were used in scripts prior to Leo 4.2.

These two facts mean that most scripts written before Leo 4.2 will continue to work in Leo 4.2.

Aside: the preferred way of get the position of the root node and the presently select node is c.rootPosition and c.currentPosition respectively.  The c.currentVnode and c.rootVnode methods exist only for compatibility with old code.

You can execute this script right now by selecting the script and choosing the "Execute Script" command.  The output from the g.es statement will go to the log pane.
@c
@color

import leoGlobals as g
windows = g.app.windowList # The list of all open _frames_
g.es("Open windows...",color="purple")
for w in windows:
	g.es(w) # A frame.
	g.es(w.c) # A commander.
	g.es(w.c.rootPosition()) # A position.
	assert(w.c.rootPosition()==w.c.rootVnode())</t>
<t tx="EKR.20040524104904.184">@color
@ The following nodes show how to do the most common tasks while scripting Leo.

You may execute the code in each node by executing the Execute Script command.
@c
@language python</t>
<t tx="EKR.20040524104904.185">@color

# The g.es method prints its arguments to the log pane.
import leoGlobals as g
g.es("Hello world")

# g.es prints multiple arguments separated by commas.
g.es("Hello","world")

# g.es converts non-string arguments using repr.
g.es(g.top())</t>
<t tx="EKR.20040524104904.186">@color

# The g.top() function returns the Commands object of the top Leo window.
import leoGlobals as g
c = g.top()
g.es(c)
g.es(c.rootPosition())

@ The windowlist attribute of the application instance contains the list of the
frames of all open windows. The commands ivar of the frame gives the commander
for that frame. Execute this code now with the Execute Script command.
@c

import leoGlobals as g
windows = g.app.windowList # get the list of all open frames.
g.es("windows...")
for f in windows:
	c = f.c # c is f's commander
	g.es(f)
	g.es(f.shortFileName())
	g.es(c)
	g.es(c.rootPosition())</t>
<t tx="EKR.20040524104904.187">@color
@ leoGlobal.py defines 6 convenience methods for redirecting stdout and stderr:

- g.redirectStderr() # Redirect stderr to the current log pane.
- g.redirectStdout() # Redirect stdout to the current log pane.
- g.restoreStderr()  # Restores stderr so it prints to the console window.
- g.restoreStdout()  # Restores stdout so it prints to the console window.
- g.stdErrIsRedirected() # Returns true if the stderr stream is redirected to the log pane.
- g.stdOutIsRedirected() # Returns true if the stdout stream is redirected to the log pane.

Calls need _not_ be paired. Redundant calls are ignored and the last call made
controls where output for each stream goes.

NOTE: you must execute Leo in a console window
to see non-redirected output from the print statement.
@c

import leoGlobals as g
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.redirectStderr()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.redirectStdout()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.restoreStderr()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.restoreStdout()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()</t>
<t tx="EKR.20040524104904.188">@color

# Here is how to access the data of a Leo window.
import leoGlobals as g
c = g.top()

p = c.currentPosition() # get the current position.
g.es(p)
g.es("head:",p.headString())
g.es("body:",p.bodyString())</t>
<t tx="EKR.20040524104904.189">@color

import leoGlobals as g
c = g.top()
p = c.currentPosition()
body = p.bodyString()
head = p.headString()

# BTW, these methods will work whether or not p is the current position.  
# This won't really anyting because we haven changed body or head.
p.setBodyStringOrPane(body)     # set body text of p to body.
p.setHeadStringOrHeadline(head) # set headline text of p to head.</t>
<t tx="EKR.20040524104904.190">@color
@ New in Leo 4.2.  The preferred way to traverse an outline is with an iterator.

c.allNode_iter is an iterator that returns all the positions of an outline in outline order.

See the node called "Iterators" below for a full discussion of all iterators.
@c

# Count the number of separate positions and distinct vnodes of this outline.
import leoGlobals as g
c = g.top()

positions = 0 ; tnodes = {}
for p in c.allNodes_iter():
	positions += 1
	if not tnodes.get(p.v.t):
		tnodes[p.v.t] = p.v.t

g.es("%8s" % "positions",positions)
g.es("%8s" % "vnodes",len(tnodes.keys()))</t>
<t tx="EKR.20040524104904.191">@color
@ Iterators are defined only by the position class;  vnodes can not have iterators because vnodes may appear in multiple places in an outline.

All iterators take an optional copy keyword argument.  You should use copy=true if your script actually alters the position returned by the iterator, say by calling p.moveToThreadNext().</t>
<t tx="EKR.20040524104904.192">@ The c.allNodes_iter returns a list of all positions in the outline.

See the children of this node for more examples.
@c

# Here is how to create a list of all positions in an outline.

import leoGlobals as g
c = g.top()

nodes = [p for p in c.allNodes_iter()]
g.es("This outline contains %d nodes" % len(nodes))</t>
<t tx="EKR.20040524104904.193"># Here is one way to count the nodes of an outline.

import leoGlobals as g
c = g.top()

count = 0
for p in c.allNodes_iter():
	count += 1
g.es("This outline contains %d nodes" % count)</t>
<t tx="EKR.20040524104904.194"># Here is one way to count the distinct vnodes of an outline.

import leoGlobals as g
c = g.top()

positions = 0 ; tnodes = {}
for p in c.allNodes_iter():
	positions += 1
	if not tnodes.get(p.v.t):
		tnodes[p.v.t] = p.v.t

g.es("%8s" % "positions",positions)
g.es("%8s" % "vnodes",len(tnodes.keys()))</t>
<t tx="EKR.20040524104904.195">@ The p.children_iter returns a list of all children of position p.
@c

import leoGlobals as g
c = g.top()
p = c.currentPosition()
parent = p.parent()

g.es("children of %s" % parent.headString(),color="purple")
for p in parent.children_iter():
	g.es(p.headString())</t>
<t tx="EKR.20040524104904.196">@
The p.parents_iter returns a list of all parents of position p, excluding p.
The p.self_and_parents_iter returns a list of all parents of position p, including p.
@c

import leoGlobals as g
c = g.top()
current = c.currentPosition()

print '-'*40

g.es("inclusive parents of %s" % current.headString(),color="purple")
for p in current.self_and_parents_iter():
	g.es(p.headString())

g.es("exclusive of %s" % current.headString(),color="purple")
for p in current.parents_iter():
	g.es(p.headString())</t>
<t tx="EKR.20040524104904.197">@
The p.siblings_iter returns a list of all siblings of position p.
The p.following_siblings_iter returns a list of all siblings that follow position p
@c

import leoGlobals as g
c = g.top()
current = c.currentPosition()

g.es("all siblings of %s" % current.headString(),color="purple")
for p in current.self_and_siblings_iter():
	g.es(p.headString())

g.es("following siblings of %s" % current.headString(),color="purple")
for p in current.following_siblings_iter():
	g.es(p.headString())</t>
<t tx="EKR.20040524104904.198">@
The p.subtree_iter returns a list of all positions in p's subtree, excluding p.
The p.self_and_subtree_iter returns a list of all positions in p's subtree, including p.
@c

import leoGlobals as g
c = g.top()
p = c.currentPosition()
parent = p.parent()

g.es("inclusive subtree of %s" % parent.headString(),color="purple")
for p in parent.self_and_subtree_iter():
	g.es(p.headString())
	
g.es("exclusive subtree of %s" % parent.headString(),color="purple")
for p in parent.subtree_iter():
	g.es(p.headString())</t>
<t tx="EKR.20040524104904.199">@color
@ Leo's commands use c.beginUpdate() and c.endUpdate() to reduce flicker.  c.beginUpdate() suppresses all drawing in the outline pane until the matching c.endUpdate() is seen.  These methods can be nested; each c.beginUpdate() must have a corresponding c.endUpdate().

c.endUpdate takes an optional parameter.  If this parameter is false, no redrawing is done.  This can sometimes be useful; inner code can tell other code whether redrawing is actually required.

c.redraw() forces an update of the entire screen.  c.endUpdate() calls c.redraw() as needed.
@c

import leoGlobals as g
from leoGlobals import true,false
c = g.top()
# Force a screen redraw
c.redraw()
# Typical way to redraw the screen:
c.beginUpdate()
# ...code that alters the screen...
c.endUpdate()
# Typical way to conditionally redraw the screen:
c.beginUpdate()
# ...code sets flag if the screen needs redrawing.
flag = true
c.endUpdate(flag)s</t>
<t tx="EKR.20040524104904.200">@color
@
Leo dispatches commands using the c.doCommand and "Menu Command Handlers"
defined in the node by the same name in leoFrame.py. This node contains the menu
handlers for _all_ of Leo's menu commands, organized by menu and submenu.

I recommend that your scripts use frame.doCommand for the following reasons:

- frame.doCommand calls the "command1" and "command2" hook routines for the given label and
- frame.doCommand catches all exceptions thrown by the command.
- the menu commands handles hide a number of implementation details.
@c

import leoGlobals as g
c = g.top()

if 1: # calls hooks.
	c.doCommand(c.markHeadline,label="markheadline")
else: # does not call hooks.
	c.markHeadline()

@
As stated above, the commands handlers in leoFrame.py hide many implementation
details involved in invoking the various commands. If you want to invoke
commands without calling frame.doCommand, you should study the corresponding
menu command handler to see what may be required.

Among these details is this: commanders create subcommanders to handle complex commands:

- The atFile class (leoAtFile.py) reads and writes files derived from @file trees.
- The LeoFind class (leoFind.py) handles the Find and Change commands.
- The leoImportCommands class (leoImport.py) handles the Import and Export commands.
- The tangleCommands class (leoTangle.py) handles the Tangle and Untangle commands.
- The undoer class (leoUndo.py) handles the Undo command.
- All other command are handled by the commander itself (leoCommands.py)</t>
<t tx="EKR.20040524104904.201">@color
@ Each commander maintains its own preferences.  Your scripts can get the following ivars:
	c.output_doc_flag
	c.page_width
	c.tab_width
	c.tangle_batch_flag
	c.tangle_directory
	c.target_language
	c.untangle_batch_flag
	c.use_header_flag
	
leoPrefs.leoPrefs.ivars is a list of the _names_ of these ivars.
@c

import leoPrefs
import leoGlobals as g
c = g.top()

g.es("Prefs ivars...\n",color="purple")
for ivar in leoPrefs.leoPrefs.ivars:
	exec("val=c."+ivar) # do val = c.ivar
	g.es("c."+ivar,val)</t>
<t tx="EKR.20040524104904.202">@color
@ Your scripts may set preferences by setting one of the following ivars:
	c.output_doc_flag
	c.page_width
	c.tab_width
	c.tangle_batch_flag
	c.tangle_directory
	c.target_language
	c.untangle_batch_flag
	c.use_header_flag
@c

import leoPrefs
import leoGlobals as g
c = g.top()
c.tab_width = 4 # Change this and see what happens.

# Your script may update the prefs panel as follows:
if c.frame.prefsPanel:
	c.frame.prefsPanel.init(c)
	c.frame.prefsPanel.setWidgets()

# If your script sets c.tab_width your script may call f.setTabWidth to redraw the screen.
c.frame.setTabWidth(c.tab_width)</t>
<t tx="EKR.20040524104904.203">@color
@ The file leoFindScript.py contains functions for finding and changing text from within scripts. The children of this node show two examples of using the functions.  See the @file leoFindScript.py tree in LeoPy.leo for full details.</t>
<t tx="EKR.20040524104904.204">@color
@
The findall function returns a list of tuples (v,pos) describing matches in c's entire tree.
@c

import leoGlobals as g
import leoFindScript
c = g.top()

pattern="import leoGlobals as g"
result = leoFindScript.findAll(c,pattern,bodyFlag=1)

g.es("%-3d instances of: '%s'...\n" % (len(result),pattern),color="purple")

for v,pos in result:
	body = v.bodyString()
	g.es('\n%-4d %s' % (pos,v.headString()))
	g.es(g.get_line_after(body,pos))</t>
<t tx="EKR.20040524104904.205">@color
@ The reFindall function returns a list of tuples (v,mo,pos),
where mo is a "Match Object".
The reFlags argument are flags to re.search()
@c

import leoGlobals as g
import leoFindScript
c = g.top()

pattern="from .* import"
result = leoFindScript.reFindAll(c,pattern,bodyFlag=1,reFlags=None)

g.es("%-3d instances of: '%s'...\n" % (len(result),pattern),color="purple")
for v,mo,pos in result:
	body = v.bodyString()
	g.es('\n%-4d %s' % (pos,v.headString()))
	g.es(g.get_line_after(body,pos))</t>
<t tx="EKR.20040524104904.206">@color
@  New in version 4.1: On startup, Leo looks for two arguments of the form --script scriptFile.  If found, Leo enters batch mode.

In batch mode Leo does not show any windows.  Leo assumes the scriptFile contains a Python script and executes the contents of that file using Leo's Execute Script command.  By default, Leo sends all output to Leo's log pane to the console window.  Scripts in the scriptFile may disable or enable this output by calling app.log.disable() or app.log.enable()

Scripts in the scriptFile may execute any of Leo's commands except the Edit Body and Edit Headline commands.  Those commands require interaction with the user.

For example, the following batch script reads a Leo file and prints all the headlines in that file.
@c

import leoGlobals as g

path = r"c:\prog\leoCVS\leo\test\test.leo"

g.app.log.disable() # disable reading messages while opening the file
flag,newFrame = g.openWithFileName(path,None)
g.app.log.enable() # re-enable the log.

for p in newFrame.c.allNodes_iter():
	g.es(g.toEncodedString(p.headString(),"utf-8"))</t>
<t tx="EKR.20040524104904.207">@color
@ leoGlobals.py contains many "utility" functions and other names.
@c

# Print all names (functions and constants) defined in leoGlobals.py.
import leoGlobals as g

g.es("Names defined in leoGlobals.py",color="purple")
names = g.__dict__.keys()
names.sort()
for name in names:
	g.es(name)</t>
<t tx="EKR.20040524104904.208">@color
@ Most scripts will use methods of the position class to access information in an outline.

The following section summarizes the most useful methods that your scripts can use.  For a complete list, see the @file leoNodes.py tree of LeoPy.leo.

N.B. Both the position and vnode classes support similar methods.  However, iterators exist only in the position class.

You may execute the code in each node by executing the Execute Script command.
@c
@language python</t>
<t tx="EKR.20040524104904.209">@color
@ This section lists the most useful ivars and methods for getting information from vnodes or positions.
@c

# Returning commanders...
p.c # The commander for p.

# Returning strings...
p.bodyString() # the body string of p.
p.headString() # the headline string of p.

# Returning ints...
p.childIndex()
p.numberOfChildren()
p.level()

# Returning bools representing property bits...
p.hasChildren()
p.isAncestorOf(v2) # true if v2 is a child, grandchild, etc. of p.
p.isCloned()
p.isDirty()
p.isExpanded()
p.isMarked()
p.isVisible()
p.isVisited()</t>
<t tx="EKR.20040524104904.210">@color
@ This section lists the most useful methods for setting data or properties of positions.
@c

# These work whether or not p is the presently selected position.
p.setBodyTextOrPane(s)       # Sets the body text of p.
p.setHeadStringOrHeadline(s) # Sets the headline text of p.

# Moving nodes...
p.moveAfter(v2)  # move p after v2
p.moveToNthChildOf(v2,n)  # move p to the n'th child of v2
p.moveToRoot()  #  make p the root position

# The "visited bit" may be used by commands or scripts for any purpose.
# Many commands use this bits for tree traversal, so these bits do not persist.
c.clearAllVisited() # Clears all visited bits in c's tree.
p.clearVisited()
p.setVisited()</t>
<t tx="EKR.20040524104904.211">@nocolor

You may customize Leo in several ways:

I.  Using leoConfig.txt

When Leo first starts, Leo looks for a file called leoConfig.txt, derived from leoConfig.leo, which contains extensive documentation for each setting.  The settings in leoConfig.txt include:

- Fonts used in Leo's body, outline and log panes.
- Colors used for syntax coloring.
- Menu shortcuts for all menu items.
- Sizes and splitter orientation for newly created windows.
- Initial entries in the Recent Files menu, and the Find, Preferences and Compare panels.
- The format of .leo files.

The section called "Using leoConfig.leo and leoConfig.txt" gives the rules for how Leo uses these two files.

II. Using plugins and hooks

New in 3.11:  It is no longer necessary to modify customizeLeo.py.  Instead of modifying customizeLeo.py you now should add plugins to the plugins directory.  In fact, customizeLeo.py will soon disappear entirely.

During startup, Leo looks for plugins, i.e., files whose name matches mod_*.py in the plugins directory.  These plugins register functions called "hooks" to be called a various times during execution.  Full details are provided below.

Plugins provide the following advantages:

- Any time you see a nice hook handler that someone has written you can just copy it to a plugin file and it runs next time you start Leo.
- You don't have to keep updating a large and growing customizeLeo.py file.
- You can disable and enable hooks by renaming the relevant plugin file.
  (or by enabling or disabling the code in the plugin that registers hook functions).
- You don't have to merge code from hooks pertaining to the same Leo event.

When executing any command or handling any event, Leo calls hook routines registered from the plugin files.  The arguments to hooks are:

- "tag", a string telling the kind of command or event about to be executed, and
- "keywords", a Python dictionary whose keys depend on the specific command or event.

This is a very simple, powerful and general mechanism for customizing Leo as you see fit.  There are dozens of kinds of hooks, including the "command1" and "command2" hooks that are called before and after each of Leo's menu commands.  Leo will allow you to override most commands and event handling.  In many cases, if a hook returns any value except None Leo will assume that the hook has completely handled the command or event and will take no further action.  The details will be explained in full below.

Leo catches all exceptions raised in hook code, so you can modify hooks without worry.

SECURITY WARNINGS: Using hooks naively can create the potential for virus-like behavior.  Please read the section called SECURITY WARNINGS for full details.

III. Using convenience routines called from hooks.

Hook routines can import any file in Leo's source code and execute routines in that file.  Leo's contains a number of convenience routines designed to make common customization tasks easier.  Hooks can use these routines to create your own menus, to translate menus into other languages, and to create entries in the Open With menu.  These convenience routines are discussed in detail below.

IV. Setting app().realMenuNameDict inside hooks to translate menus into other languages.

This is discussed below.</t>
<t tx="EKR.20040524104904.212">@nocolor

Leo will override settings in .leo files if it finds a file called leoConfig.txt in the config subdirectory.  Leo works just as before if it does not find a leoConfig.txt file.

You should make changes to leoConfig.txt by changing leoConfig.leo and then executing the Tangle All command.  There are two advantages to changing leoConfig.txt in this manner.  First, it is just easier to change leoConfig.leo.  Second, all comments are lost in leoConfig.txt when Leo updates it, so using leoConfig.leo as the primary data file means you will always have the comments available.

Leo looks for leoConfig.txt first in the directory specified by the Python variable sys.leo_config_directory.  You would typically set this variable in Python's sitecustomize.py file.  If this variable does not exist, Leo looks in the directory from which Leo was loaded.

The child of this node contains an example of leoConfig.txt that shows all the options that may be set.

Settings in leoConfig.txt overrides preferences in .leo files, but only for those items actually in leoConfig.txt, so you can choose which settings you want to override.  Also, a Leo ignores any setting in leoConfig.txt whose value is "ignore" (without the quotes). For example:

[prefs panel options]
tab_width = ignore

If a setting is overridden, it is _not_ written to the .leo file when the outline is saved.  Note that this does not change the file format: all previous versions of Leo will be able to read such .leo files.

The preceding is probably all you need to know to use leoConfig.txt.  The following discuss some minor details: 

1. When reading a .leo file, if a setting is found neither in leoConfig.txt nor in the .leo file, Leo uses a default, hard-coded value.  In leo.py 3.0 and later these default settings are found in tables that appear in the section called:

	&lt;&lt; define default tables for settings &gt;&gt;

in the file leoConfig.py. So it is now convenient to change settings in leo.py itself as well as in leoConfig.txt.

2. Leo will update leoConfig.txt unless the read_only option is on in leoConfig.txt.  

WARNING: there are problems when Leo does write leoConfig.txt: all comments are lost and options and sections are written in a random order.  This is due to problems in Python's ConfigParser module and will not be changed any time soon.

3. Provided the read_only option is off, Leo updates leoConfig.txt whenever it saves a .leo file or whenever the Preferences panel is closed without being canceled.  When updating leoConfig.txt, Leo will write only existing settings whose value is not "ignore".

4. When Leo saves a .leo file, Leo will write a Preferences setting to the .leo file only if the setting will not be written when updating leoConfig.txt.  In particular, changes made in the Preferences Panel will become permanent immediately if Leo the read_only option is off.  Otherwise the change will become permanent when any .leo file is saved.</t>
<t tx="EKR.20040524104904.213">Beginning with version 3.11, you may use plugins to customize how Leo works.  You can

- override or modify any command
- add or customize menus or
- translate menus into any language.

Plugins have full access to all of Leo's source code.  In particular, several convenience methods have been added to make customizing menus and commands easier.

Plugins are permanent: they will not go away when Leo is updated.  You can take
advantage of the latest CVS updates _without_ having to throw away your modifications.

Important warning: plugins must avoid blindly executing scripts in .leo files.  Doing so could expose all parts of your computer to malicious Python code.  The section called "Security warnings and precautions" discusses how to customize Leo safely and how to avoid several pitfalls.</t>
<t tx="EKR.20040524104904.214">@nocolor

What is a plugin?

A plugin is a .py file that appears in Leo's plugin subdirectory. Leo tries to
import all such files while starting up. This is done at "start1" time, that
is, in the call to doHook("start1") in the run function in leo.py. Plugins
exist to define "hook code".

New in 3.11: Leo looks in the plugins folder for .py files. Leo tries to
import all such files at startup ("start2") time.

New in 4.1: Leo enables only plugins whose name appears in pluginsManager.txt.
Leo loads plugins in the order in which they appear in pluginsManager.txt. Leo
loads no plugins if pluginsManager.txt does not exist in the plugins directory.

What is hook code?

Leo automatically calls hook code at various times during Leo's execution.
Typical hooks are:

- "start2", called at the end of Leo's startup process,
- "command1", called before executing any of Leo's commands
- "idle", called at Tk's idle time, when nothing else is happening,

See the documentation for hooks in this file for full details.

N.B. Plugins can use "start2" hooks to override any of Leo's classes. See
"Overriding functions, methods &amp; classes" in leoPlugins.leo for several
examples of how to do this.

How do plugins work?

Plugins register themselves when Leo imports them using the following code,
which should appear as the outer level of the .py file:

@color

"""A description of this plugin"""

registerHandler("xxx", onXXX)
__version__ = "1.2"
plugin_signon(__name__)
	
@nocolor

Line by line:

1) """A description of this plugin"""

This is a Python doc string describing the plugin. This string becomes the
value of the __name__ attribute for the module (.py file).

2) registerHandler("xxx", onXXX)

This line registers a handler called onXXX for the hook called "xxx". See the
documentation for hooks for a complete list of hook names that you can use
instead of "xxx". onXXX is the name of a function or method, presumably defined
in the plugin file, that Leo will call at "xxx" time. For example:

registerHandler("idle",onIdle)

will cause Leo to call the onIdle function at "idle" time.

You can pass a list of hook names as the first argument to registerHandler. For
example:

registerHandler(("bodykey1","bodykey2","headkey1","headkey2"), onKey)

3) __version__ = "1.2"

This assigns a version attribute to module. At present this attribute is used
by the plugin code that creates Leo's Plugins menu.

4) plugin_signon(__name__)

This line increases the count of loaded modules. The present code for
plugin_signon does not actually print separate signons--it seems to verbose.

About hook handlers

See the "About hooks" section of leoPlugins.leo for full documentation about
how to write hook handler routines, like onXXX or onKey in the examples above.
Basically, each hook should have this pattern:
	
@color

def onXXX (tag,keywords):
	c = keywords.get("c")
	otherKeyword = keywords.get("otherKeyword")
	&lt;&lt; do something with c and otherKeyword, etc. &gt;&gt;
	
@nocolor

In other words, keywords is a Python dictionary containing the keyword
arguments passed to the hook handler. See the See the "About hooks" section of
leoPlugins.leo for a list of the keywords passed to each hook handler.

The tag is the name of the hook. For example, tag would one of
"bodykey1","bodykey2","headkey1","headkey2", for the onKey hook handler in the
example above.

What's next?

It's one thing to know how to create a plugin. It's another to know how to
actually change Leo. Obviously, some study is needed. The place to start your
study is LeoPy.leo. In particular, study very carefully the section called
"Overview of code". Leo is a highly modular program, and Python is ideally
suited to this style of programming.</t>
<t tx="EKR.20040524104904.215">@nocolor

New in 3.11: Leo looks in the plugins folder for .py files. Leo tries to
import all such files at startup ("start2") time.

New in 4.1: Leo enables only plugins whose name appears in pluginsManager.txt.
Leo loads no plugins if pluginsManager.txt does not exist in the plugins directory.

The child of this node gives an example of the code that creates the Open With
menu. The following code, appearing at the end of mod_open_with.py, registers
two different hook functions. The on_idle function is the "idle" hook. The
create_open_with_menu is the "start2","open2" and "command2" hooks.

@color

# Register the handlers... 
registerHandler("idle", on_idle) 
registerHandler(("start2","open2","command2"), create_open_with_menu) 
es("...open with")
	
@nocolor
Plugins may call registerHandler with a hook name like "idle" or a list of hook
names like ("start2","open2","command2"). Also, you can use the "all" hook name
to indicate that code will be called for all hooks. This is useful for tracing
hooks. Plugins may also call registerExclusiveHandler for hooks that should not
be redefined in other plugins.

mod_open_with.py also contains the on_idle and create_open_with functions that
actually handle the hook. Such functions have two arguments: tag and keywords.
You will find many examples of this in LeoPy.leo.

About error checking:

At present Leo will disable all hooks if any hook throws an exception. In
practice this isn't a big deal, but something better could be done.

How to send me your plugins:

It should now be _much_ easier to submit a plugin for inclusion in LeoPy.leo.
Just send me a .leo file containing @file mod_your_plugin.py. Please have this
@file node be @ignored: this is more convenient for me. Ideally, your .leo file
should contain _only_ your plugin code.</t>
<t tx="EKR.20040524104904.216">@color
@language python
@ignore

"""Open With handler"""

from customizeLeo import *
from leoGlobals import *

@others

if 1: # Register the handlers...
	registerHandler("idle", on_idle)
	registerHandler(("start2","open2","command2"), create_open_with_menu)
	es("...open with")</t>
<t tx="EKR.20040524104904.217"># frame.OnOpenWith creates the dict as follows:
# dict = {"c":c, "v":v, "f":f, "path":path, "time":time}

def on_idle (tag,keywords):

	import os
	a = app()
	for dict in a.openWithFiles:
		path = dict.get("path")
		c = dict.get("c")
		v = dict.get("v")
		if path and os.path.exists(path):
			try:
				time = os.path.getmtime(path)
				if time and time != dict.get("time"):
					dict["time"] = time
					&lt;&lt; update v's body text &gt;&gt;
			except: pass</t>
<t tx="EKR.20040524104904.218">&lt;&lt; set s to the new text &gt;&gt;
body = v.bodyString()
&lt;&lt; set conflict flag &gt;&gt;

if conflict:
	# Report the conflict &amp; set update.
	import leoDialog
	d = leoDialog.leoDialog()
	message = "Conflict in %s.\n\n" % (v.headString())
	message += "Replace outline with external changes?"
	update = d.askYesNo("Conflict!",message) == "yes"
else:
	update = s != body

if update:
	h = v.headString()
	es("changed:" + h)
	v.setBodyStringOrPane(s)
	c.selectVnode(v)
	v.OpenWithOldBody = s
</t>
<t tx="EKR.20040524104904.219">try:
	# Update v from the changed temp file.
	f=open(path)
	s=f.read()
	f.close()
except:
	es("can not open " + shortFileName(path))
	break
</t>
<t tx="EKR.20040524104904.220">try:
	# The OpenWithOldBody attribute does not normally exist in vnodes.
	old_body = v.OpenWithOldBody
	conflict = body != old_body and body != s
except:
	conflict = v.isDirty() and body != s
</t>
<t tx="EKR.20040524104904.221">def create_open_with_menu (tag,keywords):

	if  (tag in ("start2","open2") or
		(tag=="command2" and keywords.get("label")=="new")):
	
		&lt;&lt; create the Open With menu &gt;&gt;

		# Enable the idle-time hook so we can check temp files created by Open With.
		from leoGlobals import enableIdleTimeHook
		enableIdleTimeHook(idleTimeDelay=500)
</t>
<t tx="EKR.20040524104904.222">@ Entries in the following table are the tuple (commandName,shortcut,data).
data is the tuple (command,arg,ext).
command is one of "os.system", "os.startfile", "os.spawnl", "os.spawnv" or "exec".
Leo executes command(arg+path) where path is the full path to the temp file.
If ext is not None, the temp file has the extension ext,
Otherwise, Leo computes an extension based on what @language directive is in effect.
@c

idle_arg = "c:/python22/tools/idle/idle.py -e "

if 1: # Default table.
 table = (
  ("&amp;Idle",   "Alt+Shift+I",("os.system",idle_arg,".py")),
  ("&amp;Word",   "Alt+Shift+W",("os.startfile",None,".doc")),
  ("Word&amp;Pad","Alt+Shift+T",("os.startfile",None,".txt")))
else: # David McNab's table.
 table = (
  ("X&amp;Emacs", "Ctrl+E", ("os.spawnl","/usr/bin/gnuclient", None)))

top().frame.createOpenWithMenuFromTable(table)
</t>
<t tx="EKR.20040524104904.223">@nowrap

At startup time Leo looks all files of the form mod_*.py in the plugins
directory. Leo assumes that these files are "plugins" containing Python modules
that customizes Leo's operation. Leo attempts to import each file.

Each module should register routines that are called at various times during
execution. Such times are identified by strings known as "tags". The code in in
one or more plugins corresponding to each tag are known as the "hook" routines
for that tag. Leo catches exceptions (including syntax errors) in hook
routines, so it is safe to hack away on this code.

Leo passes two argument to all hook routines: the tag and a keywords dictionary
containing additional information. For example, keywords["label"] indicates the
kind of command for "command1" and "command2" hooks.

For some hooks, returning anything other than None "overrides" Leo's default
action. Hooks have full access to all of Leo's source code. Just import the
relevant file. For example, top() returns the commander for the topmost Leo
window.

The following table summarizes the arguments passed to hooks: ( Overrides is
"yes" if returning anything other than None overrides Leo's normal command or
event processing.)

tag argument                                              keys in keywords
(hook name)  overrides       when called                  dictionary argument
---------    ---------       -----------                  -------------------
"bodyclick1"   yes      before normal click in body       c,v,event
"bodyclick2"            after  normal click in body       c,v,event
"bodydclick1"  yes      before double click in body       c,v,event
"bodydclick2"           after  double click in body       c,v,event
"bodykey1"     yes      before body keystrokes            c,v,ch,oldSel,undoType
"bodykey2"              after  body keystrokes            c,v,ch,oldSel,undoType
"bodyrclick1"  yes      before right click in body        c,v,event
"bodyrclick2"           after  right click in body        c,v,event
"boxclick1"    yes      before click in +- box            c,v,event
"boxclick2"             after  click in +- box            c,v,event
"command1"     yes      before each command               c,v,label (note 2)
"command2"              after  each command               c,v,label (note 2)
"drag1"        yes      before start of drag              c,v,event
"drag2"                 after  start of drag              c,v,event
"dragging1"    yes      before continuing to drag         c,v,event
"dragging2"             after  continuing to drag         c,v,event
"end1"                  start of app.quit()
"enddrag1"     yes      before end of drag                c,v,event
"enddrag2"              after  end of drag                c,v,event
"headclick1"   yes      before normal click in headline   c,v,event
"headclick2"            after  normal click in headline   c,v,event
"headrclick1"  yes      before right click in headline    c,v,event
"headrclick2"           after  right click in headline    c,v,event
"headkey1"     yes      before headline keystrokes        c,v,ch
"headkey2"              after  headline keystrokes        c,v,ch
"hypercclick1" yes      before control click in hyperlink c,v,event
"hypercclick2"          after  control click in hyperlink c,v,event
"hyperenter1"  yes      before entering hyperlink         c,v,event
"hyperenter2"           after  entering hyperlink         c,v,event
"hyperleave1"  yes      before leaving  hyperlink         c,v,event
"hyperleave2"           after  leaving  hyperlink         c,v,event
"iconclick1"   yes      before single click in icon box   c,v,event
"iconclick2"            after  single click in icon box   c,v,event
"iconrclick1"  yes      before right click in icon box    c,v,event
"iconrclick2"           after  right click in icon box    c,v,event
"icondclick1"  yes      before double click in icon box   c,v,event
"icondclick2"           after  double click in icon box   c,v,event
"idle"                  periodically (at idle time)       c,v
"menu1"        yes      before creating menus             c,v        (note 3)
"menu2"        yes      before updating menus             c,v
"open1"        yes      before opening any file           old_c,new_c,fileName (note 4)
"open2"                 after  opening any file           old_c,new_c,fileName (note 4)
"openwith1"    yes      before Open With command          c,v,openType,arg,ext
"openwith2"             after  Open With command          c,v,openType,arg,ext
"recentfiles1" yes      before Recent Files command       c,v,fileName,closeFlag
"recentfiles2"          after  Recent Files command       c,v,fileName,closeFlag
"save1"        yes      before any Save command           c,v,fileName
"save2"                 after  any Save command           c,v,fileName
"select1"      yes      before selecting a vnode          c,new_v,new_v
"select2"               after  selecting a vnode          c,new_v,old_v
"select3"               after  selecting a vnode          c,new_v,old_v
"set-mark"     no       when a mark is set                c,v           (new)
"start1"       no       after app.finishCreate()
"start2"                after opening first Leo window    c,v,fileName
"unselect1"    yes      before unselecting a vnode        c,new_v,old_v
"unselect2"             after  unselecting a vnode        c,old_v,old_v
"@url1"        yes      before double-click @url node     c,v           (note 5)
"@url2"                 after  double-click @url node     c,v           (note 5)

Notes:

(1) "activate" and "deactivate" hooks: These have been removed because they do
not work as expected.

(2) "commands" hooks: The label entry in the keywords dict contains the
"canonicalized" form of the command, that is, the lowercase name of the command
with all non-alphabetic characters removed.

Commands hooks now set the label for undo and redo commands "undo" and "redo"
rather than "cantundo" and "cantredo".

(3) "menu1" hook: Setting app().realMenuNameDict in this hook is an easy way of
translating menu names to other languages. Note: the "new" names created this
way affect only the actual spelling of the menu items, they do _not_ affect how
you specify shortcuts in leoConfig.txt, nor do they affect the "official"
command names passed in app().commandName. For example, suppose you set
app().realMenuNameDict["Open..."] = "Ouvre".

(4) "open1" and "open2" hooks: These are called with a keywords dict containing
the following entries:

old_c: The commander of the previously open window.
new_c: The commander of the newly opened window.
fileName: The name of the file being opened.

You can use old_c.currentVnode() and new_c.currentVnode() to get the current
vnode in the old and new windows.

Leo calls the "open1" and "open2" hooks only if the file is not already open. Leo
will also call the "open1" and "open2" hooks if: a) a file is opened using the
Recent Files menu and b) the file is not already open.

(5) "@url1" and "@url2" hooks are only executed if "icondclick1" hook returns None.


New in version 3.12:

The following hooks are a new breed of hook, called "stub hooks". Conceptually,
these hooks are like calls to stub routines that can be filled in by code in
plugins.

tag argument                                                       keys in keywords
(hook name)               overrides        when called           dictionary argument
---------                 ---------        -----------           -------------------
"after-redraw-outline"       no        end of tree.redraw        c (note 6)
"clear-mark"                 no        when mark is set          c,v
"close-frame"                no        in app.closeLeoWindow     c
"color-optional-markup"      yes *     (note 7)                  colorer,v (note 7)
"create-optional-menus"      no        (note 8)                  (note 8)
"destroy-all-global-windows" no        (note 12)                 None
"create-popup-menu-items"    no        in tree.OnPopup           c,v,event (new)
"enable-popup-menu-items"    no        in tree.OnPopup           c,v,event (new)
"init-color-markup"          no        (note 7)                  colorer,v,s,i,j,colortag (note 7)
"new"                        no        start of New command      old_c,new_c (note 9)
"redraw-entire-outline"      yes       start of tree.redraw      c (note 6)
"scan-directives"            no        in scanDirectives         c,v,s,old_dict,dict,pluginsList (note 10)
"set-mark"                   no        when mark is set          c,v
"show-popup-menu"            no        in tree.OnPopup           c,v,event

Notes:

(6) These hooks are useful for testing.

(7) These stub hooks allow plugins to parse and handle markup withing doc
parts, comments and Python """ strings. Note that these hooks are _not_ called
in Python ''' strings. See the color_markup plugin for a complete example of
how to use these hooks.

(8) The "create-optional-menus" stub hook is called when Leo is creating menus,
at the place at which creating new menus is appropriate. Therefore, this hook
need only create new menus in the correct order, without worrying about the
placement of the menus in the menu bar. See the plugins_menu and scripts_menu
plugins for examples of how to use this hook. Leo now executes hooks in
alphabetical order, so that the Plugins menu will be created before the Scripts
menu.

(9) The "new" stub hook is called at the beginning of the code that implements
the New command. This provides a much easier way of recognizing when Leo is
about to create a new Leo window.

(10) The "scan-directives" stub hooks is called inside the scanDirectives
global function. The dictionary returned by scanDirectives now contains an item
whose key is "pluginsList". The value of this item is a list of tuples
(d,v,s,k) where:

- d is the spelling of the @directive, without the leading @.
- v is the vnode containing the directive, _not_ the original vnode.
- s[k:] is a string containing whatever follows the @directive. k has already
been moved past any whitespace that follows the @directive.

See the add_directives plugins directive for a complete example of how to use
the "scan-directives" stub hook.

(11) The "close-frame" stub hook is called in app.closeLeoWindow just before
removing the window from app.windowList. The hook code may remove the window
from app.windowList to prevent app.closeLeoWindow from destroying the window.

(12) Leo calls the "destroy-all-global-windows" hook in app.destroyAllGlobalWindows().
This hook gives plugins the chance to clean up after themselves when Leo shuts down.</t>
<t tx="EKR.20040524104904.224">Naively using hooks can expose you and your .leo files to malicious attacks.  You will be safe as long as you follow these basic principles:

1. Hooks should _never_ blindly execute Python scripts in .leo files. Blindly executing scripts in .leo files runs the extreme risk of executing malicious code if you ever share any .leo file with someone else.  Moreover, using rexec instead of exec WILL NOT PROTECT YOU.  See the children of this node for further discussion of this important topic.

2. Hooks can execute any code safely _provided_ that all code is contained entirely within the plugin file. If you have a nifty customization that you want to do on a particular .leo file, put that code into a plugin.

3. Use only authentic copies of Leo that come from Leo's SourceForge site.</t>
<t tx="EKR.20040524104904.225">I'd like to thank Stephen Schaefer for gently insisting that we must guard against malicious code in shared .leo files.  Here is a little story Stephen told on Leo's SourceForge site that makes clear what the danger is:

"I foresee a future in which the majority of leo projects come from marginally trusted sources...I see a world of leo documents sent hither and yon - resumes, project proposals, textbooks, magazines, contracts - and as a race of Pandora's, we cannot resist wanting to see "What's in the box?" And are we going to fire up a text editor to make a detailed examination of the ASCII XML? Never! We're going to double click on the cute leo file icon, and leo will fire up in all its raging glory. Just like Word (and its macros) or Excel (and its macros)."

This succinctly illustrates the fundamental problem: when we share "our" .leo files we can _not_ assume that we know what is our "own" documents.  So hooks that naively searches through .leo files looking for scripts to execute is looking for big trouble.

The following node contains an example of the kind of code that is extremely dangerous.</t>
<t tx="EKR.20040524104904.226">@color
@ WARNING ***** Using the following routine exposes you to malicious code in .leo files! *****

Do not EVER use code that blindly executes code in .leo files!
Someone could send you malicious code embedded in the .leo file.

WARNING 1: Changing "@onloadpythonscript" to something else will NOT protect
           you if you EVER share either your files with anyone else.

WARNING 2: Replacing exec by rexec below provides NO additional protection!
           A malicious rexec script could trash your .leo file in subtle ways.
@c
if 0: # WRONG: This blindly execute scripts found in an .leo file! NEVER DO THIS!
	def onLoadFile():
		v = top().rootVnode()
		while v:
			h = v.headString().lower()
			if match_word(h,0,"@onloadpythonscript"):
				s = v.bodyString()
				if s and len(s) &gt; 0:
					try: # SECURITY BREACH: s may be malicious!
						exec(s + '\n',__builtins__,__builtins__)
					except:
						es_exception()
			v = v.threadNext()
</t>
<t tx="EKR.20040524104904.227">@color
@ It would be most foolish to expect rexec to protect you against malicious code contained in .leo files.  Remember that Leo is a repository of source code, so any text operation is potentially malicious.

For example, consider the following script.  This script is valid in rexec mode:
@c

c = top()
thisNode = c.currentVnode()
v = c.rootVnode()
while v:
	&lt;&lt; change all instances of rexec to exec in v's body &gt;&gt;
	v = v.threadNext()
&lt;&lt; delete thisNode &gt;&gt;
&lt;&lt; clear the undo stack &gt;&gt;

@ This script will introduce a security hole the .leo file without doing anything prohibited by rexec, and without leaving any traces of the perpetrating script behind.  The damage will become permanent _outside_ this script when the user saves the .leo file.
</t>
<t tx="EKR.20040524104904.228">pass</t>
<t tx="EKR.20040524104904.229">pass</t>
<t tx="EKR.20040524104904.230">pass</t>
<t tx="EKR.20040524104904.231">Hooks have full access to all of Leo's source code simply by importing it.

Moreover, several convenience methods have been added to make customizing menus and commands easier.  The following paragraphs discuss these routines and how to use them.

</t>
<t tx="EKR.20040524104904.232">The following routines enable and disable "idle" hooks.  They are defined in leoGlobals.py.

enableIdleTimeHook(idleTimeDelay=100)

Enables the "idle" hook. After this routine is called Leo will call the "idle" hook approximately every idleTimeDelay milliseconds.  Leo will continue to call the "idle" hook periodically until disableIdleTimeHook() is called.

disableIdleTimeHook()

Disables the "idle" hook.</t>
<t tx="EKR.20040524104904.233">The following convenience routines make creating menus easier.

These are methods of the leoFrame class.  Use top().frame to get the frame object for the presently active Leo window.

The plugins node in LeoPy.leo gives examples of how to use these routines to create custom menus and to add items to the Open With menu.

These convenience methods all do complete error checking and write messages to the log pane and to the console if errors are encountered.</t>
<t tx="EKR.20040524104904.234">@nocolor
createMenuItemsFromTable (self,menuName,table,openWith=0)

This method adds items to the menu whose name is menuName.  The table argument describes the entries to be created.  This table is a sequence of items of the form (name,shortcut,command).

- name is the command name
- shortcut is the shortcut, or None to indicate no shortcut.
- command is the routine to execute when the menu item is selected.

An entry of the form ("-",None,None) indicates a separator line between menu items.

For example:
@color
table =
	("Toggle Active Pane","Ctrl-T",self.OnToggleActivePane),
	("-",None,None),
	("Toggle Split Direction",None,self.OnToggleSplitDirection))

top().frame.createMenuItemsFromTable("Window",table)
@nocolor

If the openWith keyword argument is 1 the items are added to a submenu of the Open With menu.  However, it will be more convenient to use the createOpenWithMenuFromTable method to create the Open With menu.
</t>
<t tx="EKR.20040524104904.235">createNewMenu (self,menuName,parentName="top")

This method creates a new menu:

- menuName is the name of the menu to be created.
- parentName is the name of the parent menu, or "top" if the menu is to created in the menu bar.

This method returns the menu object that was created, or None if there was a problem.  Your code need not remember the value returned by this method.  Instead, your code will refer to menus by name.
</t>
<t tx="EKR.20040524104904.236">deleteMenu (self,menuName)

Deletes the menu whose name is given, including all entries in the menu.</t>
<t tx="EKR.20040524104904.237">deleteMenuItem (self,itemName,menuName="top")

Deletes the item whose name is itemName from the menu whose name is menuName.  To delete a menu in the menubar, specify menuName="top".</t>
<t tx="EKR.20040524104904.238">@nocolor
The leoFrame class creates the Window menu as follows:
@color

windowMenu = self.createNewMenu("&amp;Window")

table = (
	("&amp;Equal Sized Panes","Ctrl-E",self.OnEqualSizedPanes),
	("Toggle &amp;Active Pane","Ctrl-T",self.OnToggleActivePane),
	("Toggle &amp;Split Direction",None,self.OnToggleSplitDirection),
	("-",None,None),
	("Casca&amp;de",None,self.OnCascade),
	("&amp;Minimize All",None,self.OnMinimizeAll),
	("-",None,None),
	("Open &amp;Compare Window",None,self.OnOpenCompareWindow),
	("Open &amp;Python Window","Alt+P",self.OnOpenPythonWindow))

self.createMenuEntries(windowMenu,table)
</t>
<t tx="EKR.20040524104904.239">@nocolor

It is easy for hooks to translate menus into another language.  For example, code similar to the following code would typically be found in the "start2" hook:

@color

table = (
	("Open...","&amp;Ouvre"),
	("OpenWith","O&amp;uvre Avec..."),
	("close","&amp;Ferme"),
	("Undo Typing","French &amp;Undo Typing"), # Shows you how much French I know ;-)
	("Redo Typing","French &amp;Redo Typing"),
	("Can't Undo", "French Can't Undo"),
	("Can't Redo", "French Can't Redo"))
# Call the convenience routine to do the work.
app().setRealMenuNamesFromTable(table)</t>
<t tx="EKR.20040524104904.240">New in 4.1: The plugins test suite creates a new convention: if a plugin has a
function at the outer (module) level called unitTest, Leo will call that
function when doing unit testing for plugins. So it would be good if writers of
plugins would create such a unitTest funcion. The unitTest function should run
some tests. All unitTest needs to do to indicate failure is throw an exception
or cause an assert to fail. Leo's plugins test suite takes care of the rest.</t>
<t tx="EKR.20040524104904.241">New in Leo 4.0 and Python 2.3: Leo will draw a Leo icon in all Leo windows.  There is no need to install PIL or tkIcon.

Otherwise (for versions of Leo before 4.0 and for versions of Python before 2.3) Leo will draw a Leo icon in Leo windows only if you have installed Fredrik Lundh's PIL and tkIcon packages.

Download PIL from http://www.pythonware.com/downloads/index.htm#pil
Download tkIcon from http://www.effbot.org/downloads/#tkIcon

Many thanks to Jonathan M. Gilligan for suggesting this code.</t>
<t tx="EKR.20040524104904.242">New in 4.0: Leo can now read and write "foreign" attributes in &lt;v&gt; and &lt;t&gt; elements in .leo files:

- When reading a .leo file, Leo will create t.unknownAttributes or v.unknownAttributes ivars for any tnode and vnode object whose corresponding &lt;v&gt; or &lt;t&gt; element in the .leo file contains a foreign attribute.

- The unknownAttributes ivars are a dictionary whose keys are the attribute names and whose values are strings.

- When writing a file, Leo will write "foreign" attributes if  a vnode or tnode contains an unknownAttributes ivar.

- The only "native" attributes that Leo expects to find are the "tx" attribute in &lt;t&gt; elements and the "a", "t", "vtag" and "tnodeList" attributes of &lt;v&gt; elements.  Everything else is a foreign attribute.

New in 4.2: The "marks", "expanded" and "descendentTnodeUnknownAttributes" attributes are "native" attribute of &lt;v&gt; elements.

- Leo performs the usual xml escapes on these strings when reading or writing the unknownAttributes ivars.

Plugins may cause Leo to write such foreign attributes simply by attaching unknownAttributes ivars to a vnode or tnode.  For example:

	v.unknownAttributes = {"vnodeIcon" : pathToIcon}

It would be best not to delete other foreign attributes, so the following would be preferred:

	if hasattr(v,"unknownAttributes"):
		v.unknownAttributes["vnodeIcon"] = pathToIcon
	else:
		v.unknownAttributes = {"vnodeIcon" : pathToIcon}

Another way:

	try:
		v.unknownAttributes["vnodeIcon"] = pathToIcon
	except AttributeError:
		v.unknownAttributes = {"vnodeIcon" : pathToIcon}

See the section called "Recommended conventions for plugins" for advice about how to avoid potential conflicts in naming new attributes.

New in 4.2:

All members of these dictionaries should be "pickleable".  That is, Leo uses Python's Pickle module to encode all values in these dictionaries.  Leo will discard any attributes that can not be pickled.  This should not be a major problem to plugins.  For example, instead of putting a tnode into these dictionaries, a plugin could put the tnode's gnx (a string) in the dictionary.

Leo writes only t.unknownAttributes when writing @thin trees to the .leo file.  Leo puts (the encoding of) these elements into an attribute called descendentTnodeUnknownAttributes.  This attribute is part of the &lt;v&gt; element representing the @thin node.

The reason Leo does _not_ write v.unknownAttributes in @thin trees is that only tnodes have gnx's in thin derived files.  In effect, vnodes are anonymous.  We could attempt to get around this by identifying vnodes by their corresponding tnodes, but that's not a general solution and it is, in effect, equivalent to writing only t.unknownAttributes.  So it seems pointless to "pretend" to be writing v.unknownAttributes.

The effect of this is to make all vnodes identical, as far as using unknownAttributes is concerned.  This won't work in all cases.  For example, a plugin that creates an arbitrary directed graph between vnodes must distinguish between joined vnodes.  In that case, the plugin should confine itself to @file trees, or just vnodes in .leo files, for that matter.</t>
<t tx="EKR.20040524104904.243">Plugins may create (or add to) v.tempAttributes (for vnodes) or t.tempAttributes (for tnodes).  These will work just like the corresponding unknownAttributes dicts except that Leo will _not_ read or write these dictionaries when reading or writing files.  Note: nothing needs to change in Leo to support this convention.</t>
<t tx="EKR.20040524104904.244">@nocolor

We wish to avoid the possibility that two plugins might unwittingly choose the same name for attributes in the unknownAttributes or tempAttributes dictionaries.  The following convention eliminates that possibility.

Each plugin should create its own dictionary _inside_ any tempAttributes or unknownAttributes dictionaries that it intends to create or modify.  Something like this:

@color

# Create the tempAttributes dict for this vnode.
if not v.hasattr("tempAttributes"):
	v.tempAttributes = {}

# Create a subdictionary for the private use of my plugin.
d = v.tempAttributes.get("myPluginName")
if d is None:
	v.tempAttributes["myPluginName"] = d = {}

@nocolor

Now the plugin can set and get fields in d.  Similar code would be used for the t.tempAttributes, v.unknownAttributes and t.unknownAttributes dictionaries.</t>
<t tx="EKR.20040524104904.245">This chapter discusses the history of Leo and its various incarnations.  A large part of this chapter discusses the process by which I discovered how to implement @file trees.</t>
<t tx="EKR.20040524104904.246">Leo grew out of my efforts to use Donald Knuth's "CWEB system of Structured documentation."  I had known of literate programming since the mid 1980's, but I never understood how to make it work for me: I was confused about when to create new sections and it was difficult to keep track of all the sections once they were created.

In November 1995 I started thinking about literate programming in earnest.  Over the holidays I mused about making literate programs more understandable.  In January 1996 the fog of confusion suddenly cleared.  I summarized my thinking with the phrase, "Webs are outlines in disguise".  I strongly suspected that outline views were the key to literate programming, but many details remained obscure.  It still wasn't clear exactly how to represent webs in an outline.

March 5, 1996, is the most important date in Leo's history.   While returning from a day of skiing, I discussed my thoughts with Rebecca.  During that conversation I realized that I could use the MORE outliner as a prototype for a "literate outliner." I immediately started work on my first literate outline. It quickly became apparent that outlines work: all my old problems with literate programming vanished.   Furthermore, I realized that MORE's outlines could form the basis for Leo's screen design. Rather than opening body text within the outline, as MORE does, I decided to use a separate body pane.

In about a week I hacked a translator called M2C which allowed me to use MORE to write real code.  I would write code in MORE, copy the text to the clipboard in MORE format, then run M2C, which would tangle the outline into C code.  This process was useful, if clumsy.  I called the language used in the outline SWEB, for simplified CWEB.  Much later I converted to the noweb language. noweb is simpler than SWEB, more standard and more general.</t>
<t tx="EKR.20040524104904.247">Throughout 1996 I created a version of Leo on the Macintosh in plain C and the native Mac Toolbox.   This was a poor choice; I wasted a huge amount of time programming with these primitive tools.  However, this effort convinced me that Leo was a great way to program.

Late in 1997 I wrote a Print command to typeset an outline. Printing (Weaving) is supposedly a key feature of literate programming.  Imagine my surprise when I realized that such a "beautiful" program listing was almost unintelligible; all the structure inherent in the outline was lost!  I saw clearly that typesetting, no matter how well done, is no substitute for explicit structure.

Starting in May of 1998 I began work on a version of Leo using objective C and Apple's Yellow Box environment.  In some ways, this was the most powerful version of Leo.  Alas, a year later Apple chose not to support Yellow Box on Windows, so I had to begin again.  I was most unhappy.

In May of 1999 I began work on the Borland version of Leo for Windows.  The Borland Delphi classes were a pleasure to use and free of bugs.  I redesigned Leo's file format for the Windows version of Leo;  the Yellow Box file format is a binary format that requires the Yellow Box runtime.  Fortunately, I choose to use XML for Leo's file format. I have Marc-Antoine Parent to thank for this decision; he urged me to use XML and patiently explained how to use XML properly.  However, there are two significant problems with the Borland version of Leo.  First, it works only on Windows.  Second, it can never be Open software, because it uses Borland's Delphi classes and a commercial syntax coloring component.

In May of 2000 I began work an wxWindows version of Leo.  This was supposed to be a cross-platform version.  Alas, after much work I chose to abandon the wxWindows version.  There were too many bugs and too many incompatibilities between platforms.  Something good did come from this effort.  I spent a lot of time adding Python scripting to the wxWindows code and I became familiar with Python and its internals.

In October of 2001 I began work on the leo.py, an Open Software version of leo.py, a version of Leo written in Python and Tk.  At last I have found the proper platform for Leo.  leo.py naturally supports scripting in Python.  The combination of Python and Tk is incredibly powerful, very easy to use, and truly cross platform.  I rewrote Leo in Python in about two months!  For the first time in my career I no longer am anxious while programming; it simply isn't possible to create bad bugs in Python.</t>
<t tx="EKR.20040524104904.248">The following sections give a pseudo-chronological list of the major Aha's involved in creating Leo2. These Aha's form the real design and theory of operation of Leo. See the "Diary", "Notes" and "Letters to Speed Ream" sections in LeoDocs.leo for a more accurate and less tidy history of Leo2.

I am writing these notes for several reasons.  First, the initial design and coding of Leo2, spanning a period of about 8 weeks, was some of the most creative and rewarding work I have ever done. The result is elegant and simple.  I'm proud of it.  Second, much of the design work is not reflected in the code, because improved design often eliminated code entirely. The final code is so elegant that it obscures the hard work that created it.  Third, you must understand this design in order to understand the implementation of @file trees and their derived files.  Someday someone else may take charge of Leo. That person should know what really makes Leo2 work.</t>
<t tx="EKR.20040524104904.249">In the summer of 2001 I began work on a project that for a long time I had considered impossible.  I had long considered that "private" file formats such as .leo files were the only way to represent an outline properly and safely.  I'm not sure exactly what changed my mind, but I finally was willing to consider that information embedded in derived files might be useful.  This meant accepting the possibility that sentinel lines might be corrupted.  This was a crucial first step.  If we can trust the user not to corrupt sentinel lines than we can embed almost any kind of information into a derived file.

There were several motivations for this work.  I wanted to eliminate the need for explicit Tangle and Untangle commands. I thought of this as "Untangle on Read/Tangle on Write."  If tangling and untangling could be made automatic it would save the user a lot of work.  I also wanted to make derived files the primary sources files.  .leo files might be made much smaller derived files contained the primary source information. This hope turned out to be false.

The result of this design work was something I originally called Leo2, though I now usually prefer to talk about @file trees.  Initially most design issues were unresolved or unknown. I resolved to attempt a robust error-recovery scheme, not knowing in advance what that might involve. I also wanted to solve what I thought of as the "cross-file clone" problem: clones that point from a .leo outline into a derived file. With Leo1 cross-file clones do not exist; everything is in the same .leo file. It was clear that Leo2 would have to change some aspects of clones, but all details were fuzzy.
</t>
<t tx="EKR.20040524104904.250">The next step was also crucial.  I started to use Leo1 as a prototype to design what the new body pane would look like to the user. In retrospect, using Leo1 as a prototype for Leo2 was just as inspired as using MORE as a prototype for Leo1.  Both prototypes marked the true beginning of their respective projects.  The Leo2 prototype was a mockup in Python of the code for reading and writing derived files. The file LeoDocs.leo contain these first prototype nodes.

Writing the prototype got me thinking about improving noweb.  With my experience with Leo1, I was able to create a new markup language that took advantage of outline structure.  I called the new language  "simplified noweb", though that terminology is obsolete.  I created @file nodes to distinguish between the old and new ways of creating derived files.  In Leo1, the @code directive is simply an abbreviation for a section definition line.  Simplified noweb used @c as an abbreviation for @code.  More importantly, simplified noweb used @c to separate doc parts from code parts without necessarily specifying a section name.  It quickly became apparent that most nodes could be unnamed.  All I needed was the @others directive to specify the location for all such unnamed nodes.

From the start, simplified noweb was a joy to use. Indeed, the @others directive could replace all section definition lines.  Furthermore, I could make @doc directive optional if the body pane started in "code mode".  But this meant that plain body text could become a "literate" program! This was an amazing discovery.  These Aha's got me excited about Leo2. This was important, as it motivated me to do a lot of difficult design work.</t>
<t tx="EKR.20040524104904.251">In spite of this excitement, I was uneasy. After much "daydreaming" I realized that I was afraid that reading and writing derived files would be interrupted by a long series of alerts. I saw that designing the "user interaction" during reading and writing would be very important. The next Aha was that I could replace a long series of alerts with messages to the log window, followed by a single "summary" alert. Much later I saw how to eliminate alerts entirely.

At this time I thought there would be two kinds of "errors" while reading derived files. Warnings would alert the user that something non-serious had happened. True errors would alert the user that data might have been lost. Indeed, if Leo2 saves orphan and ignored nodes in a .leo file under an @file node, then read errors could endanger such nodes. Much later I saw that a robust error recovery scheme demands that @file nodes not contain orphan and @ignored nodes. (More on this subject later.) But if orphan and @ignored nodes are moved out of @file trees, there are no read errors that can cause data loss! So the distinction between warnings and errors finally went away.</t>
<t tx="EKR.20040524104904.252">I next turned my attention to writing @file nodes.  A huge Aha: I realized that sentinel lines must contain both a leading and a trailing newline.  The general principle is this: the write code must contain absolutely no "conditional" logic, because otherwise the read code could not figure out whether the condition should be true or false.  So derived files contain blank lines between sentinel lines. These "extra" newlines are very useful, because the read (untangle) code can now easily determine exactly where every blank, tab and newline of the derived file came from.  It would be hard to overstate how important this simplifying principle was in practice.

Much later, with urging from a customer, I realized that the write code could safely remove "extra" newlines between sentinels with a caching scheme in the low level atFile::os() routine. This scheme does not alter the body of the write code in any way: in effect, sentinels still contain leading and trailing "logical" newlines. The read code had to be modified to handle "missing" leading newlines, but this can always be done assuming that sentinels still contain logical leading and trailing newlines!

At about this time I designed a clever way of having the write code tell the read code which newlines were inserted in doc parts. (The whole point of doc parts is to have the write code format long comments by splitting long lines.) To quote from my diary:

"We can use the following convention to determine where putDocPart has inserted line breaks: A line in a doc part is followed by an inserted newline if and only if the newline is preceded by whitespace. This is a really elegant convention, and is essentially invisible to the user.
Tangle outputs words until the line would become too long, and then it inserts a newline. To preserve all whitespace, tangle always includes the whitespace that terminates a word on the same line as the word itself. Therefore, split lines always end in whitespace. To make this convention work, tangle only has to delete the trailing whitespace of all lines that are followed by a 'real' newline."

</t>
<t tx="EKR.20040524104904.253">After the write code was working I turned my attention to the read (untangle) code.  Leo's Untangle command  is the most complex and difficult code I have ever written. Imagine my surprise when I realized that the Leo2 read code is essentially trivial! Indeed, the Leo2 untangle code is like an assembler. The read code scans lines of a derived files looking for "opcodes", that is, sentinel lines, and executes some simple code for each separate opcode. The heart of this code is the scanText routine in atFile.cpp.

The read code was written and debugged in less than two days! It is the most elegant code I have ever written. While perfecting the read code I realized that sentinel lines should show the complete nesting structure found in the outline, even if this information seems redundant. For example, I was tempted to use a single sentinel to represent an @other directive, but finally abandoned this plan in favor of the @+other and @-other sentinels.

This redundancy greatly simplified the read code and made the structure of derived files absolutely clear. Moreover, it turned out that we need, in general, all the information created by the present sentinel lines. In short, sentinels are as simple as they can be, and no simpler.

The atFile::createNthChild method is a very important: it ensures that nodes will be correctly inserted into the outline. createNthChild must be bullet-proof if the Read code is to be robust. Note that the write code outputs @node sentinels, that is, section definitions, in the order in which sections are referenced in the outline, not the order in which sections appear in the outline. So createNthChild must insert the n'th node of parent p properly even if p contains fewer than n-1 children! The write code ensures that section references are properly nested: @node sentinels are enclosed in @node sentinels for all their ancestors in the @file tree. createNthChild creates dummy siblings as needed, then replaces the dummy siblings later when their actual definitions, that is, @node sentinels, are encountered.

At this point the fundamental read/write code was complete. I found three minor bugs in the code over the next week or so, but it was clear that the read/write code formed a rock-solid base from which to continue design and implementation. This was an entirely unexpected surprise.</t>
<t tx="EKR.20040524104904.254">At this point I could read and write derived files "by hand", using temporary Read and Write commands. The next step was to integrate the reading and writing of derived files with the loading and saving of .leo files.  From time to time I made minor changes to the drivers for the read/write code to accommodate the Load and Save code, but at no time did I significantly alter the read or write code itself.

The user interaction of the Load and Save commands drove the design and implementation of the load/store code. The most important questions were: "what do we tell the user?", and "what does the user do with the information?" It turns out that the user can't make any complex decision during error recovery because the user doesn't have nearly enough information to make an informed choice. In turn, this means that certain kinds of error recovery schemes are out of the question...</t>
<t tx="EKR.20040524104904.255">I now turned my attention to "attributes" of nodes.  Most attributes, like user marks, are non-essential. However, clone information is essential; we must never lose clone links. At this time I had a preliminary design for cross-file clones that involved a two part "pointer" consisting of a full path name and an immutable clone index within the derived file. Eventually such pointers completely disappeared, but the immutable clone indices remain.

My first thought was that it would be good to store all attributes in @node sentinels in the derived file, but experience showed that would be irritating. Indeed, one wants Leo2 to rewrite derived files only if something essential has changed. For example, one doesn't want to rewrite the derived file just because a different node as been selected.

At this point I had another Aha: we can use the .leo file to store all non-essential attributes. For example, this means that the .leo file, not the derived files, will change if we select a new node. In effect, the .leo file mirrors the derived file. The only reason to store nodes in the .leo file under an @file node is to carry these attributes, so Leo2 wrote dummy nodes that do not reference body text.  Much later I saw that dummy nodes were dangerous and that .leo files should contain all information found in derived files.</t>
<t tx="EKR.20040524104904.256">The concept of mirroring created a huge breakthrough with cross-file clones: Here is an excerpt of an email i sent to my brother Speed:

"I realized this morning that since a .leo file contains dummy vnodes for all nodes in a derived file, those dummy nodes can carry clone info! I changed one line to make sure that the write code always writes clone info in dummy vnodes and voila! Cross-file clones worked!"

All of Leo1's clone code could be used completely unchanged. Everything "just works".</t>
<t tx="EKR.20040524104904.257">At first I thought we could make sure that the .leo file always correctly mirrors all derived file, but disastrous experience showed that is a completely false hope. Indeed, backup .leo files will almost never mirror derived file correctly. So it became urgent to find a completely fool-proof error recovery scheme.

I had known for quite a while that error recovery should work "as if" the mirroring nodes were deleted, then recreated afresh. Several failed attempts at an error recovery scheme convinced me that error recovery would actually have to delete all dummy nodes and then do a complete reread. This is what Leo2 does.

But erasing dummy nodes would destroy any orphan and ignored nodes--by definition such nodes appear nowhere in the derived file. Therefore, I had to enforce the rule that @file nodes should contain no such nodes. Here is an email I wrote to my brother, Speed Ream discussing what turned out to be the penultimate error recovery scheme:

"The error recovery saga continues. After much pondering and some trial coding I have changed my mind about orphans and @ignored nodes. They simply should never appear as descendants of @file nodes. Fortunately, this simplifies all aspects of Leo2.
Leo2 will issue a warning (not an error) if an orphan or @ignored node appears as the descendant of an @file node when a .leo file is being saved. If any warnings occur while writing the derived file, Leo2 will write the "offending" @file tree to the .leo file instead of the derived file. This has several advantages:

1.	The user gets warned about orphan nodes. These are useful warnings! Orphan nodes arise from missing @others directives or missing section references.

2. The user doesn't have to change anything immediately in order to save an outline. This is very important. Besides warnings about orphans, Leo2 will also warn about undefined or unreferenced sections. User's shouldn't have to fix these warnings to do a Save!

3. No errors or alerts will occur during Reading or Writing, so the user's anxiety level goes way down. At worst, some informational message will be sent to the log. The user will never have to make important decisions during Loads or Saves. [At last the dubious distinction between errors and warnings disappears.]

4. Error recovery can be bullet-proof. Simple code will guarantee that after any read operation the structure of an @file node will match the structure of the derived file. Also, sentinels in derived files will now account for all children of an @file node. There are no more "missing nodes" that must be filled in using the .leo file. Finally, error recovery will never change the @file tree in any way: no more "recovered nodes" nodes.

5. The present read code can be used almost unchanged. The only addition is the posting of a warning if the structure of the .leo file does not match the structure of the derived file. We need a warning because non-essential attribute of nodes (like user marks) may be altered."

This ends the original history of Leo2. In fact, it took quite a while before Leo recovered properly from all errors. I finally saw that .leo files should duplicate all information in derived files. This allows a .leo file to be used a single backup file and allows maximal error recovery in all situations.  It took several months to stamp out several subtle bugs involving clones that caused spurious read errors. Such errors undermine confidence in Leo and can cause disastrous reversions. See my diary entries for January 2002 in leo.py for details.

</t>
<t tx="EKR.20040524104904.258">@nocolor

These papers discuss topics related to Leo.</t>
<t tx="EKR.20040524104904.259">The more I look at Tk, the more convinced I am that Python + Tk (aka tkinter) is, by far, the best way to go with Leo.py.  I now have Open Source code for tree widgets and splitter windows, and have intensely studied how to modify that code for use in Leo.  It is clear, even at this early date, that this code will provide a very pleasant base on which to build Leo.

The tree code is based on code in IDLE, the Python IDE.  This code is simple, good and plenty fast enough. The tree code draws directly to a Tk canvas object.  The look and feel matches Windows exactly.  It would be trivial to use Mac triangle icons instead of the Windows plus and minus icons.  It would also be trivial to modify the look and feel for Linux.

The tree widget code solves several intractable problems with wxTreeCtrl.  Moving nodes becomes trivial.  Bugs in wxTreeCtrl involving editing and redrawing disappear.  Using Python/Tk code simplifies the vnode class, and having access to the vnode class simplifies and speeds up the tree widget code.  There is no SWIG overhead in calling the wxTreeCtrl code.  It will now be possible to bind keystrokes properly; this simply can not be done in wxWindows.

Actually, the tree widget code shows just how trivial the Windows native tree control is.  Of course, the Tk canvas class simplifies matters, but there are several important points here:

1. The wxTreeCtrl tree class actually does very little, and does it rather badly.
2. There is absolutely no need for C++ code (except in the Tk canvas class) to draw trees.
3. Leo can _easily_ have _complete_ control over the look and feel of tree controls.
4. I can modify in the tree code to simplify the rest of Leo, especially Leo's vnode class.

Here we have a splendid example of higher-level code being superior, in _every_ way, to lower level code.  The wxTreeCtrl code is horrendously complex, and in fact does almost nothing!

Similar remarks apply to the splitter window.  The Tk code for splitter windows is about a page long.  No code could be higher level because the Tk code describes only _what_ is to be done, not _how_ it is too be done.

Another big win comes from using the Tk text widget.  This widget is extraordinarily powerful.  The only text control that rivals it is the MacOS/Yellow Box text control.  Indeed, the Tk text widget does everything that Leo could possibly want.  One can even embed images in text!

Syntax coloring Tk text will be straightforward in Python. IDLE's syntax coloring is very fast on modern workstations.  There will be no need to use or modify the Scintilla C++ code.

In short, using Tk for Leo.py will be fast enough and will greatly increase what is possible in Leo while at the same time greatly simplifying Leo's code.  I am about to convert Leo.py from wxPython to Python + Tk.

Edward K. Ream
November 4, 2001</t>
<t tx="EKR.20040524104904.260">I've known for a while that Python was interesting; I attended a Python conference last year and added Python support to Leo.  But last week I got that Python is something truly remarkable.  I wanted to convert Leo from wxWindows to wxPython, so I began work on c2py, a Python script that would help convert from C++ syntax to Python.  While doing so, I had an Aha experience.  Python is more than an incremental improvement over Smalltalk or C++ or objective-C; it is "something completely different".  The rest of this post tries to explain this difference.

Clarity: no clutter, easy prototyping
-------------------------------------

What struck me first as I converted C++ code to Python is how much less blah, blah, blah there is in Python.  No braces, no stupid semicolons and most importantly, _no declarations_.  No more pointless distinctions between const char *, char const *, char * and wxString. No more wondering whether a variable should be signed, unsigned, short or long.

Declarations add clutter, declarations are never obviously right and declarations don't prevent memory allocation tragedies.  Declarations also hinder prototyping.  In C++, if I change the type of something I much change all related declarations; this can be a huge and dangerous task.  With Python, I can change the type of an object without changing the code at all!  It's no accident that Leo's new log pane was created first in Python.

Functions returning tuples are a "minor" feature with a huge impact on code clarity.  No more passing pointers to data, no more defining (and allocating and deallocating) temporary structs to hold multiple values.

Python can't check declarations because there aren't any.  However, there is a really nifty tool called Pychecker that does many of the checks typically done by compilers.  See http://pychecker.sourceforge.net/ for details.

Power
-----

Python is much more powerful than C++, not because Python has more features, but because Python needs _less_ features.  Some examples:

1. Python does everything that the C++ Standard Template Library (STL) does, without any of the blah, blah, blah needed by STL.  No fuss, no muss, no code bloat.

2. Python's slicing mechanism is very powerful and applies to any sequence (string, list or tuple).  Python's string library does more with far less functions because slices replace many functions typically found in other string libraries.

3. Writing dict = {} creates a dictionary (hash table).  Hash tables can contain anything, including lists and other hash tables.

4. Python's special functions, like __init__, __del__, __repr__, __cmp__, etc. create an elegant way to handle any special need that might arise.

Safety
------

Before using Python I never fully realized how difficult and dangerous memory allocation is in C++.  Try doing

        aList[i:j] = list(aString)

in C.  You will write at least 10 - 20 lines of code.  Any error in this code will create a memory allocation crash or leak.

Python is fundamentally safe.  C++ is fundamentally unsafe.  When I am using Python I am free from worry and anxiety.  When I am using C++ I must be constantly "on guard."  A momentary lapse can create a hard-to-find pointer bug.  With Python, almost nothing serious can ever go wrong, so I can work late at night, or after a few beers.

And the Python debugger is always available.  If an unexpected exception occurs, the debugger/interpreter tells me just what went wrong.  I don't have to plan a debugging strategy!  Finally, wxPython recovers from exceptions, so Leo can keep right on going even after a crash!

Code Speed
----------

Python has almost all the speed of C.  Other interpretive environments such as icon and smalltalk have clarity, power and safety similar to Python.  What makes Python unique is its seamless way of making C code look like Python code.

Much of Python executes at essentially the speed of C code because most Python modules are written in C.  The overhead in calling such modules is negligible.  Moreover, if code is too slow, one can always create a C module to do the job.

In fact, Python encourages optimization by moving to _higher_ levels of expression.  For example, Leo's Open command reads an XML file.  If this command is too slow I can use Python's XML parser module.  This will speed up Leo while at the same time raising the level of the code.

Conclusions
-----------

Little of Python is completely new.  What stands out is the superb engineering judgment evident in Python's design.  Python is extremely powerful, yet small, simple and elegant.  Python allows me to express my intentions clearly and at the highest possible level.

The only hope of making Leo all it can be is to use the best possible tools.  I believe Python (possibly with tkinter) will allow me to add, at long last, the new features that Leo should have.

Edward K. Ream
October 25, 2001</t>
<t tx="EKR.20040524104904.261">This chapter discusses how Leo's code works, paying particular attention to topics that have caused difficulties in design or implementation.  This information will be of use primarily to those wanting to change Leo's code.  The previous chapter contains a full discussion of how Leo reads and writes @file trees.</t>
<t tx="EKR.20040524104904.262">This documentation describes leo.py. Other versions of Leo are similar in design; the differences between versions are generally not interesting enough to describe here.

All versions of Leo are organized as a collection of classes.  The general organization of Leo has remained remarkably stable throughout all versions of Leo, although the names of classes are different in different versions. Smalltalk's Model/View/Controller terminology is a good way to organize Leo's classes conceptually.

Model classes represent the fundamental data. The vnode and tnode classes are Leo's primary model classes.

View classes draw the screen. The main view classes are leoFrame.py and leoTree.py.  The colorizer class in leoColor.py handles syntax coloring in the body pane. In leo.py, the view classes know about data stored in the vnode class. Most events (keystrokes and mouse actions) in the outline and body pane are handled in the leoTree class. The leoFrame class also creates the Leo window, including menus, and dispatches the appropriate members of the controller classes in response to menu commands.

Controller classes (aka commanders) control the application. In Leo, controllers mostly handle menu commands. In leo.py, the Commands class creates subcommanders to handle complex commands. The atFile class reads and writes files derived from @file trees. The LeoFind class handles the Find and Change commands. The leoImportCommands class handles the Import and Export commands, the tangleCommands class handles the Tangle and Untangle commands and the undoer class handles the Undo command. Other classes could be considered controller classes.

Each Leo window has its own commander and subcommanders. Subcommanders are not subclasses of their commander. Instead, subcommanders know the commander that created them, and call that commander as needed. Commanders and subcommanders call the model and view classes as needed. For example, the Commands class handles outline commands. To move a headline, the commander for the window calls a vnode move routine to alter the data, then calls the view class to redraw the screen based on the new data.

A singleton instance of the LeoApp class represents the application itself. All code uses the app() global function to gain access to this singleton member. The ivars of the LeoApp object are the equivalent of Leo's global variables. leo.py uses no global Python variables, except the gApp variable returned by app(). leoGlobals.py defines all application constants.  Naturally, most constants are local to the class that uses them.

Several classes combine aspects of model, view and controller. For example, the LeoPrefs class represents user preferences (model), the Preference Panel (view) and the Preferences menu command (controller). Similarly, the LeoFind class represents find settings, the Find/Change dialog, and the Find/Change commands.

We use the following convention throughout this documentation. Any variable named c is a commander, i.e., an instance of the Commands class in leoCommands.py. Variables named v and t are vnodes and tnodes respectively. These classes are defined in leoNode.py.
</t>
<t tx="EKR.20040524104904.263">The vnode and tnode classes represent most of the data contained in the outline. These classes are Leo's fundamental Model classes.

A vnode (visual node) represents a headline at a particular location on the screen. When a headline is cloned, vnodes must be copied. vnodes persist even if they are not drawn on the screen. Commanders call vnode routines to insert, delete and move headlines.

The vnode contains data associated with a headline, except the body text data which is contained in tnodes. A vnode contains headline text, a link to its tnode and other information. In leo.py, vnodes contain structure links: parent, firstChild, next and back ivars. To insert, delete, move or clone a vnode the vnode class just alters those links. The Commands class calls the leoTree class to redraw the outline pane whenever it changes. The leoTree class knows about these structure links; in effect, the leoTree and vnode classes work together. The implementation of vnodes is quite different in the Borland version of Leo. This does not affect the rest of the Leo. Indeed, vnodes are designed to shield Leo from such implementation details.

A tnode, (text node) represents body text: a tnode is shared by all vnodes that are clones of each other. In other words, tnodes are the unit of sharing of body text. The tnode class is more private than the vnode class. Most commanders deal only with vnodes, though there are exceptions.

Because leo.py has unlimited Undo commands, vnodes and tnodes can be deleted only when the window containing them is closed. Nodes are deleted indirectly. Several classes, including the vnode, tnode, leoFrame and leoTree classes, have destroy() routines. These destroy() routines merely clear links so that Python's and Tkinter's reference counting mechanisms will eventually delete vnodes, tnodes and other data when a window closes.

Leo uses several kinds of node indices. Leo's XML file format uses tnode indices to indicate which tnodes (t elements) belong to which vnodes (v elements). Such indices are required. Even if we duplicated the body text of shared tnodes within the file, the file format would still need an unambiguous way to denote that tnodes are shared.

Present versions of Leo recompute these tnodes indices whenever Leo writes any .leo file. Earlier versions of Leo remembered tnode indices and rewrote the same indices whenever possible. Those versions of Leo recomputed indices when executing the Save As and Save To commands, so using these commands was a way of "compacting" indices. The main reason for not wanting to change tnode indices in .leo files was to reduce the number of changes reported by CVS and other Source Code Control Systems. I finally abandoned this goal in the interest of simplifying the code. Also, CVS will likely report many differences between two versions of the same .leo file, regardless of whether tnode indices are conserved.

A second kind of node index is the clone index used in @+node sentinels in files derived from @file trees. As with indices in .leo files, indices in derived files are required so that Leo can know unambiguously which nodes are cloned to each other.

It is imperative that clone indices be computed correctly, that is, that tnode @+node sentinels have the same index if and only if the corresponding vnodes are cloned. Early versions of leo.py had several bugs involving these clone indices. Such bugs are extremely serious because they corrupt the derived file and cause read errors when Leo reads the @file tree. Leo must guarantee that clone indices are always recomputed properly. This is not as simple as it might appear at first. In particular, Leo's commands must ensure that @file trees are marked dirty whenever any changed is made that affects cloned nodes within the tree. For example, a change made outside any @file tree may make several @file trees dirty if the change is made to a node with clones in those @file trees.</t>
<t tx="EKR.20040524104904.264">@nocolor

Leo must redraw the outline pane when commands are executed and as the result of mouse and keyboard events.  The main challenges are eliminating flicker and handling events properly.  These topics are interrelated.

Eliminating flicker.  Leo must update the outline pane with minimum flicker.  Various versions of Leo have approached this problem in different ways.  The drawing code in leo.py is robust, flexible, relatively simple and should work in almost any conceivable environment.

Leo assumes that all code that changes the outline pane will be enclosed in matching calls to the c.beginUpdate and c.endUpdate  methods of the Commands class. c.beginUpdate() inhibits drawing until the matching c.endUpdate().  These calls may be nested; only the outermost call to c.endUpdate() calls c.redraw() to force a redraw of the outline pane.

In leo.py, code may call c.endUpdate(flag) instead of c.endUpdate().  Leo redraws the screen only if flag is true.  This allows code to suppress redrawing entirely when needed.  For example, here is how the idle_body_key event handler in leoTree.py conditionally redraws the outline pane:

@language python
@color
	redraw_flag = false
  	c.beginUpdate()
	val = v.computeIcon()
	if val != v.iconVal:
		v.iconVal = val
		redraw_flag = true
	c.endUpdate(redraw_flag) # redraw only if necessary
@nocolor

The leoTree class redraws all icons automatically when c.redraw() is called.  This is a major simplification compared to previous versions of Leo.  The entire machinery of drawing icons in the vnode class has been eliminated.  The v.computeIcon method tells what the icon should be.  The v.iconVal ivar that tells what the present icon is. The event handler simply compares these two values and sets redraw_flag if they don't match.

Handling events. Besides redrawing the screen, Leo must handle events or commands that change the text in the outline or body panes.  It is surprisingly difficult to ensure that headline and body text corresponds to the vnode and tnode corresponding to presently selected outline, and vice versa. For example, when the user selects a new headline in the outline pane, we must ensure that 1) the vnode and tnode of the previously selected node have up-to-date information and 2) the body pane is loaded from the correct data in the corresponding tnode.  Early versions of Leo attempted to satisfy these conditions when the user switched outline nodes.  Such attempts never worked well; there were too many special cases.  Later versions of Leo, including leo.py, use a much more direct approach.  The event handlers make sure that the vnode and tnode corresponding to the presently selected node are always kept up-to-date.  In particular, every keystroke in the body pane causes the presently selected tnode to be updated immediately.  There is no longer any need for the c.synchVnode method, though that method still exists for compatibility with old scripts.

The leoTree class contains all the event handlers for the body and outline panes.  The actual work is done in the idle_head_key and idle_body_key methods.  These routines are surprisingly complex; they must handle all the tasks mentioned above, as well as others. The idle_head_key and idle_body_key methods should not be called outside the leoTree class.  However, it often happens that code that handles user commands must simulate an event.  That is, the code needs to indicate that headline or body text has changed so that the screen may be redrawn properly.   The leoTree class defines the following simplified event handlers: onBodyChanged, onBodyWillChange, onBodyKey, onHeadChanged and onHeadlineKey.  Commanders and subcommanders call these event handlers to indicate that a command has changed, or will change, the headline or body text.  Calling event handlers rather than c.beginUpdate and c.endUpdate ensures that the outline pane is redrawn only when needed.</t>
<t tx="EKR.20040524104904.265">The following is a definition of clones from the user's point of view.

Definition 1

A clone node is a copy of a node that changes when the original changes. Changes to the children, grandchildren, etc. of a node are simultaneously made to the corresponding nodes contained in all cloned nodes. Clones are marked by a small clone arrow by its leader character. 

As we shall see, this definition glosses over a number of complications. Note that all cloned nodes (including the original node) are equivalent. There is no such thing as a "master" node from which all clones are derived. When the penultimate cloned node is deleted, the remaining node becomes an ordinary node again. 

Internally, the clone arrow is represented by a clone bit in the status field of the vnode. The Clone Node command sets the clone bits of the original and cloned vnodes when it creates the clone. Setting and clearing clone bits properly when nodes are inserted, deleted or moved, is non-trivial. We need the following machinery to do the job properly. 

Two vnodes are joined if a) they share the same tnode (body text) and b) changes to any subtree of either joined vnodes are made to the corresponding nodes in all joined nodes.  For example, Definition 1 defines clones as joined nodes that are marked with a clone arrow.  Leo links all vnodes joined to each other in a circular list, called the join list. For any vnode n, let J(n) denote the join list of n, that is, the set of all vnodes joined to n. Again, maintaining the join lists in an outline is non-trivial. 

The concept of structurally similar nodes provides an effective way of determining when two joined nodes should also have their cloned bit set.  Two joined nodes are structurally similar if a) their parents are distinct but joined and b) they are both the nth child of their (distinct) parents.  We can define cloned nodes using the concept of structurally similar nodes as follows:

Definition 2

Clones are joined vnodes such that at least two of the vnodes of J(n) are not structurally similar to each other. Non-cloned vnodes are vnodes such that all of the vnodes of J(n) are structurally similar. In particular, n is a non-cloned vnode if J(n) is empty.

Leo ensures that definitions 1 and 2 are consistent. Definition 1 says that changes to the children, grandchildren, etc. of a node are simultaneously made to the corresponding nodes contained in all cloned nodes. Making "corresponding changes" to the non-cloned descendants of all cloned nodes insures that the non-cloned joined nodes will be structurally similar. On the other hand, cloned nodes are never structurally similar. They are created as siblings, so they have the same parent with different "child indices."  To see how this works in practice, let's look at some examples.

Example 1

+ root
	+ a' (1)
	+ a' (2)

This example shows the simplest possible clone. A prime (') indicates a cloned node.  Node a in position (1) has just been cloned to produce a' in position (2). Clearly, these two cloned nodes are not structurally similar because their parents are not distinct and they occupy different positions relative to their common parent.

Example 2

If we add a node b to either a' node we get the following tree:

+ root
	+ a'
		+ b
	+ a'
		+ b

The b nodes are structurally similar because the a' nodes are joined and each b node is the first child of its parent.

Example 3

If we now clone either b, we will get:

+ root
	+ a'
		+ b' (1)
		+ b' (2)
	+ a'
		+ b' (1)
		+ b' (2)

All b' nodes must be clones because the nodes marked (1) are not structurally similar to the nodes marked (2).

Dependent nodes are nodes created or destroyed when corresponding linked nodes are created or destroyed in another tree. For example, going from example 1 to example 2 above, adding node b to either node a' causes another (dependent) node to be created as the ancestor of the other node a'. Similarly, going from example 2 to example 1, deleting node b from either node a' causes the other (dependent) node b to be deleted from the other node a'.  Cloned nodes may also be dependent nodes. In Example 3, all the b' nodes are dependent on any of the other b' nodes.

We can now give simple rules for inserting and deleting dependent vnodes when other vnodes are created, moved or destroyed. For the purposes of this discussion, moving a node is handled exactly like deleting the node then inserting the node; we need not consider moving nodes further.  We insert a new node n as the nth child of a parent node p as follows. We insert n, then for every node pi linked to p, we insert a dependent node ni as the nth child of pi. Each ni is linked to n. Clearly, each ni is structurally similar to n.  Similarly, it is easy to delete a node n that is the nth child of a parent node p. We delete each dependent node ni that is the nth child of any node pi linked to p. We then delete n.  When inserting or deleting any vnode n we must update its join list, J(n). Updating the join list is easy because the join list is circular: the entire list is accessible from any of its members.

Inserting or deleting nodes can cause the clone bits of all joined nodes to change in non-trivial ways. To see the problems that can arise, consider deleting any of the b' nodes from Example 3. We would be left with the tree in Example 2. There are two remaining b nodes, each with the clone bit set. Unless we know that both b nodes are structurally similar, there would be no way to conclude that we should clear the clone bits in each node. In order to update clone links properly we could examine many special cases, but there is an easier way. Because of definition 2, we can define a shouldBeCloned function that checks J(n) to see whether all nodes of J(n) are structurally similar.

Leo's XML file format does not contain join lists. This makes it easy to change a Leo file "by hand." If join lists were a part of the file, as they are in the Mac version of Leo, corrupting a join list would corrupt the entire file. It is easy to recreate the join lists when reading a file using a dedicated field in the tnode.  This field is the head of a list of all vnodes that points to the tnode. After reading all nodes, Leo creates this list with one pass through the vnodes.  Leo then convert each list to a circular list with one additional pass through the tnodes.
</t>
<t tx="EKR.20040524104904.266">The find and change commands are tricky; there are many details that must be handled properly. This documentation describes the leo.py code. Previous versions of Leo used an inferior scheme.  The following principles govern the LeoFind class:

1.	Find and Change commands initialize themselves using only the state of the present Leo window. In particular, the Find class must not save internal state information from one invocation to the next. This means that when the user changes the nodes, or selects new text in headline or body text, those changes will affect the next invocation of any Find or Change command. Failure to follow this principle caused all kinds of problems in the Borland and Macintosh codes. There is one exception to this rule: we must remember where interactive wrapped searches start. This principle simplifies the code because most ivars do not persist. However, each command must ensure that the Leo window is left in a state suitable for restarting the incremental (interactive) Find and Change commands. Details of initialization are discussed below.

2. The Find and Change commands must not change the state of the outline or body pane during execution. That would cause severe flashing and slow down the commands a great deal. In particular, c.selectVnode and c.editVnode methods must not be called while looking for matches.

3. When incremental Find or Change commands succeed they must leave the Leo window in the proper state to execute another incremental command. We restore the Leo window as it was on entry whenever an incremental search fails and after any Find All and Change All command.
Initialization involves setting the self.c, self.v, self.in_headline, self.wrapping and self.s_text ivars. Setting self.in_headline is tricky; we must be sure to retain the state of the outline pane until initialization is complete. Initializing the Find All and Change All commands is much easier because such initialization does not depend on the state of the Leo window.

Using Tk.Text widgets for both headlines and body text results in a huge simplification of the code. Indeed, the searching code does not know whether it is searching headline or body text. The search code knows only that self.s_text is a Tk.Text widget that contains the text to be searched or changed and the insert and sel Tk attributes of self.search_text indicate the range of text to be searched. Searching headline and body text simultaneously is complicated. The selectNextVnode() method handles the many details involved by setting self.s_text and its insert and sel attributes.
</t>
<t tx="EKR.20040524104904.267">This section describes Leo's explicit Tangle and Untangle commands.  Such commands operate only on @root and @unit trees.  The previous chapter discusses the implicit Tangle on Write/Untangle on Read processes used to read and write @file trees.

The Tangle command translates the selected @root tree into one or more well-formatted C source files. The outline should contain directives, sections references and section definitions, as described in Chapter 4. The Untangle command is essentially the reverse of the Tangle command. The Tangle command creates a derived file from an @root tree; the Untangle command incorporates changes made to derived files back into the @root tree.

The Tangle command operates in two passes. The first pass discovers the complete definitions of all sections and places these definitions in a symbol table. The first pass also makes a list of root sections. Definitions can appear in any order, so we must scan the entire input file to know whether any particular definition has been completed.

Tangle's second pass creates one file for each @root node. Tangle rescans each section in the list of roots, copying the root text to the output and replacing each section reference by the section's definition. This is a recursive process because any definition may contain other references. We can not allow a section to be defined in terms of itself, either directly or indirectly. We check for such illegally recursive definitions in pass 2 using the section stack class.  Tangle indicates where sections begin and end using comment lines called sentinel lines.  The this part of the appendix discusses the format of the sentinels output by the Tangle command.

The key design principle of the Tangle command is this: Tangle must output newlines in a context-free manner. That is, Tangle must never output conditional newlines, either directly or indirectly. Without this rule Untangle could not determine whether to skip or copy newlines.

The Tangle command increases the indentation level of a section expansion the minimum necessary to align the section expansion with the surrounding code. In essence, this scheme aligns all section expansions with the line of code in which the reference to the section occurs. In some cases, several nested sections expansions will have the same indentation level. This can occur, for example, when a section reference in an outline occurs at the left margin of the outline.

This scheme is probably better than more obvious schemes that indent more "consistently." Such schemes would produce too much indentation for deeply nested outlines. The present scheme is clear enough and avoids indentation wherever possible, yet indents sections adequately. End sentinel lines make this scheme work by making clear where the expansion of one section ends and the expansion of a containing section resumes.

Tangle increases indentation if the section reference does not start a line. Untangle is aware of this hack and adjusts accordingly. This extra indentation handles several common code idioms, which otherwise would create under-indented code. In short, Tangle produces highly readable, given the necessity of preserving newlines for Untangle.

Untangle is inherently complex.  It must do a perfect job of updating the outline, especially whitespace, from expansions of section definitions created by the Tangle command.  Such expansions need not be identical because they may have been generated at different levels of indentation.  The Untangle command can not assume that all expansions of a section will be identical in the derived file; within the derived file, the programmer may have made incompatible changes to two different expansions of the same section. Untangle must check to see that all expansions of a section are "equivalent".  As an added complication, derived files do not contain all the information found in @root trees.  @root trees may contain headlines that generate no code at all.  Also, an outline may define a section in several ways: with an @c or @code directive or with a section definition line.  To be useful, Untangle must handle all these complications flawlessly. The this part of the appendix discusses the various conventions used in the sentinels output by the Tangle command.  These conventions allow the Untangle command to recreate whitespace correctly.

Untangle operates in two passes. The first pass finds definitions in the derived file and enters them into the Untangle Symbol Table, or UST.   Definitions often include references to other sections, so definitions often include nested definitions of referenced sections. The first pass of Untangle uses a definition stack to keep track of nested definitions. The top of the stack represents the definition following the latest reference, except for the very first entry pushed on the stack, which represents the code in the outline that contains the @root directive. The stack never becomes empty because of the entry for the @root section. All definitions of a section should match--otherwise there is an inconsistent definition. This pass uses a forgiving compare routine that ignores differences that do not affect the meaning of a program.

Untangle's second pass enters definitions from the outline into the Tangle Symbol Table, or TST. The second pass simultaneously updates all sections in the outline whose definition in the TST does not match the definition in the UST.  The central coding insight of the Untangle command is that the second pass of Untangle is almost identical to the first pass of Tangle! That is, Tangle and Untangle share key parts of code, namely the skip_body() method and its allies.  Just when skip_body() enters a definition into the symbol table, all the information is present that Untangle needs to update that definition.

</t>
<t tx="EKR.20040524104904.268">The following paragraphs discuss code-level details.  You should not need to read this section in order to use Leo.

1. Leo uses unicode objects in vnodes and tnodes to denote headline and body text.  Note that unicode strings have no encoding; only plain strings have encodings. This means that once an (encoded) plain string has been converted to a unicode string it doesn't matter how the unicode string was created.  This is the key that makes Leo's new code robust. 

So internally Leo never has to worry about encodings. The only times encoding matter is when encoded strings are converted to and from unicode when Leo reads or writes files (or when the passing strings to and from Tk.Text widgets, but the idea is the same).

2. Python expressions that mix unicode strings u and plain strings s, like:

	u + s 
or 
	u == s 
or 
	u[5] == s[2:]

are promoted to unicode objects using the "system encoding". This encoding should never be changed, but we can't assume that we know what it is, so for safety we should assume the most restrictive encoding, namely "ascii".  With this assumption, Leo's code can't throw an exception during these promotions provided that: 

- All strings are converted to unicode when Leo reads files or gets text from Tk.Text widgets. 
- All string literals in Leo's code have only ascii characters.</t>
<t tx="EKR.20040524104904.269">Only leo.py supports unlimited undo.  Unlimited undo is straightforward; it merely requires that all commands that affect the outline or body text must be undoable. In other words, everything that affects the outline or body text must be remembered.

We may think of all the actions that may be Undone or Redone as a string of beads (undo nodes). Undoing an operation moves backwards to the next bead; redoing an operation moves forwards to the next bead. A bead pointer points to the present bead. The bead pointer points in front of the first bead when Undo is disabled.  The bead pointer points at the last bead when Redo is disabled. An undo node is a Python dictionary containing all information needed to undo or redo the operation.

The Undo command uses the present bead to undo the action, then moves the bead pointer backwards. The Redo command uses the bead after the present bead to redo the action, then moves the bead pointer forwards. All undoable operations call setUndoParams() to create a new bead. The list of beads does not branch; all undoable operations (except the Undo and Redo commands themselves) delete any beads following the newly created bead.

I did not invent this model of unlimited undo.  I first came across it in the documentation for Apple's Yellow Box classes.</t>
<t tx="EKR.20040524104904.273">The Synchronization Principle simplifies everything and at long last puts Leo on a firm theoretical foundation.  This principle states that the "smallest unit of meaning" of any Leo outline is the entire outline itself.  In particular, individual derived files have meaning only in the context of a particular outline.

The Synchronization Principle has the following happy consequences:

1. We may assume that all derived files are in synch with the outline that wrote them.  This assumption allows Leo to use "hidden machinery" in the outline to associate nodes in the derived file with nodes in the outline.  This "hidden" machinery consists of a list of tnodes associated with @file vnodes in the outline.  When writing a derived file Leo creates a list of tnodes in the order they were written to the derived file.  When reading the derived file, Leo uses this list to associate nodes in the derived file with nodes in the outline.

2. Derived files must get their structure from the .leo file that wrote them.  As we have seen, this is done using the hidden machinery in the .leo file.  Consequently, there is no further need to represent outline structure in derived files.  There is no need any longer either for child indices or for sentinels to represent outline structure.  As a result, we can eliminate @+body and @-body nodes entirely because all @+node sentinels are followed by body text.

3. All .leo files must contain full outline structure.  Even "thin" outline will contain the full representation of the outline as vnodes.

4. Reading _never_ alters outline structure in the outline.  No vnodes are ever created or destroyed and reading never alters clone links.  This is true whether or not read errors occur.  The read code sets a temporary attribute of tnodes while reading.  These attributes are copied to the permanent t.bodyString attribute only if no read errors were encountered.

4. Error recovery is now trivial:  Read errors indicate that the .leo files and one or more derived files are out-of-synch.  No error recovery is attempted: the @file tree in which the error occurred reverts back to its original state.

5. The new Import Derived File command is the _only_ way to recover data from mismatched derived file.</t>
<t tx="EKR.20040524104904.274">@nocolor
@ignore</t>
<t tx="EKR.20040524104904.275">leo.py 3.1 contains Python code that may be of interest to some Python programmers.  All Python files are derived from LeoPy.leo.

See the children of this node for details.</t>
<t tx="EKR.20040524104904.276">This script does much of the grunt work of converting from C/C++ syntax to Python syntax.  It was surprisingly effective in converting Leo from C++ to Python.  These scripts don't need to be perfect to save a _lot_ of work.  And of course you can always add your own improvements...

As written, the script converts an entire Leo tree.  It would be easy to write an entry that would convert plain text files, but it's probably best to import the files to be converted into Leo first.  That way the slow algorithms in c2py.py will work on smaller pieces of text.</t>
<t tx="EKR.20040524104904.277">This code gathers and prints static statistics about Python bytecode.</t>
<t tx="EKR.20040524104904.278">The file leoUtils.py contains some small Tkinter utilities:

w,h,x,y = get_window_info(top) returns the width, height, x and y positions of the Tkinter window top.

center_dialog(top) centers the Tkinter window top on the screen.

w,f = create_labeled_frame(parent...) creates a labeled Tkinter window as a child of parent.  The caller packs widgets into f to create the frame.

leoUtils.py contains many other routines including an Python version of the Sherlock tracing package.</t>
<t tx="EKR.20040524104904.279">leoFontPanel.py puts up a Font dialog.  This dialog dispenses with the typical "sample" pane and instead changes text immediately directly on the screen.  Comes with Ok, Cancel and Revert buttons.  IMO, this dialog is much better than the sample Tk/Tkinter font dialogs available on the web.</t>
<t tx="EKR.20040524104904.280">leoColor.py contains code to syntax color Tk.Text widgets for a variety of languages.  Supporting a new language here is mostly a matter of adding another table of keywords.</t>
<t tx="EKR.20040524104904.281">Leo supports powerful outlining features, including clones.  Clones are challenging to implement, to say the least.  The vnode and tnode classes, defined in leoNodes.py, represent the underlying data.  vnodes represent nodes on the screen.  vnodes may share text, the tnode class is the "unit of sharing" of such text.  The leoTree class draws the tree and handles events, including dragging nodes around the screen.  The Commands class calls the vnode, tnode and leoTree classes to handle menu commands.  In Smalltalk's model/view/controller terminology, the vnode and tnode classes are model class, the leoTree class is a view class, and the Commands class is a controller class.</t>
<t tx="EKR.20040524104904.282">To convert an @root tree to an @file tree, choose the root of the tree to be converted, then do the following in the Python window:

	import c2py
	c2py.leo1to2()
	
This script makes numerous changes throughout the tree.  It does not, however, change @root to @file, or insert the needed @others directives.  You must do that by hand.

To convert @root trees to @file trees by hand:

1.  Change the @root node to an @file node.  That is, delete the @root &lt;filename&gt; directive from the body text and insert @file &lt;filename&gt; in the headline.  Typically, the root node contains a reference like &lt;&lt;methods of class x&gt;&gt; as the last body text.  Replace this reference with the @others directive.  The expansion of @others is all text that is not part of a section definition.

2.  Add @&lt;space&gt; to the start of all doc parts.  Leo2 starts syntax coloring in code mode rather than doc mode, so if a doc part starts body text it should start with @&lt;space&gt; or @doc.

3.  Replace all section definition lines (like &lt;&lt;name&gt;&gt;=) by @c (or @code).  This results in the node being added to the expansion of @others.

4.  Remove all unused code from the @file tree.  Leo2 does not write derived files whose @file trees contain orphan or @ignored nodes.  If an @file tree does contain an orphan or @ignored node, Leo2 issues a warning and writes the entire @file tree to the .leo file instead of the derived file.  This prohibition of orphan an @ignored nodes is necessary to make error recovery completely safe and reliable.

5.  Make sure that all nodes defining a section have a headline that starts with &lt;&lt;section&gt;&gt;.  This will typically be true when converting @root trees that use the @code directive.

6. If a section is referenced in more than one node (a rare occurrence in my code), clone the defining node and move one clone under each referencing node.

7. If a node contains the definitions of several sections, place each different definition in a different node.</t>
<t tx="EKR.20040524104904.283">@ignore</t>
<t tx="EKR.20040524104904.284">In @root and @unit trees, the @code directive indicates the start of a code section. The headline must contain a valid section name.

In @file trees, the @c directive indicates the start of a code section.

</t>
<t tx="EKR.20040524104904.285">This directive affects only the Weave (Print) command (and possibly the Create CWEB command).  It indicates the start of a chapter.  This puts the chapter title at the top of each page.</t>
<t tx="EKR.20040524104904.286">Indicates that syntax coloring is enabled for the body text in which it appears and all descendant nodes ( unless over-ridden in the descendant nodes ).</t>
<t tx="EKR.20040524104904.287">This directive indicates the delimiters to be used by the Tangle command.</t>
<t tx="EKR.20040524104904.288">@nocolor

The @delims directive changes the comment strings used to mark sentinel lines. This directive is often used to place Javascript text inside XML or HTML files.  This directive is valid only in @file trees.  You can use the @comment directive in @unit or @root trees.

The @delims directive contains one or two delimiters, separated by whitespace. If only one delim is present it delimits single-line comments. If two delims are present they delimit block comments. The @delims directive can not be used to change the comment strings at the start of the derived file, that is, the comment strings for the @+leo sentinel and the initial @+body and @+node sentinels. The @delims directive inserts @@delims sentinels into the derived file. The new delimiter strings continue in effect until the next @@delims sentinel in the derived file or the end of the derived file.

Note: Leo can not revert to previous delimiters automatically; you must change back to previous delimiters using another @delims directive. For example:

@color

@delims /* */
Javascript stuff
@delims &lt;-- --&gt;
HTML stuff

@nocolor
Adding, deleting or changing @@delims sentinels will destroy Leo's ability to read the derived file. Mistakes using the @delims directive have no effect on Leo, though such mistakes will thoroughly mess up a derived file as far as compilers, HTML renderers, etc. are concerned.</t>
<t tx="EKR.20040524104904.289">In @root and @unit trees, the @doc directive indicates the start of a comment enclosed in the beginning and ending block comment delimiters ( see @comment ).

In @file trees, the @(space) (@ followed by a space, tab or newline) indicates the start of an doc part.  @(space) is optional: it is not needed if the body text contains no doc part.

</t>
<t tx="EKR.20040524104904.290">You may use the @encoding directive to specify the encoding used in a derived file.  You can't mix encodings in a single derived file.  For example,

@encoding iso-8859-1

If the encoding used in a derived file is not "utf-8" it is represented in the @+leo sentinel line, like this:

#@+leo-encoding=iso-8859-1.

The "utf-8" encoding is used by default.  The "utf-8" encoding is a "lossless" encoding (it can represent all unicode code points), so encoding and decoding to and from utf-8 plain strings will never cause a problem.  When reading or writing a character not in a "lossy" encoding (such as iso-8859-1), Leo converts such characters to '?' and issues a warning. </t>
<t tx="EKR.20040524104904.291">Strictly speaking, @file is not a directive; it is not valid in body text.

A headline that starts with @file &lt;filename&gt; forms the root of an @file tree.  Leo writes all nodes in the tree to the derived file &lt;filename&gt; when any Save command is executed.  The @file tree is recreated from the derived file when the .leo file is opened.

The Leo2 documentation discusses how to write code in @file trees.
</t>
<t tx="EKR.20040524104904.292">The @first directive allows you to place lines at the very start of files derived from @file nodes. For example, the body text of @file spam.py might be:

	@first #! /usr/bin/env python

The body text of @file foo.perl might be:

	@first #/usr/bin/perl

@first directives are recognized only at the start of the body text of @file nodes. No text may precede @first directives. More than one @first directive may exist, like this:

	@first #! /usr/bin/env python
	@first # more comments.</t>
<t tx="EKR.20040524104904.293">This directive causes the Tangle and Untangle commands to ignore this node and all its descendants.</t>
<t tx="EKR.20040524104904.294">The @language directive specifies the comment delimiters and string types used by the Tangle and Untangle.

The form of this directive is

@language x

where x is one of the following: c,c++,html,java,objective-c,pascal,perl,python and shell.  Shell files have comments that start with #.  Case is ignored in the language specifiers, but not in the @language itself.  Thus, the following are equivalent:

@language html
@language HTML
@language hTmL

but the following is invalid:

@LANGUAGE html

The @comment directive is now officially deprecated: you should use the @language directive whenever possible.  At present Untangle will not process an @root or @unit node if an @comment directive is in effect.  Why?  Because Untangle can't be sure of properly parsing a derived file if the language of the derived file isn't known.  It might be possible to assume some defaults in this case, but that is not done at present and is not a high priority.</t>
<t tx="EKR.20040524104904.295">Indicates that syntax coloring is disabled for the body text in which it appears and all descendant nodes ( unless over-ridden in the descendant nodes ).</t>
<t tx="EKR.20040524104904.296">The @others directive is valid only in @file trees.  The @others directive causes the expansion of all unnamed nodes to be output to the derived file in the position of the @others directive.

For example, a common Python idiom is:

class myClass:
	&lt;&lt; constants of myClass &gt;&gt;
	@others
	
The @others directive inserts the expansion of all unnamed sections into the class definition, indented just as the @others directive is indented.

An @file tree may have more than one @others directive.  Each @others directive collects only those nodes found in the descendants of the node containing the @others directive.

A single node may contain at most one @others directive.  To use more than one @others directive in an @file tree, use the following pattern:

class x:
	&lt;&lt;members of x&gt;&gt;
class y:
	&lt;&lt;members of y&gt;&gt;
	
The named nodes &lt;&lt;members of x&gt;&gt; and &lt;&lt;members of y&gt;&gt; contain only an @others directive.  Define members of the x and y classes as descendants of the nodes containing @Others.

</t>
<t tx="EKR.20040524104904.297">The @pagewidth directives affects how Tangle outputs block comments:  it specifies the width of output pages in columns.  The form of the @pagewidth directive is @pagewidth n, where n is a positive integer.
</t>
<t tx="EKR.20040524104904.298">The @path directive specifies the directory to be used if an @file or @root directive does not specify a full path name. The form of the @path directive is @path filename, where filename is taken to be everything following @path to the end of the line.

If the filename in @file pathname or @root pathname is an absolute filename the location of the derived file is specified only by the filename.  Otherwise, if the filename is 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.</t>
<t tx="EKR.20040524104904.299">This directive starts the text that forms a single derived file, after all section references have been replaced by their definitions.

By default, only descendants of the @root node are examined for section definitions.  However, if the @root directive is a descendant of a node containing the @unit directive, all descendants of the @unit node are examined for section definitions.</t>
<t tx="EKR.20040524104904.300">This directive affects only the Weave (Print) command (and possibly the Create CWEB command).  It indicates the start of a section.  This puts the section title at the top of each page.</t>
<t tx="EKR.20040524104904.301">The @silent causes Tangle to output no comments for doc chunks and no sentinel lines for Untangle. Comments written by the user in code sections are always output.

</t>
<t tx="EKR.20040524104904.302">The @tabwidth directives affects how Tangle outputs leading whitespace:  it specifies the width of tabs in spaces.  The form of the @tabwidth directive is @tabwidth n, where n is a positive integer.
</t>
<t tx="EKR.20040524104904.303">The @terse directive causes Tangle not to output comments for doc chunks.  Tangle will output only those sentinel comments needed by Untangle.  As always, comments written by the user in code sections are output.

These directives are not valid in @file trees.</t>
<t tx="EKR.20040524104904.304">Expands the nodes searched for section definitions when processing an @root directive.

By default, only descendants of the @root node are examined for section definitions.  However, if the @root directive is a descendant of a node containing the @unit directive, all descendants of the @unit node are examined for section definitions.</t>
<t tx="EKR.20040524104904.305">The @verbose directive causes Tangle to output comments for doc chunks and sentinel comments needed by Untangle.  This is the default behavior if none of the @verbose, @terse or @silent directives are in effect.
</t>
<t tx="EKR.20040524104904.306"></t>
<t tx="EKR.20040524104904.307">The following error messages may be generated by the Tangle commands.  Such errors appear in the log window, which will be opened if necessary.	
</t>
<t tx="EKR.20040524104904.308">A file error occurred while trying to reopen the temporary file used during tangling.</t>
<t tx="EKR.20040524104904.309">A file error occurred while trying to change the name of the temporary file used during tangling.</t>
<t tx="EKR.20040524104904.310">An @code directive appeared in body text whose header does not contain a section name.</t>
<t tx="EKR.20040524104904.311">An @directive was seen somewhere other than the start of a line.</t>
<t tx="EKR.20040524104904.312">Tangle detected more than 20 errors.</t>
<t tx="EKR.20040524104904.313">A section was defined in terms of itself, either directly or indirectly.  The trace shows the chain of section definitions that resulted in the illegal definition.

This message is followed by a walkback of the section names that recursively reference the section.  The walkback looks like this:

called from &lt;&lt; section name &gt;&gt;
called from &lt;&lt; section name &gt;&gt;
...
</t>
<t tx="EKR.20040524104904.314">Sections can be defined in several parts in two ways:

1.  Using &lt;&lt; section name &gt;&gt;= in several places with the same section name.

2.  Using several @code directives within the _same_ body text.

As a precaution against mistakenly defining a section in more than one place, it is invalid to use @code in different nodes to define multiple parts for the same section.  In particular, this error may arise when using cloned nodes.

This error may always be eliminated by using &lt;&lt; section name &gt;&gt;= instead of @code.
	
</t>
<t tx="EKR.20040524104904.315">Tangle did not write a file because errors were found.</t>
<t tx="EKR.20040524104904.316">A C-language comment was not properly terminated.</t>
<t tx="EKR.20040524104904.317">The file name in an @root directive was not terminated with the proper delimiter.</t>
<t tx="EKR.20040524104904.318">A section name was not properly terminated before the end of the line in which it started.
</t>
<t tx="EKR.20040524104904.319">A C-language string or character constant was not properly terminated.</t>
<t tx="EKR.20040524104904.320">Something that looks like a section definition was seen in the middle of a line.</t>
<t tx="EKR.20040524104904.321">A section was defined using more than 100 levels of section definitions (!)

You could easily create an outline containing every computer program ever written in less than 50 levels.</t>
<t tx="EKR.20040524104904.322">The selected outline contained no @root directive.</t>
<t tx="EKR.20040524104904.323">A reference to an undefined section was encountered.</t>
<t tx="EKR.20040524104904.324">Tangle outputs 2-character WEB control code in a comment.  This message is given if we find such comments in a code definition.</t>
<t tx="EKR.20040524104904.325">(The text of the duplicate definition follows.)

The section may have been defined in more than one place.</t>
<t tx="EKR.20040524104904.326">The indicated section appears in the outline but is never referenced.</t>
<t tx="EKR.20040524104904.327">The following error messages may be generated by the Untangle commands.  Such errors appear in the log window, which will be opened if necessary.	
</t>
<t tx="EKR.20040524104904.328">Two expansions of &lt;&lt; section name &gt;&gt; were different in the derived file.  This typically arises when the programmer changes one of the expansions but not the other.</t>
<t tx="EKR.20040524104904.329">No end sentinel line was found for a part of the expansion of the code in the @root node.  This is likely the result of adding, deleting or altering a sentinel line.</t>
<t tx="EKR.20040524104904.330">No end sentinel line was found for the expansion of the code in the @root node.  This is likely the result of adding, deleting or altering a sentinel line.</t>
<t tx="EKR.20040524104904.331">The end sentinel name for &lt;&lt; section name &gt;&gt; was expected but not found.  This is likely the result of adding, deleting or altering a sentinel line.</t>
<t tx="EKR.20040524104904.332">The end of the file was reached before encountering the end sentinel line for
	&lt;&lt; section name &gt;&gt;.
This is likely the result of adding, deleting or altering a sentinel line.</t>
<t tx="EKR.20040524104904.333"></t>
<t tx="EKR.20040524104904.334">The following are all minor errors, meaning that no data is likely to have been lost.  You can proceed as usual.

1. Rereading file.  Clone links into this file will be lost

The .leo file is out of synch with the derived file, so non-essential information usually stored in the .leo file will be deleted.  Clone links may be severed.

2. Missing file name.  Restoring @file tree from .leo file

No file name follows @file

3. Error reading file.  Restoring @file tree from .leo file

The file name following @file could not be found

4. File name in @node sentinel does not match file's name

The name of the derived file may have been changed.

5. Ignoring text after @-leo

Some text follows the trailing @-leo sentinel line.  Make sure this text is not important.</t>
<t tx="EKR.20040524104904.335">The following are all serious errors, meaning that the data in a derived file has been corrupted.  You should restore the information from a backup .leo file using the Read Outline Only commands, followed by a Write @file Nodes command.

 1. Bad @+leo sentinel in &lt;filename&gt;
 2. Bad @delims"
 3. Bad attribute field in @+node
 4. Bad child index in @+node
 5. File may have damaged sentinels!
 6. Ignoring &lt;sentinel kind&gt; sentinel.  Expecting &lt;sentinel kind&gt;
 7. Ignoring unexpected @+leo sentinel
 8. Missing &lt;sentinel kind&gt; sentinel
 9. Missing @file in root @node sentinel
10. Outline corrupted: different nodes have same clone index!
11. Replacing body text of orphan &lt;node name&gt;
12. Unexpected end of file. Expecting &lt;sentinel kind&gt; sentinel
13. Unknown sentinel: &lt;sentinel line&gt;
</t>
<t tx="EKR.20040524104904.336">Errors while writing @file nodes are harmless.  No information is lost because all information is written to the .leo file rather than the derived file.

1. Bad @delims directive

2. Can not open &lt;file name&gt;

3. @ignore node: &lt;headline&gt;

The body text of &lt;headline&gt; contains an @ignore directive.

4. Missing file name: &lt;file name&gt;

@file is not followed by a file name.

5. Orphan node: &lt;headline&gt;

The node is referenced by no ancestor node, and no @others directive applies to it.

6. @others already expanded in: &lt;headline&gt;

The node contains more than one @others directive.

7.  Rename failed: no file created! (file may be read-only)

Leo's Save commands write derived files to a temporary file, and rename that file to be the derived file only if the old derived file is different from the temporary file.  This message means that a problem with the file system prevented the temporary file from being renamed.

8. Path does not exist: &lt;file name&gt;

The path may be specified by the Preferences panel, an @path directive or by a path in the @file node.

9.  undefined section: &lt;section name&gt; referenced from: &lt;headline&gt;
			
The node given by &lt;headline&gt; contains a reference to &lt;&lt;section name&gt;&gt;, 
but no named node for &lt;&lt;section name&gt;&gt; exists in the descendents of &lt;headline&gt;	</t>
<t tx="EKR.20040524104904.337">New for leo.py v2.0 and Borland Leo 2.6:

Leo suppresses blank lines between sentinels by default.  This is an upward compatible change in the format of derived files: leo.py v2.0 can read derived files from all previous versions of Leo, but previous versions of Leo can not read derived files without blanks lines.

To cause leo.py not to remove blank lines do the following.  In the section called &lt;&lt; initialize atFile ivars &gt;&gt; in leoAtFile.py, change:

	self.suppress_newlines = true
to
	self.suppress_newlines = false

Note: leo.py v2.0 can read derived files without blank lines between sentinels regardless of the setting of self.suppress_newlines.
</t>
<t tx="EKR.20040524104904.338">The following sections describe the comment lines embedded in derived files.  It is not necessary to understand this in detail.  All you need to know is this:

1. Sentinel lines are comment lines whose first character (following the comment delimiter) is @.
2. Do not alter sentinel lines in derived files.  Doing so will corrupt the outline structure!
3. Do not alter blank lines in front of, behind or between sentinels.  Doing so will corrupt the outline structure in older versions of Leo.</t>
<t tx="EKR.20040524104904.339">The @delims directive changes the comment strings used to mark sentinel lines.  The @delims directive contains one or two delimiters, separated by whitespace.  If only one delim is present it delimits single-line comments.  If two delims are present they delimit block comments. The @delim directive can _not_ be used to change the comment strings at the start of the derived file, that is, the comment strings for the @+leo sentinel and the initial @+body and @+node sentinels.

NB: Leo can not revert to previous delimiters automatically; you must change back to previous delimiters using another @delims directive.  For example:

@delims /* */
Javascript stuff
@delims &lt;-- --&gt;
HTML stuff
</t>
<t tx="EKR.20040524104904.340">A file produced by an @file node begins with an @+leo sentinel.  The last lines of the file should be the matching @-leo sentinel

The comment delimiters that delimit all sentinels are specified by the first line of the file, that is, the @+leo sentinel.  This sentinel has the form:

&lt;opening_delim&gt;@leo&lt;closing_delim&gt;

&lt;closing_delim&gt; may be empty, in which case single-line comments are used.  The Write code generates single-line comments if possible.  Presently, the Write logic generates single line comments for all languages except HTML.  (Block comments can be specified using the @comment directive.)</t>
<t tx="EKR.20040524104904.341">Suppose the parent node of a node N is P and that P has n children.  The sentinel 

  @+node:&lt;child_index&gt;:&lt;status_fields&gt;:&lt;headline&gt;

begins the expansion of node N.  The expansion continues until a matching

  @-node::&lt;child_index&gt;:&lt;status_fields&gt;:&lt;headline&gt;
  
sentinel.

The &lt;child_index&gt; field is a number from 1 to n indicating the index of the node in the list of its parent's children.

The &lt;status_field&gt; field the cloneIndex field of the form: "C=nnn", where nnn is an immutable clone index.

The &lt;headline&gt; field contains headline text, not reference text.

The indentation of the expansion is increased by the extra indentation of preceding the reference.  tree level never affects indentation level.</t>
<t tx="EKR.20040524104904.342">If a node contains significant I(non-whitespace) body text, @+body and @-body sentinels surround the text.  These sentinels are nested within @node directives.
</t>
<t tx="EKR.20040524104904.343">@+doc and @-doc delimit doc parts within a node that start with @doc. These sentinels are nested within @body directives.  Similarly, @+at and @-at delimit doc parts within a node that start with @&lt;whitespace&gt;.

We use the following convention to determine where putDocPart has inserted line breaks: A line in a doc part is followed by an inserted newline if and only if the newline if  preceded by whitespace.  To make this convention work, the Write deletes the trailing whitespace of all lines that are followed by a "real" newline.</t>
<t tx="EKR.20040524104904.344">@+others indicates the start of the expansion of an @+others directive, which continues until the matching @-others. @others sentinels are nested within @body sentinels; the expansion of the @others directive always occurs within the body text of some node N.
</t>
<t tx="EKR.20040524104904.345">The @delims directive inserts @@delims sentinels into the derived file. The new delimiter strings continue in effect until the next @@delims sentinel _in the derived file_ or the end of the derived file.

Adding, deleting or changing @@delim _sentinels_ will destroy Leo's ability to read the derived file.  Mistakes in using the @delims _directives_ have no effect on Leo, though such mistakes will thoroughly mess up a derived file as far as compilers, HTML renderers, etc. are concerned.</t>
<t tx="EKR.20040524104904.346">The @@&lt;text&gt; sentinel represents any line starting with @ in body text except @&lt;whitespace&gt;, @doc and @others. Examples:

  @@nocolor
  @@pagewidth 80
  @@tabwidth 4
  @@code</t>
<t tx="EKR.20040524104904.347">@verbatim indicates that the next line of the derived file is not a sentinel.  This escape convention allows body text to contain lines that would otherwise be considered sentinel lines.

New for leo.py version 2.0 and Borland Leo version 2.6:

@verbatimAfterRef is generated when a comment following a section reference would otherwise be treated as a sentinel.   In Python code, an example would be:

  &lt;&lt; ref &gt;&gt; #+others

This sentinel is required only when blank lines are suppressed between sentinel lines.</t>
<t tx="EKR.20040524104904.348">@&lt;&lt;section_name&gt;&gt; represents section reference.  If the reference does not end the line, the sentinel line ending the expansion is followed by the remainder of the reference line.  This allows the Read code to recreate the reference line exactly.</t>
<t tx="EKR.20040524104904.349">@nocolor

The 4.0 file format meets all of the following goals:

- The minimum of sentinels needed to properly recreate the outline.
- A robust way of telling whether newlines belong to sentinels or not.
- A minimum of intrusion and ugliness.

Changes to derived file format:

The @+leo sentinel indicates whether the format is 3.x or 4.x.

@+node and @-node sentinels no longer contain child or clone indices.  Therefore, such sentinels do not change when outline nodes are inserted, deleted or moved.  This will greatly reduce (but not entirely eliminate) cvs conflicts involving sentinel lines.

Leo generates @+node sentinels only for nodes containing body text.  Leo no longer generates other @+node sentinels to indicate outline structure.  As a result, there is no longer any need for @+body sentinels.

The @nl and @nonl sentinels adjust contribution of _previous_ sentinels.  This eliminates all lookahead logic and greatly simplifies the read code.

The @+others and @&lt;&lt; sentinels indicate leading whitespace appearing before @others directives and section refs.

Leo writes the @afterref whenever any non-whitespace text appears after a section references.

The @+doc and @+at sentinels now contain the whitespace that follows the corresponding @doc or @ directives.

New in 4.2:

- Files derived from @file-thin ("thin" derived files) use gnx's in @+-node sentinels to permanently and uniquely identify nodes.
gnx's have the format id.timestamp or id.timestamp.n if two gnx's would be the same otherwise.
	- id should be an string unique to a developer, e.g., a cvs id.
	- the timestamp is the date the node was first created, in yyyymmddhhmmss format.
	- n is an integer.

- The @+-all sentinels correspond to the range of the @all directive.

- The @+-middle sentinels indicate intermediate nodes between the node that references a section and the node that defines the section.  Typically no such sentinels are needed because most sections are defined in a direct child of the referencing node.</t>
<t tx="EKR.20040524104904.350">The following is a list of features I'd like to add to Leo.

Styled text and graphics

Except for syntax coloring, there is no way to style text in an outline.  The ultimate would be for Leo to support arbitrary XML code in the body pane.  Perhaps someday Tk's text panes will allow this.

Lists of sections

It would be useful to have easily available, possibly as a pop-up menu, a list of the most recently accessed sections, and possibly a full list of all section names as well.</t>
<t tx="EKR.20040524104904.351">Known bugs and limitations in all versions of Leo.

1. Untangle has no way of updating a section(chunk) whose name has been changed in the derived file.  Because of the @unit directive, there is not even a way to issue a meaningful warning.

2. Tangle treats @c like @code when in CWEB mode.
I recommend changing @c to @&lt; c @&gt;= throughout your CWEB sources and adding a reference
to @&lt; c @&gt; in all roots of CWEB files.

Known bugs and limitations of the PC version of Leo.

Syntax coloring options are not saved to the file.

The Log window has a limited capacity. This mainly affects debugging traces but could affect the output from the Tangle or Untangle commands if you tangled or untangled a large number of files.
</t>
<t tx="EKR.20040524104904.352">The following documentation applies to @file trees.

@file node:			Node whose headline starts with @file filename.
Named node:			Node whose headline starts with  &lt;&lt;section_name&gt;&gt;.
Unnamed node:		Node that is neither an @file node nor a definition node.
Organizer node:		An unnamed node with no body text.
@ignore node:		Node with an @ignore directive in its body text.
@others node:		Node with an @others directive in its body text.
Orphan node:		Ordinary node that is not part of any section definition.
Directive:			A line of body text that starts with '@'.
Doc part:			Body text from an @&lt;space&gt; or @doc directive to
					the next @c or @code directive.
Code part:			Body text from an @c or @code directive to the
					next @&lt;space&gt; or @directive.
Natural tree order:	The order of nodes would appear on the screen if all nodes
					were expanded.

An @file node forms the root of a tree whose expansion forms a derived file.

The expansion of an @file node or a section definition node is the entire text of the node with all section references replaced by their definition.  Section references is any text containing &lt;&lt;section name&gt;&gt;.  Section references are recognized anywhere within code parts, even within comments or strings.

Definition nodes must be a descendant of the node containing the section reference.  If a section is referenced in more than one node, you may use clones to "copy" the definition to more than one location.

Organizer nodes never affect the generated code, except to produce sentinels.  In particular, organizer nodes do not affect indentation of code in the derived file.

The body text of each node is assumed to start in code mode.  @ or @doc are used to create a doc part.  No escape conventions are used: if a line contains &lt;&lt; followed by &gt;&gt; then everything between the &lt;&lt; and &gt;&gt; becomes a section name.

The @others directive may be used at most once in named nodes and @file nodes.  @others refers to descendant nodes that would not otherwise be included in the derived file. More exactly, the expansion of the @others directive in node N is the set of unnamed descendants of N that are the descendants of no named node or @others node other than N.

Often, a single @others appears at the end of the body text of the @file node.  The expansion of @others is the concatenation of the body text of all ordinary nodes, in natural tree order.

For a more complex example, suppose we have a tree with the following headlines:

  @file name (contains @others in body text)
    &lt;&lt;section1&gt;&gt; (contains @others in body text)
      &lt;&lt;section2&gt;&gt; (contains @others in body text)
         node A1
		 node A2
      node B
    node C1
	node C2
	
The expansion of @others in node &lt;&lt;section2&gt;&gt; is the concatenation of the expansion of the body texts of nodes A1 and A2.  Similarly, the expansion of @others in node &lt;&lt;section1&gt;&gt; is the concatenation of the expansion of the body texts of node B.  Finally, the expansion of @others in node @file name is the concatenation of the expansion of nodes C1 and C2.

The derived file corresponding to an @file node is not written if any descendant of the @file node is an orphan. For example, the following outline contains an orphan node:

@file name (no @others)
    &lt;&lt;section1&gt;&gt; (contains @others)
      node A
    node B (orphan node)
	
Leo2 issues a warning when a .leo file is saved if any @file node contains an orphan or @ignored node.

Typically a single @others directive in the @file node suffices.  For example, the body text of the @file node would be something like:

  &lt;&lt; preliminary definitions &gt;&gt;
  @others

Sections may be defined in any descendant of the @file node provided that the method is not a descendant of any definition node.</t>
<t tx="EKR.20040524104904.354">Leo now uses unicode internally for most strings.  This solves a lot of problems.  The children of this node discuss the details...
</t>
<t tx="EKR.20040524104904.355">Leo now uses unicode internally for most strings.  The highlights:

1. Leo converts headline and body text to unicode when reading .leo files and derived files.  Both .leo files and derived files may specify their encoding, with "utf-8" being used by default.  If the encoding used in a derived file is not "utf-8" it is represented in the @+leo sentinel line.  For example:

#@+leo-encoding=iso-8859-1.

The "utf-8" encoding is a "lossless" encoding (it can represent all unicode code points), so encoding and decoding to and from utf-8 plain strings will never cause a problem.  When reading or writing a character not in a "lossy" encoding, Leo converts such characters to '?' and issues a warning. 

2. When writing .leo files and derived files Leo uses the same encoding used to read the file, again with "utf-8" used as a default.

3. leoConfig.py contains two settings used to specify the default encoding used for .leo and derived files:

default_derived_file_encoding = UTF-8 
new_leo_file_encoding = UTF-8 

I do not recommend changing new_leo_file_encoding (see the comments in leoConfig.leo) and you may set 
default_derived_file_encoding to anything that makes sense for you.

4. You may use the @encoding directive to specify the encoding used in a derived file.  You can't mix encodings in a single derived file.

This is all should need to know to use extended character sets on Leo.</t>
<t tx="EKR.20040524104904.356">leoConfig.py now contains two new settings, with the defaults shown below: 

default_derived_file_encoding = UTF-8 
new_leo_file_encoding = UTF-8 

These control the default encodings used when writing derived files and .leo files.

I do not recommend changing new_leo_file_encoding (see the comments in leoConfig.leo)

You may set default_derived_file_encoding to anything that makes sense for you.
</t>
<t tx="EKR.20040524104904.357">This Appendix describes Leo's file format.  Most users of Leo can skip this appendix.  This technical information will be of use only to those wanting to process Leo files with special-purpose filters.

Leo's uses XML for its file format.  The following sections describe this format in detail.  The last node gives an example, and it will be useful to refer to this example frequently.

In the description below sss denotes a string with the XML escapes for the &amp; &lt; and &gt; characters:

&amp; becomes &amp;amp;
&lt; becomes &amp;lt;
&gt; becomes &amp;gt;

This translation is performed on any text that could contain the &amp; &lt; or &gt; characters.

For those of you who grok DTD's a preliminary DTD for Leo's XML follows.  This DTD is under development and may contain syntax or semantics errors.  It may also simply be inaccurate.

The format of Leo2 .leo files is very similar to the format of Leo1 .leo files.  The major differences are:

1.  Leo1 .leo files have file version 1.  Leo2 .leo files have file version 2.  This allows Leo1 to issue an important warning if a version 2 file is opened.

2.  vnodes in Leo2 .leo files contain a new cloneIndex field, which records the immutable clone indices found in derived files.

3.  vnodes in Leo2 .leo files contain a new attribute byte, the "orphan" attribute.

In all other respects Leo1 and Leo2 .leo files are identical. Leo1 can open Leo2 files, but Leo1 ignores all information unique to Leo2.  However,  Leo1 treats @file nodes as regular outline nodes: Leo1 neither reads derived files when outlines (.leo files) are loaded nor writes derived files when outlines are saved.
</t>
<t tx="EKR.20040524104904.358">The heart of the file format is the &lt;vnodes&gt; element containing possibly nested &lt;v&gt; elements, and the &lt;tnodes&gt; element containing a list of (non-nested) &lt;t&gt; elements.  &lt;v&gt; elements refer to &lt;t&gt; elements using "t" attributes in &lt;v&gt; elements corresponding to "tx" attributes in &lt;t&gt; elements.

&lt;v&gt; and &lt;t&gt; elements in .leo files correspond directly to vnodes and tnodes in memory when Leo is running.  For full information about these see @file leoNodes.py in LeoPy.leo.  For full information about exactly what Leo is doing when reading and writing files, see @file leoFileCommands.py in LeoPy.leo.

New in 4.0:  &lt;v&gt; elements corresponding to @file nodes now contain tnodeList attributes.  The tnodeList attribute allows the read code in @file leoAtFile.py to recreate the order in which nodes should appear in the outline.

The tnodeList attribute is a list of gnx's: global node indices.  See the nodeIndices class in leoNodes.py for details.  A gnx has the form id.timestamp.n where .n is elided unless two nodes would have the same id.timestamp field.

The following sections of Users Guide:Customizing Leo contain new conventions that allow plugins to extend this format by adding attributes to &lt;v&gt; and &lt;t&gt; elments:

- Extending the format of .leo files
- Attaching temporary attributes to vnodes and tnodes
- Recommended conventions for plugins</t>
<t tx="EKR.20040524104904.359">Leo files start out with the following line declaring the format to be formatted as a type of XML.

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
</t>
<t tx="EKR.20040524104904.360">The &lt;leo_file&gt; tag opens an element that contains the entire file. The &lt;/leo_file&gt; tag at the end of the file ends this element.

The following sections describe the elements that may appear between the &lt;leo_file&gt; tag and the &lt;/leo_file&gt; tag.  These elements must appear in the order given.  However, the clone_windows element is optional.
</t>
<t tx="EKR.20040524104904.361">The file header element specifies information used to parse the file or to allocate data structures needed to read the file.  The header starts with &lt;leo_header and ends with /&gt;  In between are the following four required attribute fields.

file_format="1" indicates the version number of the file format: 1, 2, 3, etc.

tnodes="2" indicates the number of tnodes that appear in the file.

max_tnode_index="2"	indicates the largest tnode index.

clone_windows="0" indicates the number of clone windows specified by the file.

I'll say more about tnodes later.
</t>
<t tx="EKR.20040524104904.362">The globals element specifies information relating to the entire file.  This element starts with the following the &lt;globals body_outline_ratio="0.50"&gt; tag and ends with &lt;/globals&gt; tag.

The body_outline_ratio attribute specifies the ratio of the height of the body pane to the total height of the Leo window.  It initializes the position of the splitter separating the outline pane from the body pane.

In between the &lt;globals...&gt; tag and the &lt;/globals tag&gt; are the following two elements.  These specify the position of the Leo window and Log window in global coordinates:

&lt;global_window_position top="27" left="27" height="472" width="571"/&gt;

&lt;global_log_window_position top="183" left="446" height="397" width="534"/&gt;
</t>
<t tx="EKR.20040524104904.363">The preferences element specifies the preferences that the user can change using the Preferences command.  It starts with the &lt;preferences...&gt; tag and ends with &lt;/preferences&gt; tag.

The following three attributes may appear before the &gt; that ends the &lt;preferences...&gt; tag.

allow_rich_text="1"
tab_width="4"
page_width="132"

At present the "Allow Rich Text" option is non-functional.

Following the &lt;preferences...&gt; tag is the following element.

&lt;syntax_prefs&gt;sss&lt;/syntax_prefs&gt;

The sss string encodes the settings of the TSyntaxMemo component used for body text.  This string is simply passed to and from TSyntaxMemo and is not used by Leo in any other way.  Future versions of TSyntaxMemo will allow more settings to be encoded, and those settings will appear between the &lt;preferences...&gt; and &lt;/preferences&gt; tags.
</t>
<t tx="EKR.20040524104904.364">The find_panel_settings element specifies the settings of the Find panel at the time the file was saved.  This element starts with the &lt;find_panel_settings...&gt; tag and continues until the &lt;/find_panel_settings&gt; tag.

Zero or more of the following attributes may appear before the &gt; that terminates the &lt;find_panel_settings...&gt; tag. Leo writes these attributes in the order shown, but they may appear in any order.

whole_word="1"
search_body="1"
whole_word="1"
ignore_case="1"
pattern_match="1"
search_headline="1"
search_body="1"
suboutline_only="1"
mark_changes="1"
mark_finds="1"
reverse="1"

The default for all attributes is "0" (unchecked check box) and an attribute is written only if is "1" (checked check box).

The following elements appear after the &lt;find_panel_settings&gt; tag and before the &lt;/find_panel_settings&gt; tag.

&lt;find_string&gt;sss&lt;/find_string&gt;
&lt;change_string&gt;sss&lt;/change_string&gt;

The sss strings indicate the find and change strings in the Find panel.  Either sss string may be empty.  Both sss strings are encoded with the usual XML escapes.
</t>
<t tx="EKR.20040524104904.365">The vnodes element specifies the list of so-called vnodes of an outline.  

The vnodes element starts with &lt;vnodes...&gt; and ends with &lt;/vnodes&gt;.  In between these tags are one or more v elements.
</t>
<t tx="EKR.20040524104904.366">The v element represents a single vnode and has the following form:

&lt;v...&gt;&lt;vh&gt;sss&lt;/vh&gt; (zero or more nested v elements) &lt;/v&gt;

The vh element specifies the headline text.  As usual it starts at the &lt;vh&gt; tag and continues until the &lt;/vh&gt; tag.  sss is the headline text encoded with the usual XML escapes.

As shown above, a v element may contain nested v elements.  Each vnode corresponds to a headline on the screen, and vnodes are written to the file in the order they would appear on the screen if all headlines were fully expanded.

The nesting relationship between vnodes gives the outline structure.  v elements for child vnodes are nested within the v elements of parent vnodes.  Therefore, the outline level of a v element is the number of unclosed v elements containing it.

Zero or more of the following three attributes may appear before the &gt; that terminates the &lt;v...&gt; tag.

t="T23"
vtag="V18"
a="xxxx"

The t="Tnnn" attribute specifies the tnode associated with this vnode.  (See the section describing the &lt;t&gt; tag for more details.

The vtag="Vnnn" attributes specifies the vtag number for this node.  This tag is specified only if a clone window exists for this vnode.

The a="xxxx" attribute specifies vnode attributes.  The xxxx denotes one or more upper-case letters whose meanings are as follows:

C	The vnode is a clone.
E	The vnode is expanded so its children are visible.
M	The vnode is marked.
T	The vnode is the top visible node.
V	The vnode is the current vnode.

For example, a="CEM"  specifies that the vnode is a clone, is expanded and is marked.
</t>
<t tx="EKR.20040524104904.367">The tnodes element specifies the list of tnodes of an outline.

The tnodes element starts with &lt;tnodes...&gt; and ends with &lt;/tnodes&gt;.  In between these tags are zero or more t elements.  
</t>
<t tx="EKR.20040524104904.368">The t element represents a single tnode.  Each tnode represents body text.  Because of cloning, a tnode may be shared among several vnodes.

tnodes have the following form:

&lt;t...&gt;&lt;tb&gt;sss&lt;/tb&gt;&lt;/t&gt;

The tb element specifies the body text.  As usual it starts at the &lt;tb&gt; tag and continues until the &lt;/tb&gt; tag.  sss is the headline text encoded with the usual XML escapes.

The tx="Tnnn" attribute must appear before the &gt; that terminates the &lt;t...&gt; tag.  It specifies the tnode index of the tnode.  Vnodes refer to this index in their t="Tnnn" attribute.

The rtf="1" attribute may appear before the &gt; that terminates the &lt;t...&gt;tag.  If present it specifies that body text is encoded as Rich Text Format.  This attribute is not used at present.
</t>
<t tx="EKR.20040524104904.369">The clone_windows element is optional.  If present it specifies the list of cloned windows of an outline.

The clone_windows element starts with &lt;clone_windows&gt; and ends with &lt;/clone_windows&gt;.  In between these tags are one or more clone_window elements.  
</t>
<t tx="EKR.20040524104904.370">The clone_window element specifies a single clone window to be opened when the file opens.

The clone_window element has the following form:

	&lt;clone_window vtag="Vnnn"&gt;
		&lt;global_window_position top="nnn" left="nnnn" height="nnn" width="nnn" &gt;
	&lt;/clone_window&gt;

All attributes and elements shown above are required.

The vtag attribute must match the vtag attribute in some vnode, and associates the clone window with the vnode.

The global_window_position element specifies the size and position of the clone window.  The top and left attributes specify the position of the clone window in global coordinates.  The height and width attributes specify the size of the clone window.</t>
<t tx="EKR.20040524104904.371">&lt;!-- This is a comment --&gt;
&lt;!-- Version 1 of LEO DTD --&gt;

&lt;!DOCTYPE LeoOutlineDocumentType [

&lt;!-- A LEO file consists of the following parts (clone_windows is optional) --&gt;
&lt;!ELEMENT leo_file (header, globals, prefs, find_settings, vnodes, tnodes, clone_windows?) &gt;

&lt;!ELEMENT header EMPTY &gt;
    &lt;!ATTLIST header
        file_format     CDATA #REQUIRED  &lt;!-- An integer version number --&gt;
        tnodes          CDATA #REQUIRED  &lt;!-- Unused at present --&gt;
        max_tnode_index CDATA #REQUIRED  &lt;!-- The size of the array used to resolve tnode indices --&gt;
        clone_windows   CDATA 0 &gt;  &lt;!-- Number of clone windows --&gt;

&lt;!ELEMENT globals (global_window_position? global_log_window_position?) &gt;
    &lt;!ATTLIST globals body_outline_ratio CDATA 0.5 &gt;
    &lt;!ELEMENT global_window_position EMPTY &gt;
        &lt;!ATTLIST global_window_position
            top     CDATA #REQUIRED
            left    CDATA #REQUIRED
            height  CDATA #REQUIRED
            width   CDATA #REQUIRED &gt;
    &lt;!ELEMENT global_log_window_position EMPTY &gt;
        &lt;!ATTLIST global_window_position
            top     CDATA #REQUIRED
            left    CDATA #REQUIRED
            height  CDATA #REQUIRED
            width   CDATA #REQUIRED &gt;

&lt;!ELEMENT preferences ( syntax_options? ) &gt;
    &lt;!ATTLIST preferences
        &lt;!-- The following specify defaults for preferences --&gt;
		allow_rich_text  CDATA 0
		tab_width        CDATA 4
		page_width       CDATA 132
		font_name		CDATA "Courier New"
		font_size		CDATA 9 &gt;
    &lt;!ELEMENT syntax_options (#PCDATA) &gt;

&lt;!ELEMENT find_settings (find_string? change_string?) &gt;
    &lt;!ATTLIST find_settings
        &lt;!-- The following specify defaults for the find/change panel --&gt;
        batch            CDATA 0
        wrap_around      CDATA 0
        batch            CDATA 0
        whole_word       CDATA 1
        ignore_case      CDATA 0
        pattern_match    CDATA 0
        search_head_text CDATA 0
        search_body_text CDATA 1
        suboutline_only  CDATA 0
        mark_changes     CDATA 0
        mark_finds       CDATA 0
        reverse          CDATA 0 &gt;
    &lt;!ELEMENT find_string   (#PCDATA) &gt;
    &lt;!ELEMENT change_string (#PCDATA) &gt;

&lt;!ELEMENT vnodes (v*) &gt;
    &lt;!ELEMENT v (vh, v*) &gt;  &lt;!-- The crucial change: vnode may contain other vnodes --&gt;
        &lt;!ATTLIST v
            vtag ID    #IMPLIED       &lt;!-- for use by clone_windows section --&gt;
            t    IDREF #IMPLIED       &lt;!-- the tnode for this vnode, or none --&gt;
            a    CDATA "" &gt;    &lt;!-- V=current, M=marked, C=cloned, E=expanded --&gt;
    &lt;!ELEMENT vh (#PCDATA) &gt;

&lt;!ELEMENT tnodes (t*)&gt;
    &lt;!ELEMENT t (#PCDATA) &gt;
        &lt;!ATTLIST t
            tx  ID
            rtf CDATA 0 &gt;      &lt;!-- 1 if the #PCDATA is rtf format --&gt;

&lt;!ELEMENT clone_windows (clone_window*) &gt;
    &lt;!ELEMENT clone_window (global_clone_window_position) &gt;
        &lt;!ATTLIST clone_window
            vref IDREF #REQUIRED &gt;    &lt;!-- the vtag of the vnode that owns this clone window --&gt;
        &lt;!ELEMENT global_clone_window_position EMPTY &gt;
            &lt;!ATTLIST global_clone_window_position
                top     CDATA #REQUIRED
                left    CDATA #REQUIRED
                height  CDATA #REQUIRED
                width   CDATA #REQUIRED &gt;
]
</t>
<t tx="EKR.20040524104904.372">The following node contains the text of an actual leo file.  After that node is a node containing the outline that created the leo file.</t>
<t tx="EKR.20040524104904.373">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;leo_file&gt;
&lt;leo_header file_format="1" tnodes="4" max_tnode_index="4" clone_windows="0"/&gt;
&lt;globals body_outline_ratio="0.499"&gt;
	&lt;global_window_position top="54" left="54" height="550" width="559"/&gt;
	&lt;global_log_window_position top="2" left="630" height="397" width="336"/&gt;
&lt;/globals&gt;
&lt;preferences allow_rich_text="0" tab_width="4" page_width="72" tangle_bat="0" untangle_bat="0"&gt;
	&lt;TSyntaxMemo_options&gt;DBSoft6:OPT#8#67100656GWD#1#0GCL#11#-2147483633WRC#1#0IDS#1#1WRO#3#&amp;gt;|:FON#11#Courier NewFOS#1#9STC#8#16777215STB#7#8388608TBC#0#TBD#1#4EFF#323#18,0,0,16777215,;3,0,16777215,;4,8421504,16777215,;5,0,16777215,;6,255,16777215,;10,16711680,16777215,;11,0,16777215,;12,16711680,16777215,;14,16711680,16777215,;15,255,16777215,;16,16711680,16777215,;17,255,16777215,;18,16711680,16777215,;19,32768,16777215,;30,255,16777215,;32,0,16777215,;33,255,16777215,;36,0,16777215,;GDF#1#0MDF#1#0SDF#1#0BDF#1#0FOC#1#0RMG#1#0LNN#13#MS Sans SerifLNS#1#8LNC#11#-2147483640LNT#1#1LNE#0##END#&lt;/TSyntaxMemo_options&gt;
&lt;/preferences&gt;
&lt;find_panel_settings whole_word="1" search_body="1"&gt;
	&lt;find_string&gt;error&lt;/find_string&gt;
	&lt;change_string&gt;&lt;/change_string&gt;
&lt;/find_panel_settings&gt;
&lt;vnodes&gt;
&lt;v t="T1" a="TV"&gt;&lt;vh&gt;Headline 1&lt;/vh&gt;
&lt;v t="T2" a="E"&gt;&lt;vh&gt;Headline 2&lt;/vh&gt;
&lt;v&gt;&lt;vh&gt;Headline 3 ( No body text)&lt;/vh&gt;&lt;/v&gt;
&lt;/v&gt;
&lt;/v&gt;
&lt;v t="T3" a="C"&gt;&lt;vh&gt;Headline 4 ( a clone )&lt;/vh&gt;
&lt;v t="T4"&gt;&lt;vh&gt;Headline 5&lt;/vh&gt;&lt;/v&gt;
&lt;/v&gt;
&lt;v t="T3" a="C"&gt;&lt;vh&gt;Headline 4 ( a clone )&lt;/vh&gt;
&lt;v t="T4"&gt;&lt;vh&gt;Headline 5&lt;/vh&gt;&lt;/v&gt;
&lt;/v&gt;
&lt;/vnodes&gt;
&lt;tnodes&gt;
&lt;t tx="T1"&gt;Text of headline 1.&lt;/t&gt;
&lt;t tx="T2"&gt;Text of headline 2.&lt;/t&gt;
&lt;t tx="T3"&gt;Text of headline 4.&lt;/t&gt;
&lt;t tx="T4"&gt;Text of headline 5.&lt;/t&gt;
&lt;/tnodes&gt;
&lt;/leo_file&gt;</t>
<t tx="EKR.20040524104904.374"></t>
<t tx="EKR.20040524104904.375">Text of headline 1.</t>
<t tx="EKR.20040524104904.376">Text of headline 2.</t>
<t tx="EKR.20040524104904.377"></t>
<t tx="EKR.20040524104904.378">Text of headline 4.</t>
<t tx="EKR.20040524104904.379">Text of headline 5.</t>
<t tx="EKR.20040524104904.380">@nocolor
@ignore</t>
<t tx="EKR.20040524104904.381">We often refer to outline nodes by the directives they contain.  For example, an @root node is a node containing an @root directive, an @ignore node is a node containing an @ignore directive, and so on.

Exception: an @file node is a node whose headline starts with @file.</t>
<t tx="EKR.20040524104904.382">An @root tree is a tree whose is an @root node.  An @file tree is a tree whose root is an @file node, and so on.</t>
<t tx="EKR.20040524104904.383">The pane containing the body text of the currently selected headline in the outline pane.</t>
<t tx="EKR.20040524104904.384">The text in the body pane.  Body text is always associated with a particular headline.</t>
<t tx="EKR.20040524104904.385">A small blue box in the icon just to the left of a headline that indicates that the node contains body text.</t>
<t tx="EKR.20040524104904.386">A node directly contained by a node.</t>
<t tx="EKR.20040524104904.387">Another name for a section or part.</t>
<t tx="EKR.20040524104904.388">A copy of a tree that changes whenever the original changes.  The original and all clones are treated equally:  no special status is given to the "original" node.</t>
<t tx="EKR.20040524104904.389">A small red arrow in the icon just to the left of a headline that indicates that the node is a clone of another node.</t>
<t tx="EKR.20040524104904.390">A section containing code.  Code sections start with @c or @code directives.</t>
<t tx="EKR.20040524104904.391">A literate programming language invented by Donald Knuth and Silvio Levy.  CWEB produces derived files for the C language.

http://www-cs-faculty.stanford.edu/~knuth/cweb.html</t>
<t tx="EKR.20040524104904.392">To move right all following siblings of a node so that they become children of a node.</t>
<t tx="EKR.20040524104904.393">The output file created as the result of tangling a node containing an @root directive. The file consists of the expansion of the text following the @root directive.</t>
<t tx="EKR.20040524104904.394">An offspring of a node.  That is, a child, grandchild, etc. of a node.</t>
<t tx="EKR.20040524104904.395">A keyword, preceded by an '@' sign, that is used to control syntax coloring or the Tangle, Untangle or Weave commands.</t>
<t tx="EKR.20040524104904.396">A section containing only documentation. That is, a section that start with @.  Doc sections are associated with the immediately following code section, if any.</t>
<t tx="EKR.20040524104904.397">A convention for representing sequences of characters that would otherwise have special meaning.  Leo has only one such convention: in @root trees, @@ in the leftmost column of a code part stands for a single @ character.

Note: the markup language Leo uses in body pane is based on noweb.  However, Leo does not support noweb's @&lt;&lt; and @&gt;&gt; escape conventions.  If a line in a code part contains &lt;&lt; followed by &gt;&gt;, then that line does contain a section name, regardless of context.  If the &lt;&lt; and &gt;&gt; characters should not, if fact, delimit a section name, then you must place the &lt;&lt; and &gt;&gt; on separate lines.

Eliminating noweb's escape conventions for &lt;&lt; and &gt;&gt; characters solves some difficult problems when automatically untangling derived files.  Moreover, it is typically easier to split source lines than to use @&lt;&lt; and @&gt;&gt;.  Finally, Leo's Export and Import commands do support the @&lt;&lt; and @&gt;&gt; conventions.</t>
<t tx="EKR.20040524104904.398">The child of a child of a node.</t>
<t tx="EKR.20040524104904.399">The organizational unit of an outline.  A node.  Each headline contains headline text and (possibly empty) body text.</t>
<t tx="EKR.20040524104904.400">Hoisting a node redraws the screen that node and its descendants becomes the only visible part of the outline.  Leo prevents the you from moving nodes outside the hoisted outline.  Dehoisting a node restores the outline.

Multiple hoists may be in effect: each dehoist undoes the effect of the immediately preceding hoist.</t>
<t tx="EKR.20040524104904.401">Leo stands for Literate Editor with Outlines. That is, Leo supports both literate programming and outlining.

Leo1 denotes all versions of Leo that write version 1 .leo files, that is, all Windows version of Leo prior to version 2.0.  The last version of Leo1, version 1.15, understands enough about Leo2 to issue a warning when opening version 2 files.

Leo2 denotes all versions of Leo that write version 2 .leo files, that is, all versions of leo.py and all Windows versions with version number 2.0 and above.  Only Leo2 can generate derived files from @file trees.</t>
<t tx="EKR.20040524104904.402">A style of programming that aims at producing the highest quality program listings.  Literate programming languages apply two fundamental operations to text: weaving and tangling.  Leo supports two literate programming languages, CWEB and noweb.

Knuth's book is the best overall introduction to literate programming:
Literate Programming, by D. E. Knuth ISBN 0-937073-80-6.

More information is available at Knuth's web site:
http://www-cs-faculty.stanford.edu/%7Eknuth/lp.html</t>
<t tx="EKR.20040524104904.403">Marking a node by placing a red mark near its leader character. Marks can be placed using the Mark command, as the result of Find and Change commands, or as the result of the Mark Changed Roots and Mark Changed Items command. The Tangle Marked command tangles only those subtrees that are marked.</t>
<t tx="EKR.20040524104904.404">Within an @file tree, a node that contain a section name, like &lt;&lt;x&gt;&gt;, at the start of its headline text.

Within an @file tree, all nodes containing a section reference must have a descendant named node corresponding to the reference.

Within an @root or @unit tree, an @code directive is an abbreviation for &lt;&lt;x&gt;&gt;=, where &lt;&lt; x &gt;&gt; is found in the headline.

</t>
<t tx="EKR.20040524104904.405">The organizational unit of an outline.  A headline.  The combination of headline text and outline text.
</t>
<t tx="EKR.20040524104904.406">A simple literate programming language invented by Norman Ramsey.  noweb can produce derived files for any text-based programming language.

http://www.eecs.harvard.edu/~nr/noweb/</t>
<t tx="EKR.20040524104904.407">The children, grandchildren, etc. of a node.</t>
<t tx="EKR.20040524104904.408">An unnamed node in an @tree that contains no body text.  Such nodes may appear anywhere in an @file tree; they do not affect the derived file in any way.  In particular, organizing nodes do not affect indentation in the derived file.</t>
<t tx="EKR.20040524104904.409">An unnamed node that is either 1) a descendant of a named node or 2) the descendant of no @others node.

Orphan and @ignore nodes are not allowed in @file trees: no derived file is written if an @file node contains an @ignore or orphan node.</t>
<t tx="EKR.20040524104904.410">1. A visual representation of a hierarchy on the screen.

2. The data contained by the hierarchy.

Outlines are composed of headlines representing data.  The combination of a headline and its associated body text is called a node.
</t>
<t tx="EKR.20040524104904.411">he pane containing a visual representation of outlines.</t>
<t tx="EKR.20040524104904.412">The node the directly contains a node.</t>
<t tx="EKR.20040524104904.413">Another name for a section or chunk.</t>
<t tx="EKR.20040524104904.414">A file that can be read by Adobe Acrobat.</t>
<t tx="EKR.20040524104904.415">To move all children of a node left in an outline so that they become siblings of the node.</t>
<t tx="EKR.20040524104904.416">The first node of the entire outline.  In the PC version of Leo several nodes may be siblings of the root.</t>
<t tx="EKR.20040524104904.417">The portion of the outline in which a section definition is known. By default the scope of a section definition is the smallest subtree containing both the section and a node containing an @root directive. The @unit directive declares that the subtree containing the @unit directive is the scope for all sections defined in that tree.</t>
<t tx="EKR.20040524104904.418">A fragment of text that can be incorporated into derived files.  A syntactic unit of body text.

There are two kinds of sections: code sections and doc sections. Sections are defined in slightly different ways in @file in @root trees (that's the difference between the two kinds of trees.)

In @file trees
--------------
Code sections start with the @c directive.  The entire body text of a node is a code section by default, so the @c directive can be omitted if there are no doc sections in the body pane.  Doc sections start with @ followed by a space at the start of a line. Doc sections continue until the end of body text or until the next @c or @(space) directive.

In @root trees
--------------
Code sections start with the @c directive or section definition lines of the form:
&lt;&lt; section name &gt;&gt;=
Such lines begin named code sections.  Other code sections are unnamed. Doc sections start with @ followed by a space 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.</t>
<t tx="EKR.20040524104904.419">A name enclosed in &lt;&lt; and &gt;&gt;.  Section names may contain any characters except newlines and "&gt;&gt;".</t>
<t tx="EKR.20040524104904.420">A section name appearing in a code part. Tangling replaces all references by their definitions.</t>
<t tx="EKR.20040524104904.421">Comment lines in files derived from @file nodes.  Such lines start with an @ following the opening comment delimiter.  Sentinels embed outline structure into derived files.  Do not alter such lines!  Doing so can corrupt the outline structure.</t>
<t tx="EKR.20040524104904.422">Nodes with the same parent.  Siblings of the root have no parent.</t>
<t tx="EKR.20040524104904.423">The icon that appears just to the left of headline text in the outline pane.  This icon shows: a blue body text box if the node contains body text, a red clone arrow if the node is cloned, and a red marker bar if the node is marked.  The icon is outlined in black if the node is dirty, that is, if the node has been changed since the file was last change.
</t>
<t tx="EKR.20040524104904.424">The process of creating derived files from @root or @file trees.  Leo tangles @file automatically when writing a .leo file.  The user must explicitly tangle @root trees using the Tangle command.  Tangling expands all references in an @root node or @file node.</t>
<t tx="EKR.20040524104904.425">The language used to syntax color text.  This language determines the default comment delimiters used during tangling and untangling.
</t>
<t tx="EKR.20040524104904.426">Another name for an outline.</t>
<t tx="EKR.20040524104904.427">A node whose headline text does not start with &lt;&lt; name &gt;&gt;.

Unnamed nodes in @file trees must be a descendant of an @others node and must not be the descendant of any named node.

For example, the following tree is invalid:

@others node
  &lt;&lt; name &gt;&gt;
    unnamed node
	
The unnamed node would be an orphan node.</t>
<t tx="EKR.20040524104904.428">Updating an outline based on changes to derived files.  Untangling allows changes to be propagated from derived files back to the outline.  Especially useful when fixing syntax errors outside Leo.
</t>
<t tx="EKR.20040524104904.429">The process of creating typeset documentation from a noweb or CWEB source file.  Weaving creates documentation. Tangling creates source code files known as derived files.

Leo does not support weaving directly.  If you want to weave a file you can create noweb or CWEB files using Leo's export commands, then use the noweb or CWEB systems to weave those files.</t>
<t tx="EKR.20040601084317">Leo 4.2 alpha 3           June 1, 2004

This version fixes completes the essential features of version 4.2.  All known incompletions and bugs involving shared nodes and Leo's new file format have been fixed.  BTW, this version of Leo completes Leaps 201 and 202.

It should be safe to use this version for collaboration between Leo's developers.  I hereby encourage people to start using cvs for collaboration.  Only by doing so will we discover any possible problems.

The only item that must be completed before releasing 4.2 beta is fixing the Go To Line Number command so it supports thin derived files.

There are many known bugs in this version: most are minor bugs that have been around for a long time.  All known bugs will be fixed by the first release candidate.  See the to-do list in LeoPy.leo for the complete list.

The highlights of this version:

- All features of @file-thin are now complete and appear to be stable.
	- All .leo files in the distribution use @thin files where possible.
	- Leo ignores all directives within the range of the @all directive.
	- The @+middle and @-middle sentinels allow sections to be defined in any descendant node.
	- The @clone sentinel marks duplicate cloned siblings.
- The beginnings of a new undo scheme are in place.
- @thin, @nosent, @noref and @asis are abbreviations for @file-thin, @file-nosent, @file-noref and @file-asis.
- Created new iterators that return lists of vnodes and tnodes, including iterators that remove all duplicates from those lists.</t>
<t tx="EKR.20040601084317.2"></t>
<t tx="EKR.20040601084317.99">This happened after write errors such as orphan nodes.</t>
<t tx="EKR.20040601084317.102">Added u.registerUndoHandlers.

This will become largely unnecessary in the new undo scheme.  It's good to have though.</t>
<t tx="EKR.20040601084317.142">When writing .leo files Leo now pickle's and hexlify's all data in the v.unknownAttribute and t.unknownAttribute dictionaries.  When reading .leo files Leo does the reverse.

Leo ignores all elements in these dictionaries if some element can not be pickled.</t>
<t tx="EKR.20040601084317.161">I have fallen madly in love with generators.  The following new iterators are defined with generators.

c.all_positions_iter
c.all_tnodes_iter
c.all_vnodes_iter
c.all_unique_tnodes_iter
c.all_unique_vnodes_iter

p.tnodes_iter
p.vnodes_iter
p.unique_tnodes_iter
p.unique_vnodes_iter

v.self_and__subtree_iter
v.self_and_unique_subtree_iter</t>
<t tx="EKR.20040601101118">If the copied node was an @thin or @file-thin node node only the root node was copied.</t>
<t tx="EKR.20040601101227"></t>
<t tx="EKR.20040601101227.1"></t>
<t tx="EKR.20040601101430">This bug exists in 4.1 final.  Leo did not properly show the found text in headlines.  The fix was in the code that redraws the screen, not in the find/change code itself.</t>
<t tx="EKR.20040601101430.1"></t>
<t tx="EKR.20040601101510"></t>
<t tx="EKR.20040601101547"></t>
<t tx="EKR.20040601102115"></t>
<t tx="EKR.20040601102703">The new scheme simply saves all information in one or more vnodes and their associated tnodes.  This is a general scheme that can be used by almost any command.

At present only the u.saveTree method exists.  Coming soon, u.saveNode, u.saveNodeAndChildren and u.saveListOfNodes.</t>
<t tx="EKR.20040601102808">See the to-do list in LeoPy.leo for a list of known bugs in this version.

None of these bugs is serious:  I consider this version to be suitable for day-to-day work.</t>
<t tx="EKR.20040608091134">The @all directive is valid only in @thin trees.  This directive is similar to @others, but it is less restrictive: it dumps _all_ nodes to the derived file, including @ignore nodes and nodes that in an @others tree would be considered to be orphan nodes.

The @all directive is required for files such as @thin leoProjects.txt in LeoPy.leo.  leoProjects.txt contains so-called project nodes.  It doesn't have an meaning as a program file:  it is simply a collection of unrelated data.  @others would not work at all: it would complain about lots of orphan nodes.</t>
<t tx="EKR.20040608091134.1">In most respects @file-thin (or equivalently, @thin) works just like @file as far as writing code is concerned.  In fact, you can convert from @file to @thin simply by opening an outline, changing @file to @thin, and saving the outline.

Here are the differences between @file and @thin:

- Leo does not save the information contained in the @thin tree in the .leo file.  

- Files derived from @thin (so-called "thin" derived files) contain all information needed to recreate the @thin tree in the outline.  In particular, @+node and @-node sentinels use gnx's to uniquely identify nodes.

- The @all directive is valid only in @thin trees.  This directive is similar to @others, but it is less restrictive: it dumps _all_ nodes to the derived file, including @ignore nodes and nodes that in an @others tree would be considered to be orphan nodes.

The @all directive is required for files such as @thin leoProjects.txt in LeoPy.leo.  leoProjects.txt contains so-called project nodes.  It doesn't have an meaning as a program file:  it is simply a collection of unrelated data.  @others would not work at all: it would complain about lots of orphan nodes.

The great advantage of using @thin is that people can collaborate without having to continually update .leo files:

- Developers only need to commit thin derived files to cvs.

- The cvs repository contains "reference" .leo files. These reference files
should containing nothing but @thin nodes. Reference files will change only when
new derived files get added to the project.

- Developers will use local copies of reference files for their own work. For
example, instead of using LeoPyRef.leo directly, I use a copy call LeoPy.leo. My
local copy can contain nodes other than @thin nodes.</t>
<t tx="EKR.20040628095213">Leo 4.2 beta 2           July 5, 2004
Leo 4.2 beta 1           June 30, 2004

The highlights of 4.2 beta 2:

- Leo now writes the entire contents of @ignore'd @thin trees to the .leo file.
This change ensures that users can create and remove @ignore directives without
any chance of losing data inadvertently.

- Leo now saves and restores marks and the expansion state of nodes in @thin trees.

- Leo marks @thin nodes as dirty whenever they become "newly unignored", i.e.,
when an @thin node no longer falls in the range of an @ignore directive.

Beta 1 completes all fundamental work in the 4.2 code base. All essential code
is complete. Dozens of bugs have been fixed since the Alpha 3 release about a
month ago.

Known bugs in 4.2 beta 2:

- Not all plugins work correctly.
- Some plugins leak memory very slightly.

The highlights of Leo 4.2:

- @thin trees make Leo much more friendly to cvs. Files derived from @thin can
be committed to cvs and updated from cvs without having to commit or update the
corresponding .leo file. There is no longer any need to keep .leo files and
derived files in synch.

- Leo's data structures have been reorganized. As a result, all outline
operations are much faster. To support this organization, scripts that traverse
Leo's data structures must now use a positions rather than vnodes. Old scripts
that appear to use vnodes will still work because methods like c.currentVnode
that appear to return vnodes actually return positions.

Other features of 4.2:

- Leo is now much more friendly to using spaces instead of tabs.
- The Execute Script command reports erroneous lines more clearly.
- The usual assortment of bug features and minor features.

Coming soon in 4.2:

- Perfect Import will guarantee that Leo imports file perfectly.
- @import will allow you to study files using Leo without changing those files.</t>
<t tx="EKR.20040628095213.3">@nocolor

- Leo calls g.enableIdleTimeHook at end of startup code.
	- This means that g.idleTimeHookHandler gets called periodically, even if no hooks have been defined.
	- g.enableIdleTime hook now calls g.app.gui.setIdleTimeHook at most once.

- app.forceShutdown now calls "end1" hook before calling app.finishQuit.
	- This ensures that the "end1" hook always gets called once.
	- app.finishQuit calls doHook("end1",...) only if it hasn't been called before.
		- This isn't necessary, but it makes traces in doHook less confusing.

- idleTimeHookHandler now calls the idle-time hook for all open windows.
	- So having multiple windows open should not affect idle-time hooks.

** Warning: new convention required to workaround apparent Tk problems.
	- "idle" hooks should return if g.app.killed is True.</t>
<t tx="EKR.20040628095213.23">@color

Added the following hooks:

tag argument                                               keys in keywords
(hook name)           overrides    when called           dictionary argument
---------             ---------    -----------           -------------------

"draw-outline-box"       yes   start of drawBox          tree,p,v,x,y (note 6)
"draw-outline-icon"      yes   start of tree.drawIcon    tree,p,v,x,y (note 6)
"draw-outline-node"      yes   start of tree.drawNode    tree,p,v,x,y (note 6)
"draw-outline-text-box"  yes   start of tree.drawText    tree,p,v,x,y (note 6)
"draw-sub-outline"       yes   start of tree.drawTree    tree,p,v,x,y,h,level,hoistFlag (note 6)</t>
<t tx="EKR.20040628095213.52"></t>
<t tx="EKR.20040628095213.56"></t>
<t tx="EKR.20040628095213.60">Added support for RapidQ, css, shell scripts and PHP.</t>
<t tx="EKR.20040628095213.109">http://sourceforge.net/forum/message.php?msg_id=2429098
By: nobody

The Leo icon can eliminate the need for the word Leo.

What I did:

- Eliminate Leo in name of Find panel.
- Derived leoTkinterPrefs from leoTkinterDialog: creates icon.
- Derived leoComparePanel from leoTkinterDialog: creates icon.
- Eliminated the -t option when opening Idle: the idle window is now called "Python Shell"</t>
<t tx="EKR.20040628095213.110">- Added @language html when importing ".htm" and ".html" files.
- Added @nocolor when importing ".txt" and ".text" files
</t>
<t tx="EKR.20040628095213.113">When in headline, the Select All command selected the body text.</t>
<t tx="EKR.20040628095213.121">- idle_body_key must call g.scanDirectives in order to support @tab_width.
	- This must be done for tabs and newlines.

- Fixed bug in g.scanDirectives that was rejecting negative tabwidth values.
	- This bug did not exist in the other versions of scanDirectives.

- With a negative tabwidth, a backspace now computes what spaces are equivalent to a tab and delete all of those.  This is easy to do!
</t>
<t tx="EKR.20040628095213.143"></t>
<t tx="EKR.20040628095213.160"></t>
<t tx="EKR.20040628095213.192"></t>
<t tx="EKR.20040628095213.197">doc\leoUsersGuide.txt
doc\leoFAQ.txt
doc\leoLeaps.txt</t>
<t tx="EKR.20040628095213.198">The old code used at c.tab_width.  It should also look for @tabwidth directives.

This was not good when @tabwidth -4 was in effect.</t>
<t tx="EKR.20040628095213.202">atFile.scanHeader was not handling -encoding fields properly.</t>
<t tx="EKR.20040628095213.213"></t>
<t tx="EKR.20040628095213.225"></t>
<t tx="EKR.20040628095213.246"># namespace not handled very well.</t>
<t tx="EKR.20040628095213.264"></t>
<t tx="EKR.20040628095213.269"></t>
<t tx="EKR.20040628095213.279">I inserted "import time", and while I was at it I improved the error checking.</t>
<t tx="EKR.20040628095213.282">- By default, finishPaste command reassigns all indices in copied nodes.
- Created pasteOutlineRetainingClones.
- Added reassignIndices arg to pasteOutline, getLeoOutline and finishPaste.
- Added &lt;&lt; recreate tnodesDict &gt;&gt; in getLeoOutline.
- Simplified getTnode slightly: the "if t" code is the same for both kinds of reads.</t>
<t tx="EKR.20040628095213.297">The code now limits what can be pasted to a maximum of one line or a about 250 characters.</t>
<t tx="EKR.20040628095213.308"></t>
<t tx="EKR.20040628095213.311">@nocolor

- Leo now uses True and False everywhere instead of true and false.

- All of Leo's code uses spaces instead of tabs for indentation.</t>
<t tx="EKR.20040628095213.312"></t>
<t tx="EKR.20040628095213.314"></t>
<t tx="EKR.20040628095213.324">- Set removeTrailing to True unless ch is a newline.

This allows Alt-f to work properly.

- Return "break" after the "final" text has been computed if nothing has changed.

This suppresses spurious newlines.

A new idea:  Make sure the text _does_ have a newline at all times.  I'm not sure this will work...

- ALWAYS set the text in select.  This prevents some weird problems with trailing newlines.</t>
<t tx="EKR.20040628095213.334">- The string passed to exec now includes sentinels.

goToLineNumber needs sentinels to work properly.

- es_exception now gets the error line number from the traceback.

- Added new keyword arguments to goToLineNumber.

- Created goToScriptLineNumber, which just calls goToLineNumber.</t>
<t tx="EKR.20040628095213.346">Hitting return in middle of a headline didn't work.</t>
<t tx="EKR.20040628095213.348"></t>
<t tx="EKR.20040628095213.354"></t>
<t tx="EKR.20040628095213.366"></t>
<t tx="EKR.20040628095213.368"></t>
<t tx="EKR.20040628095213.377">Changed getVnode so it checks for v = None after calling getExistingVnode.  Creating the node seems to work in this case: I wouldn't bet my life that it works in all cases.</t>
<t tx="EKR.20040628095213.391">- Added toString to most write methods.
- Retained scriptFile option for compatibility with plugins.</t>
<t tx="EKR.20040628095213.404"></t>
<t tx="EKR.20040628095213.407"></t>
<t tx="EKR.20040628095213.408"></t>
<t tx="EKR.20040628095213.412"></t>
<t tx="EKR.20040628095213.425"></t>
<t tx="EKR.20040628095213.442">This only happened after previous write error.

The fix was to init self.errors in openWriteFile.

The whole atFile logic is pretty gruesome.  It's got to be cleaned up.</t>
<t tx="EKR.20040628095213.444">- Allow indented @all.
    - Changed to g.is_special
    - Changed leoColor.doAtKeyword
    
- Fixed bug in is_special that broke p.isAtAllNode.</t>
<t tx="EKR.20040628095213.485">There was a small hole in the format of derived files.  Leo assumed that comment delimiters do not change within any particular derived file.  This assumption is not necessarily true in files like leoProjects.txt.

What I did:

- putDirective and readDirective now check for @langauge and @comment, and change comment delims appropriately.

This is slightly dubious: after all, an @langauge directive in the middle of most derived files will cause havoc.  However, one could say that this is the users problem :-)

BTW, this doesn't really solve all problems in @all trees: Leo can still get mightily confused about comment delims if the user doesn't put proper @language directives in @all trees.
</t>
<t tx="EKR.20040628095213.490">readEndNode uses the existing tempBodyString attribute to determine if the body text has changed.  If so, we mark the tnode dirty.  The code in 

top_df.read.&lt;&lt; copy all tempBodyStrings to tnodes &gt;&gt;

propagates the dirty marks to all ancestor @file nodes.  This can't be done in readEndNode because no positions are available at that time.</t>
<t tx="EKR.20040628095213.493"></t>
<t tx="EKR.20040628095213.499"></t>
<t tx="EKR.20040628095213.501">Leo now writes t.unknownAttributes to the .leo file when writing the &lt;v&gt; element corresponding to the root of an @thin tree.  Leo will do this by writing a new xml attribute, descendentTnodeUnknownAttributes, in &lt;v&gt; element.

Leo will only write t.unknownAttributes, not v.unknownAttributes.  This is because only tnodes have gnx's in thin derived files.  In effect, vnodes are anonymous.  We could attempt to get around this by identifying vnodes by their corresponding tnodes, but that's not a general solution and it is, in effect, equivalent to writing only t.unknownAttributes.  This being so, it seems pointless to "pretend" to be writing v.unknownAttributes.

The effect of this is to make all vnodes identical, as far as using unknownAttributes is concerned.  As I've stated in the past, this won't do if, for example, a plugin is trying create an arbitrary directed graph between vnodes.  In that case, the plugin should confine itself to @file trees, or just vnodes in .leo files, for that matter.</t>
<t tx="EKR.20040628095213.512">The problem was setting endSentinelComment to None instead of "" in readDirective.

The code is pretty fragile; it should handle either None or "", but in fact it requires "".</t>
<t tx="EKR.20040628095213.513"></t>
<t tx="EKR.20040628100535">@killcolor</t>
<t tx="EKR.20040628100535.1"></t>
<t tx="edream.110203163054">@nocolor

Leo is:

- A programmer's editor, an outlining editor and a flexible browser.
- A literate programming tool, compatible with noweb and CWEB.
- A data organizer and project manager.
  Leo provides multiple views of a project within a single outline.
- Fully scriptable using Python and saves its files in XML format.
- Portable. Leo.py is 100% pure Python.
  leo.py requires Python 2.2 and tcl/tk 8.3 or above.
- Open Software, distributed under the Python License.</t>
<t tx="edream.110203163054.1">@nocolor

* Leo's main window contains two panes, an outline pane on top and a body pane below.

* The outline pane works like Windows Explorer:   Headlines expand and contract when you click the + or - icon.

* The other icon shows the status of the headline.  See the subheadlines of this headline for details.

* You can change the relative sizes of the panes by dragging the splitter area between the two panes.
</t>
<t tx="edream.110203163054.2">This is the body text of this node.  Nodes containing body text are marked with a small blue box in the status icon.</t>
<t tx="edream.110203163054.3">You can mark headlines in several ways: with the various Outline:Mark commands, with the Find or Change commands, or with the Untangle command.  The "Go To Next Marked" command will go to the next marked node, if any.</t>
<t tx="edream.110203163054.4">Cloned nodes share the same body text.  Also, the headlines of all cloned headlines change whenever a change is made to any of them.</t>
<t tx="edream.110203163054.5"></t>
<t tx="edream.110203163054.6">@nocolor

Please use Leo's SourceForge forums at

http://sourceforge.net/forum/?group_id=3458

to ask questions or suggest improvements.  That way other people can share in the discussions.</t>
<t tx="edream.110203163054.7">@nocolor

Leo owes much of its visual design to MORE, possibly the most elegant computer program ever written. Leo's clone nodes are inspired by MORE.

The following people have made generous donations to the Leo project: Robert Low, Nic Cave-Lynch.

The following people reported bugs, answered questions, and made suggestions for improving Leo: Alex Abacus, Shakeeb Alireze, Bruce Arnold, Chris Barker, Eric Brown, Darius Clarke, Bill Drissel, Wenshan Du, Allen Edwards, Chris Elliot, Mark Engleberg, Dethe Elza, Stephen Ferg, Tom Fetherston, Tomaz Ficko, Niklas Frykholm, Fred Gansevles, Jonathan M. Gilligan, Thomas Guettler, Zak Greant, Thomas Guettler, Romain Guy, Dave Hein, Tiago Castro Henriques, Gary Herron, Steve Holden, Klass Holwerda, Matthias Huening, Robert Hustead, John Jacob, Christopher P. Jobling, Eric S. Johansson, Garold Johnson, James Kerwin, Nicola Larosa, David LeBlanc, Chris Liechti, Steve Litt, Martin v. Loewis, Robert Low, Fredrik Lundh, Alex Martelli,  Marcus A. Martin, Gidion May, David McNab, Chad Netzer, Naud Olivier, Joe Orr, Marc-Antoine Parent, Paul Paterson, Davide Salomoni, Sean Shaleh Perry, Tim Peters, Scott Powell, Bruce Rafnel, Walter H. Rauser, David Speed Ream, Rich Ries, Aharon Robbins, Guido van Rossum, David Rowe, Steven Schaefer, Wolfram Schwenzer, Gil Shwartz, Paul Snively, Phil Straus, Jurjen Stellingwerff,  Jeffrey Thompson, Gabriel Valiente, Tom van Vleck, Jim Vickroy, Tony Vignaux, Ying-Chao Wang, Cliff Wells, Dan Wharton, Wim Wijnders, Vadim Zeitlin.

The following people have written code for Leo: Dave Hein wrote code to support PHP, to handle Tk version numbers properly and to open the Python window properly on Linux.  Marcus A. Martin wrote code to support LaTex. Bernhard Mulder proposed a new way of untangling derived files.  Paul Paterson wrote the first implementation of plugins and the spell checking plugin.  Steven P. Schaefer eliminated problems with end-of-line on Linux and fixed bugs in how directives were handled in @root trees.

The following deserve special mention: David Brock wrote TSyntaxMemo.  The late Bob Fitzwater kept me focused on design. Donald Knuth invented literate programming and the CWEB language. Will Munslow wrote stylesheets for Leo so Leo and Microsoft Word can talk to each other. Joe Orr created Leo stylesheets for Leo; see http://www.jserv.com/jk_orr/xml/leo.htm. Joe Orr also created an outstanding set of tutorials for Leo; see http://www.evisa.com/e/sb.htm. John K. Ousterhout created tcl/Tk. Neal Norwitz wrote PyChecker.  Marc-Antoine Parent urged me to use XML for Leo's file format and helped improve it. Paul Paterson suggested the plugin architecture and suggested an approach to spell checking.  Norman Ramsey created noweb and gave permission to quote from the noweb web documentation. Rich Ries has contributed a huge number of suggestions. Steven P. Schaefer pointed out major security problems lurking in hooks.  Gil Shwartz helped with unicode support.  Phil Straus has been a great friend and constant support. Guido van Rossum created Python, Tkinter and the Python License. Dave Winer created MORE. Dan Winkler helped support Leo on the Mac.

Special thanks to my family. My brother, David Speed Ream, tested Leo and made many useful suggestions. Rebecca, James and Linda make it all worthwhile. It was during a conversation with Rebecca that I realized that MORE could be used as a prototype for Leo. That was a crucial first step.</t>
<t tx="edream.110203163054.8">@nocolor
Here is what people are saying about Leo:</t>
<t tx="edream.110203163054.9"></t>
<t tx="edream.110203163054.10">I've written documentation in WordPerfert, Ventura, Word, PageMaker, and
FrameMaker and even though they create wonderfully looking and useful
documents, they've never been able to do what I've been looking for. HTML,
compiled help files, and later PDF came closer, but still not there. I thing
I've found it in LEO, a way to make a "living" document. A document built out
of discrete parts that can be re-organized on the fly to meet the needs of a
varying audience.

I'll be honest is saying that it will be a long road to convince management to
release LEO files as public documentation, but for all internal projects,
nothing but LEO from here on out. I've already started converting the IT
Procedures manual from Open Office to LEO because I know it's going to be much
more useful to me and anyone else. Being a convert for less than a day I've
still got a lot to learn, but just the possibility of keeping system
maintenance scripts in the IT manual is mind boggling.</t>
<t tx="edream.110203163054.11">wstapp@earthlink.net

I've just perused your program, manual and tutorials and though I have thus far
only an incomplete idea of its capabilities, it contains some of the most
clever features I've ever seen: clones of nodes for example. This program must
have cost you a great deal of effort, not at all diminished I'm sure, by the
"clearsightedness" that unfailingly shows through. I am sure that all who have
examined your program admire it and that all who use it do so with a sense of
gratitude. I know I do. My fields are linguistics and literature and what
programming I do does not go beyond these areas, but I have programmed in C,
C++, Java and Visual Basic and used a number of editors, most of which lag far
behind the programming language. Thank you for making it available.</t>
<t tx="edream.110203163054.12">From Dan Winkler, heydan@post.harvard.edu

This year my accountant is getting a beautiful printout generated by 
LaTeX and Leo.  I have a complicated tax situation this year, but I got 
it all laid out and organized in Leo.  Then I had each of the nodes that 
had something my accountant needs to see write the data out to a file in 
the form a LaTeX table.

Sometimes a row of a table would have a result that was calculated by 
adding up a list of numbers.  For that I used the modern day equivalent 
of an adding machine paper tape -- I stored a lisp s-expression in a Leo 
comment.  I like s-expressions for this because once I put the opening 
"(+" on one line and the closing ")" on another line, I can fill in 
additional numbers just by typing them and can even annotate them with 
comments.  So in the middle of generating a LaTeX file I might have 
something like this:

@
(+
1165.26 1823.70 ; May 2002
123.38 ; June 2002
13.50 ; July 2002
13.21 ; October 2002
55.25 ; November 2002
)
@c

That's an annoted record of how I arrived at the number the accountant 
will actually see.  I can just paste it into any lisp or scheme 
interpreter and get the total.  Adding additional numbers is easy.

For next year, I think I might  take this a step further.  What I did 
this year is good for adding up numbers to get a total for one row of a 
LaTeX table.  But it turns out I'd also like some more processing done 
on those tables (which I had to do by hand this time) -- I'd like the 
rows sorted in reverse order by magnitude (so that the big numbers jump 
out at you from the start of the tables) and I'd like a total of all the 
rows in the table. So I think next year, instead of having an 
s-expression that computes the total of one row for me, I think I'll use 
s-expressions that generate whole tables, formatted for LaTex, from the 
underlying data.  So I'm thinking next year my s-expressions might look 
more like this:

@
(table "Widget Related Expenses"
    ("widget insurance" (+
                    1165.26 1823.70 ; May 2002
                    123.38 ; June 2002
                    13.50 ; July 2002
                    13.21 ; October 2002
                    55.25 ; November 2002
                  ))
     ("widget shipping" (+
                    472.15 651.94 ; May 2002
                    54 ; June 2002
                   ))
     ("widget cleaning" (+
                    165.26 183.70 ; May 2002
                    123.38 ; June 2002
                    13.50 ; July 2002
                    13.21 ; October 2002
                    55.25 ; November 2002
                   ))
)
@c

The job of that "table" function would be to return the LaTeX code 
needed to display a table with the category names and values, sorted 
descending by magnitude, with the total displayed.  It's sort of a poor 
man's way of doing a spreadsheet inside Leo and then making it look 
great using LaTeX.  The idea would be as I wanted to add more data, I'd 
add it to the s-expression and then reevaluate the whole thing by 
pasting it into a lisp interpreter and then copying the result back into 
the same Leo node for LaTeX to process.

-- Dan</t>
<t tx="edream.110203163054.13">Leo has simplifyed updating and creating new scripts and .bats keeping similar
information in the same place. there is almost an addictive withdrawl effect
when I can complete an operation in so much less time with leo &amp; python than I
had become used to.
</t>
<t tx="edream.110203163054.14">@nocolor
September 3, 2002

Hello, my full name is David Speed Ream. I am known as Speed to friends and enemies alike, but I gladly answer to David or most any other handle. I am an unabashed and biased fan of Leo, the fact that it was written by my brother Edward only slightly coloring my already colored glasses. I have been testing and using Leo in software production for over 4 years. My company currently has over 50,000 lines of code in over 100 source files that are written using Leo.

My comments are from two points of view, the first being software project manager for a complicated, multi-module software product, and the second being as a production line coder. For me, Leo’s greatest and only real drawback is the learning curve. This learning curve can be shallow is if all that is required is that someone code using Leo. However, in our company we allocate 40 to 80 hours _on top_ of the normal coding load for someone to come up to speed on Leo. The ROI (return on investment) is calculated by me to be on the order of 3 months. So if I hire a consultant for less than 3 months, I don’t teach him Leo, even though all source code in our company must reside in Leo files for the reasons I won’t go into now.

I consider that my coders are 15 to 30 percent more efficient in their daily operations than my competition’s people. This indefensible claim of mine is based on the changes in my productivity as Leo grew from a test document production tool to the primary production method for all our assembly, c and cpp source code.

Personally, I hate to deal with documentation when I write code, except: 1) When I am first sitting down to solve a new problem. Then the documentation becomes quite long-winded and pontificatory, as if I were the only one on earth smart enough to solve the problem - or 2) When I come back to code I or someone else has written and find the documentation insufficient to understand the code without study (seems to be most of the time).

So I do not require my engineers or myself to do a great job of documentation, nor do I use Leo for that purpose. Rather, it is Leo’s outlining and organizing ability, and Leo’s ability to create source files from within the outline that give me what I think is a tremendous competitive advantage. Each of my company’s products run on all versions of windows from Win 3.1 to XP. In our flagship software piece, there are ten main modules, and each module is maintained by one single Leo file. In the CODEC module, one Leo file named compress.leo organizes and creates seven .asm files, forty-four .c files, twenty .h files, two .def files, four .mak files, etc. etc. etc. This one file can be checked out from source code control and given to an engineer for the addition of a new feature.

In it are contained all the known issues for the CODEC, each issue arranged in its own clone section. One clone section groups together every routine, variable or type definition that must change between different versions of Windows. These sections could be from six different c source files, two assembly files, and eight .h files. Another clone section groups together those sections relating to memory problems, which change according to the memory configuration and TSR configuration (or lack thereof) on the target machine. Another clone section groups sections that fail (or don’t fail) if the routine in question was accidentally run during the dreaded ‘interrupt time’. Another clone section is a section containing clones, each of which is named after the major bug that was fixed when the engineer who fixed the bug grouped a bunch of routines, definitions, etc. together to fix the bug.

None of the above clone sections was ‘designed’ into the document. Just the opposite happens. When the codec was first written, there was just a single Leo file with a bunch of sections for each c routine or assembly module. As the product grew and was tested on various platforms, each failure of the module was organized into clones each time a failure was fixed. This is what I call “SELF DOCUMENTING CODE”. This has nothing to do with me sitting and documenting anything. Its just that the STRUCTURE of a bug fix (or product enhancement) lives on long after the coding is done, as long as no one is foolish enough to delete the cloned sections that ‘DOCUMENT’ what happened.

In actual practice, this organizational ‘history’ is so powerful that I can’t begin to describe it. A ‘REVERSE LEARNING CURVE’ happens when an engineer gets a Leo file that already has the ‘interrupt time sensitive’ routines grouped together by the last unfortunate soul who had to work on them. There may not be any more written documentation, but the knowledge contained in the structure can be breathtaking. It is certainly timesaving. I find this particularly true in my own case. Often I’ll look at some code that seems totally unfamiliar and think ‘what idiot wrote this crap’. Then I’ll look at the version control comments and realize that I wrote the crap. Then for sure I know the documentation is non-existent, but the clones I used to develop it are still there, and they always serve to refresh my memory in an indescribable way.

Enough of this commentary, I just looked at the clock. Best wishes to anyone willing to try Leo for a week. I hope you will be glad you did.</t>
<t tx="edream.110203163054.15">By David McNab:

(Ed, don't read this - go away) 

Does anyone know of any Open Source developer awards that accept public nominations? 

I feel strongly that Ed Ream, our ever-patient, ever-productive Leo architect deserves a nomination. 

Amongst other reasons, for: 
* Delivering the first usable visual literate programming tool. 
* Adding a vast abundance of new features. 
* Making possible a previously unimaginable amount of leverage in code editing.
* Eliminating vast amounts of menial programming labour.
* Tirelessly and patiently supporting users, and catering to a wide range of feature requests.

By Gil Shwartz:

I do not know of such award, but I will definitely back the nomination. Leo is unimaginably useful and I always find new things it already knows(!) how to do. Indeed I am amazed by the never-ending resources and patience Edward is putting into it and its users community. Excellent.</t>
<t tx="edream.110203163054.16">Leo is an interactive editor for organizing text fragments hierarchically and sequentially into one or more files and hierarchical folders, without arbitrary limits on the number and size of text fragments and the depth of the hierarchy.

Tangle is a tool for combining hierarchically and sequentially organized text fragments into text files, hierarchically grouped into folders, with hierarchical or sequential organization of text within the files, and without arbitrary limits on the size and number of files and the depth of the hierarchy of folders and text nesting within the files.</t>
<t tx="edream.110203163054.17">Leo is EXACTLY the kind of outliner I was looking for--fantastic job!</t>
<t tx="edream.110203163054.18">I am a huge fan of Leo. I think it's quite possibly the most revolutionary programming tool I have ever used and it (along with the Python language) has utterly changed my view of programming (indeed of writing) forever.</t>
<t tx="edream.110203163054.19">Just a quick note to thank you for your work on Leo. It is a really nice piece of work!

It makes "literate programming" much easier. [I've been playing around from time to time, but it was tedious, so I continued with my usual way of working.]

Again, this is a great tool!
</t>
<t tx="edream.110203163054.20">I want first to thank you for Leo. This is a very useful and interesting tool. </t>
<t tx="edream.110203163054.21">Thank you very much for leo. I think my way of working with data will change forever.

I have just tried leo for 2-3 days, yet I am certain this will be a revolution. The revolution is as important as the change from sequencial linear organization of a book into a web-like hyperlinked pages.

The main concept that impress me is that the source listing isn't the main focus any more. You focus on the "non-linear", hierarchical, collapsible outline of the source code. </t>
<t tx="edream.110203163054.22">Leo is amazingly stable. Docs are often weak with Open Source Software. Not so
Leo: Leo is unusually well documented.

I gave Leo a try a while ago, but did not recognize its strengths as an
outliner. In April 2003 a gave it another try. And when I saw in the online
help mentiontioning clones almost in passing (you got to emphasis this much
more!), I knew: This is it.

If you are like me, you have a kind of knowledge base with infos gathered over
time. And you have projects, where you use some of those infos. Now, with
conventional outliners you begin to double these infos, because you want to
have the infos needed for the project with your project. With Leo you can do
this too, but if you change text in one place IT IS UPDATED IN THE OTHER PLACE
TOO! This is a feature I did not see with any other outliner (and I tried a
few). Amazing! Leo directly supports the way I work!

And when I saw, how easily I can script it with one of my favorite
programming languages (i.e. Python), I fell in love with Leo. Sounds silly,
perhaps. But with a script written and tested in about 20 minutes I extract
time expenses out of my diaries as easily as it can be. Yet I did not
discover all of Leo, but if there's anything Leo cannot do yet, I'm pretty
sure that I can script it.

Not yet convinced? Then think of this final but VERY IMPORTANT point: With Leo
YOUR DATA ARE YOURS! Leo is Open Source, Leo is written in Python, thus Leo is
platform-independent, Leo stores your infos in ASCII format (XML). This means,
that you are not locked into a company if you use Leo. YOUR DATA ARE YOURS!
Think of this if you again are working with your favorite PIM.

Edward, keep up this extraordinary good work!

fgeiger@datec.at
</t>
<t tx="edream.110203163054.23">I have been playing around with Leo and am really very impressed! It should either replace or greatly augment the development tools that I use."</t>
<t tx="edream.110203163054.24">I must say I am very impressed. I have been absolutely seduced by Leo over the
past few days. I tell you, I can not put it down. I feel like a kid with a
shiny new bike. Hopefully I can get you guys some code one of these days. I'm
already bursting with new ways I'd like to use the tool in the future.
</t>
<t tx="edream.110203163054.25">I've tried Literate Programming tools off and on for more than 10 years, mainly because the promise was so great.  I've abandoned them every time because working with the various CWeb-like tools was so awkward.

Leo changes all that.  The most important benefits promised by Literate Programming are realized by using Leo, without the awkwardness of the other tools.
</t>
<t tx="edream.110203163054.26">When first I opened Leo, it was out of curiosity.  But having used it...

I'LL NEVER GO BACK.
THEY'LL HAVE TO PRY LEO OUT OF MY COLD, DEAD FINGERS!

Seriously, it should be renamed "Crack Cocaine" because it's that addictive.
I'm ready to start a 12-Step group.
</t>
<t tx="edream.110203163054.27">I wanted to thank you for the effort you've put into Leo.  It looks fantastic.  I've always though that Literate Programming was a good idea, but the tools were completely un-workable. </t>
<t tx="edream.110203163054.28">I was turned on too a very cool tool written in Python. Leo is a marrage of outlining and literate programming. Pure genious. The main reason I am impressed with this tool is that it doesn't affect your choice of tools. You can use whatever IDE for whatever language and switch back and forth between leo and it. </t>
<t tx="edream.110203163054.29">And yes, I've been using Leo a few hours every day for more than a week, now. :^) Actually, it's become my main development platform, and I do this for a living. </t>
<t tx="edream.110203163054.30">&lt;tomlee@bigpond.net.au&gt;

I came across Leo the other day while reading through Dr. Dobbs' Journal,
and after all of five minutes I must say I'm absolutely astounded by the
power of such a simple idea! It works great and I can immediately see the
benefits of using Leo in place of the standard flat file editor.

I know this is short and sweet, but thanks very much for such an interesting
piece of software.
</t>
<t tx="edream.110203163054.31">Cloning is pure genius! I'm studying for the Chartered Financial Analyst exams, and I use Leo to take notes on the voluminous course material. Along the way, I'm developing little utility functions in the array programming language J (http://www.jsoftware.com) for working the examples and the exercises in the textbooks. J is vanishingly terse, so the literate programming facilities in Leo aid comprehension of code immensely. Even more useful than the traditional lit prog for my purpose, though, is Leo's cloning facility, which allows me to create several views on the CFA course material. My main view follows the prescribed study guide. Another view is organized like the textbooks. Yet another gives me a glossary of terms. And when I'm done, I'll have some nice libraries of J functions that I can re-use later in other projects. Also, a little exporting from Leo and post-processing with noweave should give me some printable docs.

Thanks for hunting down these bugs, and thanks for producing such a cool tool. Wanting to customize and script Leo has me itching to dust the Python books off this weekend.
</t>
<t tx="edream.110203163054.32">I just discovred Leo today. I am one of the many droves of people that came stampeeding by due to you being Slashdotted. I will say that I am extemely impressed at how stable and useful Leo appears to be. As soon as I ran though the slide presentations of how Leo works, it struck me that I have always been looking for this in an editor.

I am very impressed that you developed this app single handedly. It looks like a very impressive piece of work.
</t>
<t tx="edream.110203163054.33">Hey, Edward, please bear with us. I know you're overwhelmed, but you've come up with perhaps the most powerful new concept in code manipulation since VI and Emacs.

I'm blown away with how Leo can slice'n'dice C and Python files into their component parts.

Leo absolutely ROCKS! :) It's exactly the tool I've been wanting for years but have never got around to writing. 

One thing I really like is the ability to create functions in any order I please, and not think about what files to put them into till later. This ability alone has freed up a lot of my thought processes with coding.

---

For me, I'm so grateful I saw the Leo write-up on Slashdot, otherwise I would
probably never have come into contact with it.

A funny observation with Leo is that when I 'Leo-ise' other people's code, Leo
makes the code's structure so transparent that design faults become very quickly
apparent - eg maintenance pain caused by lack of factorisation.

Thanks again for a wonderful (I won't say 'editor' because the word doesn't
do Leo justice) code structuring system.
</t>
<t tx="edream.110203163054.34">We who use Leo know that it is a breakthrough tool and a whole new way of writing code.

Leo is a powerful tool for organizing text into tree structures, and for just generally attacking a number of problems from a tree-based perspective.

&lt;opinion&gt;
There has been a lot of hype about XML and all the uses to which it can be put. But, to my mind, the greatest benefit of XML is that it allows people to easily work with tree structures. All the benefits of XML really flow from that. Leo is the best application I've seen for conceiving and planning the trees that are then put into action via various XML technologies.
&lt;/opinion&gt;"

Outlining Editors have existed for a while (e.g. PC-Outline, MORE) but Leo takes a major leap beyond previous tools for three reasons:

1. You can embed a simple macro language inside of a Leo document to instruct Leo to assemble pieces of the Leo document into another file. This facilitates, among other things, one type of Literate Programming.

2. Leo saves its files in XML format. This means that you can easily import and export Leo documents to any number of programs that can understand XML. For example, you can use an XSLT stylesheet to export a Leo file to HTML. And you can import any XML file into Leo using another XSLT stylesheet.

3. Leo is fully scriptable via Python."</t>
<t tx="edream.110203163054.35">The Word outlines are very useful. But Leo makes Word look like a clunky toy.

#1 Reason would probably be clone nodes. One node can point to another. Another
way of putting this is is that a leaf can be on more than one tree. For
example, suppose you have a list of recipes. You simultaneously put a single
recipe under multiple categories or even multiple hierarchies. You could put "3
bean enchilada" simultaneously under Recipes-Mexican and Food-Gas. Another
example would be, if you are a biologist trying to decide under which genus to
put a new species, you could put the species under two simultaneously. In
effect, you can build a 3-D tree. For a further illustration see
http://www.3dtree.com/ev/e/sbooks/leo/sbframetoc_ie.htm

#2 Reason would probably be that Leo outlines can be embedded in external text
files. So, a Leo outline is more than an outline, it is a meta-structure that
can be added to another text without changing that text, but rather providing
an external roadmap to the text. Microsoft Word has a text (xml) version with a
commenting convention, so Leo can even be used to add outlines into Word docs,
altho it isn't set up to do that now. For example, see
http://www.3dtree.com/ev/e/sbooks/leo/sbframetoc_ie.htm In this case, the upper
window of Leo is the metastructure, and the bottom window is the file to which
the metastructure is being applied, viewed one node at a time.

I may not have made #2 very clear, but it is actually a very useful feature. It
takes some getting used to before one sees all of the possibilities tho. One
way to think of it is that Leo allows you to throw external documents into your
outline, and yet the external document remains independent and can still be
edited separately.

Some other cool things about Leo which Word doesn't feature:
1. Pure xml output that is easy to transform into other formats (next
version of Word will have true XML format, but not as easy to work with).
One consequence of this is that Leo files can be transformed pretty easily
to web pages with their outlining capability intact.
2. Easy to add features since is programmed in Tkl and open source. Maybe
your average user can't start hacking on it, but a surprising amount can be
tacked on by flipping thru the Tkl manual.
3. Free, opensource, multiplatform
4. Leo is scriptable with Python. It should be possible to build a Tickler
into Leo using Python scripting, for example.</t>
<t tx="edream.110203163054.36">@nocolor

I only have one week of Leo experience but I already know it will be my default
IDE/project manager.  I have seen several old threads on c.l.python  where people
complain about the lack of a project manager for the free/standard Python IDE's
like Idle.  Leo clearly solves that problem and in a way that commercial tools
can't touch.  I suggest we reply to future such postings with that gentle nudge.
</t>
<t tx="edream.110203163054.37">Hi, I have been interested in creation of a heirarchal text-editor for a while and I just came across Leo, which I found to be almost exactly what I had in mind, which is fantastic because I don't have to code anything!</t>
<t tx="edream.110203163054.38">I am an amateur photographer. I use plain old 35mm. film for my pictures. Over the weekend, I used LEO to organize my lists of pictures. It is quite helpful -- I can have separate nodes for pictures I have enlarged, as well as pictures I have submitted to our local camera club. Thanks!</t>
<t tx="edream.110203163054.39">Just as structured programming reveals and disciplines the flow control of a program, [Leo] allows the designer to reveal and discipline structure at many layers simultaneously: data structures, object structure, entity-relationship structure, client-server structure, design pattern structure, temporal structure, project management structure, and any other structure relevant to the system. </t>
<t tx="edream.110203163054.40">LEO reminds me a great deal of things I loved when I used Userland's Frontier
(an outlining CMS with a native OODB) - but Frontier wasn't hackable enough
for me,  and it wasn't oriented towards coding and literate programming, and
you couldn't round-trip rendered pages (big LEO win).  This is really a super
tool - in a matter of days I've started to use it on all my projects and I still
haven't figured out how I lived without it.

Thanks again.
</t>
<t tx="edream.110203163054.41">Leo is a very good concept and is a revolutionary step in the right direction for programming. I appreciate your work. </t>
<t tx="edream.110203163054.42">Leo files are so wonderful at organizing information, it'd be powerful if we could share them on the web with minimal effort.

A Leo file is an ideal documentation tool, collecting the assorted readme.txt files, the comments from the source files...as well as the config files themselves.</t>
<t tx="edream.110203163054.43">I have been using Leo for about 3 weeks and I hardly use my other programming editor anymore...I find it easy and enjoyable to use. I plan to adopt it as my presentation tool for code reviews.
</t>
<t tx="edream.110203163054.44">First of all, kudos to you for the excellent progress you've been making with Leo.  I upgraded today after about three months of using and older version and I was thrilled to see all the great improvements that have happened so fast.  I especially love the ability to go to next clone.  I think you're really showing what open source can do and your current trajectory puts you on track to kick Emacs into the dustbin of computing history.

So today I copied all my data (personal information manager and project management stuff) out of my old outliner (ThoughtManager, which synchs with and runs on the Palm) and put it into Leo.  It took me hours to do it and then to rearrange it the way I really wanted it.  But having the ability to make clones and have different ways to view my data is, as you know, fabulous.  In my case, for personal information and project management things, I used the flexibility of clones to allow me to see my data in several different views: 1) by project, the logical hierarchical breakdown by topic, 2) by person, so whenever I'm talking to someone I can easily see all the pending items related to them which may be spread over multiple projects, 3) by priority, so I can see what needs to get done sooner and what can wait for later and, 4) a special case of priority called "Today" for the things I'm going to focus on in the coming hours.

Now here's why I don't miss the ability of my old outliner to synch the entire outline with the Palm.  It turns out the main thing I really want in the Palm is the top category "Today" so all I have to do is have Leo flatten that one heading into a text file (and it kindly remembers the name and directory of the file I used last time) and then I'm done because I've told the Palm Hotsync manager that that file should be sent to Palm memo pad every time I synch.  The Palm Hotsync manager does a nice job of sending a text file to the Palm memo pad and even breaks the file up into multiple memo records if it's too big to fit in just one.  So that gives me enough to be able to browse (or full text search) the small amount of data that I really want right inside my Palm (which is also my cell phone).  Quick and dirty but it works.

For times when I want my whole outline with me, Leo wins again because thanks to its cross platform nature I can take my whole outline with me on my Mac iBook, even though I usually edit it on a Windows PC (which is the only kind of machine my old outliner would run on).  Quite frankly, although my old outliner was able to shoehorn the whole thing into my palm/cellphone, it was a pain to access it on the small screen and slow processor.  Now when I anticipate I'll need the whole thing, for example when I'm going to a meeting, I can put it on my Mac iBook (under X and Fink for now until Python can do it native under Aqua) and have real, full access to it all.

I think now in addition to being great for programming Leo is also a great PIM.  Being able to flatten a strategically chosen portion of the outline into a known file name that the Palm synch manager has been told to send to the Palm on every synch does the trick for me.  I wonder if you would consider something like an @flatten directive so I can have that done automatically for me every time I save my outline?  For now it's up to me to flatten the node I want manually, although once I've done that the transfer to the Palm is automatic.

You're my hero!  Thank you so much.

-- Dan

-----

Another day, another breakthrough using Leo -- now I realize Leo is the 
best URL bookmark manager there is.  No more bookmarks menus or 
favorites lists inside the browser for me.  With the @url directive I 
can just double click on the URL to open it in my browser.  Leo lets me 
arrange the URLs in a hierarchy (or multiple hierarchies), attach notes 
to them, save clippings of things I read on the sites.  It's sooo much 
better than anything the browsers have built in and it lets me easily 
use different browsers on different platforms and different machines 
(try that with the browsers' built-in bookmark managers).  

When using Leo as a project manager and personal information manager as 
I do I can heavily annotate every task and project with helpful and 
relevant URLs.  And since URLs can be of the file:// form, they're not 
just for web pages or HTML documents;  I can link to any file on my disk 
of any type to be opened by any program.

Leo is a quantum leap for me in terms of how many projects I can manage 
and how much information I can find and organize and store in a useful 
way.  I'm a data-mining army of one now and the web is my playground. 
 Every time I find a web page that has interesting links to others, 
those links get stored in my Leo outline too, right where I can find 
them and make practical use of them.  I can easily accept dozens of 
valuable links every day and integrate them into what I'm doing in a way 
that I'm confidant they won't get lost or forgotten.  Before I always 
used to get bogged down by the difficulty of managing bookmarks inside 
the browser.  But now I'm no longer the victim of information overload 
buried in the knowledge landslide of the Internet;  instead I'm the 
professional strip miner with the world's biggest bulldozer.  I eagerly 
plunge into mountains of data and emerge with all the valuable 
information nuggets neatly stored and organized.  And my storehouse of 
knowledge is a flexible thing where I can reorganize and prioritize and 
massage the data to my heart's content as I learn more about it and 
decide to use it in different ways for different purposes.  It's the 
difference between the pick axe and the steam shovel for me.
</t>
<t tx="edream.110203163054.45">I found this blog entry by someone (a talented former coworker of mine
actually) complaining about some poorly written code she had to maintain:

http://www.ceejbot.com/blog/space/2003-01-29#the_news_at_10

She said: "You'd need a bulldozer to start refactoring it. " That was my cue to
write a long message explaining that there is indeed such a bulldozer and it's
called Leo. (You can see my message there as a reply to her original posting.)
I gave her my recipe for how to get someone else's messy, scary code into Leo
and how to break it down into manageable chunks.
</t>
<t tx="edream.110203163054.46">@nocolor</t>
<t tx="edream.110203163054.47">Please be aware of the following problems with leo:

1. leo.py v3.0 and Borland v2.6 create derived files that can not be read by older versions of Leo!  leo.py v2.0 and Borland v2.6 can read all previous derived files.

2. Leo will report read errors when opening a .leo file that is not "in synch" with derived files.  This can happen when opening a backup copy of a .leo file.  When such errors happen you have two choice:

Choice 1: Use the "Read Outline Only" command to recover the outline using only the .leo file.  This is the recommend way because it preserves all clone links.

Choice 2: Use one or move "Read @file Nodes" commands to update the outline from derived files.  This way is will break any clone links from the outline into the </t>
<t tx="edream.110203163054.48">This node duplicates the information in Chapter 2: Installing Leo.

New in version 4.1:  The first time you start Leo, Leo will ask you for a unique identifier.  If you are using cvs, use your cvs login name.  Otherwise your initials will do.

Leo stores this identifier in leoID.txt, so you can change this identifier at any time by changing leoID.txt.</t>
<t tx="edream.110203163054.49">leo.py is Leo2 written in Python and Tk.  It should work on any platform that supports Python 2.2 or later and Tk 8.3 or later.

Download Python from http://python.org/
Download tcl/Tk from http://tcl.activestate.com/software/tcltk/

See "How to install Leo on MacOS Panther (10.3)" for installation instructions for MacOs X.  Leo will not run on MacOs 9.</t>
<t tx="edream.110203163054.50">@nocolor

leo.py requires Python 2.1 and tcl/tk 8.3 or above.

	Download Python from http://python.org/ 
	Download tcl/Tk from http://tcl.activestate.com/software/tcltk/
	
Warning: When building Tcl on Linux, do not specify "--enable-threads" .. only use Tcl
with the default "threads not enabled" case.

Leo is distributed as a single compressed folder.  Simply uncompress this folder and run leo.py.  You can run leo.py by double-clicking leo.py.  You can also run leo.py from a Python interpreter as follows:

@color

	import leo
	leo.run() # runs leo.py, opening a new outline.
	leo.go() # runs leo.py after reloading all modules.
	leo.leoOpen(fileName) # runs leo.py, reloads all modules, and opens fileName.
	
@nocolor

On Linux, the following shell script will allow you to open foo.leo files by typing leo foo

#!/bin/sh 
python &lt;leopath&gt;/leo.py $1

where &lt;leopath&gt; is replaced with the path to the leo directory. </t>
<t tx="edream.110203163054.51">@nocolor

leo.py requires Python 2.1 and tcl/tk 8.3 or above.

	Download Python from http://python.org/ 
	Download tcl/Tk from http://tcl.activestate.com/software/tcltk/

Leo is distributed as a single compressed folder.  Simply uncompress this folder and run leo.py.  You can run leo.py by double-clicking leo.py.  You can also run leo.py from a Python interpreter as follows:

@color

	import leo
	leo.run() # runs leo.py, opening a new outline.
	leo.go() # runs leo.py after reloading all modules.
	leo.leoOpen(fileName) # runs leo.py, reloads all modules, and opens fileName.
	
@nocolor

Another way to open files would be to create a batch file.  On Windows, I put the following .bat file in c:\Windows

cd c:\prog\LeoCVS\leo
c:\python22\python c:\prog\LeoCVS\leo\leo.py %1

This opens the file specified by the first argument (%1).</t>
<t tx="edream.110203163054.59">The Icons folder contains two Icons, called LeoApp and LeoDoc, that represent the Leo application and Leo documents respectively.

In Windows, to associate LeoDoc with .leo files, open the Setting:Folder Options:File Type panel, create an entry for .leo files.  Then choose Change Icon and select the LeoDoc icon.  Associate leo.py as the application to open .leo files.</t>
<t tx="edream.110203163054.60">leo.py 2.4 and above will open .leo files automatically provided that you associate leo.py with .leo files.  Here is how to open leo.py when double-clicking a .leo file on Windows 2K or XP.  I'm not sure it will work for Windows 95/98/Me.

In Windows 2K or XP, Go to Start-&gt;Settings-&gt;Control panel, open the "Folder Options" applet.
Select the "file types" tab from the Folder Options window. Press the "new" button.
Enter LEO into the "Create New Extension" File Extension text field. Press OK.

With LEO still highlighted in the Registered File Types list box, press the Advanced button.
Change the default file type field to something like "Leo Literate Outline".
Press the Icon button and browse to the LeoDoc icon in your [leo install dir]\leo-2.3\Icons folder.
Click OK. This gets the icons right and registers the description of the .leo file.

You now have to tell windows what to do to open the file properly.
Press the new button to open the "New Action" window.
In the Action field type Open.
In the "Action used to perform action" type _one_ of the following lines:

[python install dir]\pythonw.exe   [leo install dir]\leo.py %1
[python install dir]\python.exe -i [leo install dir]\leo.py %1

The first  line opens Leo files with no console window.
The second line opens Leo files with a console window and leaves the window open after Leo exits.

You should now be able to double click on a leo file in explorer with leo.py.</t>
<t tx="edream.110203163054.61">New in Leo 4.0 and Python 2.3: Leo will draw a Leo icon in all Leo windows.  There is no need to install PIL or tkIcon.

Otherwise (for versions of Leo before 4.0 and for versions of Python before 2.3) Leo will draw a Leo icon in Leo windows only if you have installed Fredrik Lundh's PIL and tkIcon packages.

Download PIL from http://www.pythonware.com/downloads/index.htm#pil
Download tkIcon from http://www.effbot.org/downloads/#tkIcon

Many thanks to Jonathan M. Gilligan for suggesting this code.</t>
<t tx="edream.110203163054.62">@nocolor

Quick start

This is the minimum you need to use Leo effectively.

1. Write body text using the noweb languages. See Using noweb, CWEB and Directives.

2. Create source files (derived files) using the Tangle command. Only @root directives under the currently selected headline are tangled by the Tangle command. Warning: The Tangle command will overwrite files specified in @root directives if they exist.

3. Use the Untangle command to propagate changes made to derived files back into the outline Untangle is useful only for making small syntactic changes. Don't attempt to change the structure of an outline by modifying derived files; it won't work.

4. Many command key abbreviations are specified in the Syntax Coloring panel.

See the Appendices for a concise summary of information about Leo.</t>
<t tx="edream.110203163054.63"></t>
<t tx="edream.110203163054.64">Leo 4.1 alpha 1                   November 3, 2003

*** Alpha quality code:  Please make full backups before playing with this code!

This release marks another significant milestone in Leo's history:

- Leo's 4.x file code is complete.  At present I have no plans to change the format of .leo files or derived files.  I am eating my own dog food: I do all my editing with the 4.1 code base.

- Leo uses immutable gnx's (id:timestamp:n) by default to associate tnodes with vnodes in .leo files.  This makes Leo as cvs friendly as possible.  From now on .leo files will be checked in to cvs with the -ko (text/keywords off) option.

- The use_gnx setting in leoConfig.txt determines whether uses gnx's (cvs friendly) or ints.  No version of Leo before 4.1 can read .leo files containing gnx.   Only gnx's are immutable.  Leo recomputes all non-gnx indices from scratch whenever writing a .leo file. It is possible to convert between 3.x and 4.1 file formats by changing the use_gnx setting.

- The 4.1 code base has been reorganized to support gui's other than tkinter.  Leo's src directory contains several new source files.

- The file test.leo in the test directory contains real regression tests for syntax coloring.   Regression testing scripts create regression tests dynamically from data in Leo's outline.  Very cool, very easy, very general.  In particular, regression tests may use temporary nodes in test.leo rather than creating separate Tk windows for testing.

Known bugs:

- The Extract commands eat one character too much.

- The __wx_gui.py plugin is only partly functional.</t>
<t tx="edream.110203163054.66">Leo 4.0.4                         October 29, 2003

- Fixed a problem with the titles in Font and Color panels.
- Worked around a Unicode assert failure in the colorizer.
- Fixed crasher in OnEndEditHeadline.
- Fixed import problems in leoPlugins.leo.
- @first and @last sentinels no longer contain corresponding text.
  This fixes a problem that affected PHP comment delimiters.

Leo 4.0.3                         October 25, 2003

- Fixes several problems with the auto_save and plugin menu plugins.
- Fixes a problem with the Go To Line Number command.

Note: This version does _not_ support Unicode file names or directory names.

Leo 4.0.2                         October 23, 2003

- Fixes a crasher in reportBadChars when a .leo file contains a character that
  can not be represented in the encoding specified in the first line of the
  .leo file.
- Leo now sends full tracebacks to the log window when Leo takes an unexpected
 exception.
- Leo now issues a more informative message when the @comment directive
  inhibits the Untangle command.

Leo 4.0.1                         October 22, 2003

- Fixes several crashers, one of which may prevent Leo from starting.
- Fixes indentation for section references that are preceded by something
  other than whitespace.
- Removes debugging traces when reading and writing unknown attributes.
- Removes some improperly cloned nodes from LeoDocs.leo.
- Adds the checkTopologyOfAllClones script.
- Fixes some problems with plugins.</t>
<t tx="edream.110203163054.67">Leo 4.0 final                     October 17, 2003

More than a year in the making, Leo 4.0 is finally here.

Highlights of 4.0 final:
-----------------------

** Improved and simplified format of derived files.
	- Eliminated child indices, extraneous blank lines and @body sentinels.
	- Eliminated @node sentinels that indicate outline structure.
	- New @nl and @nonl sentinels indicate where newlines are and aren't.
	- These changes will largely eliminate unwanted cvs conflicts.

** Greatly improved error handling.
	- Reading derived files _never_ alter outline structure or links.
	- Read errors leave the outline completely unchanged.
	- Broken clone links are gone forever.
	- As a result, 4.0 is much safer than all previous versions.

** Full compatibility will previous versions of Leo.
	- Leo 4.0 reads all derived files properly, regardless of version.
	- Leo writes new-format derived files by default, and this default may be changed.
	- New commands in the read/write menu allow you to explicitly specify the format of derived files.

* New commands:
	- Write 3.x Derived File and Write 4.x Derived File.
	- Import Derived File.
	- Clear Recent Files.

* Dozens of other improvements, including:
	- Better Unicode support.
	- New configuration settings.
	- Several new plugins.

See the notes for the various beta releases for full details.</t>
<t tx="edream.110203163054.68">Leo 4.0 beta 4                      October 13, 2003

This is the third public release of Leo 4.0. There are no known serious bugs in
this version of Leo.  This will be the last beta release before 4.0 final.

Changes made in 4.0 beta 4
--------------------------

- Changed all instances of string.letters to string.ascii_letters.
  string.letters can cause crashes in some locales (Unicode environments).
- Fixed several bugs that caused clone marks not to be set properly.</t>
<t tx="edream.110203163054.69">Leo 4.0 beta 3                      October 9, 2003

This is the third public release of Leo 4.0. There are no known serious bugs in
this version of Leo.

Highlights of 4.0 beta 3
------------------------

- Fixed problems with setting Leo's window icons.
- Plugins may now save their own information in &lt;v&gt; and &lt;t&gt; elements in .leo files.
- The usual assortment of bug fixes and minor improvements.

See the children of this node for full details.</t>
<t tx="edream.110203163054.70"></t>
<t tx="edream.110203163054.71">This was a long-standing bug.  It's effect was cosmetic, and it was important to fix.</t>
<t tx="edream.110203163054.72"></t>
<t tx="edream.110203163054.73">This could happen when the derived file was corrupted.</t>
<t tx="edream.110203163054.74"></t>
<t tx="edream.110203163054.75"></t>
<t tx="edream.110203163054.76">Leo can now read and write "foreign" attributes in &lt;v&gt; and &lt;t&gt; elements in .leo files:

- When reading a .leo file, Leo will create t.unknownAttributes or v.unknownAttributes ivars for any tnode and vnode object whose corresponding &lt;v&gt; or &lt;t&gt; element in the .leo file contains a foreign attribute.

- The unknownAttributes ivars are a dictionary whose keys are the attribute names and whose values are strings.

- When writing a file, Leo will write "foreign" attributes if  a vnode or tnode contains an unknownAttributes ivar.

- The only "native" attributes that Leo expects to find are the "tx" attribute in &lt;t&gt; elements and the "a", "t", "vtag" and "tnodeList" attributes of &lt;v&gt; elements.  Everything else is a foreign attribute.

- Leo performs the usual xml escapes on these strings when reading or writing the unknownAttributes ivars.

Plugins may cause Leo to write such foreign attributes simply by attaching unknownAttributes ivars to a vnode or tnode.  For example:

	v.unknownAttributes = {"vnodeIcon" : pathToIcon}

It would be best not to delete other foreign attributes, so the following would be preferred:

	if hasattr(v,"unknownAttributes"):
		v.unknownAttributes["vnodeIcon"] = pathToIcon
	else:
		v.unknownAttributes = {"vnodeIcon" : pathToIcon}

Another way:

	try:
		v.unknownAttributes["vnodeIcon"] = pathToIcon
	except AttributeError:
		v.unknownAttributes = {"vnodeIcon" : pathToIcon}</t>
<t tx="edream.110203163054.77"></t>
<t tx="edream.110203163054.78">Leo now warns if it can't find either the Icons directory or the LeoApp16.ico icon in that directory.</t>
<t tx="edream.110203163054.79">Leo 4.0 beta 2                      October 3, 2003

This is the second public release of Leo 4.0. There are no known serious bugs
in this version of Leo. Version 4.0 is the culmination of over a year of
collaborative design work and several months of actual implementation.

Highlights of 4.0 beta 2
------------------------
* Fixed several bugs:
  - Fixed several problems with reading and writing 4.0 derived files.
  - Fixed several Unicode-related bugs.
  - Fixed a crasher in the Go To Line Number command.
  - Fixed a problem with Importing Python files.
* Important improvements:
  - Added allow_clone_drags setting.  N.B. Allows Leo to be used with Aqua.
  - When running Python 2.3 Leo can now create window icons without third-party packages.
- The usual minor improvements and bug fixes.

See the children of this node for full details.

Highlights of 4.0 beta 1
------------------------
* Improved and simplified format of derived files.
* Greatly improved error handling.
* Full compatibility will previous versions of Leo.</t>
<t tx="edream.110203163054.80">- Fix undo/redo bug for all commands that change body text in multiple nodes without changing outline structure.
	- This is a long-standing bug that came to light when trying to make Read @file Nodes undoable.

- Make Read @file Nodes command undoable.

- Fix small bugs in the Go To Line Number command.</t>
<t tx="edream.110203163054.81"></t>
<t tx="edream.110203163054.82">The new code prints a warning if Leo's key internal strings are not Unicode.</t>
<t tx="edream.110203163054.83"></t>
<t tx="edream.110203163054.84">There were bugs involving saving the "Pattern Match" and "Subroutine Only" find settings.</t>
<t tx="edream.110203163054.85">@nocolor

Class level-code after the method definitions was dropped.  For example:

@color

class someclass:
	def __init__(self):
		pass

	# this code is dropped
	class_var = None

def some_proc():
	pass</t>
<t tx="edream.110203163054.86">The new code ensures that Leo creates and uses only Unicode strings internally.</t>
<t tx="edream.110203163054.87">Fixed Go To Outline command so it doesn't crash on 4.0 files.  More work is needed.</t>
<t tx="edream.110203163054.88">Under certain conditions the no sentinels at all were written when writing @rawfile trees.</t>
<t tx="edream.110203163054.89"></t>
<t tx="edream.110203163054.90"></t>
<t tx="edream.110203163054.91">This is much more natural and less cluttered.</t>
<t tx="edream.110203163054.92"></t>
<t tx="edream.110203163054.93"></t>
<t tx="edream.110203163054.94">Leo will create the Leo icon in Leo windows automatically when using Python 2.3.  The Python Imaging Library and the tkIcon package are only used when using previous versions of Python.</t>
<t tx="edream.110203163054.95">This is the foundation for "foreign" guis.</t>
<t tx="edream.110203163054.96"></t>
<t tx="edream.110203163054.97">allow_clone_drags

This is a workaround so that Leo may be used on Aqua.  When this setting is zero Leo always moves nodes when dragging.  The default is to enable clone-drags.

enable_drag_messages

Allows the user to suppress the message telling whether dragging nodes will move them or clone them.  The default is to enable those messages.</t>
<t tx="edream.110203163054.98">After the 4.0 beta 1 release I changed the default so that _new_ format derived files are written if leoConfig.txt does not exist.</t>
<t tx="edream.110203163054.99">leo.py 4.0 beta 1                      September 26, 2003

This is the first public release of Leo 4.0.  Version 4.0 is the culmination of over a year of collaborative design work and several months of actual implementation.

Please use caution when using this beta version of Leo.  It appears very solid and it has been tested by only a few people.

Highlights of 4.0:

** Improved and simplified format of derived files.
	- Eliminated child indices, extraneous blank lines and @body sentinels.
	- Eliminated @node sentinels that indicate outline structure.
	- New @nl and @nonl sentinels indicate where newlines are and aren't.
	- These changes will largely eliminate unwanted cvs conflicts.

** Greatly improved error handling.
	- Reading derived files _never_ alter outline structure or links.
	- Read errors leave the outline completely unchanged.
	- Broken clone links are gone forever.
	- As a result, using 4.0 is much safer than all previous versions.

** Full compatibility will previous versions of Leo.
	- Leo reads all derived files properly, regardless of version.
	- Leo writes new-format derived files by default, and this default may be changed.
	- New commands in the read/write menu allow you to explicitly specify the format of derived files.

* New commands:
	- Write 3.x Derived File.
	- Write 4.x Derived File.
	- Import Derived File.
	- Clear Recent Files.

- Several new plugins.
- Several minor bug fixes.

See the children of this node for full details.</t>
<t tx="edream.110203163054.100">The Synchronization Principle simplifies everything and at long last puts Leo on a firm theoretical foundation.  This principle states that the "smallest unit of meaning" of any Leo outline is the entire outline itself.  In particular, individual derived files have meaning only in the context of a particular outline.

The Synchronization Principle has the following happy consequences:

1. We may assume that all derived files are in synch with the outline that wrote them.  This assumption allows Leo to use "hidden machinery" in the outline to associate nodes in the derived file with nodes in the outline.  This "hidden" machinery consists of a list of tnodes associated with @file vnodes in the outline.  When writing a derived file Leo creates a list of tnodes in the order they were written to the derived file.  When reading the derived file, Leo uses this list to associate nodes in the derived file with nodes in the outline.

2. Derived files must get their structure from the .leo file that wrote them.  As we have seen, this is done using the hidden machinery in the .leo file.  Consequently, there is no further need to represent outline structure in derived files.  There is no need any longer either for child indices or for sentinels to represent outline structure.  As a result, we can eliminate @+body and @-body nodes entirely because all @+node sentinels are followed by body text.

3. All .leo files must contain full outline structure.  Even "thin" outline will contain the full representation of the outline as vnodes.

4. Reading _never_ alters outline structure in the outline.  No vnodes are ever created or destroyed and reading never alters clone links.  This is true whether or not read errors occur.  The read code sets a temporary attribute of tnodes while reading.  These attributes are copied to the permanent t.bodyString attribute only if no read errors were encountered.

4. Error recovery is now trivial:  Read errors indicate that the .leo files and one or more derived files are out-of-synch.  No error recovery is attempted: the @file tree in which the error occurred reverts back to its original state.

5. The new Import Derived File command is the _only_ way to recover data from mismatched derived file.</t>
<t tx="edream.110203163054.101"></t>
<t tx="edream.110203163054.102">The write_old_format_derived_files option in leoConfig.leo and leoConfig.txt determines which format of derived file Leo's Write and Save commands write by default.  If this option is 0 (recommended) Leo writes 4.x format derived files.  Otherwise Leo writes 3.x derived files.

Note that you can use the Write 3.x/4.x Derived Files commands in the File:Read/Write menu to write derived files in an explicitly specified format.</t>
<t tx="edream.110203163054.103">This command deletes all entries in the Recent Files submenu except the most recent file.  The files themselves are not affected, just the menu entries.</t>
<t tx="edream.110203163054.104">The Import Derived File command imports all the nodes in a derived file into the outline.  Unlike the read commands, no outline structure is preserved.  This command can import either 3.x or 4.x derived files.

This command is necessary in version 4.0 because there is no other way to read derived files that are out-of-synch with a .leo file.</t>
<t tx="edream.110203163054.105">The Write 4.x Derived Files command and Write 3.x Derived Files command work just like the Write @file Nodes command, except that they write the indicated format off derived file.  In contrast, the Write @file Nodes command writes 3.x format derived files if and only if the write_old_format_derived_files = 1 in leoConfig.txt.

All three of these commands automatically save the outline (the .leo file) if any derived file was actually written.  This is necessary so that information in the .leo file always remains in synch with all derived files.</t>
<t tx="edream.110203163054.106">Paul Paterson contributed the following new plugins:

mod_autosave.py

Autosaves the Leo document every so often.

mod_timestamp.py

Timestamps all save operations to show when they occur.

word_export.py

Exports an outline to a word document.  Clicking "plugins ... word export ... export" exports the selected outline to Word.  Word should be running with an open (empty) document before executing this command.</t>
<t tx="edream.110203163054.107"></t>
<t tx="edream.110203163054.108">Leo's read code now warns if any non-empty node is unvisited.  This check, and the check that headlines match pretty much guarantees that out-of-synch outlines will generate errors.  Thus, there is no need a gnx timestamp in @+leo sentinels!</t>
<t tx="edream.110203163054.109">Version 4.0 is a major advance in Leo's error handling.  Using 4.0 is much safer than all previous versions.  This new error handling applies to all derived files, both 3.x and 4.x format.  

Leo's read code never alters the structure of an outline, regardless of whether read errors are encountered. This means that clone links, marks, and all other information in the outline except body text remains completely unchanged during reads.  Broken clone links (the dreaded read errors) are gone forever.  
Also, the new read code makes no changes to any body text until it is known that no read errors have occured.  This ensures that absolutely no changes at all are made to the outline if there are read errors.

Leo's read code now writes a message to the log pane whenever it sees that the body text in the derived file does not match the body text in the outline.  These messages do not indicate errors, only that the body text has been changed outside of Leo, say in an external editor or by cvs.</t>
<t tx="edream.110203163054.110"></t>
<t tx="edream.110203163054.111"></t>
<t tx="edream.110203163054.112">Added encoding comments to leoGlobals.py and French plugins

This removes a warning new in Python 2.3.
</t>
<t tx="edream.110203163054.113">There is no need to recycle Python objects when the last outline window is being closed.</t>
<t tx="edream.110203163054.114">This is too annoying during testing.  The Read @file Nodes command will in fact be made undoable for the 4.0 final release.</t>
<t tx="edream.110203163054.115">This has been changed in Python 2.3 and it probably wasn't ever a good idea...</t>
<t tx="edream.110203163054.116">The read code has much simplified using look-behind rather than look-ahead.  Both the read and write code write the file line-by-line without recursion.</t>
<t tx="edream.110203163054.117"></t>
<t tx="edream.110203163054.118"></t>
<t tx="edream.110203163054.119">leo.py 3.12 Final                       July 17, 2003

Window sizes are now in pixels rather than grid units.
You will need to resize existing outlines (.leo files).  Don't panic!

Highlights of this version:

* Plugged a huge memory leak.
* Fixed a major bug involving undo.
* Added Icon &amp; Status areas to Leo window for use by plugins.
* Important new plugins:
  - The file leoPlugins.leo now contains all plugins.
  - add_directives.py allows plugins to define new directives.
  - color_markup.py supports wiki-styled markup.
  - mod_spelling.py checks spelling (requires aspell to be installed).
  - nav_buttons.py creates browser-style navigation plugins in the icon area.
  - plugins_menu.py creates a Plugins menu items for all loaded plugins.
  - scripts_menu.py creates a Scripts menu for all scripts in scripts folder.
  - spell
  - trace_gc traces all changes to memory at idle time.
* Other enhancements:
  - Redesigned the Find panel.   Non-functional options are dimmed.
  - Added @wrap and @nowrap directives.
  - Added Write Dirty @file Nodes command.
  - Added several new "stub hooks".
  - Hyperlinks are now enabled by default.
  - Leo now loads plugins in alphabetical order.
  - Leo now remembers the size and location of Leo windows.
  - Undo now restores the insert point or the selection range after most commands.
  - Added apply button to Font panel.
  - Improved the reporting of characters that do not exist in the present encoding.
* The usual assortment of bug fixes and minor improvements.
  - There are no known bugs in this version of Leo.

See the children of this node for full details.</t>
<t tx="edream.110203163054.120"></t>
<t tx="edream.110203163054.121">Undoing the following commands could corrupt outlines:

Convert All Blanks, Convert All Tabs, Extract, Extract Names, Extract Section.</t>
<t tx="edream.110203163054.122">v.nodeAfterTree was being called way too often when handling read errors.</t>
<t tx="edream.110203163054.123">- Leo wasn't properly recycling Tk widgets when redrawing the outline pane.  This was a _huge_ leak.

- Leo now recycles all objects used by a window when that window closes.

The app.destroyAllWindowObjects() routine calls o.__dict__.clear for all objects o in a window.

- Leo now longer needs destroy() methods in each major class.</t>
<t tx="edream.110203163054.124"></t>
<t tx="edream.110203163054.125">c:\prog\leoCVS\leo\src\leoNodes.py:1174: Parameter (encoding) not used

This may have been the cause of some "unicode" problems.</t>
<t tx="edream.110203163054.126">c:\prog\leoCVS\leo\src\leoFrame.py:976: No global (a) found

This may have been the cause of some problems with the log panel.</t>
<t tx="edream.110203163054.127">Leo didn't properly import .cxx files or files with upper case extensions.</t>
<t tx="edream.110203163054.128">The messages "reading: @file x" were not always showing up during Open commands.</t>
<t tx="edream.110203163054.129">Symptom: Sometimes the "reading" messages would not appear when reading an outline.

Cause: Several event handlers are called at unpredictable times during the load process.  These may try to reset the log.

Solution:
- create app.setLog, app.lockLog and app.unlocklog methods.
- call app.lockLog before opening an outline.</t>
<t tx="edream.110203163054.130"></t>
<t tx="edream.110203163054.131">The body_pane_wraps setting is now handled properly.
</t>
<t tx="edream.110203163054.132">The body keystroke handler wasn't handling the delete character properly.</t>
<t tx="edream.110203163054.133"></t>
<t tx="edream.110203163054.134">Methods with the same name confused this command.

The Go To Line Number command will be rewritten for 4.0.</t>
<t tx="edream.110203163054.135">The following was improperly indented in @nosentinel files.  The expansion of &lt;&lt; class shape declarations &gt;&gt; was indented twice.

class shape(object):
  	&lt;&lt; class shape declarations &gt;&gt;
  	# after decls</t>
<t tx="edream.110203163054.136">- Added code to check for errors in the table passed to createOpenWithMenuFromTable.

- Revised code that checks to see whether a temp file has already been created.  The old code didn't properly take into account of file extensions when checking for already opened temp files.</t>
<t tx="edream.110203163054.137">Leo now converts all tabs to blanks as you type, not just leading blanks.</t>
<t tx="edream.110203163054.138">- Moved the code into the app class.</t>
<t tx="edream.110203163054.139">This was due to a recent change in getTextSelection.</t>
<t tx="edream.110203163054.140"></t>
<t tx="edream.110203163054.141">- Several parts of the code looped on lists that were altered in the loop.
- Fixed several bugs in the code that handled shortcuts to Open With menu items.</t>
<t tx="edream.110203163054.142">- Leo's various sort commands did not work properly if two headlines were identical.

- Eliminated the unnecessary and buggy sortSequence routine.</t>
<t tx="edream.110203163054.143"></t>
<t tx="edream.110203163054.144">Recent changes interfered with dragging nodes.</t>
<t tx="edream.110203163054.145">Here are the results from running checkClones2Links script on this file:

multipleTargetsInDerivedFiles: 8

(fixed) class nodeIndices      (improperly duplicated in leoAtFile.py)
(fixed) frame.OpenWithFileName (improperly duplicated in Recent Files submenu)
(fixed) recentButtonCallback   (improperly duplicated in Mark/Goto submenu)

-- Used several times in same derived file.  Will this be valid in LeoN?

&lt;&lt; Append any unused text to the parent's body text &gt;&gt; (used several times in leoImport.py)
&lt;&lt; Check both parts for @ comment conventions &gt;&gt; (used several times in leoTangle.py)
&lt;&lt; Compare single characters &gt;&gt; (used several times in leoTangle.py)
&lt;&lt; Set the default directory &gt;&gt; (used several times in leoAtFile.py)

-- Used (properly) in two different derived files:

replacePatterns (used on purpose in setup.py and postSetup.py)

clonedAtFileNodes: 9

@file ../plugins/add_directives.py
@file ../plugins/french_fm.py
@file ../plugins/open_with.py
@file ../plugins/vim.py
@file ../plugins/xemacs.py
@file c:\prog\test\multiple.txt
@file-nosent nosentCloneTest.txt
@silentfile ../doc/PKG-INFO.TXT
@silentfile ../doc/README.TXT
</t>
<t tx="edream.110203163054.146">Fractions cause problems in some locales.  The height/width params weren't used anyway!
</t>
<t tx="edream.110203163054.147"></t>
<t tx="edream.110203163054.148"></t>
<t tx="edream.110203163054.149">- createTopologyList creates a list containing a description of a tree.  Used by several of the new scripts.

- importFromPath encapsulates a lot of details of custom importing, and makes it unnecessary to alter sys.path.

- funcToMethod allows users to add methods to any class.  Such methods immediately become available to all objects, including existing objects!

- Added do-nothing flush method to redirect class.  This routine was added to support LeoN.</t>
<t tx="edream.110203163054.150">- The checkForPossiblyBrokenLinks script does just what it says.

- The checkClones2Links script warns if nodes are used by several derived files.</t>
<t tx="edream.110203163054.151">The new code uses a common base class for all dialogs.</t>
<t tx="edream.110203163054.152">- The new code uses proper Python lists to represent join lists.  This greatly clarifies the relevant sections of code, and may even provide a performance boost.  

- tnodes now contain both headline and body text. This change creates an important invariant:  vnodes with the same vnx's always point to tnodes with the same tnx's.  This invariant is vital to resolving conflicts properly.

- rewrote joinList code and move joinLists to tnodes.</t>
<t tx="edream.110203163054.153">- There is now only a single entry point into Leo: the run() routine.

This routine uses an optional fileName arg.

- Created runMainLoop function in leo.py so the call to mainloop() is in a separate function.

This routine was added to support LeoN.</t>
<t tx="edream.110203163054.154"></t>
<t tx="edream.110203163054.155"></t>
<t tx="edream.110203163054.156">The body_pane_wraps setting is used if neither of these directives is in effect.
</t>
<t tx="edream.110203163054.157">This make the Font panel a bit less intimidating to use.</t>
<t tx="edream.110203163054.158">- Added an "icon area" at the top of each Leo frame.  Plugins may add buttons to the Icon area at the top of each Leo frame.  See the nav_buttons.py plugin for an example of how to use this area.

- Added a "status area" at the bottom of each Leo frame.  This area reports the line and column number of the cursor.  Plugins may send status messages to this this area.

- Added convenience routines for the icon and status areas to the LeoFrame class.  Plugins may use these convenience routines to create, update, manage and destroy fields in the icon and status areas.</t>
<t tx="edream.110203163054.159">These aren't quite ready for prime time.</t>
<t tx="edream.110203163054.160"></t>
<t tx="edream.110203163054.161"></t>
<t tx="edream.110203163054.162">Hypertext links now enabled by default.  Control-click any section reference to go to its definition.  I changed the colorer so that it does _not_ underline active hyperlinks in section reference.  If a section reference is underlined, it means the definition does _not_ exist.  Otherwise the section reference _does_ exist and control-clicking the reference takes you to the defining node in one of its descendants.</t>
<t tx="edream.110203163054.163">The new code is substantially more robust than the old.</t>
<t tx="edream.110203163054.164"></t>
<t tx="edream.110203163054.165"></t>
<t tx="edream.110203163054.166">Leo was not honoring the requested size of Leo windows.

As the result of this change Leo will open old .leo files much smaller than expected.  Do not panic!  Simply resize the Leo window and save it.  The next time you open the window all will be well.</t>
<t tx="edream.110203163054.167">I have found this command to be highly annoying and unwanted.</t>
<t tx="edream.110203163054.168">This is very important for the spell-checking plugin, and is quite useful in all other situations.</t>
<t tx="edream.110203163054.169"></t>
<t tx="edream.110203163054.170"></t>
<t tx="edream.110203163054.171">- Added the following stub hooks:

"after-create-leo-frame"
"close-frame"
"create-optional-menus"
"destroy-all-global-windows"
"init-color-markup"
"new"
"redraw-entire-outline"
"scan-directives"

See the section called "About hooks" for full details.

- Changed handleLeoHook to doHook.  This simplifies the code a bit.
</t>
<t tx="edream.110203163054.172">@nowrap

At startup time Leo looks all files of the form mod_*.py in the plugins
directory. Leo assumes that these files are "plugins" containing Python modules
that customizes Leo's operation. Leo attempts to import each file.

Each module should register routines that are called at various times during
execution. Such times are identified by strings known as "tags". The code in in
one or more plugins corresponding to each tag are known as the "hook" routines
for that tag. Leo catches exceptions (including syntax errors) in hook
routines, so it is safe to hack away on this code.

Leo passes two argument to all hook routines: the tag and a keywords dictionary
containing additional information. For example, keywords["label"] indicates the
kind of command for "command1" and "command2" hooks.

For some hooks, returning anything other than None "overrides" Leo's default
action. Hooks have full access to all of Leo's source code. Just import the
relevant file. For example, top() returns the commander for the topmost Leo
window.

The following table summarizes the arguments passed to hooks: ( Overrides is
"yes" if returning anything other than None overrides Leo's normal command or
event processing.)

tag argument                                              keys in keywords
(hook name)  overrides       when called                  dictionary argument
---------    ---------       -----------                  -------------------
"bodyclick1"   yes      before normal click in body       c,v,event
"bodyclick2"            after  normal click in body       c,v,event
"bodydclick1"  yes      before double click in body       c,v,event
"bodydclick2"           after  double click in body       c,v,event
"bodykey1"     yes      before body keystrokes            c,v,ch,oldSel,undoType
"bodykey2"              after  body keystrokes            c,v,ch,oldSel,undoType
"bodyrclick1"  yes      before right click in body        c,v,event
"bodyrclick2"           after  right click in body        c,v,event
"boxclick1"    yes      before click in +- box            c,v,event
"boxclick2"             after  click in +- box            c,v,event
"command1"     yes      before each command               c,v,label (note 2)
"command2"              after  each command               c,v,label (note 2)
"drag1"        yes      before start of drag              c,v,event
"drag2"                 after  start of drag              c,v,event
"dragging1"    yes      before continuing to drag         c,v,event
"dragging2"             after  continuing to drag         c,v,event
"end1"                  start of app.quit()
"enddrag1"     yes      before end of drag                c,v,event
"enddrag2"              after  end of drag                c,v,event
"headclick1"   yes      before normal click in headline   c,v,event
"headclick2"            after  normal click in headline   c,v,event
"headrclick1"  yes      before right click in headline    c,v,event
"headrclick2"           after  right click in headline    c,v,event
"headkey1"     yes      before headline keystrokes        c,v,ch
"headkey2"              after  headline keystrokes        c,v,ch
"hypercclick1" yes      before control click in hyperlink c,v,event
"hypercclick2"          after  control click in hyperlink c,v,event
"hyperenter1"  yes      before entering hyperlink         c,v,event
"hyperenter2"           after  entering hyperlink         c,v,event
"hyperleave1"  yes      before leaving  hyperlink         c,v,event
"hyperleave2"           after  leaving  hyperlink         c,v,event
"iconclick1"   yes      before single click in icon box   c,v,event
"iconclick2"            after  single click in icon box   c,v,event
"iconrclick1"  yes      before right click in icon box    c,v,event
"iconrclick2"           after  right click in icon box    c,v,event
"icondclick1"  yes      before double click in icon box   c,v,event
"icondclick2"           after  double click in icon box   c,v,event
"idle"                  periodically (at idle time)       c,v
"menu1"        yes      before creating menus             c,v        (note 3)
"menu2"        yes      before updating menus             c,v
"open1"        yes      before opening any file           old_c,new_c,fileName (note 4)
"open2"                 after  opening any file           old_c,new_c,fileName (note 4)
"openwith1"    yes      before Open With command          c,v,openType,arg,ext
"openwith2"             after  Open With command          c,v,openType,arg,ext
"recentfiles1" yes      before Recent Files command       c,v,fileName,closeFlag
"recentfiles2"          after  Recent Files command       c,v,fileName,closeFlag
"save1"        yes      before any Save command           c,v,fileName
"save2"                 after  any Save command           c,v,fileName
"select1"      yes      before selecting a vnode          c,new_v,new_v
"select2"               after  selecting a vnode          c,new_v,old_v
"select3"               after  selecting a vnode          c,new_v,old_v
"set-mark"     no       when a mark is set                c,v           (new)
"start1"       no       after app.finishCreate()
"start2"                after opening first Leo window    c,v,fileName
"unselect1"    yes      before unselecting a vnode        c,new_v,old_v
"unselect2"             after  unselecting a vnode        c,old_v,old_v
"@url1"        yes      before double-click @url node     c,v           (note 5)
"@url2"                 after  double-click @url node     c,v           (note 5)

Notes:

(1) "activate" and "deactivate" hooks: These have been removed because they do
not work as expected.

(2) "commands" hooks: The label entry in the keywords dict contains the
"canonicalized" form of the command, that is, the lowercase name of the command
with all non-alphabetic characters removed.

Commands hooks now set the label for undo and redo commands "undo" and "redo"
rather than "cantundo" and "cantredo".

(3) "menu1" hook: Setting app().realMenuNameDict in this hook is an easy way of
translating menu names to other languages. Note: the "new" names created this
way affect only the actual spelling of the menu items, they do _not_ affect how
you specify shortcuts in leoConfig.txt, nor do they affect the "official"
command names passed in app().commandName. For example, suppose you set
app().realMenuNameDict["Open..."] = "Ouvre".

(4) "open1" and "open2" hooks: These are called with a keywords dict containing
the following entries:

old_c: The commander of the previously open window.
new_c: The commander of the newly opened window.
fileName: The name of the file being opened.

You can use old_c.currentVnode() and new_c.currentVnode() to get the current
vnode in the old and new windows.

Leo calls the "open1" and "open2" hooks only if the file is already open. Leo
will also call the "open1" and "open2" hooks if: a) a file is opened using the
Recent Files menu and b) the file is not already open.

(5) "@url1" and "@url2" hooks are only executed if "icondclick1" hook returns None.


New in version 3.12:

The following hooks are a new breed of hook, called "stub hooks". Conceptually,
these hooks are like calls to stub routines that can be filled in by code in
plugins.

tag argument                                                       keys in keywords
(hook name)               overrides        when called           dictionary argument
---------                 ---------        -----------           -------------------
"after-redraw-outline"       no        end of tree.redraw        c (note 6)
"clear-mark"                 no        when mark is set          c,v
"close-frame"                no        in app.closeLeoWindow     c
"color-optional-markup"      yes *     (note 7)                  colorer,v (note 7)
"create-optional-menus"      no        (note 8)                  (note 8)
"create-popup-menu-items"    no        in tree.OnPopup           c,v,event (new)
"destroy-all-global-windows" no        (note 12)                 None
"draw-outline-box"           yes       start of drawBox          tree,p,v,x,y (note 6)
"draw-outline-icon"          yes       start of tree.drawIcon    tree,p,v,x,y (note 6)
"draw-outline-node"          yes       start of tree.drawNode    tree,p,v,x,y (note 6)
"draw-outline-text-box"      yes       start of tree.drawText    tree,p,v,x,y (note 6)
"draw-sub-outline"           yes       start of tree.drawTree    tree,p,v,x,y,h,level (note 6)
"enable-popup-menu-items"    no        in tree.OnPopup           c,v,event (new)
"init-color-markup"          no        (note 7)                  colorer,v,s,i,j,colortag (note 7)
"new"                        no        start of New command      old_c,new_c (note 9)
"redraw-entire-outline"      yes       start of tree.redraw      c (note 6)
"scan-directives"            no        in scanDirectives         c,v,s,old_dict,dict,pluginsList (note 10)
"set-mark"                   no        when mark is set          c,v
"show-popup-menu"            no        in tree.OnPopup           c,v,event

Notes:

(6) These hooks are useful for testing.

(7) These stub hooks allow plugins to parse and handle markup withing doc
parts, comments and Python """ strings. Note that these hooks are _not_ called
in Python ''' strings. See the color_markup plugin for a complete example of
how to use these hooks.

(8) The "create-optional-menus" stub hook is called when Leo is creating menus,
at the place at which creating new menus is appropriate. Therefore, this hook
need only create new menus in the correct order, without worrying about the
placement of the menus in the menu bar. See the plugins_menu and scripts_menu
plugins for examples of how to use this hook. Leo now executes hooks in
alphabetical order, so that the Plugins menu will be created before the Scripts
menu.

(9) The "new" stub hook is called at the beginning of the code that implements
the New command. This provides a much easier way of recognizing when Leo is
about to create a new Leo window.

(10) The "scan-directives" stub hooks is called inside the scanDirectives
global function. The dictionary returned by scanDirectives now contains an item
whose key is "pluginsList". The value of this item is a list of tuples
(d,v,s,k) where:

- d is the spelling of the @directive, without the leading @.
- v is the vnode containing the directive, _not_ the original vnode.
- s[k:] is a string containing whatever follows the @directive. k has already
been moved past any whitespace that follows the @directive.

See the add_directives plugins directive for a complete example of how to use
the "scan-directives" stub hook.

(11) The "close-frame" stub hook is called in app.closeLeoWindow just before
removing the window from app.windowList. The hook code may remove the window
from app.windowList to prevent app.closeLeoWindow from destroying the window.

(12) Leo calls the "destroy-all-global-windows" hook in app.destroyAllGlobalWindows().
This hook gives plugins the chance to clean up after themselves when Leo shuts down.</t>
<t tx="edream.110203163054.173">Leo now supports two new stub hooks: "clear-mark" and "set-mark".  Both fully update the marks window, so it is important that they not be called "too often", and they aren't.

As a side effect, it is no longer necessary to update the marks window after every command that affects marks, a nice simplification and generalization of the code.

While I was at it, I moved the two dialog classes used only by the nav_buttons plugin out of leoDialog.py and into nav_buttons.py where they belong.</t>
<t tx="edream.110203163054.174">Added the "create-popup-menu", "enable-popup-menu-items" and "show-popup-menu" hooks.</t>
<t tx="edream.110203163054.175">Added the "create-popup-menu", "enable-popup-menu-items" and "show-popup-menu" hooks.</t>
<t tx="edream.110203163054.176"></t>
<t tx="edream.110203163054.177">This plugin allows users to create new directives.

As an example, this plugin creates a new @markup wiki directive.</t>
<t tx="edream.110203163054.178">This plugin supports coloring for markup in doc parts and Python triple-double-quoted strings.

At present, this plugin supports wiki-style markup, and it would be easy to change the style of markup.</t>
<t tx="edream.110203163054.179">This plugin adds 4 new buttons to the icon area at the top of each Leo window:

- Back and Forward arrows that work like a typical web browser.  Clicking the back arrow button takes you to the last node in the tree you visited.  Clicking the forward arrow button moves you forward.  The forward arrow button is dimmed unless you have clicked the back arrow button recently.

- The Recent button opens a non-modal dialog showing all the nodes you have visited recently.  This dialog is updated cleanly by the tree.select method.  You will see this entries change dynamically.  There are buttons in this dialog for clearing individual entries or clearing all entries.  Double-clicking any entry in this dialog takes you to that node, as does clicking the Go button.

The entries in the Recent Nodes pane do _not_ correspond to the order implied by the Forward and Back arrows.  Rather, the most recently visited node is on top, followed by the next most recently visited node, and so on, with the additional feature that nodes appear only once in the list.

- The Marks button opens a non-modal dialog showing all marked nodes in the tree.  Marking or unmarking nodes in the tree adds or deletes entries from this dialog.  Double-clicking any entry in this dialog takes you to that node, as does clicking the Go button.</t>
<t tx="edream.110203163054.180">This creates a plugins menu describing each loaded plugin.</t>
<t tx="edream.110203163054.181">The scripts_menu.py plugin creates a Scripts menu for all scripts in scripts folder.</t>
<t tx="edream.110203163054.182">- Leo now scans all .py files in the plugins folder when looking for plugins.

Filenames need not start with mod_, and Leo scans only the plugins folder.

- Leo loads plugins in alphabetical order.

- Leo now prints only a brief summary of the number of files loaded &amp; examined to the log file.</t>
<t tx="edream.110203163054.183">1. Created config, doc, examples, plugins, scripts, src, test &amp; tools folders.

2. Removed the following files:

- nsi.leo file.  This was a duplicate of code in LeoPy.leo.  
- bdist.bat, go.bat, help.bat, sdist.bat.
- leo.rc and leo.res.  These were resource files used by the Delphi classes.</t>
<t tx="edream.110203163054.184">These were written by Frank Merenda.</t>
<t tx="edream.110203163054.185">leo.py 3.11.1                       May 1, 2003

This version fixes two bugs:
	
- Version 3.11 had startup problems on some Linux systems.

- Creating clones by control dragging did not always work.
  This bug has existed in Leo for a long time.</t>
<t tx="edream.110203163054.186">leo.py requires Python 2.1 or above and tcl/tk 8.3 or above.
leo.py will work on Linux, Windows and MacOs X Jaguar.

leo.py 3.11.1                       May 1, 2003

This version fixes the following bugs:

- Leo would crash on startup on some Linux systems due to a problem
  with Leo's local copy of getpreferredencoding.

- Leo sometimes did not set clone bits properly after creating a clone
  by control-dragging a node.  This bug has existed for about 6 months!

leo.py 3.11                         April 27, 2003

This version of Leo contains many important improvements since 3.10,
especially support for unicode and a new plugin architecture.

The Highlights of 3.11:

** Leo supports unicode.
	- New @encoding directives specifies encoding for derived files.
	- New settings specify default encodings for .leo and derived files.
	- Derived files specify encodings used to create them.
** A new plugin architecture for customizing Leo. (A major improvement.)
- New commands:
	- Toggle Angle Brackets.
	- Insert Time/Date (in headline or body text).
	- Go To First/Last Node, Parent, Next/Previous Sibling.
	- Write Missing @file Nodes.
	- Expand/Contract Node.
- Improved commands:
	- Fixed a huge performance bug that slowed moving nodes left.
	- Expand/Contract commands now operate on the selected tree.
	  ( A major improvement)
	- Sort Siblings command can now sort top-level nodes.
	- Leo now allows multiple writes of cloned nodes.
	  (Useful when different @path directives are in effect.)
- Other improvements:
	- New @lineending directive specifies line endings.
	- Improved syntax coloring for html and xml.
	- Leo scrolls partially visible headlines into full view.
	- Added "Replace tabs with spaces" checkbox in Prefs panel.
- New settings in leoConfig.leo/.txt.
	- Added "tk_encoding" setting and related logic.
	- Colors for Show Invisibles command and body_insertion_cursor
	- Settings affecting when control-drags start.
	- Defaults for unicode (see above).
- Many other bug fixes and improvements.

See the children of this node for full details.</t>
<t tx="edream.110203163054.187"></t>
<t tx="edream.110203163054.188"></t>
<t tx="edream.110203163054.189">This ensures that the outline is redrawn properly after the Read @file Nodes command.</t>
<t tx="edream.110203163054.190">Browsing the comp.lang.python yesterday I found that there are serious problems with Python's getdefaultlocale() routine.  Martin v. Löwis says "getdefaultlocale() is broken, and cannot be fixed", though he does suggest the following workaround:

leoGlobals.py uses locale.getpreferredencoding to define getpreferredencoding if locale.getpreferredencoding exists (it is new in Python 2.3alpha).  Otherwise, Leo uses the code copied from the 2.3a2 version of Python to define getpreferredencoding.  Either way, leoGlobals.py now defines getpreferredencoding and Leo uses getpreferredencoding rather than getdefaultlocale.</t>
<t tx="edream.110203163054.191">After opening the Python window the call to tkFont() threw a (caught) exception on every call to frame.setTabWidth.  The fix was to add the optional root param.</t>
<t tx="edream.110203163054.192">skip_long was throwing an exception if there were no valid digits following a + or - sign.</t>
<t tx="edream.110203163054.193"></t>
<t tx="edream.110203163054.194">- tangle.scanAllDirectives was not setting self.encoding when handling @encoding.
- tangle.scanAllDirectives wasn't scanning the @encoding line properly.
- fixed crashers in Tangle and Untangle logic.</t>
<t tx="edream.110203163054.195">Fixed bug in handleLinesFollowingSentinel:
c:\prog\LeoCVS\leo\leoAtFile.py:482: No global (i) found
Removed i arg from rfind.

Fixed bug in definition of BadLeoFile:
c:\prog\LeoCVS\leo\leoFileCommands.py:27: Base class (exceptions.Exception) __init__() not called
Added call to Exception.__init__(self,message)

Fixed bug in askYesNoCancel
c:\prog\LeoCVS\leo\leoDialog.py:283: Variable (no) used before being set.
Disabled defaultButton logic.  New code would have to be thoroughly tested.

Removing unused routine: setDefaultLoc.
c:\prog\LeoCVS\leo\leoNodes.py:2581: No class attribute (defaultLoc) found

Fixed bug in put: changed a to app()
c:\prog\leoCvs\leo\leoFrame.py:4973: No global (a) found
</t>
<t tx="edream.110203163054.196">I had completely misunderstood __del__ methods!  __del__ methods disable the gc's ability to collect circular garbage (!!) and so __del__ methods will _never_ be called (!!)

BTW, when deleting an entire Leo window Leo calls various destroy methods to unlink items.  This allows the garbage collector to collect all data structures.  Because of unlimited undo only these destroy methods have the potential for creating "real" garbage.</t>
<t tx="edream.110203163054.197"></t>
<t tx="edream.110203163054.198">This adds http:\\ to url's if needed.</t>
<t tx="edream.110203163054.199">New in version 3.11.  The @lineending directive allows you to specify the line endings for individual derived files.  This directive will override the output_newline setting in leoConfig.txt.  Note that @lineending _never_ affects the line endings in .leo files themselves:  we must have consistent line endings in .leo files!  See below for more details.

The valid forms of the new @lineending directive are:

@lineending nl       (the default, Linux)
@lineending cr       (Mac)
@lineending crlf     (Windows)
@lineending lf       (same as nl, not recommended)
@lineending platform (same as platform value for output_newline setting in leoConfig.txt)</t>
<t tx="edream.110203163054.200">This will have no effect until version 4.0.</t>
<t tx="edream.110203163054.201">Leo now uses unicode internally for most strings.  This solves a lot of problems.  The children of this node discuss all the details...</t>
<t tx="edream.110203163054.202">This fixes several bugs.</t>
<t tx="edream.110203163054.203">In particular, the locale returned by locale.getdefaultlocale()[1] need not be a valid unicode encoding.
</t>
<t tx="edream.110203163054.204">Leo now uses unicode internally for most strings.  The highlights:

1. Leo converts headline and body text to unicode when reading .leo files and derived files.  Both .leo files and derived files may specify their encoding, with "utf-8" being used by default.  If the encoding used in a derived file is not "utf-8" it is represented in the @+leo sentinel line.  For example:

#@+leo-encoding=iso-8859-1.

The "utf-8" encoding is a "lossless" encoding (it can represent all unicode code points), so encoding and decoding to and from utf-8 plain strings will never cause a problem.  When reading or writing a character not in a "lossy" encoding, Leo converts such characters to '?' and issues a warning. 

2. When writing .leo files and derived files Leo uses the same encoding used to read the file, again with "utf-8" used as a default.

3. leoConfig.py contains two settings used to specify the default encoding used for .leo and derived files:

default_derived_file_encoding = UTF-8 
new_leo_file_encoding = UTF-8 

I do not recommend changing new_leo_file_encoding (see the comments in leoConfig.leo) and you may set 
default_derived_file_encoding to anything that makes sense for you.

4. You may use the @encoding directive to specify the encoding used in a derived file.  You can't mix encodings in a single derived file.

This is all should need to know to use extended character sets on Leo.</t>
<t tx="edream.110203163054.205">leoConfig.py now contains two new settings, with the defaults shown below: 

default_derived_file_encoding = UTF-8 
new_leo_file_encoding = UTF-8 

These control the default encodings used when writing derived files and .leo files.

I do not recommend changing new_leo_file_encoding (see the comments in leoConfig.leo)

You may set default_derived_file_encoding to anything that makes sense for you.
</t>
<t tx="edream.110203163054.206">The following paragraphs discuss code-level details.  You should not need to read this section in order to use Leo.

1. Leo uses unicode objects in vnodes and tnodes to denote headline and body text.  Note that unicode strings have no encoding; only plain strings have encodings. This means that once an (encoded) plain string has been converted to a unicode string it doesn't matter how the unicode string was created.  This is the key that makes Leo's new code robust. 

So internally Leo never has to worry about encodings. The only times encoding matter is when encoded strings are converted to and from unicode when Leo reads or writes files (or when the passing strings to and from Tk.Text widgets, but the idea is the same).

2. Python expressions that mix unicode strings u and plain strings s, like:

	u + s 
or 
	u == s 
or 
	u[5] == s[2:]

are promoted to unicode objects using the "system encoding". This encoding should never be changed, but we can't assume that we know what it is, so for safety we should assume the most restrictive encoding, namely "ascii".  With this assumption, Leo's code can't throw an exception during these promotions provided that: 

- All strings are converted to unicode when Leo reads files or gets text from Tk.Text widgets. 
- All string literals in Leo's code have only ascii characters.</t>
<t tx="edream.110203163054.207"></t>
<t tx="edream.110203163054.208">It is now much easier to customize Leo.  The new scheme is based on plugins (files in the plugins directory) rather than modifying customizeLeo.py.  Many thanks to Paul Paterson for suggesting this scheme and for doing the first implementation.
</t>
<t tx="edream.110203163054.209">@nocolor

New in 3.11. Leo now looks in the plugins folder for files whose name matches
mod_*.py. Leo tries to import all such files at startup ("start2") time. 

The child of this node gives an example of the code that creates the Open With
menu. The following code, appearing at the end of mod_open_with.py, registers
two different hook functions. The on_idle function is the "idle" hook. The
create_open_with_menu is the "start2","open2" and "command2" hooks.
@color

if 1: # Register the handlers... 
	registerHandler("idle", on_idle) 
	registerHandler(("start2","open2","command2"), create_open_with_menu) 
	es("...open with")
	
@nocolor
Plugins may call registerHandler with a hook name like "idle" or a list of hook
names like ("start2","open2","command2"). Also, you can use the "all" hook name
to indicate that code will be called for all hooks. This is useful for tracing
hooks. Plugins may also call registerExclusiveHandler for hooks that should not
be redefined in other plugins.

mod_open_with.py also contains the on_idle and create_open_with functions that
actually handle the hook. Such functions have two arguments: tag and keywords.
You will find many examples of this in LeoPy.leo.

About distribution:

1. LeoPy.leo now contains all the plugins in @ignore'd @file nodes. This way
Leo won't complain when you open LeoPy.leo.

2. Most plugins actually are disabled: the code that registers the hooks is
contained in #if 0: blocks. So to create a pluging you have to remove the
@ignore and you have to change #if 0: to #if 1.

3. Most mod_*.py will never be part of Leo distributions, and the single-click
installer will create an plugins folder containing just mod_open_with.py.

4. There is no longer a need for a customizeLeo.py file.

About error checking:

At present Leo will disable all hooks if any hook throws an exception. In
practice this isn't a big deal, but obviously something better could be done. I
won't do anything until after 3.11b1 goes out.

How to send me your plugins:

It should now be _much_ easier to submit a plugin for inclusion in LeoPy.leo.
Just send me a .leo file containing @file mod_your_plugin.py. Please have this
@file node be @ignored: this is more convenient for me. Ideally, your .leo file
should contain _only_ your plugin code.</t>
<t tx="edream.110203163054.210">@color
@language python
@ignore

"""Open With handler"""

from customizeLeo import *
from leoGlobals import *

@others

if 1: # Register the handlers...
	registerHandler("idle", on_idle)
	registerHandler(("start2","open2","command2"), create_open_with_menu)
	es("...open with")</t>
<t tx="edream.110203163054.211"># frame.OnOpenWith creates the dict as follows:
# dict = {"c":c, "v":v, "f":f, "path":path, "time":time}

def on_idle (tag,keywords):

	import os
	a = app()
	for dict in a.openWithFiles:
		path = dict.get("path")
		c = dict.get("c")
		v = dict.get("v")
		if path and os.path.exists(path):
			try:
				time = os.path.getmtime(path)
				if time and time != dict.get("time"):
					dict["time"] = time
					&lt;&lt; update v's body text &gt;&gt;
			except: pass</t>
<t tx="edream.110203163054.212">&lt;&lt; set s to the new text &gt;&gt;
body = v.bodyString()
&lt;&lt; set conflict flag &gt;&gt;

if conflict:
	# Report the conflict &amp; set update.
	import leoDialog
	d = leoDialog.leoDialog()
	message = "Conflict in %s.\n\n" % (v.headString())
	message += "Replace outline with external changes?"
	update = d.askYesNo("Conflict!",message) == "yes"
else:
	update = s != body

if update:
	h = v.headString()
	es("changed:" + h)
	v.setBodyStringOrPane(s)
	c.selectVnode(v)
	v.OpenWithOldBody = s
</t>
<t tx="edream.110203163054.213">try:
	# Update v from the changed temp file.
	f=open(path)
	s=f.read()
	f.close()
except:
	es("can not open " + shortFileName(path))
	break
</t>
<t tx="edream.110203163054.214">try:
	# The OpenWithOldBody attribute does not normally exist in vnodes.
	old_body = v.OpenWithOldBody
	conflict = body != old_body and body != s
except:
	conflict = v.isDirty() and body != s
</t>
<t tx="edream.110203163054.215">def create_open_with_menu (tag,keywords):

	if  (tag in ("start2","open2") or
		(tag=="command2" and keywords.get("label")=="new")):
	
		&lt;&lt; create the Open With menu &gt;&gt;

		# Enable the idle-time hook so we can check temp files created by Open With.
		from leoGlobals import enableIdleTimeHook
		enableIdleTimeHook(idleTimeDelay=500)
</t>
<t tx="edream.110203163054.216">@ Entries in the following table are the tuple (commandName,shortcut,data).
data is the tuple (command,arg,ext).
command is one of "os.system", "os.startfile", "os.spawnl", "os.spawnv" or "exec".
Leo executes command(arg+path) where path is the full path to the temp file.
If ext is not None, the temp file has the extension ext,
Otherwise, Leo computes an extension based on what @language directive is in effect.
@c

idle_arg = "c:/python22/tools/idle/idle.py -e "

if 1: # Default table.
 table = (
  ("&amp;Idle",   "Alt+Shift+I",("os.system",idle_arg,".py")),
  ("&amp;Word",   "Alt+Shift+W",("os.startfile",None,".doc")),
  ("Word&amp;Pad","Alt+Shift+T",("os.startfile",None,".txt")))
else: # David McNab's table.
 table = (
  ("X&amp;Emacs", "Ctrl+E", ("os.spawnl","/usr/bin/gnuclient", None)))

top().frame.createOpenWithMenuFromTable(table)
</t>
<t tx="edream.110203163054.217">Simplified and regularized hooks:

- replaced "event1" and "event2" hooks with 'regular' hooks.
	* Much easier to understand.
- added "iconrclick" hooks.
- added "bodyrclick" hooks.
- added "save1" and "save2" hooks
- added "dragging" hooks.
	* These are called when drag hook called while already dragging.
- added "hyperenter" and "hyperleave" hooks.
	* These only fire if use_hyperlinks = 1 in leoConfig.txt.
- removed "activate" and "deactivate" hooks.
	* These were not reliable.
- almost all hooks now have c,v arguments.
- "command" hooks now return "undo" and "redo" rather than "cantundo" and "cantredo"

Improved code:

- improved the tracing of hooks.
- the tracing code also checks to make sure that most hooks have c,v keywords.
- created es_event_exception().
- put all event handlers in try/except blocks that call es_event_exception on errors.</t>
<t tx="edream.110203163054.218">At startup time Leo looks all files of the form mod_*.py in the plugins
directory. Leo assumes that these files are "plugins" containing Python modules
that customizes Leo's operation. Leo attempts to import each file.

Each module should register routines that are called at various times during
execution. Such times are identified by strings known as "tags". The code in in
one or more plugins corresponding to each tag are known as the "hook" routines
for that tag. Leo catches exceptions (including syntax errors) in hook
routines, so it is safe to hack away on this code.

Leo passes two argument to all hook routines: the tag and a keywords dictionary
containing additional information. For example, keywords["label"] indicates the
kind of command for "command1" and "command2" hooks.

For some hooks, returning anything other than None "overrides" Leo's default
action. Hooks have full access to all of Leo's source code. Just import the
relevant file. For example, top() returns the commander for the topmost Leo
window.

The following table summarizes the arguments passed to hooks: ( Overrides is
"yes" if returning anything other than None overrides Leo's normal command or
event processing.)

tag argument                                              keys in keywords
(hook name)  overrides       when called                  dictionary argument
---------    ---------       -----------                  -------------------
"bodyclick1"   yes      before normal click in body       c,v,event (new)
"bodyclick2"            after  normal click in body       c,v,event (new)
"bodydclick1"  yes      before double click in body       c,v,event (new)
"bodydclick2"           after  double click in body       c,v,event (new)
"bodykey1"     yes      before body keystrokes            c,v,ch,oldSel,undoType
"bodykey2"              after  body keystrokes            c,v,ch,oldSel,undoType
"bodyrclick1"  yes      before right click in body        c,v,event (new)
"bodyrclick2"           after  right click in body        c,v,event (new)
"boxclick1"    yes      before click in +- box            c,v,event (new)
"boxclick2"             after  click in +- box            c,v,event (new)
"command1"     yes      before each command               c,v,label (note 2)
"command2"              after  each command               c,v,label (note 2)
"drag1"        yes      before start of drag              c,v,event (new)
"drag2"                 after  start of drag              c,v,event (new)
"dragging1"    yes      before continuing to drag         c,v,event (new)
"dragging2"             after  continuing to drag         c,v,event (new)
"end1"                  start of app.quit()
"enddrag1"     yes      before end of drag                c,v,event (new)
"enddrag2"              after  end of drag                c,v,event (new)
"headclick1"   yes      before normal click in headline   c,v,event (new)
"headclick2"            after  normal click in headline   c,v,event (new)
"headrclick1"  yes      before right click in headline    c,v,event (new)
"headrclick2"           after  right click in headline    c,v,event (new)
"headkey1"     yes      before headline keystrokes        c,v,ch
"headkey2"              after  headline keystrokes        c,v,ch
"hypercclick1" yes      before control click in hyperlink c,v,event (new)
"hypercclick2"          after  control click in hyperlink c,v,event (new)
"hyperenter1"  yes      before entering hyperlink         c,v,event (new)
"hyperenter2"           after  entering hyperlink         c,v,event (new)
"hyperleave1"  yes      before leaving  hyperlink         c,v,event (new)
"hyperleave2"           after  leaving  hyperlink         c,v,event (new)
"iconclick1"   yes      before single click in icon box   c,v,event (new)
"iconclick2"            after  single click in icon box   c,v,event (new)
"iconrclick1"  yes      before right click in icon box    c,v,event (new)
"iconrclick2"           after  right click in icon box    c,v,event (new)
"icondclick1"  yes      before double click in icon box   c,v,event (new)
"icondclick2"           after  double click in icon box   c,v,event (new)
"idle"                  periodically (at idle time)       c,v
"menu1"        yes      before creating menus             c,v (note 3)
"menu2"        yes      before updating menus             c,v
"open1"        yes      before opening any file           old_c,new_c,fileName (note 4)
"open2"                 after  opening any file           old_c,new_c,fileName (note 4)
"openwith1"    yes      before Open With command          c,v,openType,arg,ext
"openwith2"             after  Open With command          c,v,openType,arg,ext
"recentfiles1" yes      before Recent Files command       c,v,fileName,closeFlag
"recentfiles2"          after  Recent Files command       c,v,fileName,closeFlag
"save1"        yes      before any Save command           c,v,fileName
"save2"                 after  any Save command           c,v,fileName
"select1"      yes      before selecting a vnode          c,new_v,new_v
"select2"               after  selecting a vnode          c,new_v,old_v
"start1"       no       after app.finishCreate()
"start2"                after opening first Leo window    c,v,fileName
"unselect1"    yes      before unselecting a vnode        c,new_v,old_v (new)
"unselect2"             after  unselecting a vnode        c,old_v,old_v (new)
"@url1"        yes      before double-click @url node     c,v (note 5)
"@url2"                 after  double-click @url node     c,v (note 5)

Notes:

(1) "activate" and "deactivate" hooks: These have been removed because they do
not work as expected.

(2) "commands" hooks: The label entry in the keywords dict contains the
"canonicalized" form of the command, that is, the lowercase name of the command
with all non-alphabetic characters removed.

Commands hooks now set the label for undo and redo commands "undo" and "redo"
rather than "cantundo" and "cantredo".

(3) "menu1" hook: Setting app().realMenuNameDict in this hook is an easy way of
translating menu names to other languages. Note: the "new" names created this
way affect only the actual spelling of the menu items, they do _not_ affect how
you specify shortcuts in leoConfig.txt, nor do they affect the "official"
command names passed in app().commandName. For example, suppose you set
app().realMenuNameDict["Open..."] = "Ouvre".

(4) "open1" and "open2" hooks: These are called with a keywords dict containing
the following entries:

old_c: The commander of the previously open window.
new_c: The commander of the newly opened window.
fileName: The name of the file being opened.

You can use old_c.currentVnode() and new_c.currentVnode() to get the current
vnode in the old and new windows.

Leo calls the "open1" and "open2" hooks only if the file is already open.
Leo will also call the "open1" and "open2" hooks if:
a) a file is opened using the Recent Files menu and
b) the file is not already open.

(5) "@url1" and "@url2" hooks are only executed if "icondclick1" hook returns
None.</t>
<t tx="edream.110203163054.219">See the Code:Customizing Leo:Plugins folder in LeoPy.leo for full details of all plugins.

- Added disabled support for @folder.

- Demoted up/down arrow stuff to a disabled plugin for now.</t>
<t tx="edream.110203163054.220">The idle-time hook now checks for dirty @file nodes that have been modified in an external editor since the last check.  An alert is raised when such conflicting changes are found.

Improved sanitize_filename utility (in leoGlobals.py) so that it converts all characters used to denote filenames to underscores.</t>
<t tx="edream.110203163054.221">This allows output from registering hooks to appear in the log pane.</t>
<t tx="edream.110203163054.222"></t>
<t tx="edream.110203163054.223">The following new plugins are now in LeoPy.leo.

- mod_script_io_to_body.py
	Redirect output from scripts to end of body pane.

- mod_vim.py
	Adds support for VIM editor.

- mod_french_fm.py
	Full translation of all Leo's menus into French.</t>
<t tx="edream.110203163054.224">Added support for the following options:

show_invisibles_space_background_color
show_invisibles_tab_background_color
</t>
<t tx="edream.110203163054.225">This option controls when the control key is considered to start a control-drag.

If look_for_control_drag_on_mouse_down = 1 the the control key must be down when dragging starts.  Otherwise, the control key must be down when dragging ends.</t>
<t tx="edream.110203163054.226">This allows Leo to be used with a black background.</t>
<t tx="edream.110203163054.227">Two new settings in leoConfig.leo/.txt specify the format of the time/date
strings inserted by the Insert Body Time/Date and Insert Headline Time/Date
commands:

body_time_format_string
headline_time_format_string

These settings are really the format string passed to time.strftime(format).

See http://www.python.org/doc/current/lib/module-time.html for a complete list
of the format options. The "%m/%d/%Y %H:%M:%S" format is used by default,
resulting in a time/date format such as: 1/30/2003 8:31:55

</t>
<t tx="edream.110203163054.228"></t>
<t tx="edream.110203163054.229">- if the headline is bracketed (named) then the &lt;&lt; &gt;&gt; are removed.
- if the headline is not bracketed (unnamed) then the &lt;&lt; &gt;&gt; are inserted. 
</t>
<t tx="edream.110203163054.230">The Insert Body Time/Date and Insert Headline Time/Date commands are in the
Edit Body and Edit Headline menus respectively. They insert the formatted time
&amp; date into the body or headline text. You must be editing a headline to be
able to insert the time/date into the headline. If you aren't Leo will say:
"Edit headline to append date/time"

Two new settings in leoConfig.leo/.txt specify the time/date format:

body_time_format_string
headline_time_format_string

These settings are really the format string passed to time.strftime(format).

See http://www.python.org/doc/current/lib/module-time.html for a complete list
of the format options. The "%m/%d/%Y %H:%M:%S" format is used by default,
resulting in a time/date format such as: 1/30/2003 8:31:55</t>
<t tx="edream.110203163054.231">These commands select the first or last node of an outline and make that node visible.</t>
<t tx="edream.110203163054.232">This command selects the parent of the previously selected node and makes that node visible.</t>
<t tx="edream.110203163054.233">These commands select the previous or following sibling of a node and make the newly selected node visible.</t>
<t tx="edream.110203163054.234">This command writes any files (in the presently selected outline) that do not exist.</t>
<t tx="edream.110203163054.235"></t>
<t tx="edream.110203163054.236">This allows time to be expressed as local time or gmttime.</t>
<t tx="edream.110203163054.237"></t>
<t tx="edream.110203163054.238">The Expand To Level n commands now expand only the nodes in the presently selected outline.  This makes these commands much more useful.

With these changes there is no longer any need for the Expand Subheads command.</t>
<t tx="edream.110203163054.239">This can be useful when clones are in the range of different @path directives.</t>
<t tx="edream.110203163054.240"></t>
<t tx="edream.110203163054.241">1. Leo now longer warns when writing customizeLeo.py.

2. Inserted a lock that prevents customizeLeo.py from being written unless use_customize_leo_dot_py = 1 in leoConfig.txt.  Leo writes a message to the log if customizeLeo.py is dirty but was not written because of the setting in leoConfig.txt.
</t>
<t tx="edream.110203163054.242"></t>
<t tx="edream.110203163054.243"></t>
<t tx="edream.110203163054.244"></t>
<t tx="edream.110203163054.245">This makes the file name easier to see in the Windows task bar.
</t>
<t tx="edream.110203163054.246"></t>
<t tx="edream.110203163054.247">This allows Leo to syntax color comments with @language plain.
The @comment directive must follow the @langauge directive.</t>
<t tx="edream.110203163054.248">In other words, the Pressing the Enter key in the Find panel executes the Find Next command.
</t>
<t tx="edream.110203163054.249">The syntax colorer now colors all element tags.  See the example in the child of this node.</t>
<t tx="edream.110203163054.250">@language html
@color
@ignore
&lt;HTML&gt;
&lt;!-- Author: Edward K. Ream, edream@tds.net --&gt;
&lt;HEAD&gt;
  &lt;META NAME="GENERATOR" CONTENT="Microsoft FrontPage 4.0"&gt;
  &lt;TITLE&gt; Leo's Home Page &lt;/TITLE&gt;
  &lt;META NAME="description" CONTENT="This page describes Leo.
Leo adds powerful outlines to the noweb and CWEB literate programming languages."&gt;
  &lt;META NAME="keywords" CONTENT="LEO, LITERATE PROGRAMMING, OUTLINES, CWEB,
NOWEB, OUTLINES, EDWARD K. REAM, DONALD E. KNUTH, SILVIO LEVY, OPEN SOFTWARE"&gt;
&lt;/HEAD&gt;
&lt;!-- Last Modified: May 12, 2002 --&gt;
&lt;BODY BGCOLOR="#fffbdc"&gt;

&lt;H1 ALIGN=CENTER&gt;&lt;a NAME="top"&gt;&lt;/a&gt;&lt;IMG SRC="Blank.gif" width=
"32" height="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"&gt;&lt;IMG SRC="leo.gif" 
WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"&gt;&lt;a href="leo_TOC.html#top"&gt;&lt;IMG SRC=
"arrow_rt.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"&gt;&lt;/a&gt; &amp;nbsp;&lt;/H1&gt;

&lt;H1 ALIGN=CENTER&gt; Leo's Home Page&lt;/H1&gt;

&lt;p align="center"&gt;&lt;a href="http://www.python.org/"&gt;&lt;img border="0" src="PythonPowered.gif" width="110" height="44"&gt; &lt;/a&gt; &lt;A HREF="http://sourceforge.net/"&gt;&lt;IMG SRC="http://sourceforge.net/sflogo.php?group_id=3458&amp;type=1" NATURALSIZEFLAG="0" ALT="SourceForge Logo"&gt;&lt;/A&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;A HREF="http://sourceforge.net/project/?group_id=3458"&gt;Leo at SourceForge&lt;/A&gt;&amp;nbsp;&amp;nbsp;
&lt;a href="icons.html"&gt;&lt;img border="0" src="LeoCodeGray.gif" width="77" height="42"&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;
&lt;a href="icons.html"&gt;&lt;img border="0" src="LeoProse.gif" width="81" height="42"&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;

&lt;H3&gt;&lt;A NAME="anchor127554"&gt;&lt;/A&gt;Summary&lt;/H3&gt;

&lt;UL&gt;
  &lt;LI&gt;Leo is a &lt;i&gt; programmer's editor&lt;/i&gt;  and a flexible &lt;i&gt;browser&lt;/i&gt; for
    projects, programs, classes or data. Leo clarifies design, coding, debugging, testing
  and maintenance.
  &lt;LI&gt;Leo is an &lt;i&gt;outlining editor&lt;/i&gt;. Outlines clarify the big picture while
    providing unlimited space for details.
  &lt;LI&gt;Leo
    is a &lt;a HREF="http://www.literateprogramming.com/"&gt;&lt;i&gt;literate
    programming&lt;/i&gt;&lt;/a&gt; tool, compatible with &lt;A HREF="http://www.eecs.harvard.edu/~nr/noweb/"&gt;noweb&lt;/A&gt;
    and &lt;a HREF="http://www-cs-faculty.stanford.edu/~knuth/cweb.html"&gt;CWEB&lt;/a&gt;.
    Leo enhances any text-based
programming language, from assembly language and C to Java, Python and XML.
  &lt;LI&gt;Leo is also a &lt;i&gt;data organizer&lt;/i&gt;. A single Leo outline can generate complex
    data spanning many different files.&amp;nbsp; Leo has been used to manage web sites.
  &lt;LI&gt;Leo is a &lt;i&gt; project manager&lt;/i&gt;. Leo provides multiple views
of a project within a single outline. Leo naturally represents tasks that remain
    up-to-date.
  &lt;LI&gt;Leo is fully &lt;i&gt; scriptable&lt;/i&gt; using &lt;A HREF="http://www.python.org/"&gt;Python&lt;/A&gt;
  and saves its files in &lt;A HREF="http://www.w3.org/XML/"&gt;XML&lt;/A&gt; format.
  &lt;LI&gt;Leo is &lt;i&gt;portable&lt;/i&gt;.&amp;nbsp; Leo.py is 100% pure Python and will run on
    any platform supporting &lt;A HREF="http://www.python.org/"&gt;Python&lt;/A&gt;
    and &lt;a href="http://tcl.activestate.com/"&gt;Tk/tcl&lt;/a&gt;, including Windows,
    Linux and MacOS X.&amp;nbsp; Leo.exe runs on any Windows platform.
  &lt;LI&gt;Leo is &lt;a href="http://www.opensource.org/"&gt; &lt;i&gt; Open Software&lt;/i&gt;&lt;/a&gt;, distributed under
    the &lt;a href="http://www.python.org/doc/Copyright.html"&gt; Python License&lt;/a&gt;.
&lt;/UL&gt;

&lt;H3&gt;More Information and downloads&lt;/H3&gt;

&lt;ul&gt;
  &lt;LI&gt;An excellent &lt;a href="http://www.3dtree.com/ev/e/sbooks/leo/sbframetoc_ie.htm"&gt;online
    tutorial&lt;/a&gt; and &lt;A HREF="http://www.jserv.com/jk_orr/xml/leo.htm"&gt;Leo resource
  page&lt;/A&gt;, both written by &lt;a href="http://www.jserv.com/jk_orr"&gt;Joe Orr&lt;/a&gt;.
  &lt;LI&gt;My brother's &lt;a href="SpeedReam.html"&gt;slashdot
    article about Leo&lt;/a&gt;, the best description about why Leo is special.
  &lt;LI&gt;&lt;A HREF="testimonials.html#anchor104391"&gt;What people are saying about Leo&lt;/A&gt;
  &lt;LI&gt;&lt;A HREF="leo_TOC.html#anchor964914"&gt;Complete users guide&lt;/A&gt;
    and
    &lt;A HREF="intro.html#anchor887874"&gt;tutorial introduction&lt;/A&gt;  with
  screen shots.
  &lt;li&gt;&lt;a href="FAQ.html"&gt;FAQ&lt;/a&gt; and &lt;a href="http://sourceforge.net/forum/?group_id=3458"&gt;help and discussion
    forums&lt;/a&gt;, preferable to &lt;A HREF="mailto:edream@tds.net"&gt;email&lt;/A&gt; so others may join
    in.&lt;/li&gt;
  &lt;li&gt;&lt;a href="icons.html"&gt;Icons&lt;/a&gt; for bragging about Leo.&lt;/li&gt;
&lt;/ul&gt;

&lt;a href="http://sourceforge.net/project/showfiles.php?group_id=3458"&gt;Download
    Leo&lt;/a&gt; from &lt;A HREF="http://sourceforge.net/project/?group_id=3458"&gt;Leo's SourceForge
site&lt;/A&gt;.

&lt;P ALIGN=left&gt;Leo's author is &lt;A HREF="http://personalpages.tds.net/~edream/index.html"&gt;Edward
  K. Ream&lt;/A&gt; email: &lt;A HREF="mailto:edream@tds.net"&gt;edream@tds.net&lt;/A&gt; voice: (608) 231-0766

&lt;HR ALIGN=LEFT&gt;

&lt;p align="center"&gt;

&lt;IMG SRC="Blank.gif" ALIGN="left" NATURALSIZEFLAG=
"3" width="34" height="34"&gt;&lt;IMG SRC="leo.gif" ALIGN="left" NATURALSIZEFLAG=
"3" width="32" height="32"&gt;&lt;a HREF="leo_TOC.html"&gt;&lt;IMG SRC="arrow_rt.gif" WIDTH="32"
HEIGHT="32" ALIGN="left" NATURALSIZEFLAG="3"&gt;

&lt;/BODY&gt;
&lt;/HTML&gt;
</t>
<t tx="edream.110203163054.251">- Added "Replace tabs with spaces" checkbox.

- The close button is equivalent to the "Cancel" button rather than the "Ok" button.</t>
<t tx="edream.110203163054.252">This was causing great confusion.</t>
<t tx="edream.110203163054.253"></t>
<t tx="edream.110203163054.254"></t>
<t tx="edream.110203163054.255">- There was a bug that prevented the command from working properly if the line number preceded the present line.

- The goto line number option only works on full path names in @file nodes. 
It does not work for relative paths or in combination with an @path directive.</t>
<t tx="edream.110203163054.256">This problem only arose with languages such as html that have no single-line comment delimiter.
</t>
<t tx="edream.110203163054.257"></t>
<t tx="edream.110203163054.258">Leo did not properly handle configuration settings containing the % character.
</t>
<t tx="edream.110203163054.259"></t>
<t tx="edream.110203163054.260">Double-clicking the icon box used to set the cursor to the hand.
</t>
<t tx="edream.110203163054.261">Every call to v.unjoinNode was calling c.clearAllVistied.

Fixing this bug will allow me not to use inodes &amp; locations for the foreseeable future.</t>
<t tx="edream.110203163054.262"></t>
<t tx="edream.110203163054.263"></t>
<t tx="edream.110203163054.264">In the unusual case that a language has no single-line comment delimiter, Leo will remove the block delimiters from the headline text in node sentinels.  createNthChild must take this into account by doing a second comparison of headlines if the normal comparison fails.  If the second comparison of headlines succeeds we assume that we should use the headline from the outline instead of the derived file.  I believe some kind of kludge like this will also be required for 4.0.</t>
<t tx="edream.110203163054.265">- Translating the "Tangle..." label differently from the "Tangle" one was 
impossible without modifying leo's source code (same thing for "Untangle..." 
and "Untangle").

- Couldn't translate either "Show Invisibles" and "Hide Invisibles". First 
toggle is OK then an error occurs after the second...</t>
<t tx="edream.110203163054.266">- changed copyPart so it returns on @code as well as @c.

- changed convertVnodeToWeb so that it takes account of the "at_root_bodies_start_in_doc_mode" setting.

- For the most part, directives other than @c, @code, @space, @doc, @others get written to the file as @@directive.  There are minor differences between how this is handled in @root and @file trees. This might be considered a bug, and I am not going to do anything unless someone complains loudly.
</t>
<t tx="edream.110203163054.267">Enabling or disabling @language or @comment now recolors entire text.</t>
<t tx="edream.110203163054.268"></t>
<t tx="edream.110203163054.269">I had forgotten to compile leo.nsi.</t>
<t tx="edream.110203163054.270"></t>
<t tx="edream.110203163054.271"></t>
<t tx="edream.110203163054.272">Python 2.3a1 contains a bug in the tkinter code.  This bug has been fixed on Python's cvs site.  Until this bug is fixed in an official Python release Leo must use:

true,false = 1,0

rather than:

true,false = True,False</t>
<t tx="edream.110203163054.273">leo.py 3.10                             December 14, 2002

This version of Leo corrects bugs, improves Leo's documentation and adds many new features:

- Rewrote the Scripting Chapter in Leo's Users Guide.
- Improved the Customization Chapter of the Users Guide.
- Adds several customizations contributed by Leo's users.
  Among these: @read-only nodes. Reading empty .leo files.
  Redirecting stderr and stdout to Leo's log pane.
- New Mark Clones and Go To Next Clone commands.
- New Export Headlines command.
- Control-dragging a node now clones it.
- New "Node Only checkbox in the Find/Change panel.
- @root-code trees start in code mode by default.
  This allows @root trees to work like @file trees.
- @root-doc  trees start in doc  mode by default.
- Converted leoConfig.py to use @root-code
- New at_root_bodies_start_in_doc_mode option in leoConfig.py.
  Specifies whether @root trees work like @root-code or @root-doc.
- New synonyms: @file-asis = @silentfile
  @file-nosent = @nosentinelsfile ; @file-noref = @rawfile.
- Leo now supports navigation of menus using underlined menus.
- Added an easy way to replace any Leo method by a function.
  The code in customizeLeo.py can now override any part of Leo's code!
- Added routines to redirect stderr and stdout to Leo's log pane.
  These routines can be called from customizeLeo.py.
- Added "event1" and "event2" hooks for customize event handling.
- Improved Leo's window icon, and improved how that icon is loaded.
- The usual assortment of bug fixes and minor improvements.
  Actually, this release fixes more than the usual number of bugs.

See the children of this node for full details.

The quote of the month:

I must say I am very impressed. I have been absolutely seduced by Leo over the
past few days. I tell you, I can not put it down. I feel like a kid with a
shiny new bike...I'm already bursting with new ways I'd like to use the tool in
the future -- Lyn Adams Headley</t>
<t tx="edream.110203163054.274"></t>
<t tx="edream.110203163054.275">The old code did not allow &lt;tag /&gt; in many cases.  The new code reads minimal.leo without complaint.  It is:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;leo_file&gt;
&lt;leo_header file_format="2" /&gt;
&lt;globals /&gt;
&lt;preferences /&gt;
&lt;find_panel_settings /&gt;
&lt;vnodes /&gt;
&lt;tnodes /&gt;
&lt;/leo_file&gt;
</t>
<t tx="edream.110203163054.276">Apparently the F4 shortcuts interferes with the Alt-F4 shortcut.</t>
<t tx="edream.110203163054.277">The content formerly on evisa.com, including the Leo tutorials is now on 3dtree.com.</t>
<t tx="edream.110203163054.278">Leo improperly added extra blank lines and tabs in @file-nosent trees.</t>
<t tx="edream.110203163054.279">Untangle was warning about a missing section if the section had only an @doc part.</t>
<t tx="edream.110203163054.280">Leo was not handling the class keyword properly.</t>
<t tx="edream.110203163054.281">When leo.py was launched from the command line specifying a non-existent file the message "file not found" was displayed but the outline pane was not drawn properly.</t>
<t tx="edream.110203163054.282">@nosentinelsfile nodes were not being marked dirty properly.

Also, the message in atFile.writeAll about "no @file node found"  did not include these nodes.  The message was generalized.</t>
<t tx="edream.110203163054.283">While scanning for the initial state we must make sure that i &lt; old_len and i &lt; new_len.

Leo was not handling Python ''' strings properly.</t>
<t tx="edream.110203163054.284">It is not correct to do:

	exec s in __builtins__

because that pollutes the namespaces of the __builtin__ module.  Correct is simply:

  exec s in {}</t>
<t tx="edream.110203163054.285">Previous versions of Leo did not properly recycle bindings in the outline pane.

This was reported by David LeBlanc and fixed with major hints from Chad Netzer.
</t>
<t tx="edream.110203163054.286"></t>
<t tx="edream.110203163054.287"></t>
<t tx="edream.110203163054.288">The lambda functions for callbacks were not working properly.</t>
<t tx="edream.110203163054.289">The fix was made to atFile.scanAllDirectives() and leoGlobals.scanDirectives()
tangle.scanAllDirectives() was not affected.

# Reversion fix: 12/06/02: We must use elif here, not if.
elif not old.has_key("language") and dict.has_key("language"):</t>
<t tx="edream.110203163054.290">This bug was created recently by the new underline/realMenuName logic.  We must not set the undo/redoRealMenuName ivars in clearUndoState: that should only be done when actually setting the menu names.</t>
<t tx="edream.110203163054.291"></t>
<t tx="edream.110203163054.292">Both command are enabled only if the presently selected node is a clone.  Mark Clones marks all nodes that are clones of the present node.  Go To Next Clone goes to the next node that is a clone of the present node. A little experimentation convinced me that this command should wrap.  So this command endlessly cycles among the nodes.  Trying to end the this endless cycling would not be easy, as my experience with the Find command shows.

These are straightforward (and surprisingly useful) commands.  Please report any problems immediately.</t>
<t tx="edream.110203163054.293">This works just like the Flatten Outline command except it writes only headlines.</t>
<t tx="edream.110203163054.294">How did I ever live without this.

Also improved messages and fixed a major performance bug: tree.numberOfVisibleNodes was being called repeatedly!</t>
<t tx="edream.110203163054.295">The Node Only checkbox takes precedence over Suboutline Only if they are both checked.</t>
<t tx="edream.110203163054.296">New in Leo 3.10:  Leo allows you to choose whether body text in @root trees will start in code mode or doc mode by default.

@root-doc filename and @root-code filename specify that body text is assumed to start in doc mode or code mode respectively.  The options (-doc and -code) must follow @root immediately with no intervening whitespace.  In effect, @root-code and @root-doc are two new directives.

These @root options override the new at_root_bodies_start_in_doc_mode option in leoConfig.py.  This option affects only @root trees without options.  Such "plain" @root trees are now deprecated, which only means that it is now better style to use either @root-code or @root-doc.  The reason is simple: the meaning of plain @root trees will depend on the at_root_bodies_start_in_doc_mode option, and that isn't good.

By default, at_root_bodies_start_in_doc_mode = 1 for compatibility for old @root trees.  I actually don't think this option is good for much; I created it before I created @root-doc and @root-code, and I decided it wouldn't hurt to leave it in.  Anyway, you now have complete flexibility about how @root works, and in particular you can make @root work just like @file.</t>
<t tx="edream.110203163054.297"></t>
<t tx="edream.110203163054.298">@file-asis is a synonym for @silentfile.
@file-nosent is a synonym for @nosentinelsfile.
@file-noref is a synonym for @norefsfile.</t>
<t tx="edream.110203163054.299">Completed a major revision of the menu handling code to handle underlined menus.  As is typical on Windows, you specify the underlined character by preceding it with an ampersand character.</t>
<t tx="edream.110203163054.300">Created a new icon and improved the code that loads it.</t>
<t tx="edream.110203163054.301">This is the funcToMethod function in customizeLeo.py.</t>
<t tx="edream.110203163054.302">See the relevant section of customizeLeo.py</t>
<t tx="edream.110203163054.303">"event1" and "event2" are generated for many Leo events. keywords.get("kind") returns one of the following for "event1" and "event2" hooks:

"activate",             activate window event   (not uniform across window managers).
"deactivate"            deactivate window event (not uniform across window managers).
"boxClick"              The +- box has been clicked.
"drag"                  Generated repeated while dragging nodes.
"endDrag"               mouseUp that ends a drag.
"headClick"             Left-click in a headline.
"headPopup"             Right-click in a headline.
"headKey"               A keypress in a headline.
"hyperLinkControlClick" Control-click on a hyperlink.
"hyperLinkEnter"        Mouse moves over a hyperlink.       Disabled at present.
"hyperLinkLeave"        Mouse moves away from a hyperlink.  Disabled at present.
"iconDoubleClick"       The icon box has been double-clicked.</t>
<t tx="edream.110203163054.304"></t>
<t tx="edream.110203163054.305"></t>
<t tx="edream.110203163054.306">The present code properly handles undo/redo for operations that copy trees, but copying trees itself causes problems for further undoes.  I've disabled further undos, as was done previously, but this is a pity.

To fix this, we may have to hack on the beads to indicated that a copy has been made.  No doubt about it: copying trees is tricky.</t>
<t tx="edream.110203163054.307">leo.py 3.9                               Nov 23, 2002

This is one of the most interesting versions of Leo ever released:

* Major performance improvements:
  - Incremental syntax coloring speeds response when typing.
  - Incremental undo drastically reduces memory used.

* Major improvements in customizing Leo:
  - Leo looks in the file customizeLeo.py for user-specific customizations.
  - Leo calls "hook routines" in customizeLeo.py for all commands and events.
    These hook routines can modify or replace any command or event.
  - New convenience routines simplify creating and modifying menus.
  - Easy translation of menus to other languages using customizeLeo.py.

* Better integration with other tools:
  - The Open With command allows you to communicate back and forth to other editors.
  - The Go To Line Number command converts lines numbers in derived files
    to locations in the outline.
  - Double-clicking the icon of a @url node launches any url in your web browser.
  - The Execute Script command executes Python code in any body pane.
    This is much more convenient than opening Leo's Idle window.
  - Much better support for cweb. At last, Leo has a power user of cweb.
    By default, @space, @* and @** sections are colored as latex text.
    Leo properly generates @q..@&gt; sentinels.
  - @nosentinelfile is like @file except Leo writes no sentinel lines.

* Other improvements:
  - Optional Emacs-style auto-indent.
  - Reformat Paragraph command.
  - Leo will optionally create nonexistent directories specified in
    @file, @root or @path, including all nonexistent parent directories.
  - Leo will place its own icon in Leo windows provided that you have
    installed Fredrik Lundh's PIL and tkIcon packages.
  - The usual assortment of bug fixes.

See the children of this node for full details.

P.S. Here is what Travers A. Hough recently said about Leo:

"When first I opened Leo, it was out of curiosity.  But having used it...I'LL NEVER GO BACK. THEY'LL HAVE TO PRY LEO OUT OF MY COLD, DEAD FINGERS! Seriously, it should be renamed "Crack Cocaine" because it's that addictive. I'm ready to start a 12-Step group."
</t>
<t tx="edream.110203163054.308"></t>
<t tx="edream.110203163054.309">The cweb prefs panel setting was overriding @language python (!)</t>
<t tx="edream.110203163054.310">@language pascal
@color

private
uses</t>
<t tx="edream.110203163054.311">app().log is now set correctly when there are multiple windows.  Previously, app().log depended on activate events, and was not reliable.  The following routines now set app().log:

- frame.doCommand
- frame.OnMenuClick

Thus, top() will be reliable after any command is executed.  Creating a new window and opening a .leo file also set app().log correctly, so it appears that all holes have now been plugged.

Note: The value of top() may change during a new or open command, which may change the routine used to execute the "command1" and "command2" hooks.  This is not a bug, and hook routines must be aware of this fact.
</t>
<t tx="edream.110203163054.312">Leo no longer massages comments when importing Java files.

There was a bug in massageBody that prevented text from being undented properly.  There was a bug in find_line_start (!!) that caused the start of the previous line to be found if s[i] was a newline.  It's amazing that these bugs were undiscovered for so long.

Treat interface like class.</t>
<t tx="edream.110203163054.313"></t>
<t tx="edream.110203163054.314">Version 3.9 contains many new features and commands.  The children of this node document them.</t>
<t tx="edream.110203163054.315"></t>
<t tx="edream.110203163054.316">Undo now uses incremental syntax coloring.  This speed up undo tremendously.</t>
<t tx="edream.110203163054.317">Previous versions of Leo stored the complete body text whenever any change was made to the body text.  The present version of undo stores only enough information to undo or redo the typing: typically two lines of text.  This results in about a 90% reduction in the memory used by undo.
</t>
<t tx="edream.110203163054.318">These are discussed in the child of this node.</t>
<t tx="edream.110203163054.319">@nocolor

You may customize Leo in several ways:

I.  Using leoConfig.txt

When Leo first starts, Leo looks for a file called leoConfig.txt, derived from leoConfig.leo, which contains extensive documentation for each setting.  The settings in leoConfig.txt include:

- Fonts used in Leo's body, outline and log panes.
- Colors used for syntax coloring.
- Menu shortcuts for all menu items.
- Sizes and splitter orientation for newly created windows.
- Initial entries in the Recent Files menu, and the Find, Preferences and Compare panels.
- The format of .leo files.

The section called "Using leoConfig.leo and leoConfig.txt" gives the rules for how Leo uses these two files.

II. Using plugins and hooks

New in 3.11:  It is no longer necessary to modify customizeLeo.py.  Instead of modifying customizeLeo.py you now should add plugins to the plugins directory.  In fact, customizeLeo.py will soon disappear entirely.

During startup, Leo looks for plugins, i.e., files whose name matches mod_*.py in the plugins directory.  These plugins register functions called "hooks" to be called a various times during execution.  Full details are provided below.

Plugins provide the following advantages:

- Any time you see a nice hook handler that someone has written you can just copy it to a plugin file and it runs next time you start Leo.
- You don't have to keep updating a large and growing customizeLeo.py file.
- You can disable and enable hooks by renaming the relevant plugin file.
  (or by enabling or disabling the code in the plugin that registers hook functions).
- You don't have to merge code from hooks pertaining to the same Leo event.

When executing any command or handling any event, Leo calls hook routines registered from the plugin files.  The arguments to hooks are:

- "tag", a string telling the kind of command or event about to be executed, and
- "keywords", a Python dictionary whose keys depend on the specific command or event.

This is a very simple, powerful and general mechanism for customizing Leo as you see fit.  There are dozens of kinds of hooks, including the "command1" and "command2" hooks that are called before and after each of Leo's menu commands.  Leo will allow you to override most commands and event handling.  In many cases, if a hook returns any value except None Leo will assume that the hook has completely handled the command or event and will take no further action.  The details will be explained in full below.

Leo catches all exceptions raised in hook code, so you can modify hooks without worry.

SECURITY WARNINGS: Using hooks naively can create the potential for virus-like behavior.  Please read the section called SECURITY WARNINGS for full details.

III. Using convenience routines called from hooks.

Hook routines can import any file in Leo's source code and execute routines in that file.  Leo's contains a number of convenience routines designed to make common customization tasks easier.  Hooks can use these routines to create your own menus, to translate menus into other languages, and to create entries in the Open With menu.  These convenience routines are discussed in detail below.

IV. Setting app().realMenuNameDict inside hooks to translate menus into other languages.

This is discussed below.</t>
<t tx="edream.110203163054.320">@nocolor

Leo will override settings in .leo files if it finds a file called leoConfig.txt in the config subdirectory.  Leo works just as before if it does not find a leoConfig.txt file.

You should make changes to leoConfig.txt by changing leoConfig.leo and then executing the Tangle All command.  There are two advantages to changing leoConfig.txt in this manner.  First, it is just easier to change leoConfig.leo.  Second, all comments are lost in leoConfig.txt when Leo updates it, so using leoConfig.leo as the primary data file means you will always have the comments available.

Leo looks for leoConfig.txt first in the directory specified by the Python variable sys.leo_config_directory.  You would typically set this variable in Python's sitecustomize.py file.  If this variable does not exist, Leo looks in the directory from which Leo was loaded.

The child of this node contains an example of leoConfig.txt that shows all the options that may be set.

Settings in leoConfig.txt overrides preferences in .leo files, but only for those items actually in leoConfig.txt, so you can choose which settings you want to override.  Also, a Leo ignores any setting in leoConfig.txt whose value is "ignore" (without the quotes). For example:

[prefs panel options]
tab_width = ignore

If a setting is overridden, it is _not_ written to the .leo file when the outline is saved.  Note that this does not change the file format: all previous versions of Leo will be able to read such .leo files.

The preceding is probably all you need to know to use leoConfig.txt.  The following discuss some minor details: 

1. When reading a .leo file, if a setting is found neither in leoConfig.txt nor in the .leo file, Leo uses a default, hard-coded value.  In leo.py 3.0 and later these default settings are found in tables that appear in the section called:

	&lt;&lt; define default tables for settings &gt;&gt;

in the file leoConfig.py. So it is now convenient to change settings in leo.py itself as well as in leoConfig.txt.

2. Leo will update leoConfig.txt unless the read_only option is on in leoConfig.txt.  

WARNING: there are problems when Leo does write leoConfig.txt: all comments are lost and options and sections are written in a random order.  This is due to problems in Python's ConfigParser module and will not be changed any time soon.

3. Provided the read_only option is off, Leo updates leoConfig.txt whenever it saves a .leo file or whenever the Preferences panel is closed without being canceled.  When updating leoConfig.txt, Leo will write only existing settings whose value is not "ignore".

4. When Leo saves a .leo file, Leo will write a Preferences setting to the .leo file only if the setting will not be written when updating leoConfig.txt.  In particular, changes made in the Preferences Panel will become permanent immediately if Leo the read_only option is off.  Otherwise the change will become permanent when any .leo file is saved.</t>
<t tx="edream.110203163054.321">Beginning with version 3.11, you may use plugins to customize how Leo works.  You can

- override or modify any command
- add or customize menus or
- translate menus into any language.

Plugins have full access to all of Leo's source code.  In particular, several convenience methods have been added to make customizing menus and commands easier.

Plugins are permanent: they will not go away when Leo is updated.  You can take
advantage of the latest CVS updates _without_ having to throw away your modifications.

Important warning: plugins must avoid blindly executing scripts in .leo files.  Doing so could expose all parts of your computer to malicious Python code.  The section called "Security warnings and precautions" discusses how to customize Leo safely and how to avoid several pitfalls.</t>
<t tx="edream.110203163054.322">@nocolor

What is a plugin?

A plugin is a .py file that appears in Leo's plugin subdirectory. Leo tries to
import all such files while starting up. This is done at "start1" time, that
is, in the call to doHook("start1") in the run function in leo.py. Plugins
exist to define "hook code".

New in 3.11: Leo looks in the plugins folder for .py files. Leo tries to
import all such files at startup ("start2") time.

New in 4.1: Leo enables only plugins whose name appears in pluginsManager.txt.
Leo loads plugins in the order in which they appear in pluginsManager.txt. Leo
loads no plugins if pluginsManager.txt does not exist in the plugins directory.

What is hook code?

Leo automatically calls hook code at various times during Leo's execution.
Typical hooks are:

- "start2", called at the end of Leo's startup process,
- "command1", called before executing any of Leo's commands
- "idle", called at Tk's idle time, when nothing else is happening,

See the documentation for hooks in this file for full details.

N.B. Plugins can use "start2" hooks to override any of Leo's classes. See
"Overriding functions, methods &amp; classes" in leoPlugins.leo for several
examples of how to do this.

How do plugins work?

Plugins register themselves when Leo imports them using the following code,
which should appear as the outer level of the .py file:

@color

"""A description of this plugin"""

registerHandler("xxx", onXXX)
__version__ = "1.2"
plugin_signon(__name__)
	
@nocolor

Line by line:

1) """A description of this plugin"""

This is a Python doc string describing the plugin. This string becomes the
value of the __name__ attribute for the module (.py file).

2) registerHandler("xxx", onXXX)

This line registers a handler called onXXX for the hook called "xxx". See the
documentation for hooks for a complete list of hook names that you can use
instead of "xxx". onXXX is the name of a function or method, presumably defined
in the plugin file, that Leo will call at "xxx" time. For example:

registerHandler("idle",onIdle)

will cause Leo to call the onIdle function at "idle" time.

You can pass a list of hook names as the first argument to registerHandler. For
example:

registerHandler(("bodykey1","bodykey2","headkey1","headkey2"), onKey)

3) __version__ = "1.2"

This assigns a version attribute to module. At present this attribute is used
by the plugin code that creates Leo's Plugins menu.

4) plugin_signon(__name__)

This line increases the count of loaded modules. The present code for
plugin_signon does not actually print separate signons--it seems to verbose.

About hook handlers

See the "About hooks" section of leoPlugins.leo for full documentation about
how to write hook handler routines, like onXXX or onKey in the examples above.
Basically, each hook should have this pattern:
	
@color

def onXXX (tag,keywords):
	c = keywords.get("c")
	otherKeyword = keywords.get("otherKeyword")
	&lt;&lt; do something with c and otherKeyword, etc. &gt;&gt;
	
@nocolor

In other words, keywords is a Python dictionary containing the keyword
arguments passed to the hook handler. See the See the "About hooks" section of
leoPlugins.leo for a list of the keywords passed to each hook handler.

The tag is the name of the hook. For example, tag would one of
"bodykey1","bodykey2","headkey1","headkey2", for the onKey hook handler in the
example above.

What's next?

It's one thing to know how to create a plugin. It's another to know how to
actually change Leo. Obviously, some study is needed. The place to start your
study is LeoPy.leo. In particular, study very carefully the section called
"Overview of code". Leo is a highly modular program, and Python is ideally
suited to this style of programming.</t>
<t tx="edream.110203163054.323">@nocolor

New in 3.11: Leo looks in the plugins folder for .py files. Leo tries to
import all such files at startup ("start2") time.

New in 4.1: Leo enables only plugins whose name appears in pluginsManager.txt.
Leo loads no plugins if pluginsManager.txt does not exist in the plugins directory.

The child of this node gives an example of the code that creates the Open With
menu. The following code, appearing at the end of mod_open_with.py, registers
two different hook functions. The on_idle function is the "idle" hook. The
create_open_with_menu is the "start2","open2" and "command2" hooks.

@color

# Register the handlers... 
registerHandler("idle", on_idle) 
registerHandler(("start2","open2","command2"), create_open_with_menu) 
es("...open with")
	
@nocolor
Plugins may call registerHandler with a hook name like "idle" or a list of hook
names like ("start2","open2","command2"). Also, you can use the "all" hook name
to indicate that code will be called for all hooks. This is useful for tracing
hooks. Plugins may also call registerExclusiveHandler for hooks that should not
be redefined in other plugins.

mod_open_with.py also contains the on_idle and create_open_with functions that
actually handle the hook. Such functions have two arguments: tag and keywords.
You will find many examples of this in LeoPy.leo.

About error checking:

At present Leo will disable all hooks if any hook throws an exception. In
practice this isn't a big deal, but something better could be done.

How to send me your plugins:

It should now be _much_ easier to submit a plugin for inclusion in LeoPy.leo.
Just send me a .leo file containing @file mod_your_plugin.py. Please have this
@file node be @ignored: this is more convenient for me. Ideally, your .leo file
should contain _only_ your plugin code.</t>
<t tx="edream.110203163054.324">@color
@language python
@ignore

"""Open With handler"""

from customizeLeo import *
from leoGlobals import *

@others

if 1: # Register the handlers...
	registerHandler("idle", on_idle)
	registerHandler(("start2","open2","command2"), create_open_with_menu)
	es("...open with")</t>
<t tx="edream.110203163054.325"># frame.OnOpenWith creates the dict as follows:
# dict = {"c":c, "v":v, "f":f, "path":path, "time":time}

def on_idle (tag,keywords):

	import os
	a = app()
	for dict in a.openWithFiles:
		path = dict.get("path")
		c = dict.get("c")
		v = dict.get("v")
		if path and os.path.exists(path):
			try:
				time = os.path.getmtime(path)
				if time and time != dict.get("time"):
					dict["time"] = time
					&lt;&lt; update v's body text &gt;&gt;
			except: pass</t>
<t tx="edream.110203163054.326">&lt;&lt; set s to the new text &gt;&gt;
body = v.bodyString()
&lt;&lt; set conflict flag &gt;&gt;

if conflict:
	# Report the conflict &amp; set update.
	import leoDialog
	d = leoDialog.leoDialog()
	message = "Conflict in %s.\n\n" % (v.headString())
	message += "Replace outline with external changes?"
	update = d.askYesNo("Conflict!",message) == "yes"
else:
	update = s != body

if update:
	h = v.headString()
	es("changed:" + h)
	v.setBodyStringOrPane(s)
	c.selectVnode(v)
	v.OpenWithOldBody = s
</t>
<t tx="edream.110203163054.327">try:
	# Update v from the changed temp file.
	f=open(path)
	s=f.read()
	f.close()
except:
	es("can not open " + shortFileName(path))
	break
</t>
<t tx="edream.110203163054.328">try:
	# The OpenWithOldBody attribute does not normally exist in vnodes.
	old_body = v.OpenWithOldBody
	conflict = body != old_body and body != s
except:
	conflict = v.isDirty() and body != s
</t>
<t tx="edream.110203163054.329">def create_open_with_menu (tag,keywords):

	if  (tag in ("start2","open2") or
		(tag=="command2" and keywords.get("label")=="new")):
	
		&lt;&lt; create the Open With menu &gt;&gt;

		# Enable the idle-time hook so we can check temp files created by Open With.
		from leoGlobals import enableIdleTimeHook
		enableIdleTimeHook(idleTimeDelay=500)
</t>
<t tx="edream.110203163054.330">@ Entries in the following table are the tuple (commandName,shortcut,data).
data is the tuple (command,arg,ext).
command is one of "os.system", "os.startfile", "os.spawnl", "os.spawnv" or "exec".
Leo executes command(arg+path) where path is the full path to the temp file.
If ext is not None, the temp file has the extension ext,
Otherwise, Leo computes an extension based on what @language directive is in effect.
@c

idle_arg = "c:/python22/tools/idle/idle.py -e "

if 1: # Default table.
 table = (
  ("&amp;Idle",   "Alt+Shift+I",("os.system",idle_arg,".py")),
  ("&amp;Word",   "Alt+Shift+W",("os.startfile",None,".doc")),
  ("Word&amp;Pad","Alt+Shift+T",("os.startfile",None,".txt")))
else: # David McNab's table.
 table = (
  ("X&amp;Emacs", "Ctrl+E", ("os.spawnl","/usr/bin/gnuclient", None)))

top().frame.createOpenWithMenuFromTable(table)
</t>
<t tx="edream.110203163054.331">Naively using hooks can expose you and your .leo files to malicious attacks.  You will be safe as long as you follow these basic principles:

1. Hooks should _never_ blindly execute Python scripts in .leo files. Blindly executing scripts in .leo files runs the extreme risk of executing malicious code if you ever share any .leo file with someone else.  Moreover, using rexec instead of exec WILL NOT PROTECT YOU.  See the children of this node for further discussion of this important topic.

2. Hooks can execute any code safely _provided_ that all code is contained entirely within the plugin file. If you have a nifty customization that you want to do on a particular .leo file, put that code into a plugin.

3. Use only authentic copies of Leo that come from Leo's SourceForge site.</t>
<t tx="edream.110203163054.332">I'd like to thank Stephen Schaefer for gently insisting that we must guard against malicious code in shared .leo files.  Here is a little story Stephen told on Leo's SourceForge site that makes clear what the danger is:

"I foresee a future in which the majority of leo projects come from marginally trusted sources...I see a world of leo documents sent hither and yon - resumes, project proposals, textbooks, magazines, contracts - and as a race of Pandora's, we cannot resist wanting to see "What's in the box?" And are we going to fire up a text editor to make a detailed examination of the ASCII XML? Never! We're going to double click on the cute leo file icon, and leo will fire up in all its raging glory. Just like Word (and its macros) or Excel (and its macros)."

This succinctly illustrates the fundamental problem: when we share "our" .leo files we can _not_ assume that we know what is our "own" documents.  So hooks that naively searches through .leo files looking for scripts to execute is looking for big trouble.

The following node contains an example of the kind of code that is extremely dangerous.</t>
<t tx="edream.110203163054.333">@color
@ WARNING ***** Using the following routine exposes you to malicious code in .leo files! *****

Do not EVER use code that blindly executes code in .leo files!
Someone could send you malicious code embedded in the .leo file.

WARNING 1: Changing "@onloadpythonscript" to something else will NOT protect
           you if you EVER share either your files with anyone else.

WARNING 2: Replacing exec by rexec below provides NO additional protection!
           A malicious rexec script could trash your .leo file in subtle ways.
@c
if 0: # WRONG: This blindly execute scripts found in an .leo file! NEVER DO THIS!
	def onLoadFile():
		v = top().rootVnode()
		while v:
			h = v.headString().lower()
			if match_word(h,0,"@onloadpythonscript"):
				s = v.bodyString()
				if s and len(s) &gt; 0:
					try: # SECURITY BREACH: s may be malicious!
						exec(s + '\n',__builtins__,__builtins__)
					except:
						es_exception()
			v = v.threadNext()
</t>
<t tx="edream.110203163054.334">@color
@ It would be most foolish to expect rexec to protect you against malicious code contained in .leo files.  Remember that Leo is a repository of source code, so any text operation is potentially malicious.

For example, consider the following script.  This script is valid in rexec mode:
@c

c = top()
thisNode = c.currentVnode()
v = c.rootVnode()
while v:
	&lt;&lt; change all instances of rexec to exec in v's body &gt;&gt;
	v = v.threadNext()
&lt;&lt; delete thisNode &gt;&gt;
&lt;&lt; clear the undo stack &gt;&gt;

@ This script will introduce a security hole the .leo file without doing anything prohibited by rexec, and without leaving any traces of the perpetrating script behind.  The damage will become permanent _outside_ this script when the user saves the .leo file.
</t>
<t tx="edream.110203163054.335">pass</t>
<t tx="edream.110203163054.336">pass</t>
<t tx="edream.110203163054.337">pass</t>
<t tx="edream.110203163054.338">Hooks have full access to all of Leo's source code simply by importing it.

Moreover, several convenience methods have been added to make customizing menus and commands easier.  The following paragraphs discuss these routines and how to use them.

</t>
<t tx="edream.110203163054.339">The following routines enable and disable "idle" hooks.  They are defined in leoGlobals.py.

enableIdleTimeHook(idleTimeDelay=100)

Enables the "idle" hook. After this routine is called Leo will call the "idle" hook approximately every idleTimeDelay milliseconds.  Leo will continue to call the "idle" hook periodically until disableIdleTimeHook() is called.

disableIdleTimeHook()

Disables the "idle" hook.</t>
<t tx="edream.110203163054.340">The following convenience routines make creating menus easier.

These are methods of the leoFrame class.  Use top().frame to get the frame object for the presently active Leo window.

The plugins node in LeoPy.leo gives examples of how to use these routines to create custom menus and to add items to the Open With menu.

These convenience methods all do complete error checking and write messages to the log pane and to the console if errors are encountered.</t>
<t tx="edream.110203163054.341">@nocolor
createMenuItemsFromTable (self,menuName,table,openWith=0)

This method adds items to the menu whose name is menuName.  The table argument describes the entries to be created.  This table is a sequence of items of the form (name,shortcut,command).

- name is the command name
- shortcut is the shortcut, or None to indicate no shortcut.
- command is the routine to execute when the menu item is selected.

An entry of the form ("-",None,None) indicates a separator line between menu items.

For example:
@color
table =
	("Toggle Active Pane","Ctrl-T",self.OnToggleActivePane),
	("-",None,None),
	("Toggle Split Direction",None,self.OnToggleSplitDirection))

top().frame.createMenuItemsFromTable("Window",table)
@nocolor

If the openWith keyword argument is 1 the items are added to a submenu of the Open With menu.  However, it will be more convenient to use the createOpenWithMenuFromTable method to create the Open With menu.
</t>
<t tx="edream.110203163054.342">createNewMenu (self,menuName,parentName="top")

This method creates a new menu:

- menuName is the name of the menu to be created.
- parentName is the name of the parent menu, or "top" if the menu is to created in the menu bar.

This method returns the menu object that was created, or None if there was a problem.  Your code need not remember the value returned by this method.  Instead, your code will refer to menus by name.
</t>
<t tx="edream.110203163054.343">createOpenWithMenuFromTable (self,table)

This method adds items to submenu of the Open With menu item in the File menu.

The table argument describes the entries to be created.  This table is a sequence of items of the form (name,shortcut,data).

- name is the command name
- shortcut is the shortcut, or None to indicate no shortcut.
- data is a tuple of the form (command,arg,ext)
- command is one of "os.system", "os.startfile", "os.spawnl", "os.spawnv" or "exec".
- arg is an argument to be passed to the given command.
- ext is a file extension or None.

When the user selects the Open With item corresponding to the table item Leo executes command(arg).
If ext is not None, the temp file has the given extension.
Otherwise, Leo computes an extension based on what @language directive is in effect.

For example:

table = (
	("Idle",   "Alt+Shift+I",("os.system",idle_arg,".py")),
	("Word",   "Alt+Shift+W",("os.startfile",None,".doc")),
	("Wordpad","Alt+Shift+T",("os.startfile",None,".txt")))

top().frame.createOpenWithMenuFromTable(table)
	</t>
<t tx="edream.110203163054.344">deleteMenu (self,menuName)

Deletes the menu whose name is given, including all entries in the menu.</t>
<t tx="edream.110203163054.345">deleteMenuItem (self,itemName,menuName="top")

Deletes the item whose name is itemName from the menu whose name is menuName.  To delete a menu in the menubar, specify menuName="top".</t>
<t tx="edream.110203163054.346">@nocolor
The leoFrame class creates the Window menu as follows:
@color

windowMenu = self.createNewMenu("&amp;Window")

table = (
	("&amp;Equal Sized Panes","Ctrl-E",self.OnEqualSizedPanes),
	("Toggle &amp;Active Pane","Ctrl-T",self.OnToggleActivePane),
	("Toggle &amp;Split Direction",None,self.OnToggleSplitDirection),
	("-",None,None),
	("Casca&amp;de",None,self.OnCascade),
	("&amp;Minimize All",None,self.OnMinimizeAll),
	("-",None,None),
	("Open &amp;Compare Window",None,self.OnOpenCompareWindow),
	("Open &amp;Python Window","Alt+P",self.OnOpenPythonWindow))

self.createMenuEntries(windowMenu,table)
</t>
<t tx="edream.110203163054.347">@nocolor

It is easy for hooks to translate menus into another language.  For example, code similar to the following code would typically be found in the "start2" hook:

@color

table = (
	("Open...","&amp;Ouvre"),
	("OpenWith","O&amp;uvre Avec..."),
	("close","&amp;Ferme"),
	("Undo Typing","French &amp;Undo Typing"), # Shows you how much French I know ;-)
	("Redo Typing","French &amp;Redo Typing"),
	("Can't Undo", "French Can't Undo"),
	("Can't Redo", "French Can't Redo"))
# Call the convenience routine to do the work.
app().setRealMenuNamesFromTable(table)</t>
<t tx="edream.110203163054.348">New in 4.0: Leo can now read and write "foreign" attributes in &lt;v&gt; and &lt;t&gt; elements in .leo files:

- When reading a .leo file, Leo will create t.unknownAttributes or v.unknownAttributes ivars for any tnode and vnode object whose corresponding &lt;v&gt; or &lt;t&gt; element in the .leo file contains a foreign attribute.

- The unknownAttributes ivars are a dictionary whose keys are the attribute names and whose values are strings.

- When writing a file, Leo will write "foreign" attributes if  a vnode or tnode contains an unknownAttributes ivar.

- The only "native" attributes that Leo expects to find are the "tx" attribute in &lt;t&gt; elements and the "a", "t", "vtag" and "tnodeList" attributes of &lt;v&gt; elements.  Everything else is a foreign attribute.

- Leo performs the usual xml escapes on these strings when reading or writing the unknownAttributes ivars.

Plugins may cause Leo to write such foreign attributes simply by attaching unknownAttributes ivars to a vnode or tnode.  For example:

	v.unknownAttributes = {"vnodeIcon" : pathToIcon}

It would be best not to delete other foreign attributes, so the following would be preferred:

	if hasattr(v,"unknownAttributes"):
		v.unknownAttributes["vnodeIcon"] = pathToIcon
	else:
		v.unknownAttributes = {"vnodeIcon" : pathToIcon}

Another way:

	try:
		v.unknownAttributes["vnodeIcon"] = pathToIcon
	except AttributeError:
		v.unknownAttributes = {"vnodeIcon" : pathToIcon}

See the section called "Recommended conventions for plugins" for advice about how to avoid potential conflicts in naming new attributes.</t>
<t tx="edream.110203163054.349">Leo creates nonexistent directories only if create_nonexistent_directories = 1 in leoConfig.txt.

Previous versions of Leo created a new directory only if its parent directory already existed.  Now, Leo will create all non-existing directories as required.

For example.  Suppose neither dir1 nor dir2 exists.  Leo will create both dir1 and dir1 when it writes the following @file \root\dir1\dir2\spam.py.</t>
<t tx="edream.110203163054.350"></t>
<t tx="edream.110203163054.351">Double-clicking the icon box of a node whose headline has the form:

@url &lt;any url&gt;

executes the url in your default web browser.

Leo checks that the url is valid before doing so. A valid url is:

-- 3 or more lowercase alphas,
-- followed by one ':',
-- followed by one or more of: $%&amp;'()*+,-./0-9:=?@A-Z_a-z{}~
-- followed by one of:         $%&amp;'()*+/0-9:=?@A-Z_a-z}~

Url's should contain no spaces: use %20 to indicate spaces.

You may use any type of url that your browser supports: http,mailto,ftp,file,etc.
</t>
<t tx="edream.110203163054.352"></t>
<t tx="edream.110203163054.353">The present version should be quite usable for its main purpose: tracking
down lines corresponding to error messages. In particular, except for possible
pathological cases, Leo should always put the cursor in the node containing the
referenced line. Possible pathologies involve asking Leo to "go to" a sentinel
line. It won't always be clear what node contains the sentinel.

I am well aware that Leo may not put the cursor on the proper line within
the vnode, but human beings being the excellent pattern matchers that we are,
we should be easily be able to find a line within a node.

Notes in LeoPy.leo, in the node called (Go to line number), discuss a variety
of issues that may cause the cursor not to go to the "proper" line. It also
discusses a better way to position the cursor.

Internally, there are two main versions of this command: one for @silentfile
trees, and one for @rawfile and @file trees. In the first case, there are no
sentinels in the derived file, so Leo just steps through the outline. This is
the easy case, and should work well. In the second case (@rawfile and @file
trees), the derived file contains sentinels, and Leo uses those sentinels to
determine in what vnode the given line occurs.

In this second case, Leo can almost always position the cursor within the
proper node, because Leo just scans back in the derived file looking for the
proper @+node sentinel. However, in order to "count" lines in the derived file
(to place the cursor properly _within_ the body text) Leo must recreate exactly
the logic used by the atFile.read logic, and that isn't easy. Moreover, there
is _no_ guarantee that the derived file is unchanged from when it was written;
after all, if you get syntax errors you tend to want to fix them ;-)

Please do not report bugs in this command, unless the bug involves a
crash, which would be reported both in Leo's log pane and in the console
window. This command will probably be improved in 3.10.</t>
<t tx="edream.110203163054.354">At last Leo has a power user of cweb.  Cweb mode is now fully tested and fully functional.  The following improvements have been made to cweb mode:

1. Corrected sentinels used in cweb mode.

Leo must double _all_ @ signs following the @q@. For example, an @@color sentinel gets turned into @q@@@@@color@&gt;.

2. Leo colors cweb doc parts and C comments in LaTex mode by default.

In cweb mode Leo colors @space, @* and @** sections using LaTeX coloring by default.  The color_cweb_doc_parts_with_latex option in leoConfig.py/.txt affects this default.

Similarly, Leo colors C comments in cweb mode using LaTeX coloring by default. The color_cweb_comments_with_latex option in leoConfig.py/.txt affects this default.

3. Cweb mode works similarly in @file and @root trees.

See the child of this node for full details about cweb mode.
</t>
<t tx="edream.110203163054.355">Cweb mode refers to how Leo tangles an outline when @language cweb is in effect or the cweb option in the Preferences Panel is in effect.

Leo treats _all_ cweb code in cweb mode as unevaluated text.  That is, Leo treats cweb control codes, including @&lt;...@&gt;, @&lt;...@&gt;=, @c, @space, @* and @** as "raw" text within cweb mode.  Leo does _not_ expand _cweb_ section references when writing derived files in cweb mode.  However, Leo _does_ expand _noweb_ section references, so you may use noweb sections to organize cweb files! You can create _noweb_ code and doc sections using the @code and @doc directives in place of @c and @space directives.

By default, cweb colors @space, @* and @** sections using the same syntax coloring as for LaTeX.  In addition, cweb colors C // and /*..*/ comments using LaTeX coloring by default.  You may change these defaults using the color_cweb_doc_parts_with_latex and color_cweb_comments_with_latex options in leoConfig.py.</t>
<t tx="edream.110203163054.356">The Open With command allows you to communicate with external editor.  When you select this command Leo creates a temporary file and invokes an external program.  Leo periodically checks whether this temporary file has changed; Leo changes the corresponding node in the outline if so.

You must create the entries in the Open With submenu. This would typically be done in a hook routine, using the createOpenWithMenuFromTable routine described in the child of this node.

The @file mod_open_with.py node in LeoPy.leo gives a complete example of handling the Open With menu.</t>
<t tx="edream.110203163054.357">Leo now supports optional Emacs-style auto-indent.  This style of auto-indent aligns newly created lines with unmatched ( [ or { brackets in the previous line. This feature is enabled only if smart_auto_indent = 1 in leoConfig.txt.

This code was contributed by David McNab, david@rebirthing.co.nz.</t>
<t tx="edream.110203163054.358">New in leo.py v3.9

Whether importing text from an outside source, typing in text, or modifying text, eventually you end up with a block of text in which some lines are too long and some are too short.  The Reformat Paragraph command will rearrange the words in a text paragraph to fill each line as full as possible, up to the @pagewidth setting.

A paragraph is delimited by blank lines, Leo directives, and (of course) start and end of text in a node.  The width of the line used by the reformatting operation is governed by @pagewidth and the indentation that would be applied to the node when tangled (as part of a @root) or written (as part of a @file).

The command operates on the paragraph containing the insert cursor.  If the insert cursor is on a blank line or directive, nothing happens.  If the cursor is on a line containing text, then the paragraph containing that text line is reformatted and the insert cursor is moved to the next paragraph.

Be careful that you don't do this on source code!  Of course, if you do reformat something that should have been left alone, then just Undo.

NOTE: Lines with hanging indentation are handled so that the hanging indentation is preserved.  This is most useful for bulleted or numbered lists, such as:

  1. This is the first paragraph, and
     it has a hanging indentation.

  2. This is the second paragraph, and
     it too has a hanging indentation.</t>
<t tx="edream.110203163054.359">An @rawfile tree is a tree whose root headline starts with @rawfile &lt;filename&gt;.  Similarly, for @silentfile and @nosentinelsfile trees.

Leo creates files derived from @file and @nosentinelsfile trees in exactly the same way.  The _only_ difference is that files derived from @file trees contain sentinels, while files derived from @nosentinelsfile trees do not.  Therefore, Leo can not update outlines from changed made from files derived from @nosentinelfile trees.

Leo creates files derived from @rawfile and @silentfile trees by writing the body text of all nodes of the tree in outline order.  Leo writes the body text _as is_, without recognizing section definitions, without expanding section references, and without treating directives specially in any way.  In particular, Leo copies all directives, including @space or @c directives, to the derived file as text. However, Leo recognizes the @ignore directive in the _ancestors_ of @rawfile or @silentfile nodes, so you may use the @ignore directive as usual to prevent Leo from writing @rawfile and @silentfile trees.

There are several difference between @rawfile and @silentfile trees:

1. Leo writes no sentinel lines when writing @silentfile trees.  When writing @rawfile trees, Leo writes only the @+leo, @-leo, @+node, @-node, @+body and @-body sentinels. Therefore, Leo can update @rawfile trees, but _not_ @silentfile trees from changes made in derived files. Unlike @file and @rawfile trees, the primary source of information for an @silentfile tree is the outline containing it.

2. Within @silentfile trees only, if a headline starts with @@, Leo writes everything in the headline following the @@ just before the corresponding body text.

3. Files derived from @silentfile trees contain _nothing_ not contained in body text (or @@ headlines).  In particular, if body text does not end in a newline, the first line from the next node will concatenated to the last line of the preceding node.

In short, you can get any combination of sentinels/no sentinels and references/no references using @file, @nosentinelsfile, @rawfile and @silentfile trees.  This is shown in the following table:

                     Derived files        Sections and 
    Type of tree   contain sentinels?   @others expanded?
    ------------   ------------------   -----------------
           @file   yes                  yes
@nosentinelsfile   no                   yes
        @rawfile   yes                  no
     @silentfile   no                   no

New in Leo 3.10:

@file-asis is a synonym for @silentfile.
@file-nosent is a synonym for @nosentinelsfile.
@file-noref is a synonym for @rawfile.
</t>
<t tx="edream.110203163054.360">leo.py 3.8                               October 29, 2002

Many major improvements have been made to Leo, all made as the result of user requests:

- New @rawfile and @silentfile trees complement @file trees.
  @rawfile and @silentfile trees create derived files without using sections.
  @rawfile files contain only those sentinels needed to automatically untangle them.
  @silentfile trees contain no sentinels at all.
- New @raw and @end_raw directives allow unformatted code within @file trees.
- Much better support for CWEB.  You may organize .w files using noweb!
- The @comment and @language directives may now apply simultaneously.
- Leo can now read, remember and write &lt;?xml-stylesheet...?&gt; lines,
  under control of the new stylesheet option.
- The new output_newline option specifies the line endings used when writing files.
- The new output_initial_comment option specifies the text to appear
  in an @comment sentinel at the start of each derived file.
- New commands in the help menu make it much easier to change configuration options.
- Dozens of minor improvements and bug fixes.

This month Dave Hein and I discovered how to uniquely and permanently identify nodes, regardless of where those nodes are located and regardless of how many people are working simultaneously on them.  This discovery will greatly improve Leo, and will simplify how people use Leo with CVS.  Leo 4.0, due out in a month or two, will be the first version of Leo to use this breakthrough.

See the children of this node for full details.
</t>
<t tx="edream.110203163054.361"></t>
<t tx="edream.110203163054.362"></t>
<t tx="edream.110203163054.363">The warning for "unknown language" had an unbound var.</t>
<t tx="edream.110203163054.366"></t>
<t tx="edream.110203163054.368">Leo now properly handles @delims directives in @file trees.</t>
<t tx="edream.110203163054.369">Leo now properly recognizes all sentinel lines when @language cweb is in effect.</t>
<t tx="edream.110203163054.370">Fixed a bug that caused Leo to say "methods" rather than "functions" when importing C code.

Leo now adds @root &lt;filename&gt; statement when importing to @root nodes.</t>
<t tx="edream.110203163054.371"></t>
<t tx="edream.110203163054.372"></t>
<t tx="edream.110203163054.373"></t>
<t tx="edream.110203163054.374"></t>
<t tx="edream.110203163054.375">Previously, Java only had block comments, and the ending delim wasn't being removed from doc parts.</t>
<t tx="edream.110203163054.376"></t>
<t tx="edream.110203163054.377">The present code explicitly eliminates control-T processing in headlines, which means that control-T does not switch panes when editing headline text.  Control-T _does_ switch panes in all other cases.

This appears to be another Tk bug.</t>
<t tx="edream.110203163054.378">Only shortcut pastes worked before.</t>
<t tx="edream.110203163054.379"></t>
<t tx="edream.110203163054.380">Leo 3.7 significantly offers you several new ways to create derived files.</t>
<t tx="edream.110203163054.381">@rawfile and @silentfile trees are important new additions to Leo.  They work like @file trees, but are simpler to use.  See the child of this node for full details.</t>
<t tx="edream.110203163054.382">The @raw and @end_raw directives delimit a region of "raw" text.  No section references are recognized within "raw" text, and no additional leading whitespace is generated within "raw" text when writing the derived file.

The @quiet directive is valid only within @root trees.  It suppresses all sentinels except the @+node sentinels used to mark headlines.

See the children of this node for full details.</t>
<t tx="edream.110203163054.383">The @raw and @end_raw directives are valid only within @file trees.  The @raw directive starts a section of "raw" text.  The @end_raw directive ends such a section, as does the end of body text. No section references are recognized within "raw" text, and no additional leading whitespace is generated within "raw" text when writing the derived file.
</t>
<t tx="edream.110203163054.384">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 adds 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.</t>
<t tx="edream.110203163054.385">It is now possible to create CWEB (.w) files from @file trees.  When @language cweb is in effect the following happen:

1. Leo does not recognize @space and @c directives.

2. The colorizer now recognizes both cweb and noweb section definitions and references.

3. Leo uses @q@ and @&gt; for comment delimiters in files derived from @file or @rawfile trees, and Leo replaces @ by @@ within such comments.

4. Leo now properly warns about orphan nodes when @langauge cweb was in effect.

See the child of this node for the new documentation that applies to cweb mode.</t>
<t tx="edream.110203163054.386">It is now possible to have both the @comment and @language directives to be in effect at the same time.  To do this, both directives must appear in the same node, and the @comment directive must follow the @language directive.</t>
<t tx="edream.110203163054.387"></t>
<t tx="edream.110203163054.388">Leo preserves the &lt;?xml-stylesheet...?&gt; line if it is already present in the .leo file.

Otherwise, Leo writes a &lt;?xml-stylesheet...?&gt; line only if the stylesheet option is present in the configuration file.  The stylesheet option specifies s in &lt;?xml-stylesheet s?&gt;</t>
<t tx="edream.110203163054.389">The Open LeoConfig.leo command opens the configuration file.  The apply setting command applies any changes to settings made as the result of changing leoConfig.leo.</t>
<t tx="edream.110203163054.390">This option allows a comment to be inserted in derived files just after the initial @+leo line.  The comment will appear in an @comment sentinel.  See leoConfig.leo for full details.</t>
<t tx="edream.110203163054.391">This option allows you to specify the line endings to be used when writing derived files and when exporting files.  See leoConfig.leo for full details.</t>
<t tx="edream.110203163054.392">Changed the path_directive_creates_directories option in leoConfig.leo to create_nonexistent_directories.

The old name was too misleading.  Indeed, this option applies not just to @path directives, but to all situations in which the path name specified in @path directives or @root, @file, @rawfile or @silentfile nodes does not exist.

</t>
<t tx="edream.110203163054.393"></t>
<t tx="edream.110203163054.394"></t>
<t tx="edream.110203163054.395"></t>
<t tx="edream.110203163054.396">The new names are less cluttered than the old.</t>
<t tx="edream.110203163054.397">Leo now prints a summary of any exception taken to the log window, and a full traceback to the console window.</t>
<t tx="edream.110203163054.398">This is taken from Python Cookbook.

This may be of use to people developing Leo, though it's not clear how useful this is with Tk programs.</t>
<t tx="edream.110203163054.399">A small convenience that is actually quite nice to have.</t>
<t tx="edream.110203163054.400">Sentinel lines in Java files now start with //@.</t>
<t tx="edream.110203163054.401">It wasn't always completely clear when the command was complete.</t>
<t tx="edream.110203163054.402">Recently I have discovered a way of creating true, immutable global identifiers (called global tnode indices or gti's for short).  Version 4.0, due late this year or early next, will be the first version of Leo to take full advantage of the opportunities created by gti's.

Gti's will be a way of permanently and uniquely identifying every node (headline and body text) ever created by Leo, even when many people are working on the same .leo and derived files.  For the first time, Leo will be able reliably to associate nodes in .leo files with nodes in derived files.

No previous version of Leo, including 3.7, has this ability, although that may not be so apparent to the casual user.  As a work around in all previous versions of Leo, .leo files contain copies of all information in derived files.  This "mirroring scheme" is needed so that clones in .leo files can be associated with their cloned counterparts in derived files.

While the mirroring scheme usually works well, it has some significant problems:

1. .leo files are much larger than they need to be.

2. Read errors occur if the derived files get out-of-synch with the information in the .leo file.  All clone links get broken when read errors occur, which basically ruins the resulting .leo file.  The only real way to recover is to use the Read Outline Only command.

3. Because out-of-synch conditions are so serious, it becomes a dicey proposition to save .leo files as backups; to create a reliable backup one must save the leo file along with all derived files.

Gti's solve all these problems:

1. .leo files no longer need to save a copy of all information in all derived files.  Leo will write only the root node of @file trees to the outline, secure in the knowledge that it can reliably recreate the outline from the derived file.

2. The dreaded read errors will be impossible because there is no longer any data in the .leo file that can become out-of-synch with data in the derived files.

3. Because .leo files can never become out-of-synch with derived files, we can, for the first time, safely backup a project by creating a "fat" .leo file that contains all information in all derived files.  Most .leo files will be "thin."  Saving "fat" .leo files will only happen as the result of a new Save Backup
command. 

I am excited about Leo 4.0.  It promises to revolutionize how people use Leo.</t>
<t tx="edream.110203163054.403">leo.py 3.7                                 October 9, 2002

Many improvements have been made to Leo.  The highlights:

- Now works with Python 2.1.  Previous versions required Python 2.2.
- Many new user options, including user-definable shortcuts for all commands
  and colors for all parts of Leo's windows.
  As a result, it is now possible to use arrow keys as you desire.
- Minimal support for Unicode Latin-1 (iso-8859-1) encoding. Better support is coming.
- Improved handling of relative path names.
- The @first directive allows lines to precede the opening @+leo sentinel line.
- The @last  directive allows lines to follow  the closing @-leo sentinel line.
- Better support for Perl+pod.
- Leo now ends all lines with '\n' regardless of platform.
- Leo is now compatible with Python 2.1.
- Simplified sentinels reduce spurious CVS diffs.
- Many other minor improvements and bug fixes.

Warning: Leo expects that all characters in derived files and .leo files are contained in the encoding specified by the xml_version_string option in leoConfig.txt.  Characters will be garbled if this restriction is not followed.  This restriction will be removed in the next release.

See the children of this node for full details.</t>
<t tx="edream.110203163054.404"></t>
<t tx="edream.110203163054.405"></t>
<t tx="edream.110203163054.406">The old code did not handle @comment /* */ in C mode because the */ given in the comment improperly terminated the scanning.

Changed find to rfind when scanning @@ sentinels.</t>
<t tx="edream.110203163054.407"></t>
<t tx="edream.110203163054.408">Under certain circumstances # was not properly colored when coloring plain text.</t>
<t tx="edream.110203163054.409">single quote colorized text in plain text mode.  This was due to missing parentheses.</t>
<t tx="edream.110203163054.410">The old code did not properly set the text selection in all cases.

This bug affected the Indent, Unindent, Extract and Extract Section.</t>
<t tx="edream.110203163054.411"></t>
<t tx="edream.110203163054.412">Body text was being cleared in a node in an @file tree if the node contained a reference to a section defined in a grandchild.  This was the first serious bug ever reported in the @file read logic.

The problem: Body text was being updated as the result of @+node sentinels rather than @+body sentinels.
This was wrong, as extra @+node sentinels are often generated when no body text is generated. The result is
that the body text was being cleared. 

The fix: I simply moved the code that creates body text from the @+node logic to the @+body logic in
scanText.</t>
<t tx="edream.110203163054.413">The new code resets the error count when reading each derived file, so errors in one file do not cascade to following derived files.</t>
<t tx="edream.110203163054.414"></t>
<t tx="edream.110203163054.415"></t>
<t tx="edream.110203163054.416">st_enter was not returning part numbers, which would have affected the Untangle command.</t>
<t tx="edream.110203163054.417">The old code undid the changes to only one headline of a group of cloned nodes. This was a serious bug because it would destroy the assumed equality between all cloned headlines.</t>
<t tx="edream.110203163054.418">The Find Previous command would get stuck once it found a match.</t>
<t tx="edream.110203163054.419">The original bug report:

"If you set the @tabwidth to something other than the Preference value, you'll see the body displayed appropriately. However, if you do a Ctrl-s to save the leo file, the body is redisplayed using the Preferences setting--of course, clicking on another node and then back to the original node displays with the correct tab setting again."</t>
<t tx="edream.110203163054.420">The old code remembered the insertion point only if it were set as the result of a keystroke.
</t>
<t tx="edream.110203163054.421">This was too confusing to users.  setup.py is intended only to create official distributions.</t>
<t tx="edream.110203163054.422">These improvements are listed in the approximate order of importance.</t>
<t tx="edream.110203163054.423"></t>
<t tx="edream.110203163054.424"></t>
<t tx="edream.110203163054.425">path_directive_creates_directories

Specifies whether to create a directory mentioned in an @file, @root node or @path directive if it does not exist.</t>
<t tx="edream.110203163054.426">relative_path_base_directory 

The directory to be used as a prefix for &lt;filename&gt; in @path &lt;filename&gt; and @file &lt;filename&gt; and @root &lt;filename&gt; when &lt;filename&gt; is a relative path.

Valid values for this option:

"!" means relative to the location leo.py (the default).
"." means relative to the location of the .leo file in the top window.
An absolute path (in platform-dependent format).

Relative paths are not allowed: such paths would be dangerous because their meaning would depend on the changing value of the current working directory.</t>
<t tx="edream.110203163054.427">remove_sentinels_extension

Sets the string to be appended to file names resulting from the Remove Sentinels command.  If the value starts with . the extension is appended to the original file name. Otherwise, the extension is appended before the file extension.

Example 1:
	File name x.y
	remove_sentinels_extension = _ns
	Result: x_ns.y

Example 2:
	File name x.y
	remove_sentinels_extension = .txt
	Result: x.y.txt
</t>
<t tx="edream.110203163054.428">write_clone_indices 

Indicates whether derived files will contain clone indices.

Please specify no clone indices if you are going to submit files to Leo's CVS site.</t>
<t tx="edream.110203163054.429">The following options now exist in the &lt;&lt; Options for newly opened windows &gt;&gt; section of LeoConfig.leo.

initial_horizontal_secondary_ratio

Sets the ratio of outline pane size to log pane size when splitting the primary panes horizontally.
The primary panes are the body pane and the secondary pane.

initial_vertical_secondary_ratio

Sets the ratio of tree pane size to body pane size when splitting the primary panes vertically.
The primary panes are the body pane and the secondary pane.


</t>
<t tx="edream.110203163054.430">The following options now exist in the &lt;&lt; Window options &gt;&gt; section of LeoConfig.leo.

body_text_foreground_color
body_text_background_color

The foreground and background colors of body text.

body_cursor_foreground_color
body_cursor_background_color

The foreground and background colors for the cursor in body text.

headline_text_unselected_foreground_color
headline_text_unselected_background_color

The foreground and background colors of unselected headline text.
Both must be specified for either to take effect.

headline_text_selected_foreground_color 
headline_text_selected_background_color

The foreground and background colors of selected headline text that is not being edited.
Both must be specified for either to take effect.

headline_text_editing_foreground_color
headline_text_editing_background_color

The foreground and background colors of unselected headline text in a headline that is being edited.
Both must be specified for either to take effect.

headline_text_editing_selection_foreground_color
headline_text_editing_selection_background_color

The foreground and background colors of selected text headline text in a headline that is being edited.
Both must be specified for either to take effect.

outline_pane_background_color

The background color of outline pane itself.

log_text_foreground_color
log_text_background_color

The foreground and background colors of log text.</t>
<t tx="edream.110203163054.431">The &lt;&lt; Keyboard shortcuts settings &gt;&gt; section of leoConfig.leo allows the user to specify keyboard shortcuts for all commands.

Notes:

1. There is one option for every command in Leo's menus; they won't be listed separately here.

2. For full documentation, see the

&lt;&lt; Keyboard shortcuts settings &gt;&gt; and
&lt;&lt; About keyboard shortcuts &gt;&gt;

sections of leoConfig.leo.  The gist of this documentation is that you must use names known to Tk, and Leo also provides a few other names.

3. At most one shortcut may be associated with a command.  If one really wanted to have two shortcuts, one would have to use two different command names. In particular, there is now only one shortcut for the Find Next command.
</t>
<t tx="edream.110203163054.432">Leo checks all characters that are entered (via typing or via paste) into headline and body text to see whether they can be represented in the encoding specified by the xml_version_string setting in leoConfig.txt.  Leo issues a message and disallows the entry of the character if it can't be represented in that encoding.

This draconian behavior shouldn't be too much of a nuisance, at least temporarily. Note that _all_ characters are valid in the UTF-8 encoding, so the present version of Leo will allow you to specify all characters if you must. But the Latin-1 (iso-8859-1) encoding, being a one-byte encoding, limits you to at most 256 separate characters. 

In 3.8 I plan to allow you to use all Unicode characters, regardless of encoding, by using character references.  This will require some reorganization of the present code, and I don't want to delay 3.7 to handle them.

Warning: The present code does not handle well files (.leo or derived files) that contain characters outside the specified encoding.  At present, your best bet is to remove such characters for now.  Hopefully 3.8 will do a much better job handling characters "foreign" to the specified encoding.</t>
<t tx="edream.110203163054.433">Leo now writes only \n (Linux newlines) in derived files and .leo files.  This was done simply by opening derived files and .leo files in "wb" mode.</t>
<t tx="edream.110203163054.434"></t>
<t tx="edream.110203163054.435">1. Leo now supports relative_path_base_directory and path_directive_creates_directories user options.  See the discussion of those options in this document.

2. Leo now retains file modes when tangling and writing derived files.</t>
<t tx="edream.110203163054.436">Blank lines now precede and follow =pod and =cut.

Improvements made to @first and @last directives.</t>
<t tx="edream.110203163054.437">These were added so to resolve the debate about what the Esc key should do.  The user can now bind Esc to either of these commands.</t>
<t tx="edream.110203163054.438">Leo no longer gives an error message when reading or writing cloned @file nodes.</t>
<t tx="edream.110203163054.439"></t>
<t tx="edream.110203163054.440">Leo writes derived files a bit differently than before.  These changes are compatible with the Borland version of Leo, provided that xml_version_string = UTF-8 in leoConfig.txt.

The changes:

1. Eliminated writing clone indices in derived files.  This reduces the number of spurious changes reported by CVS.  Leo now relies solely on information in .leo files to recreate clone indices.  This is safe because read errors clear clone indices anyway.  You can force clone indices to be written using the write_clone_indices user option in leoConfig.txt.

2. Removed extra newline following @+leo directive.  This is part of an unfinished plan to eliminate all extra blank lines in derived files.  It's not clear whether this plan will ever succeed.</t>
<t tx="edream.110203163054.441">Leo enables the Tangle and Untangle items in popup menus if any descendant of the selected node contains an @root node.  Similarly, Leo enables the Read @file nodes and Write @file nodes items in popup menus if any descendant of the selected node contains an @file node.</t>
<t tx="edream.110203163054.442"></t>
<t tx="edream.110203163054.443">leo.py 3.6                                 September 11, 2002

Highlights:

- Fixed a large number of bugs, especially bugs that appear only on Linux.
- Leo now remembers the previous insertion point and location of the scrollbar when switching between nodes.
- Added Match Brackets command.
- Added support for MouseWheel (Linux only).
- Added support for LaTex and PHP.
- Improved all aspects of the Help menu.
- Discovered a minor bug involving the Python (Idle) window and documented a workaround.

See the children of this node for full details.</t>
<t tx="edream.110203163054.444">The following minor bug can not easily be fixed because it involves an interaction between Leo and Idle.

After opening Idle with the Open Python Window command, opening another Leo window shows both the Leo window and a blank, square window.  Closing either of the new windows may cause exceptions, either immediately or later.

The best workaround is simply not to open any new Leo windows after using the Open Python Window command.</t>
<t tx="edream.110203163054.445"></t>
<t tx="edream.110203163054.446"></t>
<t tx="edream.110203163054.447">os.rename can fail on some Linux systems.</t>
<t tx="edream.110203163054.448">When starting Leo with no arguments the 'NewHeadline' node was not displayed. </t>
<t tx="edream.110203163054.449">Changed:

bitmap_name = os.path.join(self.loadDir,"Icons\LeoApp.ico") 

to:

bitmap_name = os.path.join(self.loadDir,"Icons","LeoApp.ico") 
</t>
<t tx="edream.110203163054.450">There were problems handling relative path names in @root and @path directives.</t>
<t tx="edream.110203163054.451">With Tk/Tcl 8.4, the Preferences window is empty (no buttons, fields, labels). 

Tcl 8.4 complains about using "col" in the grid() calls.</t>
<t tx="edream.110203163054.452">This routine does a better job of checking the Tk version than the old code in leoApp.py</t>
<t tx="edream.110203163054.453"></t>
<t tx="edream.110203163054.454">Only the last directive was in effect in @root trees.  The new code allows node-by-node control.</t>
<t tx="edream.110203163054.455">This involved calling readlineForceUnixNewline instead of readline in the atFile:read logic.</t>
<t tx="edream.110203163054.456"></t>
<t tx="edream.110203163054.457">How did I ever live without this?</t>
<t tx="edream.110203163054.458"></t>
<t tx="edream.110203163054.459">The cursor now changes to an arrow when it moves over a link in the About Leo dialog.

The About Leo dialog now includes a build revision number.

Fixed problems with the Leo icon in the About Leo dialog.

Improved download dialog in Tutorial command.</t>
<t tx="edream.110203163054.460">CVS conflict files produce so many error messages that these errors are useless.</t>
<t tx="edream.110203163054.461"></t>
<t tx="edream.110203163054.462"></t>
<t tx="edream.110203163054.463"></t>
<t tx="edream.110203163054.464">The Match Brackets command is enabled if the cursor is next to one of the following characters in the body pane:

( ) [ ] { } &lt; &gt;

This command looks for the matching character, searching backwards through the body text if the cursor is next to ) ] } or &gt; and searching forward through the text otherwise.  If the cursor is between two brackets the search is made for the bracket matching the leftmost bracket.

If a match is found, the entire range of characters delimited by the brackets is highlighted and the cursor is placed just to the left of the matching characters.  Thus, executing this command twice highlights the range of matched characters without changing the cursor.</t>
<t tx="edream.110203163054.465">This code is due to Dave Hein.

Leo understands the following PHP keywords:

&lt;?php, ?&gt;, __CLASS__, __FILE__, __FUNCTION__, __LINE__, and,	as, break, case, cfunction, class, const, continue, declare, default, do, else, elseif,  enddeclare, endfor, endforeach, endif, endswitch, endwhile, eval,  extends, for, foreach, function, global, if, new, old_function, or, static, switch, unset(), use, var, while, xor,

Leo does not yet color the following keywords containing():

array(), die(), echo(), empty(), exit(), include(), include_once(), isset(), list(), print(), require(), require_once(), return()</t>
<t tx="edream.110203163054.466">This code is due to Marcus A. Martin.

Leo understands the following LaTex keywords: capitalization is significant.  For example, \vert produces a single vertical line and \Vert produces a double vertical line.

\@, \(, \), \{, \},

\acute, \addcontentsline, \addtocontents, \addtocounter, \address,
\addtolength, \addvspace, \AE, \ae, \aleph, \alph, \angle, \appendix, 
\approx,\arabic, \arccos, \arcsin, \arctan, \ast, \author,

\b, \backmatter, \backslash, \bar, \baselineskip, \baselinestretch,
\begin, \beta, \bezier, \bf, \bfseries, \bibitem, \bigcap, 
\bigcup, \bigodot, \bigoplus, \bigotimes, \bigskip, \biguplus, 
\bigvee, \bigwedge,\bmod, \boldmath, \Box, \breve, \bullet,

\c, \cal, \caption, \cdot, \cdots, \centering, \chapter, 
\check, \chi, \circ, \circle, \cite, \cleardoublepage, \clearpage, 
\cline,\closing, \clubsuit, \coprod, \copywright, \cos, \cosh, 
\cot, \coth,csc,

\d, \dag, \dashbox, \date, \ddag, \ddot, \ddots, \decl, 
\deg, \Delta, \delta, \depthits, \det, 
\DH, \dh, \Diamond, \diamondsuit, \dim, \div, \DJ, \dj, 
\documentclass, \documentstyle, \dot, \dotfil, \downarrow,

\ell, \em, \emph, \end, \enlargethispage, \ensuremath, 
\enumi, \enuii, \enumiii, \enuiv, \epsilon, \equation, \equiv,
\eta, \example, \exists, \exp,

\fbox, \figure, \flat, \flushbottom, \fnsymbol, \footnote, 
\footnotemark, \fotenotesize, 
\footnotetext, \forall, \frac, \frame, \framebox, \frenchspacing, 
\frontmatter,

\Gamma, \gamma, \gcd, \geq, \gg, \grave, \guillemotleft, 
\guillemotright,\guilsinglleft, \guilsinglright,

\H, \hat, \hbar, \heartsuit, \heightits, \hfill, \hline, \hom, \hrulefill,\hspace, \huge,\Huge,\hyphenation

\Im, \imath, \include, includeonly, indent, \index, \inf, \infty, \input, \int, \iota,\it, \item, \itshape,

\jmath, \Join,

\k, \kappa, \ker, \kill,

\label, \Lambda, \lambda, \langle, \large, \Large, \LARGE, 
\LaTeX, \LaTeXe, 
\ldots, \leadsto, \left, \Leftarrow, \leftarrow, \lefteqn, \leq,
\lg, \lhd, \lim, \liminf, \limsup, \line, \linebreak, 
\linethickness, \linewidth,\listfiles,
\ll, \ln, \location, \log, \Longleftarrow, \longleftarrow, 
\Longrightarrow,longrightarrow,

\mainmatter, \makebox, \makeglossary, \makeindex,\maketitle, \markboth, \markright,
\mathbf, \mathcal, \mathit, \mathnormal, \mathop,
\mathrm, \mathsf, \mathtt, \max, \mbox, \mdseries, \medskip,
\mho, \min, \mp, \mpfootnote, \mu, \multicolumn, \multiput,

\nabla, \natural, \nearrow, \neq, \newcommand, \newcounter, 
\newenvironment, \newfont,
\newlength,\newline, \newpage, \newsavebox, \newtheorem, \NG, \ng,
\nocite, \noindent, \nolinbreak, \nopagebreak, \normalsize,
\not, \nu, nwarrow,

\Omega, \omega, \onecolumn, \oint, \opening, \oval, 
\overbrace, \overline,

\P, \page, \pagebreak, \pagenumbering, \pageref, \pagestyle, 
\par, \parbox,\paragraph, \parindent, \parskip, \part, 
\partial, \per, \Phi, \phi,\Pi, \pi, \pm, 
\pmod, \pounds, \prime, \printindex, \prod, \propto, \protext, 
\providecomamnd, \Psi,\psi, \put,

\qbezier, \quoteblbase, \quotesinglbase,

\r, \raggedbottom, \raggedleft, \raggedright, \raisebox, \rangle, 
\Re, \ref, \renewcommand, \renewenvironment, \rhd, \rho, \right, 
\Rightarrow,\rightarrow, \rm, \rmfamily,
\Roman, \roman, \rule, 

\s, \samepage, \savebox, \sbox, \sc, \scriptsize, \scshape, 
\searrow, \sec, \section,
\setcounter, \setlength, \settowidth, \settodepth, \settoheight, 
\settowidth, \sf, \sffamily, \sharp, \shortstack, \Sigma, \sigma, 
\signature, \sim, \simeq, \sin, \sinh, \sl, \SLiTeX,
\slshape, \small, \smallskip, \spadesuit, \sqrt, \sqsubset,
\sqsupset, \SS,
\stackrel, \star, \subsection, \subset, 
\subsubsection, \sum, \sup, \supressfloats, \surd, \swarrow,

\t, \table, \tableofcontents, \tabularnewline, \tan, \tanh, 
\tau, \telephone,\TeX, \textbf,
\textbullet, \textcircled, \textcompworkmark,\textemdash, 
\textendash, \textexclamdown, \textheight, \textquestiondown, 
\textquoteblleft, \textquoteblright, \textquoteleft,
\textperiod, \textquotebl, \textquoteright, \textmd, \textit, \textrm, 
\textsc, \textsl, \textsf, \textsuperscript, \texttt, \textup,
\textvisiblespace, \textwidth, \TH, \th, \thanks, \thebibligraphy,
\Theta, theta, 
\tilde, \thinlines, 
\thispagestyle, \times, \tiny, \title,\today, \totalheightits, 
\triangle, \tt, 
\ttfamily, \twocoloumn, \typeout, \typein,

\u, \underbrace, \underline, \unitlength, \unlhd, \unrhd, \Uparrow,
\uparrow,\updownarrow, \upshape, \Upsilon, \upsilon, \usebox,
\usecounter, \usepackage, 

\v, \value, \varepsilon, \varphi, \varpi, \varrho, \varsigma, 
\vartheta, \vdots, \vec, \vector, \verb, \Vert, \vert, \vfill,
\vline, \vphantom, \vspace,

\widehat, \widetilde, \widthits, \wp,

\Xi, \xi,

\zeta</t>
<t tx="edream.110203163054.467">leo.py 3.5                                  August 14, 2002

Highlights:

- Added new entries in the help menu.
 (Including a link to Joe Orr's excellent ScreenBook tutorial).
- Added the importFiles script in leoImport.py.
- Added configuration options for horizontal scrollbars.
- Added better warnings for read-only files.
- Removed all '\r' when reading derived files.
- Fixed crasher in Read Outline Only command.
- Fixed crasher when leoConfig.txt did not exist.
- Many small improvements and bug fixes.</t>
<t tx="edream.110203163054.468"></t>
<t tx="edream.110203163054.469">This may be the cause of truncated leoConfig.txt files on Linux.</t>
<t tx="edream.110203163054.470"></t>
<t tx="edream.110203163054.471"></t>
<t tx="edream.110203163054.472">Removed '\r' characters when reading.  The write logic is unchanged.</t>
<t tx="edream.110203163054.473">Relative paths should not set the global default paths.  Instead, the relative path is concatenated to the global default path when the file is opened.</t>
<t tx="edream.110203163054.474"></t>
<t tx="edream.110203163054.475"></t>
<t tx="edream.110203163054.476">Added log_pane_wraps and outline_pane_scrolls_horizontally configuration settings.</t>
<t tx="edream.110203163054.477"></t>
<t tx="edream.110203163054.478">Note: b4 contains a fix to b3 in this area:  for writing, we must first test whether the file exists.  Otherwise we may get a false indication that the (non-existent) file is read-only.</t>
<t tx="edream.110203163054.479">Added the importFiles script in leoImport.py. Use this script as follows:

- Select the node under which you want the imported files to appear.
- Open the Python window within Leo.
- Type the following in the Python window:

import leoImport
dir = "c:/prog/test"  # or some other directory
type = ".py"  # Type of files you want to import.
leoImport.importFiles(dir,type)

If you want to import all files in a directory, replace the last line with:

leoImport.importFiles(dir)</t>
<t tx="edream.110203163054.480">leo.py 3.4                                     August 11, 2002

This release contains many small improvements and bug fixes.  The highlights:

- Fixed several crashers involving Unicode.
- The Show Invisibles command now makes blanks and tabs look much better.
- Created leoConfig.leo, from which leoConfig.txt is now derived.
- Added save_clears_undo_buffer configuration option.
- Fixed a large number of problems with the configuration code.
- The usual minor improvements and bug fixes.

See the children of this node for full details.</t>
<t tx="edream.110203163054.481"></t>
<t tx="edream.110203163054.482">The problem is that the ratio is saved in the .leo file and the split direction is not. So if leoConfig.txt is read-only you the Toggle Split Direction command will permanently change the body-outline ratio _without_ permanently changing the split direction itself.

This basically sucks, and here are my reasons: 

1. I do not want to be adding more options to .leo files; the whole idea of leoConfig.txt is to move in the opposite direction. 

2. You can make everything work more like you would expect by making leoConfig.txt read-write. 

3. Especially in the case of the split direction, I expect people to have strong preferences one way or the other, so even if leoConfig.txt is read-only it shouldn't be too odious to pick a split direction and live with it.</t>
<t tx="edream.110203163054.483">The undo buffer creates a lot of strings.  On some system this may be a problem.  If save_clears_undo_buffer = 1 the Save command (and only the Save command) will clear the undo buffer.</t>
<t tx="edream.110203163054.484">The new spelling is to limit_directory_search_extension.  Note that this affects the valid entries in leoConfig.txt.</t>
<t tx="edream.110203163054.485">This allows us to create leoConfig.txt more easily, and provides a safe place to permanently store comments when read-write mode is on.</t>
<t tx="edream.110203163054.486">If a setting was missing or "ignore" it could never be set!  This no doubt could have caused a wide variety of symptoms.  In particular, in the distributed leoConfig.txt file it meant that settings for "default" fonts and sizes were never updated!</t>
<t tx="edream.110203163054.487">The new code properly deletes previous entries regardless of case or path separators.</t>
<t tx="edream.110203163054.488">There were a couple of bugs here.

Note that the ratio (whichever the direction) is stored in the .leo file.  The initial_splitter_orientation setting in leoConfig.txt applies to _all_ files.  The initial_vertical_ratio and the corresponding initial_horizontal_ratio  apply only to new files, so are essentially useless.

Yes, this is pretty stupid; it's the result of not wanting to add more stuff to Leo's file format.</t>
<t tx="edream.110203163054.489"></t>
<t tx="edream.110203163054.490"></t>
<t tx="edream.110203163054.491"></t>
<t tx="edream.110203163054.492"></t>
<t tx="edream.110203163054.493">leo.py 3.1 contains Python code that may be of interest to some Python programmers.  All Python files are derived from LeoPy.leo.

See the children of this node for details.</t>
<t tx="edream.110203163054.494">This script does much of the grunt work of converting from C/C++ syntax to Python syntax.  It was surprisingly effective in converting Leo from C++ to Python.  These scripts don't need to be perfect to save a _lot_ of work.  And of course you can always add your own improvements...

As written, the script converts an entire Leo tree.  It would be easy to write an entry that would convert plain text files, but it's probably best to import the files to be converted into Leo first.  That way the slow algorithms in c2py.py will work on smaller pieces of text.</t>
<t tx="edream.110203163054.495">This code gathers and prints static statistics about Python bytecode.</t>
<t tx="edream.110203163054.496">The file leoUtils.py contains some small Tkinter utilities:

w,h,x,y = get_window_info(top) returns the width, height, x and y positions of the Tkinter window top.

center_dialog(top) centers the Tkinter window top on the screen.

w,f = create_labeled_frame(parent...) creates a labeled Tkinter window as a child of parent.  The caller packs widgets into f to create the frame.

leoUtils.py contains many other routines including an Python version of the Sherlock tracing package.</t>
<t tx="edream.110203163054.497">leoFontPanel.py puts up a Font dialog.  This dialog dispenses with the typical "sample" pane and instead changes text immediately directly on the screen.  Comes with Ok, Cancel and Revert buttons.  IMO, this dialog is much better than the sample Tk/Tkinter font dialogs available on the web.</t>
<t tx="edream.110203163054.498">leoColor.py contains code to syntax color Tk.Text widgets for a variety of languages.  Supporting a new language here is mostly a matter of adding another table of keywords.</t>
<t tx="edream.110203163054.499">Leo supports powerful outlining features, including clones.  Clones are challenging to implement, to say the least.  The vnode and tnode classes, defined in leoNodes.py, represent the underlying data.  vnodes represent nodes on the screen.  vnodes may share text, the tnode class is the "unit of sharing" of such text.  The leoTree class draws the tree and handles events, including dragging nodes around the screen.  The Commands class calls the vnode, tnode and leoTree classes to handle menu commands.  In Smalltalk's model/view/controller terminology, the vnode and tnode classes are model class, the leoTree class is a view class, and the Commands class is a controller class.</t>
<t tx="edream.110203163054.500"></t>
<t tx="edream.110203163054.501">Now at last it is clear why Leo hasn't been writing derived files affected by clones.  It's not enough to mark v dirty.  We must mark all the cloned nodes of v's tree dirty as well.

However, we only need do this when a node is deleted, and we definitely do _not_ want to do this otherwise, for that would mark far too many nodes dirty.  To get around this, we leave v.setDirty() as it was, and use the new code only in v.setDirtyDeleted.

Note that the undo and redo cases handle this automatically because they call c.doDelete.

So now we can state a rule that should not ever be broken: after doing a Save command, a Write @file Nodes command should always report "unchanged" for all files.</t>
<t tx="edream.110203163054.502"></t>
<t tx="edream.110203163054.503">Added setRevertVars to update revert settings.  This is called from __init__ and onOk.</t>
<t tx="edream.110203163054.504">Changed idle_body_key and idle_head_key, leoTangle::os and tnode::setTnodeText.

We must remove backticks from messages that might contain unicode characters so they will print properly.  There were only a few instances, and they are all error messages that hardly ever get executed, so I hope I was careful putting them in.  I should be able to find them all by looking for '"'.</t>
<t tx="edream.110203163054.505">Repeated double-clicking (without intervening single-click) caused the selection to move to the left.</t>
<t tx="edream.110203163054.506"></t>
<t tx="edream.110203163054.507"></t>
<t tx="edream.110203163054.508">This is consistent with what the Import commands do for the other file types.  It's also much safer.</t>
<t tx="edream.110203163054.509"></t>
<t tx="edream.110203163054.510">This makes selected text look much better and makes Show Invisibles look much better as well.  

This was not easy to do.  Apparently tag settings interfere with the Tk.Text settings.  I have not found a way to specify the selectbackground color for tags.  The only way I could get things to work is define whitespace tags only when in showInvisibles mode.</t>
<t tx="edream.110203163054.511">.tmp files disappear On Windows XP after Leo exits!</t>
<t tx="edream.110203163054.512">leo.py 3.3                                     August 3, 2002

This version of Leo:

- Added support for Unicode.
- Improved the Import commands.
- Fixed numerous bugs related to configuration settings.
- Fixed the "Javadoc" bug and several latent bugs related to it.

See the children of this node for details.

Edward K. Ream</t>
<t tx="edream.110203163054.513">It is now possible to use non-Ascii characters in Leo!

Leo uses the xml_version_string setting to encode Unicode characters in .leo files.  This will be UTF-8 by default.  I've also very briefly tested ISO-8859-1.

I am a complete Unicode ignoramus.  It seemed trivial to add Unicode support to Leo, and if there are any fine points that should have been considered I no doubt did not consider them...</t>
<t tx="edream.110203163054.514">The Import command now does a better job of removing excess leading whitespace.

When importing .java files, Leo now preserves newlines in leading block comments.  This makes the typical weird Java comments look better.  For example,

/**  This is a typical,
  * brain-dead,
  * Java comment.
  */

Now gets rendered as

@ * This is a typical
 * brain-dead,
 * Java comment.
@c

The comment will be reconstituted properly when rewritten.
</t>
<t tx="edream.110203163054.515">This never happened before because all languages had either 1 or 3 delims.  But Java now has only 2 delims to force block comments.</t>
<t tx="edream.110203163054.516">Leo should now handle negative tab widths properly.</t>
<t tx="edream.110203163054.517">- Negative tab widths are now honored properly.

- Made 'additional_body_text_border' setting functional.

- Made 'body_pane_wraps' setting functional.

- There was a bug that made the following non-functional.

	"read_only"
	"xml_version_string"
	"limit_count"
	"body_pane_wraps"

That is, only the default settings in leoConfig.py were used, not the settings in leoConfig.txt.

- The old code did not use the "page_width" and "tab_width" settings from leoConfig.txt.</t>
<t tx="edream.110203163054.518">leo.py 3.2                                     July 30, 2002

This version generalizes the @others directive, improves the Import command and fixes several bugs.  See the children of this node for full details.

The highlights:

- Nested @others directives are now valid, an important improvement.
  This simplifies files that define more than one class.
- Improved the Import command and squashed several bugs lurking there.
- Made the various Go commands in the Outline-Move/Select menu functional
  by reassigning keyboard shorts
- Fixed a crasher in the Prefs Panel.
- Fixed numerous bugs in the Set Colors command.
- Fixed syntax coloring of C strings that span multiple lines.
- The usual minor improvements and bug fixes.

Edward K. Ream</t>
<t tx="edream.110203163054.519">Nested @others directives are now valid, even when no named node intervenes.  This is a significant enhancement to Leo because it is now easier to define multiple classes in a single file.  The leoNode.py file also uses nested @others directives.

The outline shown in the child of this node shows the general idea.

The Import command uses nested @others to great effect in Python files containing many classes.  For example, try importing the file Python/Lib/Compiler/ast.py.</t>
<t tx="edream.110203163054.520">@color
@ignore

# This is the "outer" @others
@others
</t>
<t tx="edream.110203163054.521">class a:
	# This is an "inner" @others.  No named node intervenes.
	@others</t>
<t tx="edream.110203163054.522">def one():
	pass</t>
<t tx="edream.110203163054.523">def two():
	pass</t>
<t tx="edream.110203163054.524">class b:
	# This is an "inner" @others.  No named node intervenes.
	@others</t>
<t tx="edream.110203163054.525">def one():
	pass</t>
<t tx="edream.110203163054.526">def two():
	pass</t>
<t tx="edream.110203163054.527">The Import command creates nested @others directives when parsing Python classes.

Fixed two bugs in the Import command:

1. The Import command now properly places the first @others directive of Python files.  Previously the @others directive was placed before section references, so code could be rearranged.

2. The Import command now properly handles all C preprocessor directives.  Previously there were problems handling the #ifndef directive which could ruin imports.

Two other minor improvements:

1. This is reasonable: we don't wan't people generating files from imported files unless they take some positive action.

2. The Import command now checks that different branches of #if, #else, #endif directives have the same net number of braces, and warns if they do not.  This logic was inserted while trying to fix bug #2 above.</t>
<t tx="edream.110203163054.528">It's too confusing to have arrow keys mean different things in different panes.

For one thing, we want to leave the focus in the body pane after the first click in the outline pane, but that means that the arrow keys must still be functional in the body pane!

Alas, all the various combinations of key bindings of arrow keys appear to do something; there are none left to use for moving around in the outline pane.  So we are stuck with poor shortcuts.</t>
<t tx="edream.110203163054.529">Leo could sometimes crash when the user selected Cancel in the Preferences panel.</t>
<t tx="edream.110203163054.530"></t>
<t tx="edream.110203163054.531">There were too many problems in the old color panel.

- Completely revised the Revert logic in the main Color panel.
- The color name picker now reverts properly.
- Color names and color swatches are now properly updated in all cases,
  so there is no need to write color values to the log window.
- Eliminate quotation marks around color names and values.
- The color picker now shows the value of the present color, not the revert color.
- Increased the width of name buttons to handle long color names.
</t>
<t tx="edream.110203163054.532">Thanks to Thomas Guettler for suggesting this.</t>
<t tx="edream.110203163054.533">This script uses the dis module to print static statistics about Python bytecode.  Of no use to anyone but me.</t>
<t tx="edream.110203163054.534">leo.py 3.1                                     July 20, 2002

This version fixes a blunder that affects only leo.py 3.0.  I recommend that all users of 3.0 upgrade to this version.

With this release Leo's to-do list is now empty! I shall fix bugs as they are reported. I'll add new features only if convinced that they contribute significantly to Leo.

The highlights:

- Fixed a blunder: Leo 3.0 did nothing when it was opened directly from leo.py.
  (Opening leo using openLeo.py did work.)
- Created a compare panel to control scripts in leoCompare.py.
- Added many new settings in leoConfig.txt to initialize the compare panel.
- The FAQ tells how to add support for new languages.
  (These instructions also appear in the "Notes/How To" section in LeoPy.leo)
- The usual minor improvements and bug fixes.

Edward K. Ream</t>
<t tx="edream.110203163054.535">The file comparison window helps people verify that imported files are, in fact, precisely equivalent to the original files.</t>
<t tx="edream.110203163054.536">Here are the new settings in leoCompare.txt:

# Initial settings of the Compare panel.
# 	These correspond to the keyword parameters of the leoCompare constructor.
# 	Exception: there are no keywords for compare file names in the constructor.

[compare options]

# ----- Options specifying files for the Compare panel.

compare_file_1 = c:/prog/test/compareTest1/file1.txt
#	Path to the first file or directory to be compared.
#	Directory compares ignore a filename part of the path, if present.
#	E.g., c:/directory1/spam.py is valid for directory compares.

compare_file_2 = c:/prog/test/compareTest2/file2.txt
#	Path to the second file or directory to be compared.
#	Directory compares ignore a filename part of the path, if present.
#	E.g., c:/directory2/spam.py is valid for directory compares

output_file = c:/prog/test/compareResults.txt
#	Path to the output file.
#	Leo will silently write to this file, regardless of whether it already exists.
#	Leo will write to the log pane if this path is empty or invalid.

append_output_to_output_file = 0
#	0: Replace output file with results of compare.
#	1: Append output to output file.

# ----- Options related to directory compares.
#	These options has no effect when comparing files.

limit_directory_search_extenstion = .py
#	Limit directory searches to files with the given file extension.
# 	Examples:
#		None	Compare all files when comparing directories.
#		.py  	Compare .py files when comparing directories.

# ----- Options related to file compares.
#	These options have no effect when comparing directories.

ignore_blank_lines = 1
#	1: Ignore blanks lines when comparing files.

ignore_first_line_of_file_1 = 0
#	1: Ignore the first line of compare_file_1 when comparing files.

ignore_first_line_of_file_2 = 0
#	1: Ignore the first line of compare_file_2 when comparing files.

ignore_interior_whitespace = 0
#	1: Ignore whitespace after the leading whitespace of a line when comparing files.

ignore_leading_whitespace = 0
#	1: Ignore leading whitespace of each line when comparing files.
#	Not recommended when comparing .py files.

ignore_sentinel_lines = 0
#	1: Ignore sentinel lines when comparing files.
#	Leo sets sentinel comment delimiters from the first line of each file.
#	This option has no effect if the first line is not a @+leo line.

# ----- Options affecting how Leo shows the results of file compares.
#	(Leo gathers statistics regardless of these options.)

limit_count = 9
#	0: Show lines regardless of the number of mismatches.
#	n: Stop showing lines after n mismatches.

make_whitespace_visible = 0
#	1: Show blanks as [ ] and tabs as [t]

print_both_lines_for_matches = 0
#	0: Print only the line of compare_file_1 when showing matching lines.
#	1: Print lines of both files when showing matching lines.

print_matching_lines = 0
#	1: Print lines that match using the print_both_lines_for_matches option.

print_mismatching_lines = 1
#	1: Print lines that do not compare equal to each other.

print_trailing_lines = 1
#	1: Print lines all lines in one file after an end-of-file is seen on the other file.</t>
<t tx="edream.110203163054.537">The new rules allow leo.py 3.1 to read and write .leo files more like leo.py 2.x when there is no leoConfig.txt file.  The scheme used in leo.py 3.0 meant that preferences were _never_ written to .leo files.  It's advantage was that all defaults were specified in:

	leoConfig.&lt;&lt; define default tables for settings &gt;&gt;

I think the present scheme is more natural, but we shall see...

In effect, Leo sets and gets various options in the following order of precedence:

1. Use explicit settings in leoConfig.txt if they exist.

2. Use defaults for leoConfig.txt, but only if leoConfig.txt exists.  These defaults are found in:

	leoConfig.&lt;&lt; define default tables for settings &gt;&gt;

3. Use settings in .leo files if leoConfig.txt does not exist.

4. If leoConfig.txt does not exist, and the .leo file does not specify a setting, use hard-coded settings in the various classes, just as leo.py 2.x did.</t>
<t tx="edream.110203163054.538">The @pagewidth, @tabwidth and @language directives could not have worked while tangling. Apparently nobody has every used these directives in @root trees!</t>
<t tx="edream.110203163054.539">The Flatten Outline command must use an escape convention so that it can distinguish between the "+" and "-" characters that denote a headline and any "+" and "-" characters that start a line of body text.

The old version of Flatten Outline inserted a backspace before _all_ "+", "-" and backspace characters.  The new version of Flatten Outline inserts a backspace before such characters only if they are the first non-whitespace character of a line.

This change affects the "file format" used by the Import Flattened Outline command.  If you import a file flattened with the old version of Flatten Outline, the new Import Flattened Outline will remove the inserted backspace only if it is the first non-whitespace character of the line.  In practice, this is unlikely to be a problem: you could just manually convert "\\", "\+" and "\-" to "\", "+" and "-" throughout the imported file.</t>
<t tx="edream.110203163054.540">The Open Python Window command now attempts to add IDLE's location to sys.path if import idle fails.

Bernhard Mulder contributed the code that made this improvement possible.

</t>
<t tx="edream.110203163054.541"></t>
<t tx="edream.110203163054.542">leo.py 3.0                                     July 16, 2002

This version is called 3.0 because it can optionally produce files that can NOT be read by the leo.py 2.x or the Borland version of Leo.  However, by default, leo.py 3.0 DOES produce files that all previous versions of Leo can read.

See the children of this node for full details.  The highlights:

- Support for many user options stored in leoConfig.txt, including, among others,
  fonts in all panes, colors for syntax coloring and default window size and position.
- Support for .leo files with XML types like "ISO-8859-1", controlled by a user option.
  Note: by default, Leo writes files compatible with previous versions of Leo.
- Powerful new Color and Font pickers, fully connected to user options.
- Added Toggle Split Direction command, under control of user options.
- Added autoscrolling in the outline pane.
- Windows open at the position in which they were saved.
- The size and position of new windows can be controlled with user options.
- Eliminated drawing problems while opening files.
- Improved syntax coloring for @comment plain.
- The Convert All Blanks and Convert All Tabs commands are now undoable.
- Leo warns and aborts if Python 2.2 or above is not running.
- The usual bug fixes.

At least one more version of leo.py is planned.</t>
<t tx="edream.110203163054.543">You now have a choice: you can configure Leo to please previous versions of Leo or to please XML parsers:

Leo now uses the xml_version_string configuration setting, if present, to override the UTF-8 setting used in all previous versions of Leo.  The default value of this setting is UTF-8, so by default leo.py will write files that may be read by any previous version of leo.py or the Borland version of Leo.

However, xml_version_string = ISO-8859-1 will produce .leo files that are more acceptable to XML parsers when those .leo files contain Unicode characters that are not found in the UTF-8 (Ascii) character set.  In any event, the choice of whether to please previous versions of Leo or XML parser is completely up to you. 

If the setting does not exist, whatever value is present in the .leo file will be written when the .leo file is written.  For new files, a value of UTF-8 will be used when this setting is not present.

Notice that this also affects what is written to the clipboard.</t>
<t tx="edream.110203163054.544"></t>
<t tx="edream.110203163054.545">This version supports many more options than before.  See leoConfig.txt for the full list.

Leo looks for leoConfig.txt in the same places as in leo.py 2.5.  If Leo does not find leoConfig.txt, This version will use defaults specified in tables defined in the section
	&lt;&lt; define default tables for settings &gt;&gt;
in leoConfig.py.  So it is now convenient to change settings in leo.py itself as well as in leoConfig.txt.</t>
<t tx="edream.110203163054.546">Including the split direction and split ration.

Leo now uses all configuration settings from leoConfig.txt.</t>
<t tx="edream.110203163054.547">If you drag a headline above or below the outline pane the outline pane will scroll automatically.  As before, Leo will cancel the drag if you release a headline anywhere but over another headline's icon.</t>
<t tx="edream.110203163054.548">You can specify colors for each syntax coloring construct using a color wheel or by choosing one of the standard Tk color names.  When a color becomes active Leo writes its value or color name to the log pane for your reference.  This is useful when setting coloring options in leoConfig.txt.</t>
<t tx="edream.110203163054.549">Using this panel should be self-explanatory (what you see is what you get) with the following exceptions:

1.  When a font becomes "active", the new font appears in the panes whose check boxes are selected.  A font becomes active when you double-click its name, or check or uncheck any checkbox.

It would be much better to have a font become active if you just select its name.  Alas, that is not possible due to a well-known gap in the Tk.Listbox class.

2. Font sizes must be greater than 0 and less than 100 for them to become in effect.

3. Choosing very _small_ values for font sizes may cause Leo's window to _expand_ its width.

4. When you choose OK or Cancel Leo writes the fonts presently active in each pane to the log pane for your reference.  This is useful when setting font options in leoConfig.txt.</t>
<t tx="edream.110203163054.550">This was a supremely irritating bug.</t>
<t tx="edream.110203163054.551">This command switches between vertical and horizontal orientations of the Leo window.  In the vertical orientation, the body pane appears below the pane containing the outline and log panes.  In the horizontal orientation, the body pane appears to the left the pane containing the outline and log panes.

leoConfig.txt specifies the default direction.  If leoConfig.txt does not exist, or does not specify the direction, the "vertical" orientation is used, just as in previous versions.

By default, the ratio of pane outline pane to the body pane is 0.5 in the vertical orientation and 0.3 in the horizontal orientation.  These two ratios may be changed using leoConfig.txt.</t>
<t tx="edream.110203163054.552">The @comment directive no longer suppresses syntax coloring.  Leo directives (but not doc parts) are colored when @language plain is in effect.  The user can, as always, suppress all coloring by using @nocolor.  The new rules are much more natural than the old, and much less confusing.</t>
<t tx="edream.110203163054.553"></t>
<t tx="edream.110203163054.554"></t>
<t tx="edream.110203163054.555">The old colorer colored all Leo directives blue, the same color as keywords in whatever language is current. I think the distinction between Leo directives and language keywords is useful.  Of course, you can control syntax coloring yourself by altering leoConfig.txt.</t>
<t tx="edream.110203163054.556">This message is printed to the console, not the log pane.  On windows, this may not always be visible.</t>
<t tx="edream.110203163054.557">Leo will convert underscores in the @comment directives to significant spaces.  For example,

@comment REM_

causes the comment delimiter to be "REM " (Note the trailing space).</t>
<t tx="edream.110203163054.558"></t>
<t tx="edream.110203163054.559">This happened sometimes when using @comment.</t>
<t tx="edream.110203163054.560">Leo directives were mostly being colored using the colors for keywords.  This didn't show up because both were colored blue.</t>
<t tx="edream.110203163054.561">Only one window now appears when opening a .leo file, and the window is completely drawn before anything gets written to the log pane.</t>
<t tx="edream.110203163054.562">Added new code for Convert All Blanks and Convert All Tabs.

Fixed a bug that resulted in Convert Tabs being undoable.</t>
<t tx="edream.110203163054.563">This makes the panel much more convenient to use.</t>
<t tx="edream.110203163054.564"></t>
<t tx="edream.110203163054.565">leo.py version 2.5.1                            July 7, 2002

2.5.1 This version corrects crashers that affect undo/redo move commands.
Version 2.5 has been withdrawn.
Anyone using 2.5 should use 2.5.1 instead.

This is a major step forward to completing leo.py.  It adds significant new features and corrects many bugs.  Full details are found in the children of this node.  Here are the highlights, in approximate order of importance:

1. Leo supports tab widths properly, and negative tab widths cause Leo to convert tabs to blanks as you type.  Three new commands appear in the Edit Body menu: Convert Tabs, Convert All Tabs and Convert All Blanks.  Convert All Tabs and Convert All Spaces convert the entire selected tree.

2. Leo now allows you to override selected preferences using a configuration file called leoConfig.txt. Leo acts as before if this file does not exist.  An option in leoConfig.txt specifies whether leoConfig.txt is read-only.

3. The Preferences panel is now a modal dialog containing Ok, Cancel and Revert buttons.  This makes it clear what preferences are being set.

4. At long last, cut and paste work properly in all situations.  You can cut and paste between Leo and other applications, or between two different copies of Leo.

5. Added the Recent Files submenu to the File menu.  Very nice to have.

6. Fixed a number of bugs, including several crashers.  Fixed several bugs in the Import commands.  Leo will no longer abort reading if it detects an invalid directory name in the Default Tangle Directory in the Preferences panel.

leo.py is almost complete.  The only remaining tasks on my list are:

1. Make the Set Font... and Set Colors... commands functional.  This will be easy now that leoConfig.txt exists.
2. Fix the Javadoc bug.</t>
<t tx="edream.110203163054.566">The following are listed in the approximate order of their importance.  The marked nodes are particularly important.</t>
<t tx="edream.110203163054.567">Gary Herron suggested this changes.</t>
<t tx="edream.110203163054.568">These commands convert an entire tree.</t>
<t tx="edream.110203163054.569">This command converts leading tabs to blanks in a single node.</t>
<t tx="edream.110203163054.570">Previous versions of Leo ignored the tab width field!  This field is now fully functional.  </t>
<t tx="edream.110203163054.571">Leo converts tabs to blanks as you type when a negative tab width is specified.</t>
<t tx="edream.110203163054.572">The Preferences panel is now a modal dialog.  This solves a number of problems, both for the implementation and for the user.  It is now completely clear which preferences are being set, viz., the preferences for the window on top.  In addition, the Prefs panel now shows the name of the window whose preferences are to be set.

The Prefs panel now contains OK, Cancel and Revert buttons.  These are useful, and they are possible only because we have a modal dialog.</t>
<t tx="edream.110203163054.573">You may now cut and paste between Leo and other apps, or between two different copies of Leo.</t>
<t tx="edream.110203163054.574">The elements of this submenu are saved in leoConfig.txt, if present.

Leo adds files to this submenu even if leoConfig.txt is missing or read-only, but those additions will not be remembered unless leoConfig.txt is present and writable.</t>
<t tx="edream.110203163054.575"></t>
<t tx="edream.110203163054.576"></t>
<t tx="edream.110203163054.577"></t>
<t tx="edream.110203163054.578">1. Importing the following script

class C:
    def __init__(self):
        pass

created an outline with class C appearing in two nodes.

2. Importing the following file created orphan nodes for declaration.

import sys # This line becomes an orphaned node
class C:
    xyz = 'xyz' # This line becomes an orphaned node
    def __init__(self):
        pass

3. Importing a Python file containing classes without methods resulted in nested classes. There is still a minor problem:  The following

class A:
	pass

puts the "pass" in a section called &lt;&lt; class A declarations &gt;&gt;.  This is not easy to fix: you will have to correct it by hand.

4. Improved the Import to @root command.  Added @root &lt;filename&gt; to the body text of the root of tree and eliminated @language and @others directives.</t>
<t tx="edream.110203163054.579">This is important, because it means that invalid entries in, say, the Default Tangle Directory preference will no longer abort an attempted read.</t>
<t tx="edream.110203163054.580"></t>
<t tx="edream.110203163054.581">This would happen if the Default Tangle Directory did not exist in the Prefs panel.</t>
<t tx="edream.110203163054.582">This command always crashed, perhaps due to a reversion.</t>
<t tx="edream.110203163054.583">The crash happened if the Import command was executed in a new, unsaved file.

The fix was to the directory logic in import.scanAllDirectives.</t>
<t tx="edream.110203163054.584"></t>
<t tx="edream.110203163054.585"></t>
<t tx="edream.110203163054.586">The bug involves only the clone mark itself: nodes have always been properly joined.</t>
<t tx="edream.110203163054.587">Gary Herron reported this bug and told me how to fix it. This change is to the default file extension field of file dialogs.  It seems to have no effect on Windows. Apparently this makes a difference in Linux...</t>
<t tx="edream.110203163054.588">These commands no longer change the file name associated with a window if the user cancels the Save or Save As dialog.</t>
<t tx="edream.110203163054.589">This involved changing the documentation for the Demote, Insert Headline, Extract Headline, Syntax Coloring... and Font... commands.  Removed documentation for the Open/Close Log Window command.</t>
<t tx="edream.110203163054.590"></t>
<t tx="edream.110203163054.591">leo.py version 2.4                             June 20, 2002

This version fixes some annoying bugs and adds some nice features.  The children of this node contain full details.

1. Leo now properly highlights the headline of a newly created node.  Similarly, the Edit Headline command (control-H) now works.  Double-clicking in a headline now does what you would expect: it selects the word under the cursor.  Similarly, triple-clicking now selects the entire headline.  Also fixes several other minor bugs.

2. Drag and drop.  You can now reorganize outlines by dragging nodes around.  You must drag from a node's headline and release on another node's headline.  See a child of this node for complete details.

3. You can now open .leo files in leo.py by double clicking on .leo files.  You must associate leo.py with .leo files.  See a child of this node for detailed instructions about how to do this.

4. Improves error recovery when there are errors writing .leo files.

5. Updates this file to match the documentation of Leo's web site.  At long last, Leo's documentation is complete.</t>
<t tx="edream.110203163054.592">1. Fixed a bug in app.finishCreate that caused Leo to take an exception on MacOS X.

2. Leo now properly highlights the headline of a newly created node.  Similarly, the Edit Headline command (control-H) now works properly.

3. Removed a useless assert in st_enter_root_name that could fail under unusual circumstances.</t>
<t tx="edream.110203163054.593">When writing a .leo file, say f.leo, Leo now attempts to create a backup file called f.leo.back.  If there is an error while writing f.leo, Leo will restore f.leo from f.leo.back.  Note that Leo will write derived files correctly even when there is an error writing the .leo file.</t>
<t tx="edream.110203163054.594">New in leo.py v2.4: You may drag an node (including all its descendents) from one place to another in an outline.  To start a drag, press the main (left) mouse button while the cursor is over the icon for a node.  The cursor will change to a hand icon. If you release the mouse button while the hand cursor is above the icon for another node, Leo will move the dragged node after that node.  If you release the mouse button when the hand cursor is not over an icon, Leo will print "not moved" and leave the outline pane as it is.  This can result in the dragged node not being visible on the screen, but it seems less alarming not to force the current node to become visible as that would undo any scrolling that has just been done.

New in leo.py 3.0: If you drag outside the outline pane, the outline pane will scroll automatically.

Leo scrolls the outline pane as the result of mouse-moved events, so to continue scrolling you must keep moving the mouse.  I experimented with scrolling the outline pane whenever the cursor is dragged outside it, but the results were not good.  There was a noticeable delay between releasing the cursors and halting the scrolling.  The present code is simpler and more likely to work on all platforms.

Leo only allows dragging from one icon to another.  In particular, you can't move a node to the first child of another node unless that node is already expanded.   I experimented with automatically open nodes when the cursor moves over an unexpanded node with children.  However, this was confusing and alarming.  It seems best to expand and contract nodes explicitly.</t>
<t tx="edream.110203163054.595">leo.py version 2.3                             June 5, 2002

This version fixes a minor problem with Leo.

1.  The code that reads and writes @file nodes now uses the directory containing the .leo file as a default when the Default Tangle Directory setting is empty in the Preferences panel.  This is a reasonable default because derived files are most often created in the same directory as the .leo file.  BTW, the Tangle and Untangle commands have used this convention for a long time.

Note: This default allows us to distribute LeoPy.leo without specifying a directory in the Preferences Panel.</t>
<t tx="edream.110203163054.596">leo.py version 2.2                             June 1, 2002

The version fixes two bugs that happen rarely and can cause loss of data when they do happen.

1.  In certain circumstances leo.py v2.1 would delete most of an outline when a node was moved in front of the previous root node!

2.  All previous versions of leo.py will crash when saving body text containing unicode characters.  This could occur as the result of cutting and pasting text from another application into the body pane.  Leo.py now writes body text containing unicode characters using Python's u-prefixed notation.  That is, the body text is written as: u'escaped_text'  where escaped text replaces unicode characters not in the ascii character set by escape sequences of the form \uxxxx.  The result contains nothing but ascii characters, so leo.py will have no problem reading it.  Naturally, compilers and other tools may not understand Python's notation, so you may have to convert escaped text to something that your tools can understand.

3.  This file, LeoDocs.leo, now more closely matches the documentation on Leo's web site.</t>
<t tx="edream.110203163054.597">leo.py version 2.1                             May 16, 2002

This version of Leo adds Import and Export commands and fixes several bugs:

1. All Import and Export commands now work. Several of these commands are found only in Leo.py.  Some of these commands may be of beta quality.

I use Import commands mainly for studying other people's code.  Be wary of generating source files from trees generated by the Import commands.

2. Fixed a bug that caused Leo to crash when a node was moved up in front of the previous root node.

3. Fixed several bugs in the syntax colorer.  One of these bugs caused Leo to crash when handling CWEB.

4. Leo now colors strings green.</t>
<t tx="edream.110203163054.598">I use Import commands mainly for studying other people's code.  Be wary of generating source files from trees generated by the Import commands.

The Remove Sentinels command can "clean" files for publication or walk-throughs.  You can also use the Remove Sentinels command to prepare files for comparisons.  For example, one could study a file, say f.py, as follows:

1. Use the Import Files command to create an @file tree, say @file f2.py, for study.  Changing the name to f2.py ensures that saving the .leo file won't destroy the original file.

2. Use the Remove Sentinels command to create a file f3.py.  Use a file comparison program to ensure that f1.py is identical to f3.py.</t>
<t tx="edream.110203163054.599">Fixed several bugs that caused Leo to hang when moving an outline up before the previous root node.</t>
<t tx="edream.110203163054.600">Fixed a bug that caused Leo to hang when syntax coloring noweb code with the CWEB syntax colorer.

The syntax colorizer now handles Python triple strings and C preprocessor directives properly.

Leo now colors strings with the same green used by IDLE.  I think this color looks very good.

Improved the syntax coloring for CWEB.</t>
<t tx="edream.110203163054.601">leo.py version 2.0                             March 4, 2002

leo.py v2.0 and Borland Leo v2.6 are being released simultaneously.  I urge all users of Leo to upgrade to one or both of these versions.  Note: the Untangle commands of both v2.0 and v2.6 should be considered beta quality.  Please report any problems with Untangle ASAP.

This is an important milestone in Leo's history, for several reasons:

1. For the first time, leo.py (v2.0) and the Borland Leo (v2.6) are functionally identical.  In particular, their respective Tangle commands produce identical output.

2. All "mission critical" aspects of leo.py are now complete: only the Import commands remain unfinished. leo.py v2.0 adds unlimited Undo/Redo, Untangle and full syntax coloring.  Unlimited Undo/Redo are reason enough to upgrade to v2.0.

3. leo.py v2.0 and Borland Leo v2.6 introduce an optimized format for derived files: both versions remove blank lines from between sentinel lines.  This is an upward compatible change in the format of derived files: leo.py v2.0 and Borland Leo v2.6 can read derived files from all previous versions of Leo, but previous versions of Leo can not read derived files without blanks lines between sentinels.

See the children of this node for full details.</t>
<t tx="edream.110203163054.602">leo.py v2.0 optionally can remove blanks from between sentinel lines in derived files.  This is an upward compatible change in the format of derived files: leo.py v2.0 can read derived files from all previous versions of Leo, but previous versions of Leo can not read derived files without blanks lines.

Removing blank lines requires a new kind of sentinel, the "verbatimAfterRef" sentinel.  This allows Leo to handle comments following section references that would otherwise be treated as sentinels themselves.  For example:
   
   &lt;&lt; section &gt;&gt; #+others
   
Leo removes blanks lines between sentinels by default.  To cause Leo not to remove blank lines do the following.  In the section called &lt;&lt; initialize atFile ivars &gt;&gt; in leoAtFile.py, change:

	self.suppress_newlines = true
to
	self.suppress_newlines = false

Note: leo.py v2.0 can read derived files without blank lines between sentinels regardless of the setting of self.suppress_newlines.
</t>
<t tx="edream.110203163054.603">leo.py supports unlimited Undo and Redo.  All outline operations and all typing operations may be undone and redone.  Undo state persists even after Saves.  Even the Change All command is undoable.  Only the "Read @file Nodes" command is undoable; it clears the entire undo state. This command raises a dialog to allow the user to cancel.

Think of the actions that may be Undone or Redone as a string of beads.  A "bead pointer" points to the present bead.  Performing an operation creates a new bead after the present bead and removes all following beads.  Undoing an operation moves the bead pointer backwards; redoing an operation moves the bead pointer forwards.  The Undo command is disabled when the bead pointer moves in front of the first bead; the Redo command is disabled when the bead pointer points to the last bead.

</t>
<t tx="edream.110203163054.604"></t>
<t tx="edream.110203163054.605">leo.py syntax colors all languages mentioned in the Preferences Panel.</t>
<t tx="edream.110203163054.606">1. Show Invisibles command works in @nocolor mode.

2. @unit, @root, @nocolor and @color now terminate doc parts.

3. Three characters were colored blue at the start of a section def in:

  &lt;&lt;name&gt;&gt;=
  
This didn't show up if there is a space after the &lt;&lt;.</t>
<t tx="edream.110203163054.607">Leo adds extra space at the end of headlines so that headlines now have enough room to show all text.  This works around an apparent Tk bug.</t>
<t tx="edream.110203163054.608"></t>
<t tx="edream.110203163054.609">The Untangle command is beta quality. Please make backups before untangling.</t>
<t tx="edream.110203163054.610">leo.py v2.0 fixes two bugs present in Borland v2.5 and fixed in Borland v2.6:

1. Untangle did not work properly for languages like Perl and Python that do not have block comments. 

2. Untangle did not recognize @ on a line by itself as the start of a doc part.</t>
<t tx="edream.110203163054.611">@c now works the same as @code.  This makes the syntax colorers agree with what the Tangle commands actually do.  Previously, the syntax colorers indicated that everything following an @c was code, while the Tangle commands placed everything following an @c in the doc part!</t>
<t tx="edream.110203163054.612">Previous versions of untangle silently trimmed trailing lines from all nodes, which seems rude.</t>
<t tx="edream.110203163054.613">The font size for code text is now 12 on Linux.

Changed code so that the path to the Icons folder is computed correctly on all platforms.</t>
<t tx="edream.110203163054.614">leo.py version 1.0                             February 10, 2002

Version 1.0 adds many new features and fixes several bugs.  I recommend that all users of leo.py upgrade to this version.  This version deserves the number 1.0; it has no known bugs.

Here are the highlights of this release.  See the children of this node for details.

1. Fixed bugs: the Tangle All and Tangle Marked commands didn't work at all. Fixed several bugs in the Find and Change commands.  The "Suboutline Only" option now applies to the Search All and Change All commands.  Settings in the Preferences Panel now "stick" properly to the currently selected window.  Fixed many minor bugs.

2. leo.py now re-marks @file trees as dirty if errors are found while writing those trees.  This makes it difficult to write derived files that will be out-of-synch when read again.

3. New commands and features:  Added the Revert, Select All, Delete, Sort Children, Sort Siblings, Contract Parent (very useful!) and Toggle Active Pane commands, and all commands in the Edit Body menu, and all the Go To commands in the Move/Select menu. The Show Invisibles commands is ugly, and useful nonetheless.

The Edit Body commands work much more reliably than the similar commands in the Borland version of Leo.  You may now specify Python scripts rather than .bat files in the Preferences panel. Added a way, albeit clumsy, to cut and paste nodes between Borland Leo and leo.py.  When syntax coloring Python text, leo.py increments the auto-indentation by one tab after a trailing colon.  This provides a subtle reminder to add such colons.

4. leo.py handles events and shortcuts properly.  The shortcut for the Insert Node command is now Control-I, as it is in the Borland version of Leo.  Worked around a TK bug that prevented double-clicks from properly selecting words.  leo.py enables and disables all menu items properly.</t>
<t tx="edream.110203163054.615">Removed the Print and Page setup commands because Tk provides no support for printing.  This is not significant: we can use the export commands to create text files.  These text files can then be formatted and printed as desired.

The following commands remain unfinished.  They will be finished in this order:

1. Untangle commands. 
	
2. Import/Export commands.

3. Unlimited Undo and Redo.

4. Toggle Split Direction, Cascade and Recent Windows commands.

5. Font Panel and Syntax Coloring commands.</t>
<t tx="edream.110203163054.616">It should be possible to cut a node or tree in Borland Leo and paste it using the Copy Node command in leo.py.  At present, cutting and pasting trees between applications can only be done indirectly.  Do this:

1. Copy the tree in Borland Leo using the Copy Node or Cut Node command.
2. Paste the tree into empty body text of leo.py using the Paste command from the Edit menu, _not_ the Paste Node command from the Outline menu.
3. Select all the body text and choose Copy or Cut from the Edit menu.
4. Move to the tree view, and choose Paste Node.

I hope to make this unpleasantness go away soon.</t>
<t tx="edream.110203163054.617">1. Fixed the Tangle All and Tangle Marked commands.  They always crashed.

2. The Change command did not work in headlines because of a reversion in how headline text is selected.

3. All event handlers now return "break".  This prevents further event handling and allows leo.py to handle events properly.  This cleared up the last major mystery in leo.py.

4. Settings in the Prefs Panel now "stick" to windows.  That is, they change when the user selects a new Leo window.  In particular, the Default Tangle Directory is restored properly.  This is important, as otherwise the Tangle commands might write files to the wrong place.

5. Removed calls to trace during shutdown.  In general, it is not possible to call app() during shutdown because the app object may no longer exist.

6. @others was not syntax colored properly if it was indented.</t>
<t tx="edream.110203163054.618">1. Adding trailing whitespace to a line in body text does not set the file-dirty mark.  This can never cause a derived file to become "out-of-synch" because the read code does not compare body text.

Apparently there is no way to fix this bug because of holes in Tk's event mechanism.  Specifically, tree.idle_body_key has no way to tell directly what keystroke caused it to be entered.

2. Cutting and pasting between applications can only be done indirectly.  See the node called
"How to copy an outline from Borland Leo to Leo.py".</t>
<t tx="edream.110203163054.619">leo.py version 0.08                             February 3, 2002

Version 0.08 adds important new features and fixes several bugs.  All users of version 0.07 should upgrade to this version.  This code seems solid, and significant bugs may remain.  Note: this code has been tested only on Windows XP.  Please report any problems with Linux or Macintosh.

This is the first version of Leo to feel as smooth as the Borland v2.5. leo.py is now less buggy than v2.5; the Borland version will soon be upgraded to match leo.py.

Here is a summary of new features.  See the children of this node for full details.

1. The Find and Change commands are fully functional.  These commands support Tk's "advanced regular expressions" when the "pattern match" option is checked.  Tk's regular expressions are documented at:

  http://tcl.activestate.com/man/tcl8.4/TclCmd/regexp.htm

2. The Tangle commands work; leo.py now supports @root trees.  The next release will support the Untangle commands.  Converting the Untangle code to Python is almost complete.

3. Leo now ensures that the currently selected headline is always visible, scrolling the outline pane as needed.

4. Improved Leo's memory management and eliminated several serious bugs.  One bug caused errors while reading @file trees.  Eliminating this is a huge step forward.  This bug exists in the Borland version of Leo and will be fixed soon.

5. Leo now underlines undefined section references.  Added support for hyperlinking, but disabled hyperlinking because it is not very useful without browser navigation buttons.</t>
<t tx="edream.110203163054.620">leo.py handles Find and Change commands much more smoothly than does the Borland version of Leo.  Indeed, I plan to rewrite the Borland code to match the code in leo.py.

In general, leo.py handles the Find and Change commands more smoothly than does the Borland version of Leo.  Note: the node that "anchors" wrapped searches is the current node when any change is made to the Find panel.  The anchor is recomputed after a wrapped search fails.

Changed the meaning of a Find panel setting from "batch" to "context".  This will be changed in a future Borland version.  In the meantime, setting the "context" option in leo.py will set the "batch" option in the Borland version.

The "context" option affects only the "Find All" and "Change All" commands.  When this option is in effect, more context information is printed when matches are found.

The "reverse" option affects all Searches and Changes, both those initiated from the Find Panel itself, and those initiated from menu commands.  In particular, F3 will find the previous search if the "reverse" option is in effect.</t>
<t tx="edream.110203163054.621">The Tangle command has passed significant tests, and bugs may remain.  Be warned.

leo.py's Tangle command produces output that is slightly different from Leo v2.5. The differences are insignificant; here is the complete list:

1. The header line, i.e., the first comment line of the tangled file: leo.py produces forward slashes in the path name, Leo v2.5 produces back slashes.

2. Leading whitespace: leo.py produces "optimized" leading whitespace.  leo.py removes blanks if they do not affect the visual appearance of whitespace; this depends on the tab width specified in the Preferences Panel.  Leo v2.5 copies leading whitespace exactly.  The leo.py way is preferable; it will produce output acceptable to Python's tabnanny regardless of tab width used while running Python.

3. Trailing blanks lines in body text: leo.py removes all trailing whitespace.  Leo v2.5 does not.  Conceivably, leo.py might have to change to make the Untangle command work properly.  More likely the leo.py way is just better.</t>
<t tx="edream.110203163054.622">Underlining "live" links clutters the screen too much, and hyperlinks from section references to section definitions isn't very useful without the standard "back" and "forward" buttons typically found in web browsers.  For these reasons, I have disabled hyperlinking.

To enable hyperlinking, just set:

	self.use_hyperlinks = true
	
in color.__init__ in the @file leoColor.py tree.</t>
<t tx="edream.110203163054.623">1. Fixed several bugs involving cloned headlines.  One bug caused cloned headlines not to be updated in synch.  Another bug caused @file trees not to be marked as dirty under certain conditions.

Both bugs could have caused read errors while reading @file trees, so fixing these bugs is a big step forward.  I have experienced no read errors since fixing these bugs.  A huge step forward.  This bug exists in the Borland versions of Leo and should be fixed ASAP.

2. There was a big performance bug lurking in the tree code that became apparent during testing of the Find and Change commands.  Closing a window could take almost a minute if the tree had been redrawn many times.  Old widgets were never deleted until the window was closed.  This may be a problem with tkinter, and the workaround was straightforward.

3. Fixed a bug in the "Save To" command.  After doing a Save To, a following Save command used the Save To file name!  This explains why some saves "didn't take".

4. Fixed a bug in the Save commands.  Cancelling a Save dialog did not work: instead it wrote a file called ".leo".  I am not sure whether this bug occurred in previous releases. 

5. All Save commands now always recompute file indices.  This old logic accomplished very little, and introduced needless differences between the various kinds of Save commands.

6. Made file and path name processing more portable.  Removed all calls to os.chdir().

7. Fixed a bug that caused a control-d to delete a character in the body pane when the Move Down command didn't do anything, i.e., when the presently selected node was the bottom node on the screen.</t>
<t tx="edream.110203163054.624">1. Used Tk.Text widgets in headlines rather than Tk.Entry widgets.  This allows the Find/Change commands to search headlines.  Control-k no longer deletes text following the cursor in headlines.

2. Improved the performance of screen updates and markedly reduced flicker in the body pane.

3. Found a way to handle keystrokes without knowing the status of the control and alt keys.  The idle event handlers now ignore the actual keystrokes in most cases, and take action solely based on whether the headline or body text has actually changed as the result of those keystrokes.  If not, we can assume that a command has been entered and we do not set the dirty or changed bits.

4. Replaced es_newline global with app().log.es_newline, i.e., frame.es_newline.  This is better than before because each log stream now has its own newline count.

5. Reduced width of the log pane to give more space to the tree pane.

6. The LeoPy folder now contains a dummy file called __init__.py.  This file marks the LeoPy folder as a potential package.

7. Added several new functions to the file leo.py.  These are useful for invoking leo.py from a Python interpreter.  See the section "How to Install &amp; Run Leo" for details.</t>
<t tx="edream.110203163054.625">Previous version of leo.py did not release memory when windows close.  This version does.

Memory management is remarkably easy in Python/Tk.  Added __del__ routines and corresponding destroy routines to the frame, vnode and tree classes.  The destroy routines eliminate circular references between objects. The __del__ routines do nothing except print debugging traces; we know that all references to an object have been removed when its __del__ routine is called.

Added app.deleteOnClose ivar to control memory management.  When true, Leo deletes all frame objects when a frame closes.  This is always true at present.

Fixed a memory botch: previously a dummy vnode was allocated for every vnode created while reading files.</t>
<t tx="edream.110203163054.626">Starting with this release, you will see trace statements throughout the code.  The trace function is defined in leoUtils.py; trace implements much of the functionality of my Sherlock tracing package.  Traces are more convenient than print statements for two reasons: 1) you don't need explicit trace names and 2) you can disable them without recompiling.

In the following examples, suppose that the call to trace appears in function f.

trace(string) prints string if tracing for f has been enabled.  For example, the following statement prints from s[i] to the end of the line if tracing for f has been enabled.

	j = skip_line(s,i) ; trace(s[i:j])

trace(function) executes the function if tracing for f has been enabled.  For example,

	trace(self.f2)

You enable and disable tracing by calling init_trace(args).  Examples:

	init_trace("+*")         # enable all traces
	init_trace("+a","+b")    # enable traces for a and b
	init_trace(("+a","+b"))  # enable traces for a and b
	init_trace("-a")         # disable tracing for a
	traces = init_trace("?") # return the list of enabled traces

If two arguments are supplied to trace, the first argument is the "tracepoint name" and the second argument is the "tracepoint action" as shown in the examples above.  If tracing for the tracepoint name is enabled, the tracepoint action is printed (if it is a string) or executed (if it is a function name).

"*" will not match an explicit tracepoint name that starts with a minus sign.  For example,

	trace("-nocolor", self.disable_color)</t>
<t tx="edream.110203163054.627">Rewrote the code that computes file names.  This should have two beneficial effects:

Note:  This code has only been tested on Windows XP.

1. The code should be more portable.  I've used os.path.join throughout to concatenate parts of filenames, and this should handle differences involving path separators on different platforms.

2. The code no longer calls os.chdir().  The "current application directory" changes only as the result of completing file open and save dialogs.  In particular, @path, @root and @file do not change the current application directory.

3. Used leo.__file__ to get the directory from which leo.py was loaded.  This seems to be reliable, though it has only been tested on Windows XP.</t>
<t tx="edream.110203163054.628">The following features of leo.py will be incorporated into the Borland version 2.6 of Leo:

1. Improve leading whitespace handling in Tangle.

2. Fix clone bugs (rewrite vnode::setDirty).  These bugs can cause errors while reading @file nodes.

3. Improve Find/Change commands. Change "batch" to "context".  This will make the Preferences Panel work identically in both programs.

4. Always recompute file indices and compute file indices.  This will make derived files produced by v2.6 identical to the files produced by leo.py.

5. Make sure all file names end in .leo.</t>
<t tx="edream.110203163054.629">I urge anyone using leo.py upgrade to this version.  This is the first version of leo.py that has been thoroughly tested.

See the children of this node details about this release.  Here are the highlights:

1. Fixed many bugs, including a bug that can cause body text to be lost when creating a new headline.

2. The Python window now works. You can now run Python scripts from within leo.py!

3. Added a script to convert Leo files from Leo 1 to Leo 2 format.

4. @nocolor and @color are now inherited properly from ancestor nodes.

5. Added Leo Documentation to Help menu.  This command opens LeoDocs.leo.
	
6. Added auto indent to body pane.

For even more details, see the diary entries for January 6-9 in LeoPy.leo.

See the To Do lists in LeoPy.leo for a list of unfinished features.  The primary unfinished features are the Find/Change commands, preferences settings and the Tangle/Untangle commands.</t>
<t tx="edream.110203163054.630">This is the first version of leo.py that has been heavily tested.  About 70 percent of my work on leo.py has been done using leo.py itself.   I know of no remaining bugs that can cause data to be lost.</t>
<t tx="edream.110203163054.631">I have concentrated on removing all significant irritations encountered while using leo.py.  Far fewer still remain than before.  Among the remaining irritations:

1. Syntax coloring happens at "idle time", that is, after all events have been handled.  This means that characters are initially colored black, then changed to another couple after an obvious delay.  The obvious event-handling code does not work.  Perhaps using a "virtual event" may work.

2. Keystrokes that should initiate commands _also_ get passed to widgets.  I am hoping to find a way around this, and it may take a bit of work.  The two biggest offender:  Control-k while editing a headline deletes from the cursor to the end of the headline (in addition to creating a new node!)  Control-i gets passed to the body pane as a tab.

3. The border around the tree pane gets over-written by headlines.  I'm not sure how to fix this: it is certainly a Tk bug.</t>
<t tx="edream.110203163054.632">Fixed a bug that can cause body text to be lost when creating a new node.</t>
<t tx="edream.110203163054.633">Choosing Open Python Window brings up IDLE, the standard Python IDE, from which scripts may be run and debugged.

Note: The path to idle.py must exist in sys.paths.  For Python2.1 on windows, this path will typically be \Python21\Tools\idle  If this path does not exist, a message will be sent to the log pane.  The usual way to add a path to sys.paths is to modify the sitecustomize.py file.

Changed names of several vnode and commands methods to make them compatible with the scripting documentation on Leo's web site.   You may now run any script that runs on Borland Leo on leo.py.

When running scripts from leo.py, you may refer to any method or instance variable (attribute) in the code for leo.py.  If you want to run those scripts on Borland Leo you should restrict yourself to the methods documented in the Scripting chapter of Leo's online documentation.</t>
<t tx="edream.110203163054.634">To convert an @root tree to an @file tree, choose the root of the tree to be converted, then do the following in the Python window:

	import c2py
	c2py.leo1to2()
	
This script makes numerous changes throughout the tree.  It does not, however, change @root to @file, or insert the needed @others directives.  You must do that by hand.</t>
<t tx="edream.110203163054.635">At long last it is possible to open this file, LeoDocs.leo, from the help menu.

This command will work only if LeoDocs.leo is located in the directory in which leo.py exists.</t>
<t tx="edream.110203163054.636">The body pane now has auto-indent on at all times.</t>
<t tx="edream.110203163054.637">leo.py version 0.06 (alpha)                     December 20, 2001

This version fixes several minor problems that prevented leo.py from running on Linux.  There is no need to upgrade to this version if leo.py works on your system.  This version is neither more nor less stable than version 0.05.  This file, LeoDocs.leo, has also been improved substantially.

There still may be problems running leo.py on Linux.  You may be able to fix those problems yourself after reading this file... I'll be on vacation until about January 8.  I may be able to answer questions on Leo's SourceForge site, and I'll make no code changes until then.

Problems fixed:

1.  Removed call to print_stack() in es() logic.  If there are problems during initialization this logic printed "Null log" and then printed a stack dump.  This dump was more confusing than helpful.

2.  Changed "darkblue" to "DarkBlue".  The standard colors known to Tk are listed at
	http://tcl.activestate.com/man/tcl8.4/TkCmd/colors.htm
	
If you have more problems with unknown colors, please use a color listed above.

3.  Eliminated some accelerators (Linux only).  You may take an exception in createAccelerators() in leoFrame.py if Linux does not support the accelerators defined in one of the following sections:

  &lt;&lt; control key bindings &gt;&gt;
  &lt;&lt; alt key bindings &gt;&gt;
  
Just comment out the relevant entry.  Please let me know which accelerators don't work.  I can add platform-specific code to deal with them.

4.  Added loaddir code to leo.py.  Leo tries to guess where leo.py was loaded from.  If this doesn't work leo may take an exception in leo.py.

As a temporary hack, please set loaddir correctly in the following code at the start of leo.py:

  # loaddir should be the directory that contains leo.py
  if sys.platform=="win32":
    loaddir = "c:\\prog\\LeoPy\\"
  else:
    loaddir = "LeoPy"
	
5. Removed bullet 0x95 characters from this file. They don't show up well on Linux.

6. In leoTree.py, changed the filenames from x.gif to x.GIF.  Linux is more picky about case in filenames than Windows.

Edward K. Ream
December 20, 2001</t>
<t tx="edream.110203163054.638">leo.py version 0.05 (alpha)                      December 17, 2001

This version of Leo marks a major milestone in Leo's history.  leo.py is the first functional version of Leo written completely in Python and Tkinter, Python's interface to the tcl/Tk system.

leo.py is quite useable. leo.py should work on any machine with recent Python and tcl/Tk interpreters.  This version of Leo was created using Windows XP, Python 2.1 and tcl/Tk 8.3.

Warning: This version is alpha quality.  Use extreme caution: please save your work often and make full backups of all .leo files and derived files.

Please read this node's children before sending bug reports or feature requests.  Send all bug reports to Leo's SourceForge web site at: http://sourceforge.net/projects/leo/

Edward K. Ream</t>
<t tx="edream.110203163054.639">I have been happily using leo.py to develop itself for the last three days without serious problems.  leo.py reads and writes all its source files exactly as does the Borland version.  This is an important test, and significant errors may remain.

Performance on a 1.2 Ghz Pentium is good to excellent.  Drawing the screen happens quickly, smoothly and without flicker.  Expanding and contracting nodes is usually excellent, and slows when a many nodes have been expanded.  Syntax coloring appears instantaneous, even with an unsophisticated algorithm.  Loading LeoPy.leo files takes about 3 seconds. This could be improved by using Python's XML classes.</t>
<t tx="edream.110203163054.640">You must have recent versions of Python and tcl/Tk installed on your machine.
Download Python from http://python.org/
Download tcl/Tk from http://tcl.activestate.com/software/tcltk/

After installing Python and Tk, run Leo double clicking the file leo.py in the LeoPy folder.  On Windows this will bring up a Leo window and a black Python interpreter window.

The LeoPy folder contains all files in this distribution.  leo.py is the main source file; run Leo by double clicking leo.py.  The Python interpreter will create corresponding .pyc files as .py files are imported by leo.py.

LeoPy.leo is the master source code file; all .py files were derived from LeoPy.leo.  c2py.py and leoCompare.py are tools that should be run from a Python interpreter.
</t>
<t tx="edream.110203163054.641"></t>
<t tx="edream.110203163054.642">Functional Commands and Features

    Open, Save, Save As, Save To commands.
    Read @file Nodes command.
    Read Outline Only command.
    Write Outline Only command. Warning: this has not been tested thoroughly.
    Insert Node, Delete Node and Clone commands.
    Move Node Right/Left/Up/Down commands.
    Cut Node, Copy Node, Paste Node commands.
    Syntax coloring for Python only.
    The @color and @nocolor directives, but these are not inherited yet.</t>
<t tx="edream.110203163054.643">Unfinished Commands and Features:

	Revert.
	All Tangle and Untangle commands.
	All Import commands.
	All Find and Change commands.
	Sort Children command.
	Toggle Split Direction, Toggle Active Pane and Cascade commands.
	Auto indent in the body pane.
	The Preferences panel is semi-functional: see note one below.
	The Find panel is non-functional.
	The Python scripting window is non-functional.
	Syntax Coloring Options and Font Options windows are not ready yet.
	@color and @nocolor directives are not inherited yet.

Notes:

1. The Preferences panel is partly functional.  The default target language option has no effect: syntax coloring is for Python only.  Tab width can not be changed; tabs are 8 characters wide.

2. Menu items are not yet dynamically dimmed and undimmed.  Some non-functional commands have undimmed menus.  Keyboard accelerators work even for dimmed menus.

3. Scripting Leo is not possible yet.  You can't control Leo from the Python interpreter because control passes to the Tk event loop.

4. Leo's Save commands do not yet save the information about which node was visible at the top of the tree.

5. The Save/SaveAs/SaveTo dialogs don't handle shortcuts to folders properly; they try to replace the shortcut with the .leo file.

6. Initialization code in leo.py computes the directory from which Leo was loaded using argv[0].  I am not sure this is proper, though I have had no problems recently.  Tree icons will not load properly if argv[0] does not specify this directory.  If the path is invalid Leo will print: os.chdir failed: `dir`

7. The tree class does not automatically ensure that the current node is visible after an outline operation.

8. The font used in the body pane is not great.  I hope to improve it.

9. Headline text is sometimes obscured.
</t>
<t tx="edream.110203163054.644">leo.py already feels less buggy than the wxWindows versions of Leo.  Rewriting Leo in Python and Tkinter has greatly improved the code. Further improvements are possible.  BTW, work began in earnest on this version of Leo in late October, 2001.  It's been a great month.

The following problems have resisted my initial attempts at solving them.  Any help from Tk experts would be appreciated:

1. Window icons are the Tk icon, not the nifty Leo icon.  Really, there _must_ be a way to do this!

2. Can variable-width tabs can be done in Tk?  If not, Leo may have to convert tabs to blanks as specified by the preferences panel.

3. Cut, copy and paste work in the log and body panes using Control-X, Control-C and Control-V keys.  However, there are no Cut, Copy or Paste menu items in the Edit menu.  Is it possible to send simulated keystrokes to a text widget?

4. Some menu accelerators do not seem to be available in Tk.  In particular, many of the items in the submenus of the Outline menu have no accelerators yet.  These commands are useful only if they can be chosen from the keyboard rather than the menu.

5. The border of the tree control is gray.  It can be overwritten by large headlines.  This appears to be a Tk or Tkinter bug; I haven't found any way to eliminate the border or color it white.

6. There doesn't seem to be a way to select all the headline text when editing starts.  The click that starts editing always clears the selection.

7. Changing the type of leo.py to .pyw doesn't seem to work.

8. A message flash briefly on the screen when leo.py exits, too fast to read. These messages do not appear when invoking leo.py from the Python interpreter.  They probably would be visible in a Linux window.</t>
<t tx="edream.110203163054.645">It will be much easier to make such improvements to leo.py than to previous versions of Leo. Here is my list of new things to do:

1. Create "hyperlinks" from section references to section definitions.  This will happen in the next release.

2. Add automatic "tab nanny" checking and full syntax checking of Python body text.

3. Build a file/directory comparison window using code in leoCompare.py.

4. Build a Python debugger into Leo.  Python provides excellent hooks for debugging and tracing.  Python's stand-alone IDLE debugger doesn't seem to work well with the Tk command loop.

5. Expand Leo's file format to take advantage of the power of Tk text widgets.
</t>
<t tx="edream.110203163054.646"></t>
<t tx="edream.110203163054.647">Leo Borland version 2.6                             May 15, 2002

This version fixes a bug that can cause errors while reading derived files.  Earlier versions do not ensure that clone indices in derived files are distinct.

I recommend that all users of the Windows version of Leo upgrade to this version.</t>
<t tx="edream.110203163054.648">Leo Borland version 2.6                             March 4, 2002

leo.py v2.0 and Borland Leo v2.6 are being released simultaneously.  I urge all users of Leo to upgrade to one or both of these versions.  This is an important milestone in Leo's history,  For the first time, leo.py (v2.0) and the Borland Leo (v2.6) are functionally identical.  In particular, their respective Tangle commands produce identical output.

Borland version 2.6 fixes major problems and contains numerous changes to make it fully compatible with leo.py v2.0.  Highlights of Borland v2.6:

1. Fixes bugs that caused spurious errors while reading @file trees.  Such errors can destroy clone links.

2. Supports an improved format for derived files.  This format is used by leo.py 2.0.  This is an upward compatible change: previous versions of Leo can not read the new format, and this version of Leo can read all previous derived files.

3. Fixes two long-standing bugs in the Untangle command.

4. As mentioned above, the Tangle commands are byte-for-byte compatible with leo.py v2.0.  Also, @c is now equivalent to @code.

5. Adds two very useful commands: Sort Siblings and Contract Parent.

See the Children of this node for full details.</t>
<t tx="edream.110203163054.649">This version of Leo removes blanks from between sentinel lines in derived files.  This version of Leo is fully compatible with leo.py v2.0 in this regard.

This is an upward compatible change in the format of derived files: Borland Leo v2.6 can read derived files from all previous versions of Leo, but previous versions of Leo can not read derived files without blanks lines.

Removing blank lines requires a new kind of sentinel, the "verbatimAfterRef" sentinel.  This allows Leo to handle comments following section references that would otherwise be treated as sentinels themselves.  For example:
   
   &lt;&lt; section &gt;&gt; #+others</t>
<t tx="edream.110203163054.650">Whenever a node changes, Leo now ensures that all nodes cloned to it, and all ancestor @file nodes are marked dirty.  This is the cause of spurious read errors.

As a side effect, nodes now become dirty when they move.

This change was made in leo.py v0.8.

It is also vital that @file nodes remain dirty until they are written without errors.  Otherwise, a Save command will succeed without warning, and a later read may cause the dreaded "clones have been cleared" message.

This change was made in leo.py v1.0.</t>
<t tx="edream.110203163054.651">@c now works the same as @code.  This makes the syntax colorers agree with what the Tangle commands actually do.  Previously, the syntax colorers indicated that everything following an @c was code, while the Tangle commands placed everything following an @c in the doc part!</t>
<t tx="edream.110203163054.652">This version fixes two long-standing bugs:

1. Untangle did not work properly for languages like Perl and Python that do not have block comments. 

2. Untangle did not recognize @ on a line by itself as the start of a doc part.</t>
<t tx="edream.110203163054.653">The Tangle commands are now byte-for-byte compatible with leo.py 2.0.  Tangle outputs "optimized" leading whitespace just as leo.py does.  This can be important in Python programs.

All the Save commands now recompute clone indices just as in leo.py 2.0.</t>
<t tx="edream.110203163054.654">The "Show Context" checkbox in the Find Panel is presently non-functional.  (In leo.py it affects the messages produced by the Find All and Change All commands.)</t>
<t tx="edream.110203163054.655">Unlike leo.py, the Borland version of Leo can not ensure that saved outlines have .leo extensions.

There are two problems:

1.  The ensureExtension routine is called after the dialog closes.  If this routine changes the file name we could overwrite an existing file!

2.  There appears to be problems with the Borland DefaultExt field.  Setting this field causes crashes.</t>
<t tx="edream.110203163054.656">This version fixes several serious bugs.  All users of Leo2 should upgrade to version 2.5 immediately.

1. Eliminated the ill-fated automatic updating feature.  This turns out to be very dangerous and disconcerting.  If one makes changes to the .leo file and does not save those changes, a later update could erase those unsaved changes!

2. Removing automatic updating also fixed another bug:  The current outline node was not being selected properly when a .leo file was read, so that in some cases the body text did not correspond to the selected outline node.  This never caused loss of data, and was disconcerting.

3. Fixed a bug that caused Find/Change settings to be saved to a file only if a find or change command was actually executed.

4. Restored several parts of Leo2(cb).leo that were inadvertently erased due to earlier bugs.  In particular, the outlines for xbuf.c and xbuf.h have now been restored.

One bug remains.  On Windows XP, the cursor is obscured in the Find/Change dialog when it is at the far left of the Find or Change text areas.  This may be a botch in the XP text control itself.  The solution would be to create a border in the text areas, and there is no obvious way to do this using the Borland classes.</t>
<t tx="edream.110203163054.657">Version 2.4 is a major improvement in Leo2.  I urge all users of Leo2 to upgrade to this version.  See the children of this node for full details.

The "old" Leo2 tried to save space by not writing all information in @file trees.  This was a serious mistake.  The "new" Leo2 saves all information in an outline to the .leo file, including all information in @file trees.
Once again you may back up a project merely by backing up the project's .leo file.  There is no Archive command, and no need for one.  All .leo files are now safe archives.

As the result of the change in file formats, Leo 2.4 may clear clone links when loading derived files created with previous versions of Leo.  Leo 2.4 will issue detailed messages when that happens.

The new Leo2 is much safer and more convenient to use than the old Leo2.  Error messages and error recovery have been improved.

Leo2 updates @file trees automatically when Leo2 is activated.  For example, suppose you change a derived file in another editor, say in an IDE.  Leo2 will update the @file tree when you switch to Leo, provided that you have saved the file in the IDE.  Warning: due to several apparent bugs in the Delphi code, this feature only works if the main Leo window is at least partially visible on the screen (!)
</t>
<t tx="edream.110203163054.658">Version 2.4 fixes several bugs involving clones.

1. Version 2.4 rewrites clone indices when writing derived filed, so node sentinels accurately reflect the clone status of the node.  The node sentinel for the root node no longer contains the maximum clone index.  Leo2 clears the root's clone index on reading and writing so that the root node is not mistakenly joined so another node!

2. Version 2.4 takes more care to recreate clone links properly when reading derived files.  A derived file can be read into a .leo file different from the .leo that wrote the derived file, so Leo2 makes sure that clone links are proper in the .leo file being opened.  A minor drawback: .leo files now are "big", so reading them is a little slower.

Note: Clone links into @file trees work only if the .leo file is "in synch" with the files derived from the @file trees.  Clone links will break if the .leo file and derived files are not in synch.  Typically "backup" .leo files will be out-of-synch with present derived files, so it's best to use "backup" .leo files only in emergencies, for example to revert a project to a previous state.</t>
<t tx="edream.110203163054.659">The "old" Leo2 tried to save space by not writing all information in @file trees.  This was a serious mistake.  The "new" Leo2 saves all information in an outline to the .leo file, including all information in @file trees.  It is once again possible to back up a project merely by backing up the project's .leo file.</t>
<t tx="edream.110203163054.660">The archive command was a backup disaster waiting to happen.  It has been replaced by the following four file commands are located in the File:Read/Write submenu.

Read Outline Only: reads an outline using only the .leo file, not any files derived from @file nodes.  This command is useful for reverting a project to a previously saved state.

Read @file Nodes: updates all @file nodes in an outline.  This ensures that the state of an outline matches all files derived from @file nodes.  Included for completeness.  This happens automatically when a .leo file is first read, and it also happens automatically when Leo2 is reactivated.

Write Outline Only: saves an outline without writing any @file trees.  Useful for inserting an @file node into an outline without modifying a derived file with the same name.

Write @file Nodes: forces an update of all @file trees.  Surprisingly useful.</t>
<t tx="edream.110203163054.661">Leo2 updates @file trees automatically when Leo2 is activated.  For example, suppose you change a derived file in another editor, say in an IDE.  Leo2 will update the @file tree when you switch to Leo, provided that you have saved the file in the IDE.

Warning: due to several apparent bugs in the Delphi code, this feature only works if the main Leo window is at least partially visible on the screen (!)</t>
<t tx="edream.110203163054.662">Revised for version 2.4

Loading and saving .leo files usually keeps the .leo file and derived files "in synch".  However, if you create backup .leo files, it can easily happen that the structure of @file nodes in the backup .leo files no longer matches that structure in the derive files.  Leo2 will detect this condition the next time you next open the old .leo file.  When that happens, Leo2 discards the entire out-of-synch @file tree, and recreates it solely using the derived file.  In the process all marks and clone links from outside the file are lost. Leo2 issues the messages:

	Error reading @file &lt;filename&gt;
	-- Rereading file.  Clone links into this file will be lost.

to remind you that the .leo file you are using is out-of-date.  Saving the .leo file will bring it up to date.

If one or more sentinel lines in a derived file have been corrupted in some way, by inserting, deleting, altering or moving a sentinel, Leo issues these messages:

	Error reading @file &lt;filename&gt;
	&lt;An error message about a bad sentinel&gt;
	-- Rereading file.  Clone links into this file will be lost.
	&lt;An error message about a bad sentinel&gt; (again)
	----- File may have damaged sentinels!

Data may not actually be lost, and the outline structure will be seriously damaged.  The most sensible thing to do is to restore the derived file from a .leo file using the Read Outline Only command.

No error recovery is attempted when automatically updating @file trees.  If an error is found the update is canceled (leaving the outline unchanged) and the following message is given:

    -- Update canceled due to structure errors
	
We don't attempt error recovery because error recovery would clear clone links.  For example, suppose we are editing a .leo file, and for some reason we also edit a derived file _without_ saving the .leo file.  Now the files could be out of synch!  So it is best not to press on with an automatic update.
	</t>
<t tx="edream.110203163054.663">Revised for version 2.4

If Leo2 detects orphan or ignored nodes while writing an @file node it saves all information in the @file tree in the outline (.leo) file.  No information is lost.  When the .leo file is read again Leo2 will load the information in the @file tree from the .leo file, not the derived file.

As a reminder, Leo2 marks the erroneous @file node as dirty so that saving the .leo file will attempt to rewrite the @file node.  Version 2.4 no longer marks the @file node as "stuck on dirty".  If you save the .leo file the dirty mark will be cleared.  However, the @file node will be dirty every time the file is read until all errors are corrected.
</t>
<t tx="edream.110203163054.664">@file trees are less flexible than @root trees:

1.  You can not use section definitions in more than one file.  For example, you can't define declarations in one file to be used in another file.  If you need all the features of noweb you must use @root trees.

2. @file trees use no escape conventions whatever.  A code part in an @file tree contains a section reference if &lt;&lt; precedes &gt;&gt; on the line, regardless of whether &lt;&lt; or &gt;&gt; are contained in strings or comments.  In practice, such "false references" occur infrequently, and the workaround is simply to split the offending line.  Moreover, noweb's escape conventions (@&lt;&lt; and @&gt;&gt;) cause problems in @root trees, so this "drawback" is very minor.

3. Clone links into @file trees work only if the .leo file is "in synch" with the files derived from the @file trees.  In particular, backup .leo files will usually be out of synch with derived files.  Clone links will break otherwise.  To recover from such errors, simply use the "Read Outline Only" command.</t>
<t tx="edream.110203163054.665">Note: 10/19/01: I recommend that all users upgrade to version 2.4.  There are some serious problems with version 2.3.

This version of Leo contains some significant improvements.  See the children of this node for details:

1. The new @first directive allows you to place lines at the very start of files derived from @file nodes. For example, @first #!/usr/bin/env python

2. The log window is now part of the Leo window.  Very handy.

3. Fixed several bugs involving the Find command.

4. A new Archive command saves an entire outline (including all @file trees) to a .leo file.  Use this command with caution.  Loading and then saving a .leo file created with the Archive command will revert an entire project to the state it had when the archived .leo file was created.</t>
<t tx="edream.110203163054.666">The @first directive allows you to place lines at the very start of files derived from @file nodes. For example, the body text of @file spam.py might be:

@first #! /usr/bin/env python

The body text of @file foo.perl might be:

@first #/usr/bin/perl

@first directives are recognized only at the start of the body text of @file nodes.  No text may precede @first directives.  More than one @first directive may exist, like this:

@first #! /usr/bin/env python
@first # more comments.</t>
<t tx="edream.110203163054.667">The Archive command writes all nodes of an outline to a .leo file, including all parts of @file trees.  All @file trees are marked in such a way that when the archived .leo file is read 1) all @file trees will be restored from the archived outline rather from derived files and 2) all @file trees will be marked dirty so that when the archived .leo file is written all @file nodes will be updated.

Use the Archive command (and the files written by it) with caution: loading and then saving an archived .leo file will back up an entire project to its state when the archive was originally written!</t>
<t tx="edream.110203163054.668">Added support for @c in syntax colorers for Python, Pascal, Perl, Java and HTML.</t>
<t tx="edream.110203163054.669">Fixed a bug in the Change, Then Find command.  The Change, Then Find command would rescan the newly changed text if the "change text" contained the "find text" preceded by other text of length greater or equal to the length of the original "find text".

For example, changing "blah" to "const blah" would result in rescanning the newly inserted "blah".  This would cause the "Change All" command to hang.

The old code advanced the search point by the length of the "find text."  The new code advances the insertion point by the length of the "change text".

Fixed the Find/Change panel: some captions were cut off.</t>
<t tx="edream.110203163054.670">@file nodes are now marked dirty whenever any change is made in the @file tree, including changes made as the result of changing cloned nodes outside the @file tree.</t>
<t tx="edream.110203163054.671">Made the log window part of the Leo window.  Having the log be part of the leo window is very convenient.</t>
<t tx="edream.110203163054.672">Leo2 readme file
Borland version 2.2, 9/16/01

This version fixes several bugs in Leo2:

1. Fixed a bug that causes all data in an @file tree to be lost under the following conditions:

A. The @file tree was erroneous, i.e., it contained orphan or ignored nodes.
B. The .leo file containing the erroneous tree was saved twice.

Leo2 now marks an erroneous @file node as "stuck on dirty" until the tree is fixed.  Recall that dirty nodes have icons with a black border rather than a gray border.  Whenever a file Save operation occurs, Leo2 will attempt to write all dirty @file trees, thereby reminding you that errors remain.  However, the .leo file itself is not "stuck on unsaved", so you won't be prompted to save the .leo file endlessly.

While fixing this bug I also improved error and warning messages relating to reading and writing @file nodes.  This should make it clear that a) data in erroneous @file trees is saved to the .leo file and b) data is recovered from the .leo file when reading erroneous @file nodes.

2. Fixed a bug relating to clones that could cause loss of data.  Leo2 now marks all clones dirty when any clone changes, and makes sure to mark @file nodes dirty that contain changed clones.

3.  Changed the code that writes @file trees to end lines with "\r\n" rather than "\n".  I hope this will improve matters, though I have my doubts.  Please report any problems with the new scheme immediately.

4. Added Write @file Nodes command.  The command writes all @file nodes in the selected tree, regardless of whether they have been changed.

5. Made the commands in the Main Leo2 window functional.</t>
<t tx="edream.110203163054.673">Version 2.1 is the first public release of Leo2.  This version appears stable, and should be used with caution.

The major feature of Leo2 is that tangling and untangling happen automatically for all code derived from @file nodes.  

Remember to back up all files derived from @file nodes; such files are original source files!  It is no longer possible to back up an entire project by backing up a single .leo file.</t>
<t tx="edream.110203163054.674"></t>
<t tx="edream.110203163054.675">Version 1.15 can read @file trees.  Leo warns when reading @file files, and changing @file trees in Leo v1.15 is not recommended.</t>
<t tx="edream.110203163054.676">This version corrects a problem with double-clicking Leo icons under Windows Me.  You may now launch Leo by double-click the icon for any .leo file and you may open any .leo file by double-clicking on it.</t>
<t tx="edream.110203163054.677">This version of Leo corrects a problem with how whitespace was handled in @silent mode.</t>
<t tx="edream.110203163054.678">Barring serious bugs, version 1.12 is likely to be the last Borland/Windows version of Leo for a while.  The wxWindows versions of Leo are usable enough to justify putting all further work into them.

There are several important improvements in version 1.12:

1. Added the Sort command to the Outline menu.  This command sorts all the children of a node into alphabetical order.

2. A major improvement to Tangle.  In @silent mode, Tangle now outputs derived files with "verbatim" whitespace, that is, without any extra blanks, tabs and newlines.  This makes Tangle much more useful for Python, and in other applications.  For example, it is now possible to do the following in Python:

if &lt;&lt;condition1&gt;&gt; &amp;&amp; &lt;&lt;condition2&gt;&gt;:
	print &lt;&lt;list of vars&gt;&gt;

In the derived file, expansions of the sections will be placed on the lines in which the reference appears.  This works in Python as long as the expansions themselves appear on a single logical line.

This "verbatim" expansion only happens in @silent mode, so these kinds of derived files can not be Untangled.

3. Tangle now reports errors more fully and less redundantly.  Errors involving missing or erroneous path names (specified in @root directives, @path directives or the Preferences Panel) are more specific.  These errors are reported only once per Tangle command, and these errors terminate the Tangle command immediately.  This is wise; we don't want to write files to the wrong directory!  Finally, Tangle no longer prints the actual text of a section when giving the "possibly duplicate section definition" error.  This should be helpful: no longer are huge error messages generated.  It should be easy enough to find the relevant section definitions using Leo's find command.</t>
<t tx="edream.110203163054.679">This version corrects a problem that can cause the Import CWEB Files command to hang in an endless loop.

This file also contains improved documentation (see the children of this node) in two sections:

1.  Added an explanation of the following error message given by the Tangle command: "Multiple parts not allowed for &lt;&lt; section name &gt;&gt;"

2.  Added a warning about using Untangle to update cloned nodes.
(See the last paragraph of the node.)</t>
<t tx="edream.110203163054.680">Sections can be defined in several parts in two ways:

1.  Using &lt;&lt; section name &gt;&gt;= in several places with the same section name.

2.  Using several @code directives within the _same_ body text.

As a precaution against mistakenly defining a section in more than one place, it is invalid to use @code in different nodes to define multiple parts for the same section.  In particular, this error may arise when using cloned nodes.

This error may always be eliminated by using &lt;&lt; section name &gt;&gt;= instead of @code.
	
</t>
<t tx="edream.110203163054.681">The Untangle, Untangle All and Untangle Marked commands are the reverse of the corresponding Tangle commands.  They update an outline based on changes made to one or more derived files.  These are exceptionally useful commands.

For example, suppose you create a new part of the outline and Tangle it for the first time.  When you compile the resulting derived files for the first time, 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 not all the code is changed the same way in derived files.  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 only reliable way to update text in cloned nodes is to make the change in the .leo file rather than the derived files.</t>
<t tx="edream.110203163054.682">Version 1.10 incorporates the following changes:

1. The Untangle command no longer updates @doc chunks under any circumstances.  This makes Untangle safe to use when the "Tangle outputs doc chunks" preferences is not selected.  In previous versions the Untangle command would delete all @doc chunks in the outline when a derived file had been Tangled without "Tangle outputs doc chunks".

The new version of Untangle is experimental; only one line of code has been added.  I welcome any comments about this change.  This change also fixes (or rather bypasses) a crasher reported in Untangle.

2. The shortcut for the Execute Script command has been changed from Alt-E to Shift-Alt-E to avoid conflicting with the shortcut that brings up the edit menu.

</t>
<t tx="edream.110203163054.683">Version 1.9 contains several improvements that make Leo more Python-friendly:

1. The Execute Script command (Alt-E) in the Edit menu allows you to execute Python scripts directly from body text.

2. Several small changes make the Python window significantly easier to use.

Also, considerable reference (study-only) code has been removed from leo(CB).leo.</t>
<t tx="edream.110203163054.684">It is now possible to execute any Python script directly from any body text.  Just select the script in the body text (including a trailing newline) and use the Execute Script (Alt-E) command from the edit menu.  The script is copied to the Python window and executed as usual.
</t>
<t tx="edream.110203163054.685">Several small changes make the Python window significantly easier to use:

1. The paste command now works in the Python window whenever the Python window is visible.  This fixes a bug that required a mouse click in either pane before paste would work.

2. It is now possible to execute scripts multi-line scripts pasted into the input pane.  Other changes make it easier (or possible) to terminate continued code.</t>
<t tx="edream.110203163054.686">Fixed a crasher that makes it impossible to tangle outlines containing doc parts in languages like HTML that have no single-line comment delimiter.</t>
<t tx="edream.110203163054.687">Leo v 1.7 accepts a slightly more general file format so that it can read XML generated from external XML tools.  Leo v 1.7 can read all previous .leo files.  Leo's Save commands remain unchanged.

Leo still only understands Leo files.  However, Leo now understands a slightly generalized form of Leo files. Specifically:

1.  Attributes may now appear in any order.  (Leo writes attributes in a fixed order, but some XSLT tools rewrite Leo files with attributes in a different order.)

2.  Leo will now accept &lt;tag/&gt; instead of &lt;tag&gt;stuff&lt;/tag&gt; when "stuff" is empty.
</t>
<t tx="edream.110203163054.688">This version corrects a small bug: the wrong text is selected when the syntax colorer changes.  This is a cosmetic bug only; the selected text will not be replaced when further typing occurs.

Unless major bugs are found, this will be the last version of Leo for several months.  I want to freeze the code so that I can work on the wxWindows version.</t>
<t tx="edream.110203163054.689">This version is a major milestone in Leo's code.  Improvements were made throughout Leo's code in an attempt to correct an extremely hard-to-find bug that can cause data in body panes to be lost.  Only time will tell if the bug has, in fact, finally been eradicated.

This version also corrects a minor bug; icons in a newly cloned tree were not always drawn properly.  Also, the currently selected headline no longer changes if you click on the + or - icons that expand and contract headlines.  This new behavior is a result of simplifying the event handlers; I won't consider changing this behavior until it is clear that the data loss bug has finally been fixed.

Use this version of Leo with caution until the new code has been thoroughly tested.  New asserts will guard against silent data loss and other unexpected events.  I don't expect these asserts to fail, but then one never does...

The following lists the changes that were made the code.  You don't need to read the following details; they are provided only for completeness.

1.  Greatly simplified the event handlers.  This should have been done long ago.

The event handlers now handle _all_ aspects of switching tree nodes and updating data structures when the body pane changes.  In particular, this guarantees that tnodes are "synched" when the body pane changes.  This is a major simplification and a major improvement: it should no longer be possible to lose data once it appears in the body pane.

The reverse is not true: the code must still take care that the body pane is updated if tnodes are changed "by hand."  (This is typically done when new nodes are being created.  Such nodes are never the current node and so are not shown in the body pane.)  I re-checked all code to make sure this constraint is satisfied.

Removed synchVnodes and updateBodyPane methods.  These have always been the most error-prone methods in Leo.  Removing them was made possible because the global constraint that tnodes are up-to-date is now guaranteed by the event handlers.

Created a new updateSyntaxColorer routine, which is called when moving a node or changing its text might affect syntax coloring.  This routine can never affect tnodes.

2.  Removed reference counting from tnodes.  The new code deletes tnodes only during the read process.  After that, tnodes are never deleted.  This could be called a memory leak, but it ensures that tnodes can never be deleted out from under a vnode.  I don't this was ever the problem with losing data, and the new code makes sure that it can't be.

3.  Improved how icons are redrawn.  Event handlers now set the dirty bit when text changes, which simplifies matters.

4.  Added asserts to guard against silent data loss, unexpected calls to event handlers, and mismatches between vnodes and their commanders.

6.  Added the mCommands data member to vnodes.  This member ensures that the correct commander is returned by vnode::commands().  The old code got the commander by looking for the current window.  Conceivably this could have caused the wrong commander to be used in some cases.</t>
<t tx="edream.110203163054.690">This version adds the following features:

1. Outline to noweb command.
2. Python scripts for finding and changing text in Leo outlines.
3. A Python method of the vnode class returning the commander corresponding to a vnode.
4. Documentation for Leo's import/export commands.

This may be the last version of Leo for a while; I am about to start work on a cross-platform wxWindows version of Leo.  However, bug reports and requests for new features are always welcome.

Edward K. Ream
September 19, 2000
</t>
<t tx="edream.110203163054.691">The "Outline To Noweb" command converts the selected outline to a flat file containing noweb text.  The name of the root section is taken from the @root directive.  &lt;&lt;*&gt;&gt; is used if the @root directive is not followed by any file name.</t>
<t tx="edream.110203163054.692">Leo's Python scripting does not support Leo's Find and Replace commands directly because these commands are interactive.  Calling these commands from a Python script would be clumsy.

Instead you can use the new find and change scripts to search and replace text.  These scripts use Python's powerful re module.</t>
<t tx="edream.110203163054.693">The commands() method has been added to the Python vnode class.

c=v.commands()

This method returns the commander for the window containing v.  This method can be used to avoid passing commanders as arguments to vnode methods.  For example, given just v, we can call either of the following:

	v.commands().synchNode()
	v.commands().Repaint()</t>
<t tx="edream.110203163054.694">This version corrects a problem with the Save As command;  it worked only once!  That is, after the Save As command was executed the window's title would change, but a later Save command would change the file specified before the Save As command was executed.</t>
<t tx="edream.110203163054.695">This version of Leo introduces Python scripting.  This is a major new addition to Leo.  See the new Chapter 7 of this documentation.  Python support still has rough edges; the next release will be cleaner.  Any suggestions for improvements to Leo's support for Python would be appreciated.

Alt-V now toggles the "View All Characters" option.  This is especially useful when editing Python code.

Besides Python support, a number of minor bug fixes have been made:

Added syntax coloring for try and catch to the C parsers.

Control-K, I now indents blocks of text uniformly, regardless of the language being syntax colored, and regardless of @nocolor and @color directives.  Similarly, Control-K, U now undents blocks of text.  The old keys, control-[ and control-] only worked when the current language was C and syntax coloring was enabled.

Removed the menu items that had the enter key as a shortcut.  The only way to create a new node now is with Control-I.  Using the enter key for a shortcut is not a good idea: it causes problems throughout the code.

Fixed a bug in forgiving compare.  The code that was calling compare_comments wasn't handling mismatched whitespace properly.

Got the Import command for Python working.  I found a bug in Tangle: in @silent mode we must always output a newline in the place of the function name.  Otherwise the Python indentation will be wrong.

The Untangle is now disabled when in @silent mode.  Nothing good can happen in that case!

Fixed a minor problem with the @path directive:  ff a _new_ file has not been saved we issue a warning, not an error if no path has been specified.  We can't really test the @root command for a path because the @root command may be found much later.  Fortunately, this warning will happen very rarely.  It's important, however, to warn that the file may be written to the standard directory if no path is specified in the @root command.  Otherwise, Leo's behavior would be quite confusing.</t>
<t tx="edream.110203163054.696">This version corrects an oversight in the Flatten Outline command.  In order to recreate the outline structure it is not enough to know whether each node has children; you must also know how many children each node has.

The new version of the Flatten Outline command represents the outline the same way the Export MORE Text does:  a child headline is indented one tab more than its parent headline.</t>
<t tx="edream.110203163054.697">The Tangle commands now examine all nodes, including cloned nodes that have previously been visited.  Previously, such nodes were skipped during tangling.  The new logic allows clones to represent code common to more than one unit. You can always insert an @ignore directive in an ancestor of a cloned node to prevent the node from being processed during tangling.
</t>
<t tx="edream.110203163054.698">Version 0.19 fixes some bugs and eliminates some problematic features of Leo.  Also, the role of CWEB mode has been documented more thoroughly.

The PC version of PC is feature complete.  I will release version 1.0 after people have played with this version for a while.

As always, I'll be happy to fix bugs or add urgently needed features.
</t>
<t tx="edream.110203163054.699">Fixed a bug that could result in Tangle outputting derived files in the wrong directory.

Tangle and Untangle now set the current directory using @path directive if it exists, otherwise the directory specified in the Preferences panel if it exists, otherwise the directory set by the Load or Save commands if it exists.  (The Save As and Save To never alter this directory.) Finally, a check to see if the @root directive specifies a full path.  If so, the current directory is not changed.

If none of these directories exists an error is raised so that no Tangling or Untangling is done.  This error can only occur if Tangling or Untangling a file that has just been created by the New command and never saved with the Save command.</t>
<t tx="edream.110203163054.700">Added the @language html, @language perl and @language perlpod directives, and added HTML, Perl and Perl + POD items in the Preferences panel.

The HTML script is rudimentary at present.  Suggestions for improvement are welcome.</t>
<t tx="edream.110203163054.701">The @cweb and @noweb commands are no longer functional.  The new @language cweb directive replaces @cweb, and the other @language directives effectively replace @noweb.  There is an new CWEB option in the Preference panel.
</t>
<t tx="edream.110203163054.702">Leo now parses the @language directive as you type, so if you change the language specified by the @language directive you will see the effect immediately.

There is no longer a limit of 6 languages that can be syntax colored. Let me know if you would like Leo to support another language.</t>
<t tx="edream.110203163054.703">The Print command is now much more flexible and convenient: it will print any node and all its descendents, whether or not the node contains @unit, @root or @ignore directives.  
</t>
<t tx="edream.110203163054.704">Modified massage_block_comment so that it converts the first of a series of newlines to a blank and deletes the rest; Untangle no longer mangles modified @doc sections.

A more complete solution would be for Tangle to insert a flag for inserted newlines ( say backslash newline) so that Untangle could know which newlines to remove.  I'd like to wait until all Tangle/Untangle code is converted to C++ before doing a more thorough job.
</t>
<t tx="edream.110203163054.705">Leo no longer supports clone _windows_.  Cloned outlines, however, will remain with Leo forever.  

Clone windows were never very useful and were buggy.  Eliminating clone windows has made it possible to handle events more smoothly and powerfully.</t>
<t tx="edream.110203163054.706">The Extended Noweb Syntax option in the Preferences panel is gone.  This option has always been deprecated.</t>
<t tx="edream.110203163054.707"></t>
<t tx="edream.110203163054.708">Version 0.18 changes the file format in an upward compatible way.  That is, version 0.18 can read all previous versions of Leo files, but you must have version 0.18 of Leo to read files written by version 0.18.</t>
<t tx="edream.110203163054.709">Fixed a bug that caused @doc section not to be output properly for those languages like Fortran and Perl that do not have block comments.</t>
<t tx="edream.110203163054.710">The @noheader directive suppresses the header line normal written by Tangle at the start of each derived file.  The @noheader directive is especially useful in Perl.  Also added the corresponding "Tangle outputs header line" checkbox in the preferences panel.  This checkbox sets the default which may be over-ridden by the @header or @noheader directives.</t>
<t tx="edream.110203163054.711">@language fortran specifies that comments start with C.
@language fortran90 specifies that comments start with !.</t>
<t tx="edream.110203163054.712">@language perlpod specifies the Perl language with block comments being delimited by =pod and =cut</t>
<t tx="edream.110203163054.713">Version 0.17 fixes some bugs and puts some finishing touches on Leo.

The Borland C++ Builder version of Leo is now feature complete; there are no further items on the to-do list.  Yes, I'll be happy to fix bugs or add urgently needed features.
</t>
<t tx="edream.110203163054.714">Tangle and Untangle now treat &lt;&lt;*&gt;&gt;= as a synonym for @root filename if the _headline_ starts with text of the form @root filename.  This convention allows full compatibility with noweb.
</t>
<t tx="edream.110203163054.715">The @path, @tabwidth and @pagewidth directives are new.

These directives allow the user to override the defaults specified in the Prefs panel on a file-by-file basis.   For the first time, every option in the Preferences panel may be overridden by a directive.</t>
<t tx="edream.110203163054.716">I fixed several severe bugs involving CWEB mode.  It is now possible to tangle and untangle files when in CWEB mode, though CWEB mode has still not been tested thoroughly.</t>
<t tx="edream.110203163054.717">Reduced the default size of Leo windows so that they can be more easily resized on a small screen.</t>
<t tx="edream.110203163054.718">Version 0.16 is a significant new release of Leo.  All users of the PC version of Leo should upgrade to version 0.16.

Significant changes have been made to Tangle and Untangle:  these commands should now be able to handle code in almost any language.  The new @language directive specifies the comment and string conventions used when Tangling and Untangling.

The @verbose, @terse and @silent directives are new:  they control how Tangle outputs comments.

The Import Files command now handles Pascal, Python and Java files in addition to C and C++ files.

Besides the major changes a number of bug fixes and other minor features have been added.

Acknowledgements:  Thanks to Zak Greant for numerous suggestions and bug fixes, and to Garold Johnson for improving this file.</t>
<t tx="edream.110203163054.719">Version 0.16 fixes all bugs mentioned on the SourceForge site as of April 27, 2000.  These bugs involved problems with

@comment &lt;empty&gt;
@comment 2 delims
Not inheriting @comment properly
non-delimited filenames in @root directives
Crashes while Tangling
Problems with Untangle with languages other than C.

Later sections discuss some of these in more detail.</t>
<t tx="edream.110203163054.720">Version 0.16 fixes a crasher related to changing windows.

This _may_ have been the source of crashes when cutting and pasting outlines, but don't count on it!  Make sure you back up files _before_ cutting and pasting outlines!</t>
<t tx="edream.110203163054.721">The @language directive is new.  The @language directive actually specifies the comment delimiters and string types used by the Tangle and Untangle.

The form of this directive is

@language x

where x is one of the following: c,c++,html,java,objective-c,pascal,perl,python and shell.  Shell files have comments that start with #.  Case is ignored in the language specifiers, but not in the @language itself.  Thus, the following are equivalent:

@language html
@language HTML
@language hTmL

but the following is invalid:

@LANGUAGE html

The @comment directive is now officially deprecated: you should use the @language directive whenever possible.  At present Untangle will not process an @root or @unit node if an @comment directive is in effect.  Why?  Because Untangle can't be sure of properly parsing a derived file if the language of the derived file isn't known.  It might be possible to assume some defaults in this case, but that is not done at present and is not a high priority.</t>
<t tx="edream.110203163054.722">Scanning for @directives is now much faster.  As a result, the @language and @comment directives will be recognized anywhere in an outline.  This means

1) child nodes will "inherit" @language or @comment directives from ancestors unless over-ridden in the child node and

2) @language and @comment directives need not be placed in @unit or @root nodes.  This is a much more intuitive and powerful way of handling these directives.</t>
<t tx="edream.110203163054.723">Key parts of the untangle logic have been generalized so that they can handle essentially any computer language. The following routines no longer have any C-specific code and have essentially been completely rewritten:

scan_derived_file (formerly scan_c_file)
forgiving_compare (formerly c_compare)

Tangle now will properly output comments using the present comment delimiters as specified by either the @language directive or the @comment directive.  As mentioned before, you should use @language instead of @comment wherever possible.</t>
<t tx="edream.110203163054.724">As a side effect of the Untangle command, Leo now removes trailing blank lines from the body text of all nodes being untangled.  This finally crushes a long-standing bug.  If the body text ends with one or more blank lines, the altered body text contains exactly one trailing newline.

Nodes that are altered in this way are not marked, nor is the file-changed mark set.  This seems to be the most appropriate action to take:  it would be confusing to prompt the user to save a changed file if the only changes involve trailing whitespace.</t>
<t tx="edream.110203163054.725">The @verbose, @terse and @silent directives determine how Tangle outputs comments.  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.  Note: comments written by the user in code sections are always output: these directives control only:

1.  The comments containing doc chunks and
2.  Sentinel comments that delimit the beginning and end of code chunks.

@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.</t>
<t tx="edream.110203163054.726">At long last Leo has a useful notion of default directory.  By default, the default directory is the directory containing the .leo file.  This may be over-ridden using the "Tangle Default Directory" option in the Preferences panel.

The default directory is used whenever a file name in an @root directive contains no path component.
</t>
<t tx="edream.110203163054.727">The Import Files command looks at the file extension to see how it should handle files.

Extension	Language
.c			C
.cpp		C++
.java		Java
.pas		Pascal
.py			Python

If the extension is not one of the above the Import files commands merely puts the entire file into the body text of a single node.

The Import Files command probably needs quite a bit of work.</t>
<t tx="edream.110203163054.728">Control-T now changes the pane that is currently active.  If the outline pane was active, the body pane becomes active, and vice versa.  This command makes it possible to switch between panes without using the mouse.</t>
<t tx="edream.110203163054.729">In previous versions of leo.leo I used slash instead of backslash as path delimiters.  This should never have worked, but somehow it did.  The present code uses the correct backslash in all @root directives.</t>
<t tx="edream.110203163054.730">Many improvements were made to the code.  See the diary section of leo.leo if you are interested.  In particular, I created args.h and args.c to define arguments.  This cleans up the code quite a bit.</t>
<t tx="edream.110203163054.731">Changed Tangle and Untangle so that empty section names like &lt;&lt; &gt;&gt; and &lt;&lt; &gt;&gt;= are treated as ordinary characters.  No warning is issued, which is debatable.</t>
<t tx="edream.110203163054.732">As mentioned in the main documentation, you must not change sentinel lines in derived files in any way.  In particular, 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.
</t>
<t tx="edream.110203163054.733">Leo is being used to develop HTML files for web sites.  In this context it is natural to define sections that are shared between files.  Don't expect Untangle to update such sections if you make changes to them in derived files.  The natural place to change sections shared by several roots is in the outline, not in the files derived from the outline.

If you do change code in a derived file that appears in several derived files, and try to use Untangle to update the code in the outline one of two things will happen:

1) You untangle an @root node.  Untangle will never compare examine the common section of code for changes, as the common section appear under a @unit node, not the @root node. Untangle will complain about an orphan node.
 
2) You untangle an @unit node.  Untangle will examine each @root node under the @unit node.  Unless the change is made in the last root examined, Untangle will propagate the change when it first sees it, then go right ahead and undo the change when it sees the next expansion of the node in a derived file.
 
Untangle tests for inconsistent expansions of a section only within a single derived file.  Such tests are not done between different derived files because we do not want disallow sections with the same names in different roots.</t>
<t tx="edream.110203163054.734">Known bugs and limitations in all versions of Leo.

1. Untangle has no way of updating a section(chunk) whose name has been changed in the derived file.  Because of the @unit directive, there is not even a way to issue a meaningful warning.

2. Tangle treats @c like @code when in CWEB mode.
I recommend changing @c to @&lt; c @&gt;= throughout your CWEB sources and adding a reference
to @&lt; c @&gt; in all roots of CWEB files.

Known bugs and limitations of the PC version of Leo.

Syntax coloring options are not saved to the file.

The Log window has a limited capacity. This mainly affects debugging traces but could affect the output from the Tangle or Untangle commands if you tangled or untangled a large number of files.
</t>
<t tx="edream.110203163054.833">The Execute Script command executes body text as a Python script.  Leo execute the selected text, or the entire body text if no text is selected.

Scripts are executed in a "pristine" environment, that is, with __builtins__ as both the local and global environments.

New in version 4.1:  Body text may now contain @directives and section references. This is a major step forward: you can now use all of Leo's features to organize scripts that you execute interactively.

Section definitions must appear in the node containing the script or in descendant nodes.  Leo "preprocesses" all scripts by simulating the writing of a derived file to a string.

The Execute Script command sets app.scriptDict["script1"] to the value of the script before preprocessing, and sets app.scriptDict["script2"] to the value of the script after preprocessing.  Scripts may examine and change app.scriptDict as they please.</t>
<t tx="edream.110203163054.890">@nocolor
@language python

This chapter documents scripting for Leo using Python.

This chapter describes only the most useful functions, classes and methods in leo.py.  However, keep in mind the following:

	** Your scripts have complete access to _all_ of Leo's source code **

Therefore, the most complete documentation for scripting is Leo's source code itself, that is, the file LeoPy.leo.  In particular, see the node called "Overview of the Code", the first child of the node called "Code".

You can execute all of the scripts in this chapter by selecting the node containing the script and executing the "Execute Script" command.  N.B.  Leo's Execute Script command now understands all aspects of Leo's markup, including @others directives, doc parts and section references.  This means that you don't have to select just the "code" part in the examples below: you can select the entire node!</t>
<t tx="edream.110203163054.891">@nocolor
@ Leo's source code is a collection of classes, along with utility functions in leoGlobals.py.  The preferred way of accessing the functions and data in leoGlobals.py is as follows:
@c
@color
	
import leoGlobals as g
from leoGlobals import true,false

@nocolor
@ After these imports you may call function x in leoGlobals as follows: g.x()

g.app refers to the application object representing the entire Leo application.
The ivars (instance variables) of g.app represent Leo's global variables.

A _commander_ (an instance of the Commands class) represents the operations that can be performed on a _particular_ window.  Each open Leo window has its own commander.  g.top() returns the commander of the top window.  By convention, any variable named c refers to a commander.

A _frame_ (an instance of the leoFrame class) contains all the internal data needed to manage a Leo window.  Given a commander c, c.frame refers to the commanders frame.  Given a frame f, f.c refers to the frame's commander.

A _vnode_ represents an outline node.  New in 4.2:  a node may appear several times within the same outline.  You can use vnode methods to get and set headline text, body text and properties such as whether the node is dirty or marked.  By convention, any variable named v,v1 or v2 refers to a vnode.  vnodes have v._parent, v._next and v._back links that "point" to the vnodes parent and siblings.  Leo moves vnodes around by changing these links.

Joined vnodes are updated together.  Cloned nodes are joined, as are corresponding nodes in the subtrees of cloned nodes.

A _tnode_ represents the actual data in a vnode, including headline and body text.  Vnodes that are joined to each other have the same tnode.  For any vnode v, v.t is v's tnode.

New in Leo 4.2:  tnodes contain a t._firstChild link that points to a _vnode_.  Because cloned vnodes share the same tnode, they also share the same v.t._firstChild link.  In other words, cloned vnodes use a _single_ subtree to represent their common descendant trees.  A _shared subtree_ is a tree of vnodes shared by multiple cloned nodes.  The root of a shared subtree is always some v.t._firstChild link.

N.B. The vnodes of a shared subtree will appear multiple times on the screen.  That means that in Leo 4.2 in later vnodes no longer represent a _single_ location on the screen, nor do vnodes represent a particular position in a traversal of a tree.

New in Leo 4.2:  a _position_ object represents the location of a particular node in a tree traversal or on the screen.  By convention, any variable named p or p1 or p2 refers to a position.  For any position p, p.v is the vnode at that position and p.v.t is the tnode at that position.

Leo's code uses position objects very much like vnodes were used in pre-4.2 versions of Leo.  In particular, please note the following extremely important properties of commanders and positions:
	
- In Leo 4.2 the c.currentVnode and c.rootVnode methods return _positions_, not vnodes.
- position objects support all the common vnode methods that were used in scripts prior to Leo 4.2.

These two facts mean that most scripts written before Leo 4.2 will continue to work in Leo 4.2.

Aside: the preferred way of get the position of the root node and the presently select node is c.rootPosition and c.currentPosition respectively.  The c.currentVnode and c.rootVnode methods exist only for compatibility with old code.

You can execute this script right now by selecting the script and choosing the "Execute Script" command.  The output from the g.es statement will go to the log pane.
@c
@color

import leoGlobals as g
windows = g.app.windowList # The list of all open _frames_
g.es("Open windows...",color="purple")
for w in windows:
	g.es(w) # A frame.
	g.es(w.c) # A commander.
	g.es(w.c.rootPosition()) # A position.
	assert(w.c.rootPosition()==w.c.rootVnode())</t>
<t tx="edream.110203163054.892">@color
@ The following nodes show how to do the most common tasks while scripting Leo.

You may execute the code in each node by executing the Execute Script command.
@c
@language python</t>
<t tx="edream.110203163054.893">@color

# The g.top() function returns the Commands object of the top Leo window.
import leoGlobals as g
c = g.top()
g.es(c)
g.es(c.rootPosition())

@ The windowlist attribute of the application instance contains the list of the
frames of all open windows. The commands ivar of the frame gives the commander
for that frame. Execute this code now with the Execute Script command.
@c

import leoGlobals as g
windows = g.app.windowList # get the list of all open frames.
g.es("windows...")
for f in windows:
	c = f.c # c is f's commander
	g.es(f)
	g.es(f.shortFileName())
	g.es(c)
	g.es(c.rootPosition())</t>
<t tx="edream.110203163054.894">@color
@ leoGlobal.py defines 6 convenience methods for redirecting stdout and stderr:

- g.redirectStderr() # Redirect stderr to the current log pane.
- g.redirectStdout() # Redirect stdout to the current log pane.
- g.restoreStderr()  # Restores stderr so it prints to the console window.
- g.restoreStdout()  # Restores stdout so it prints to the console window.
- g.stdErrIsRedirected() # Returns true if the stderr stream is redirected to the log pane.
- g.stdOutIsRedirected() # Returns true if the stdout stream is redirected to the log pane.

Calls need _not_ be paired. Redundant calls are ignored and the last call made
controls where output for each stream goes.

NOTE: you must execute Leo in a console window
to see non-redirected output from the print statement.
@c

import leoGlobals as g
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.redirectStderr()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.redirectStdout()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.restoreStderr()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()

g.restoreStdout()
print "stdout isRedirected:", g.stdOutIsRedirected()
print "stderr isRedirected:", g.stdErrIsRedirected()</t>
<t tx="edream.110203163054.895">@color

# Here is how to access the data of a Leo window.
import leoGlobals as g
c = g.top()

p = c.currentPosition() # get the current position.
g.es(p)
g.es("head:",p.headString())
g.es("body:",p.bodyString())</t>
<t tx="edream.110203163054.896">@color

import leoGlobals as g
c = g.top()
p = c.currentPosition()
body = p.bodyString()
head = p.headString()

# BTW, these methods will work whether or not p is the current position.  
# This won't really anyting because we haven changed body or head.
p.setBodyStringOrPane(body)     # set body text of p to body.
p.setHeadStringOrHeadline(head) # set headline text of p to head.</t>
<t tx="edream.110203163054.897">@color
@ New in Leo 4.2.  The preferred way to traverse an outline is with an iterator.

c.allNode_iter is an iterator that returns all the positions of an outline in outline order.

See the node called "Iterators" below for a full discussion of all iterators.
@c

# Count the number of separate positions and distinct vnodes of this outline.
import leoGlobals as g
c = g.top()

positions = 0 ; tnodes = {}
for p in c.allNodes_iter():
	positions += 1
	if not tnodes.get(p.v.t):
		tnodes[p.v.t] = p.v.t

g.es("%8s" % "positions",positions)
g.es("%8s" % "vnodes",len(tnodes.keys()))</t>
<t tx="edream.110203163054.898">@color
@ Leo's commands use c.beginUpdate() and c.endUpdate() to reduce flicker.  c.beginUpdate() suppresses all drawing in the outline pane until the matching c.endUpdate() is seen.  These methods can be nested; each c.beginUpdate() must have a corresponding c.endUpdate().

c.endUpdate takes an optional parameter.  If this parameter is false, no redrawing is done.  This can sometimes be useful; inner code can tell other code whether redrawing is actually required.

c.redraw() forces an update of the entire screen.  c.endUpdate() calls c.redraw() as needed.
@c

import leoGlobals as g
from leoGlobals import true,false
c = g.top()
# Force a screen redraw
c.redraw()
# Typical way to redraw the screen:
c.beginUpdate()
# ...code that alters the screen...
c.endUpdate()
# Typical way to conditionally redraw the screen:
c.beginUpdate()
# ...code sets flag if the screen needs redrawing.
flag = true
c.endUpdate(flag)s</t>
<t tx="edream.110203163054.899">@color
@
Leo dispatches commands using the c.doCommand and "Menu Command Handlers"
defined in the node by the same name in leoFrame.py. This node contains the menu
handlers for all of Leo's menu commands, organized by menu and submenu.

I recommend that your scripts use frame.doCommand for the following reasons:

- frame.doCommand calls the "command1" and "command2" hook routines for the given label and
- frame.doCommand catches all exceptions thrown by the command.
- the menu commands handles hide a number of implementation details.
@c

import leoGlobals as g
c = g.top()

if 1: # calls hooks.
	c.doCommand(c.markHeadline,label="markheadline")
else: # does not call hooks.
	c.markHeadline()

@
As stated above, the commands handlers in leoFrame.py hide many implementation
details involved in invoking the various commands. If you want to invoke
commands without calling frame.doCommand, you should study the corresponding
menu command handler to see what may be required.

Among these details is this: commanders create subcommanders to handle complex commands:

- The atFile class (leoAtFile.py) reads and writes files derived from @file trees.
- The LeoFind class (leoFind.py) handles the Find and Change commands.
- The leoImportCommands class (leoImport.py) handles the Import and Export commands.
- The tangleCommands class (leoTangle.py) handles the Tangle and Untangle commands.
- The undoer class (leoUndo.py) handles the Undo command.
- All other command are handled by the commander itself (leoCommands.py)</t>
<t tx="edream.110203163054.900">@color
@ Each commander maintains its own preferences.  Your scripts can get the following ivars:
	c.output_doc_flag
	c.page_width
	c.tab_width
	c.tangle_batch_flag
	c.tangle_directory
	c.target_language
	c.untangle_batch_flag
	c.use_header_flag
	
leoPrefs.leoPrefs.ivars is a list of the _names_ of these ivars.
@c

import leoPrefs
import leoGlobals as g
c = g.top()

g.es("Prefs ivars...\n",color="purple")
for ivar in leoPrefs.leoPrefs.ivars:
	exec("val=c."+ivar) # do val = c.ivar
	g.es("c."+ivar,val)</t>
<t tx="edream.110203163054.901">@color
@ Your scripts may set preferences by setting one of the following ivars:
	c.output_doc_flag
	c.page_width
	c.tab_width
	c.tangle_batch_flag
	c.tangle_directory
	c.target_language
	c.untangle_batch_flag
	c.use_header_flag
@c

import leoPrefs
import leoGlobals as g
c = g.top()
c.tab_width = 4 # Change this and see what happens.

# Your script may update the prefs panel as follows:
if c.frame.prefsPanel:
	c.frame.prefsPanel.init(c)
	c.frame.prefsPanel.setWidgets()

# If your script sets c.tab_width your script may call f.setTabWidth to redraw the screen.
c.frame.setTabWidth(c.tab_width)</t>
<t tx="edream.110203163054.902">@color
@ The file leoFindScript.py contains functions for finding and changing text from within scripts. The children of this node show two examples of using the functions.  See the @file leoFindScript.py tree in LeoPy.leo for full details.</t>
<t tx="edream.110203163054.903">@color
@
The findall function returns a list of tuples (v,pos) describing matches in c's entire tree.
@c

import leoGlobals as g
import leoFindScript
c = g.top()

pattern="import leoGlobals as g"
result = leoFindScript.findAll(c,pattern,bodyFlag=1)

g.es("%-3d instances of: '%s'...\n" % (len(result),pattern),color="purple")

for v,pos in result:
	body = v.bodyString()
	g.es('\n%-4d %s' % (pos,v.headString()))
	g.es(g.get_line_after(body,pos))</t>
<t tx="edream.110203163054.904">@color
@ The reFindall function returns a list of tuples (v,mo,pos),
where mo is a "Match Object".
The reFlags argument are flags to re.search()
@c

import leoGlobals as g
import leoFindScript
c = g.top()

pattern="from .* import"
result = leoFindScript.reFindAll(c,pattern,bodyFlag=1,reFlags=None)

g.es("%-3d instances of: '%s'...\n" % (len(result),pattern),color="purple")
for v,mo,pos in result:
	body = v.bodyString()
	g.es('\n%-4d %s' % (pos,v.headString()))
	g.es(g.get_line_after(body,pos))</t>
<t tx="edream.110203163054.905">@color
@ Most scripts will use methods of the position class to access information in an outline.

The following section summarizes the most useful methods that your scripts can use.  For a complete list, see the @file leoNodes.py tree of LeoPy.leo.

N.B. Both the position and vnode classes support similar methods.  However, iterators exist only in the position class.

You may execute the code in each node by executing the Execute Script command.
@c
@language python</t>
<t tx="edream.110203163054.906">@color
@ This section lists the most useful ivars and methods for getting information from vnodes or positions.
@c

# Returning commanders...
p.c # The commander for p.

# Returning strings...
p.bodyString() # the body string of p.
p.headString() # the headline string of p.

# Returning ints...
p.childIndex()
p.numberOfChildren()
p.level()

# Returning bools representing property bits...
p.hasChildren()
p.isAncestorOf(v2) # true if v2 is a child, grandchild, etc. of p.
p.isCloned()
p.isDirty()
p.isExpanded()
p.isMarked()
p.isVisible()
p.isVisited()</t>
<t tx="edream.110203163054.907">@color
@ This section lists the most useful methods for setting data or properties of positions.
@c

# These work whether or not p is the presently selected position.
p.setBodyTextOrPane(s)       # Sets the body text of p.
p.setHeadStringOrHeadline(s) # Sets the headline text of p.

# Moving nodes...
p.moveAfter(v2)  # move p after v2
p.moveToNthChildOf(v2,n)  # move p to the n'th child of v2
p.moveToRoot()  #  make p the root position

# The "visited bit" may be used by commands or scripts for any purpose.
# Many commands use this bits for tree traversal, so these bits do not persist.
c.clearAllVisited() # Clears all visited bits in c's tree.
p.clearVisited()
p.setVisited()</t>
<t tx="edream.110203163054.909">@color
@ leoGlobals.py contains many "utility" functions and other names.
@c

# Print all names (functions and constants) defined in leoGlobals.py.
import leoGlobals as g

g.es("Names defined in leoGlobals.py",color="purple")
names = g.__dict__.keys()
names.sort()
for name in names:
	g.es(name)</t>
<t tx="edream.110203163054.1050">@nocolor</t>
<t tx="edream.110203163054.1051"></t>
<t tx="edream.110203163054.1052">First, read the introduction to Leo at:
http://webpages.charter.net/edreamleo/intro.html

Then study LeoPy.leo, the source code for leo.py. The best way to learn about
Leo is to spend 15 or 20 minutes just browsing through the outline, not
worrying about details but just seeing how most nodes are organized and how
directives and section references are typically used. Then read Chapter 4 to
learn the details.

When studying leo.py, I would suggest paying particular attention to the
following:

1. The (Projects) tree shows how to use clones to represent tasks.

2. The @file leoNodes.py tree shows how to define more than one class in a
single file using several @others directives. Note that the @others directives
must be in separate nodes.

3. Most other files show how to use a single @others directive to define one
class.

4. Note in particular that the vast majority of methods are defined in unnamed
nodes.</t>
<t tx="edream.110203163054.1053">The file LeoDocs.leo contains two "Hello World" programs, using @file trees and
@root trees.

The file LeoPy.leo contains a large number of other examples, some small, some
large and complex.</t>
<t tx="edream.110203163054.1054">Leo's clones provide an excellent way of solving any organizational problem.
The fundamental principle is this: Clones create multiple views of data.

For example, whenever I have a task to do, say a new feature to implement, or a
non-trivial bug to fix, I create a new headline to represent that task. Let's
call such a headline a task headline. By convention, I enclose the headline in
parentheses and put an @ignore in the body text of the headline, but that's
just a convention I use.

I clone all nodes that relate to that task and move the clones under the
headline. Voila. I now have a new view of Leo's source code, containing all and
only those nodes that relate to the task. It is now trivial to find the parts
of code relating to the task. Note that I can change the cloned nodes under the
headline task in any way, and the clones under the @file tree also change and
the @file node itself is marked dirty so that when I save the .leo file all
affected @file trees are also saved. The task headline is a perfect place to
place notes about the task: why some approaches didn't work, to-do lists, test
data, whatever. You could even create @file nodes to create test files if you
want.

There are situations where you need to use @root trees. However, those
situations are rare. Most of the time you can use clones to great effect. For
extended examples, look at the (Projects) section in LeoPy.leo. That section
contains a large number of views of Leo itself.</t>
<t tx="edream.110203163054.1055">Leo's @file trees and @root trees represent derived files within an outline.
Leo outlines may contain both @root and @file trees, and I recommend using
@file trees whenever possible.

Indeed, @file trees are much easier to use than @root trees:

1. @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.

2. 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.

1. Within @file trees, sections must be defined in descendants of the node that
contains the section reference.

2. 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.

3. The meaning of section definitions in @root trees are independent of their
position within the tree.</t>
<t tx="edream.110203163054.1056"></t>
<t tx="edream.110203163054.1057">Internally, Leo represents all strings as unicode. Leo translates from a particular encoding to unicode when reading .leo files or derived files. Leo translates from unicode to a particular encoding when writing derived files. You may see strange looking characters if your text editor is expecting a different encoding.

The encoding used in any derived file is shown in the #@+leo line like this: #@+leo-encoding=iso-8859-1. Exception: the encoding is UTF-8 if no -encoding= field exists.  You can also use the @encoding directive to set the encoding for individual derived files.

If no @encoding directive is in effect, Leo uses settings in leoConfig.leo/.txt to translate to and from unicode. These settings are in the section in leoConfig.leo called

&lt;&lt; General configuration options, especially read-only mode &gt;&gt;

Here is a summary of those settings:

default_derived_file_encoding

This is the encoding used for derived files if no @encoding directive is in
effect. This setting is also used to encode files created by the Tangle
commands. The default is UTF-8 (case not important).

new_leo_file_encoding

This is the encoding specified in the following line of new .leo files: &lt;?xml
version="1.0" encoding="UTF-8"&gt; The default is UTF-8 (upper case for
compatibility for old versions of Leo). Important: once a .leo file is created
the &lt;?xml..."&gt; line can only be changed by hand. Changing the &lt;?xml..."&gt; line
by hand may cause unicode errors the next time the .leo file is loaded, so you
should change the &lt;?xml..."&gt; line by hand only when first creating a .leo file.

tk_encoding

This is the encoding that Leo uses to communicate with Tk text widgets. You
would typically use this setting only in an emergency. The section called &lt;&lt;
set app.tkEncoding &gt;&gt; in app.finishCreate sets this encoding as follows:

a)using the tk_encoding setting if it exists,
b) using locale.getpreferredencoding if it exists, or the equivalent code in pre-python
2.3 versions,
c) using sys.getdefaultencoding
d) defaulting to "utf-8"

Neither b nor c are guaranteed to give a valid encoding in all systems, and Leo
will ignore invalid encodings returned from b or c. Therefore, setting
tk_encoding in leoConfig may be needed.</t>
<t tx="edream.110203163054.1058">The encoding used in the file being imported doesn't match the encoding in
effect for Leo. You have two options:  Use the @encoding directive in an
ancestor of the node selected when doing the Import command to specify the
encoding of file to be imported.Set the tk_encoding option in
leoConfig.leo/.txt to the encoding you normally use. See the previous answer.</t>
<t tx="edream.110203163054.1059"></t>
<t tx="edream.110203163054.1060">You have two options, depending on whether you want to be able to use sections
or not.

Option 1: Use @nosentinelsfile trees.

Files derived from @nosentinelsfile trees contain no sentinels. However, Leo
creates derived files just as in @file trees. In particular, Leo expands
section references and understands the @others directive.

Option 2: Use @silentfile trees.

Files derived from @silentfile trees contain no sentinels. Moreover, Leo does
not expand section references in @silentfile trees. In other words, Leo creates
the derived file simply by writing all body text in outline order.

Leo can't update the outline unless the derived file contains sentinels, so Leo
does not update @nosentinelfile trees or @silentfile trees automatically when
you change the derived file in an external editor.

For complete details about @nosentinelfile trees and @silentfile trees, see the
child of this node.</t>
<t tx="edream.110203163054.1061">You have two options, depending on whether you want sentinel lines in your
derived file or not.

Option 1: Use @rawfiles trees.

Leo creates files derived from @rawfile trees by writing all the nodes of the
tree to the derived file in outline order. The derived file _does_ contain some
sentinels, so you _can_ update @rawfile trees from changes made to derived
files.

Option 1: Use @silentfiles trees.

Files derived from @silentfile trees contain no sentinels. Leo creates the
derived file simply by writing all body text in outline order.

Leo can't update the outline unless the derived file contains sentinels, so Leo
does not update @silentfile trees automatically when you change the derived
file in an external editor.

For complete details about @rawfile and @silentfile trees, see the child of
this node.</t>
<t tx="edream.110203163054.1062">The import commands insert @ignore directives in the top-level node. Leo does
this so that you won't accidentally overwrite your files after importing them.
Change the filename following @file or @root as desired, then remove the
@ignore directive. Saving the outline will then create the file.</t>
<t tx="edream.110203163054.1063">Q: I'm writing a Windows Script Component, which is an XML file with a CData
section containing javascript. I can get the XML as I want it by setting the
language to html, but how can I get the tangling comments inside the CData
section to be java-style comments rather than html ones?

A: In @file trees you use the @delims directive to change comment delimiters.
For example:

@delims /* */ 
Javascript stuff 
@delims &lt;-- --&gt; 
HTML stuff

Important: Leo2 can not revert to previous delimiters automatically; you must
change back to previous delimiters using another @delims directive.

In @root trees you can work around this problem using the @silent directive.</t>
<t tx="edream.110203163054.1064">Here is a letter from Zvi Boshernitzan which might be helpful:

I was having trouble disabling &lt;?php with comments (and couldn't override the
comment character for the start of the page).

Finally, I found a solution that worked, using php's heredoc string syntax:

-------------------------------
@first &lt;?php
@first $comment = &lt;&lt;&lt;EOD
EOD;

// php code goes here.
echo "boogie";

$comment2 = &lt;&lt;&lt;EOD
@last EOD;
@last ?&gt;
--------------------

  -- or --

---------------------
@first &lt;?php
@first /*
*/

echo "hi";

@delims /* */
@last ?&gt;
------------------------</t>
<t tx="edream.110203163054.1065">Use the @first directive @file or @nosentinelsfile trees. Use the @silent in
@root trees.

The @first directive allows you to place lines at the very start of files
derived from @file nodes. For example, the body text of @file spam.py might be:

@first #! /usr/bin/env python

The body text of @file foo.perl might be:

@first #/usr/bin/perl

@first directives are recognized only at the start of the body text of @file nodes.
No text may precede @first directives. More than one @first directive may exist,
like this:

@first #! /usr/bin/env python
@first # more comments.
</t>
<t tx="edream.110203163054.1066">Leo has good support for cweb. In @file trees can organize any part of cweb
code using _noweb_ sections. You can also use @rawfile, @silentfile or
@nosentinelsfile trees to create cweb files.

By default, cweb colors @space, @* and @** sections using the same syntax
coloring as for LaTeX. In addition, cweb colors C // and /*..*/ comments using
LaTeX coloring by default. You may change these defaults using the
color_cweb_doc_parts_with_latex and color_cweb_comments_with_latex options in
leoConfig.leo.

See the child of this node for full details.</t>
<t tx="edream.110203163054.1067">Everything in an @file tree must be part of the derived file: orphan and
@ignore nodes are invalid in @file trees. This restriction should not be
troublesome. For example, you can organize your outline like this:

+ myClass
..+ ignored stuff
..+ @file myClass

As usual, + denotes a headline. So you simply create a new node, called
myClass, that holds your @file tree and stuff you don't want in the @file tree.</t>
<t tx="edream.110203163054.1068">There are many ways to customize Leo.  The child of this node is a clone of Chapter 8: Customizing Leo of Leo's Users Guide.</t>
<t tx="edream.110203163054.1069">Step 1: Set use_plugins = 1 in leoConfig.leo, then execute the Tangle All
command.

Or you can set use_plugins = 1 directly in leoConfig.txt.

Step 2: For a particular @file node in leoPlugins.leo, enable the code that
calls registerHandler by changing if 0: to if 1:

For example:

if 1: # Register the handlers...
	registerHandler("start2", onStart)

</t>
<t tx="edream.110203163054.1070">1. What's the best way to go about adding a new @language? 

In the short term, the instructions are in LeoPy.leo in the Notes:How To:How to
add support for a new language section. This section contains clones of all
relevant parts of Leo that you will change.

Longer term, I plan to move to a scheme like JEdit's, which uses language
description files. Perhaps Leo could even use these files. However, this won't
happen for quite a while...

2. How can the changes be best folded back into Leo?

For now, you can only change Leo's source code and submit the changes for
inclusion in Leo's "official" code. Longer term you will be able to create
your own language description file.</t>
<t tx="edream.110203163054.1071"></t>
<t tx="edream.110203163054.1073">@nocolor

Here are the steps involved in adding a new language.

- Add a new language constant in leoGlobals.&lt;&lt;define global constants&gt;&gt;

- Add a new Tk.Radiobutton in leoPrefs.&lt;&lt;create the Target Language frame&gt;&gt;

- Add a new entry for the language in self.languageNameDict in leoConfig.py.&lt;&lt;initialize constant ivars&gt;&gt;.

This entry represents the name of the language in leoConfig.txt.

- Modify the utility routines set_delims_from_language and set_language to handle the new language.

- Modify the code in leoFileCommands.getPrefs.&lt;&lt; check for syntax coloring prefs &gt;&gt; to support the new language.

This involves making new entries in lists in each function.

- Modify leoColor.py so that colorizeAnyLanguage will handle the new language:

a. Add an entry in the list called "languages" defined  in
	leoColor.&lt;&lt;configure language-specific settings&gt;&gt;

b. Add a list containing the keywords of the new language to
	leoColor.&lt;&lt; define colorizer keywords &gt;&gt;
	
Note: the name of this list must be x_keywords, where x is the entry in language in step a.
	
For example, to add tcltk:
	
	languages = (..., "tcltk",...) # list of names of keyword lists.
	tcltk_keywords = ("after", "append", ...) # The keyword list for the tcl/tk language.
		
c. Add any language-specific code to leoColor.colorizeAnyLanguage.

For most languages nothing need be done in this step because colorizeAnyLanguage gets the comment delimiters from set_delims_from_language.

-  Make the following tests:

1. Test the syntax coloring for the new language by using the @language directive.

2. Test workings of the Preferences Panel by choosing the language in the panel and by looking at code that is _not_ under control of an @language directive.

3. Test the leoConfig.txt by setting default_target_language to the name of the new language.  When you restart Leo, the new language should be selected in the Prefs panel.

4. Remove leoConfig.txt, select the new language in the Prefs panel, and save the .leo file.  Open the file with a text editor and check to make sure that the &lt;preferences&gt; tag (near the top) contains an entry like this:

&lt;preferences allow_rich_text="0" defaultTargetLanguage="Python"&gt;
&lt;/preferences&gt;

but with the name of your new language instead of "Python".

5. Create an @root node and verify that you can Tangle it.

</t>
<t tx="edream.110203163054.1074"># We put an @color here so it is unambiguous.

@ignore
@language python
@color</t>
<t tx="edream.110203163054.1075"># General constants...
true = 1
false = 0 # Better than None
body_newline = '\n'
body_ignored_newline = '\r'
prolog_string = "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;"

# New in leo.py 3.0
prolog_prefix_string = "&lt;?xml version=\"1.0\" encoding="
prolog_version_string1 = "UTF-8" # for leo.py 2.x
prolog_version_string2 = "ISO-8859-1" # for leo.py 3.x
prolog_postfix_string = "?&gt;"

# These are set by the @langauge directive.
# Used by Tangle, Untangle and syntax coloring.
ada_language =		 1
c_language =		 2  # C, C++ or objective C.
cweb_language =		 3  # CWEB syntax coloring
cobol_language =	 4  # literate cobol??
fortran_language =	 5  # Comments start with C
fortran90_language =	 6  # Comments start with !
html_language =		 7
java_language =		 8
lisp_language =		 9
pascal_language =	10
plain_text_language =	11
perl_language =		12  # just ##
perlpod_language =	13  # ## and =pod and =cut
python_language =	14
shell_language =	15  # shell scripts
tcltk_language = 16
unknown_language =	17  # Set when @comment is seen.

# Synonyms for the bits returned by is_special_bits...
color_bits =    0x00001
comment_bits =	 0x00002
cweb_bits =     0x00004
header_bits =   0x00008
ignore_bits =   0x00010
language_bits = 0x00020
nocolor_bits =	 0x00040
noheader_bits = 0x00080
noweb_bits =    0x00100
#               0x00200 #unused
page_width_bits=0x00400
path_bits =	    0x00800
root_bits =	    0x01000 # Also represents &lt; &lt; * &gt; &gt; =
silent_bits =	  0x02000
tab_width_bits =0x04000
terse_bits = 	  0x08000
unit_bits = 	   0x10000
verbose_bits =	 0x20000</t>
<t tx="edream.110203163054.1076"># Frame and title
w,target = create_labeled_frame (outer,caption="Default Target Language")
w.pack(padx=2,pady=2,expand=1,fill="x")

# Frames for two columns of radio buttons
lt = Tk.Frame(target)
rt = Tk.Frame(target)
lt.pack(side="left")
rt.pack(side="right")

# Left column of radio buttons.
left_data = [
	("C/C++",c_language), ("CWEB", cweb_language),
	("HTML", html_language), ("Java", java_language),
	("Pascal", pascal_language) ]

for text,value in left_data:
	button = Tk.Radiobutton(lt,anchor="w",text=text,
		variable=self.lang_var,value=value,command=self.set_lang)
	button.pack(fill="x") 
	
# Right column of radio buttons.
right_data = [ ("Perl", perl_language), ("Perl+POD", perlpod_language),
	("Plain Text", plain_text_language), ("Python", python_language),
	("tcl/tk", tcltk_language) ]
	
for text,value in right_data:
	button = Tk.Radiobutton(rt,anchor="w",text=text,
		variable=self.lang_var,value=value,command=self.set_lang)
	button.pack(fill="x")</t>
<t tx="edream.110203163054.1077">leoKeywords = (
	# Leo 2 directives.
	"@","@c","@code","@doc","@color","@comment",
	"@delims","@first","@language","@nocolor","@others",
	"@pagewidth","@path","@tabwidth",
	# Leo 1 directives.
	"@ignore","@root","@unit","@silent","@terse","@verbose")
	
c_keywords = (
	# C keywords
	"auto","break","case","char","continue",
	"default","do","double","else","enum","extern",
	"float","for","goto","if","int","long","register","return",
	"short","signed","sizeof","static","struct","switch",
	"typedef","union","unsigned","void","volatile","while"
	# C++ keywords
	"asm","bool","catch","class","const_cast",
	"delete","dynamic_cast","explicit","false","friend",
	"inline","mutable","namespace","new","operator",
	"private","protected","public","reinterpret_cast","static_cast",
	"template","this","throw","true","try",
	"typeid","typename","using","virtual","wchar_t")
	
cweb_keywords = c_keywords

html_keywords = (
	# HTML constructs.
	"&lt;","&lt;/","&gt;",
	'"',
	"&lt;!---","&lt;!--","&lt;!",
	"&lt;%","%&gt;",
	"&lt;a","&lt;/a",
	"&lt;img",
	"&lt;cf","&lt;/cf",
	# Common tags: tables
	"&lt;table","&lt;/table",
	"&lt;td","&lt;/td",
	"&lt;th","&lt;/th",
	"&lt;tr","&lt;/tr",
	"&lt;caption","&lt;/caption",
	"&lt;col","&lt;/col",
	"&lt;colgroup","&lt;/colgroup",
	"&lt;tbody","&lt;/tbody",
	"&lt;tfoot","&lt;/tfoot",
	"&lt;thead","&lt;/thead",	
	# Common tags: styles
	"&lt;style","&lt;/style",
	# Common tags: scripts
	"&lt;script","&lt;/script",
	# Escapes
	"&amp;amp;", "&amp;lt;", "&amp;gt;", "&amp;quot;" )

java_keywords = (
	"abstract","boolean","break","byte","byvalue",
	"case","cast","catch","char","class","const","continue",
	"default","do","double","else","extends",
	"false","final","finally","float","for","future",
	"generic","goto","if","implements","import","inner",
	"instanceof","int","interface","long","native",
	"new","null","operator","outer",
	"package","private","protected","public","rest","return",
	"short","static","super","switch","synchronized",
	"this","throw","transient","true","try",
	"var","void","volatile","while")

pascal_keywords = (
	"and","array","as","begin",
	"case","const","class","constructor","cdecl"
	"div","do","downto","destructor","dispid","dynamic",
	"else","end","except","external",
	"false","file","for","forward","function","finally",
	"goto","if","in","is","label","library",
	"mod","message","nil","not","nodefault""of","or","on",
	"procedure","program","packed","pascal"
	"private","protected","public","published",
	"record","repeat","raise","read","register",
	"set","string","shl","shr","stdcall",
	"then","to","true","type","try","until","unit","uses"
	"var","virtual","while","with","xor"
	# object pascal
	"asm","absolute","abstract","assembler","at","automated",
	"finalization",
	"implementation","inherited","initialization","inline","interface",
	"object","override","resident","resourcestring",
	"threadvar",
	# limited contexts
	"exports","property","default","write","stored","index","name" )

perl_keywords = (
	"continue","do","else","elsif","format","for","format","for","foreach",
	"if","local","package","sub","tr","unless","until","while","y",
	# Comparison operators
	"cmp","eq","ge","gt","le","lt","ne",
	# Matching ooperators
	"m","s"
	# Unary functions
	"alarm","caller","chdir","cos","chroot","exit","eval","exp",
	"getpgrp","getprotobyname","gethostbyname","getnetbyname","gmtime",
	"hex","int","length","localtime","log","ord","oct",
	"require","reset","rand","rmdir","readlink",
	"scalar","sin","sleep","sqrt","srand","umask",
	# Transfer ops
	"next","last","redo","go","dump",
	# File operations...
	"select","open",
	# FL ops
	"binmode","close","closedir","eof",
	"fileno","getc","getpeername","getsockname","lstat",
	"readdir","rewinddir","stat","tell","telldir","write",
	# FL2 ops
	"bind","connect","flock","listen","opendir",
	"seekdir","shutdown","truncate",
	# FL32 ops
	"accept","pipe",
	# FL3 ops
	"fcntl","getsockopt","ioctl","read",
	"seek","send","sysread","syswrite",
	# FL4 &amp; FL5 ops
	"recv","setsocket","socket","socketpair",
	# Array operations
	"pop","shift","split","delete",
	# FLIST ops
	"sprintf","grep","join","pack",
	# LVAL ops
	"chop","defined","study","undef",
	# f0 ops
	"endhostent","endnetent","endservent","endprotoent",
	"endpwent","endgrent","fork",
	"getgrent","gethostent","getlogin","getnetent","getppid",
	"getprotoent","getpwent","getservent",
	"setgrent","setpwent","time","times","wait","wantarray",
	# f1 ops
	"getgrgid","getgrnam","getprotobynumber","getpwnam","getpwuid",
	"sethostent","setnetent","setprotoent","setservent",
	# f2 ops
	"atan2","crypt",
	"gethostbyaddr","getnetbyaddr","getpriority","getservbyname","getservbyport",
	"index","link","mkdir","msgget","rename",
	"semop","setpgrp","symlink","unpack","waitpid",
	# f2 or 3 ops
	"index","rindex","substr",
	# f3 ops
	"msgctl","msgsnd","semget","setpriority","shmctl","shmget","vec",
	# f4 &amp; f5 ops
	"semctl","shmread","shmwrite","msgrcv",
	# Assoc ops
	"dbmclose","each","keys","values",
	# List ops
	"chmod","chown","die","exec","kill",
	"print","printf","return","reverse",
	"sort","system","syscall","unlink","utime","warn")

perlpod_keywords = perl_keywords
	
python_keywords = (
	"and",       "del",       "for",       "is",        "raise",    
	"assert",    "elif",      "from",      "lambda",    "return",   
	"break",     "else",      "global",    "not",       "try",      
	"class",     "except",    "if",        "or",        "yield",   
	"continue",  "exec",      "import",    "pass",      "while",
	"def",       "finally",   "in",        "print")
	
tcltk_keywords = ( # Only the tcl keywords are here.
	"after",     "append",    "array",
	"bgerror",   "binary",    "break",
	"catch",     "cd",        "clock",
	"close",     "concat",    "continue",
	"dde",
	"encoding",  "eof",       "eval",
	"exec",      "exit",      "expr",
	"fblocked",  "fconfigure","fcopy",     "file",      "fileevent",
	"filename",  "flush",     "for",       "foreach",   "format",
	"gets",      "glob",      "global",
	"history",
	"if",        "incr",      "info",      "interp",
	"join",
	"lappend",   "lindex",    "linsert",   "list",      "llength",
	"load",      "lrange",    "lreplace",  "lsearch",   "lsort",
	"memory",    "msgcat",
	"namespace",
	"open",
	"package",   "parray",    "pid",
	"proc",      "puts",      "pwd",
	"read",      "regexp",    "registry",   "regsub",
	"rename",    "resource",  "return",
	"scan",      "seek",      "set",        "socket",   "source",
	"split",     "string",    "subst",      "switch",
	"tell",      "time",      "trace",
	"unknown",   "unset",     "update",     "uplevel",   "upvar",
	"variable",  "vwait",
	"while" )</t>
<t tx="edream.110203163054.1078"># Define has_string, keywords, single_comment_start, block_comment_start, block_comment_end

(single_comment_start,
	block_comment_start,
	block_comment_end) = set_delims_from_language(language)

has_string = language != plain_text_language

languages = ["c","cweb","html","java","pascal","perl","perlpod","python","tcltk"]

keywords = []
if language==cweb_language:
	for i in c_keywords:
		keywords.append(i)
	for i in cweb_keywords:
		keywords.append(i)
else:
	for name in languages:
		exec("if language==%s_language: keywords=%s_keywords" % (name,name))

if 1: # 7/8/02: Color plain text unless we are under the control of @nocolor.
	state = choose(flag,normalState,nocolorState)
else: # Stupid: no coloring at all in plain text.
	state = choose(language==plain_text_language,nocolorState,normalState)

lb = choose(language==cweb_language,"@&lt;","&lt;&lt;")
rb = choose(language==cweb_language,"@&gt;","&gt;&gt;")</t>
<t tx="edream.110203163054.1079"># Must match longer tags before short prefixes.
language = c_language # default

if self.matchTag("CWEB"):
	language = cweb_language ; self.getDquote();
elif self.matchTag("C"):
	language = c_language ; self.getDquote()
elif self.matchTag("HTML"):
	language = html_language ; self.getDquote()
elif self.matchTag("Java"):
	language = java_language ; self.getDquote()
elif self.matchTag("Pascal"):
	language = pascal_language ; self.getDquote()
elif self.matchTag("PerlPod"):
	language = perlpod_language ; self.getDquote()
elif self.matchTag("Perl"):
	language = perl_language ; self.getDquote()
elif self.matchTag("Plain"):
	language = plain_text_language ; self.getDquote()
elif self.matchTag("Python"):
	language = python_language ; self.getDquote()
elif self.matchTag("tcl/tk"):
	language = tcltk_language ; self.getDquote()
	
# print(`language`)

c.target_language = language</t>
<t tx="edream.110203163054.1080"># Language names.
self.languageNameDict = {
	c_language: "C",
	cweb_language: "CWEB",
	html_language: "HTML",
	java_language: "Java",
	pascal_language: "Pascal",
	perl_language: "Perl",
	perlpod_language: "PerlPod",
	plain_text_language: "Plain",
	python_language: "Python",
	tcltk_language: "tcl/tk" }

# Names of sections.
self.configSection = "config options"
self.compareSection = "compare options"
self.findSection = "find/change options"
self.prefsSection = "prefs panel options"
self.recentFilesSection = "recent files"
self.colorsSection = "syntax coloring options"
self.windowSection = "window options"</t>
<t tx="edream.110203163054.1081"># Returns a tuple (single,start,end) of comment delims

def set_delims_from_language(language):
	
	# trace(`language`)

	for lang, val in [ (cweb_language, "// /* */"),
		(c_language, "// /* */"), (java_language, "// /* */"),
		(fortran_language, "C"), (fortran90_language, "!"),
		(html_language, "&lt;!-- --&gt;"), (pascal_language, "// { }"),
		(perl_language, "#"), (perlpod_language, "# =pod =cut"),
		(plain_text_language, "#"), # 7/8/02: we have to pick something.
		(shell_language, "#"), (python_language, "#"),
		(tcltk_language, "#") ]: # 7/18/02
		if lang == language:
			# trace(`val`)
			return set_delims_from_string(val)

	return None, None, None # Indicate that no change should be made</t>
<t tx="edream.110203163054.1082">@  Scans the @language directive that appears at s[i]. 'default' returns default_language.

Returns (language, delim1, delim2, delim3)
@c

def set_language(s,i,issue_errors_flag,default_language):

	tag = "@language"
	# trace(`get_line(s,i)`)
	assert(i != None)
	assert(match_word(s,i,tag))
	i += len(tag) ; i = skip_ws(s, i)
	# Get the argument.
	j = i
	i = skip_c_id(s,i)
	# Allow tcl/tk.
	arg = string.lower(s[j:i])
	if len(arg) &gt; 0:
		for name, language in [ ("ada", ada_language),
			("c", c_language), ("c++", c_language),
			("cweb", cweb_language), ("default", default_language),
			("fortran", fortran_language), ("fortran90", fortran90_language),
			("html", html_language), ("java", java_language),
			("lisp", lisp_language), ("objective-c", c_language),
			("pascal", pascal_language), ("perl", perl_language),
			("perlpod", perlpod_language),
			("plain", plain_text_language), # 7/8/02
			("python", python_language),
			("shell", shell_language),
			("tcl", tcltk_language) ]: # 7/18/02.  Note: this also matches tcl/tk.
		
			if arg == name:
				delim1, delim2, delim3 = set_delims_from_language(language)
				return language, delim1, delim2, delim3

	if issue_errors_flag:
		es("ignoring: " + get_line(s,i))

	return None, None, None, None,</t>
<t tx="edream.110203163054.1083">tags = (
	"blank", "comment", "cwebName", "docPart", "keyword", "leoKeyword",
	"link", "name", "nameBrackets", "pp", "string", "tab")

def colorizeAnyLanguage(self,v,body,language,flag):
	
	#trace(`language`)

	hyperCount = 0 # Number of hypertext tags
	self.body = body # For callbacks
	s = body.get("1.0", "end")
	sel = body.index("insert") # get the location of the insert point
	start, end = string.split(sel,'.')
	start = int(start)
	# trace(`self.count` + `v`)
	# trace(`body.tag_names()`)

	if 0: # Remove all tags from the selected line.
		for tag in self.tags:
			body.tag_remove(tag, index(start,0), index(start,"end"))
	else: # Remove all tags from body.
		body.tag_delete(
			"blank", "comment", "cwebName", "docPart", "keyword", "leoKeyword",
			"link", "name", "nameBrackets", "pp", "string", "tab")
	&lt;&lt; configure tags &gt;&gt;
	&lt;&lt; configure language-specific settings &gt;&gt;
	self.count += 1
	
	lines = string.split(s,'\n')
	n = 0 # The line number for indices, as in n.i
	for s in lines:
		n += 1 ; i = 0 ; sLen = len(s)
		# trace(`n` + ", " + `s`)
		while i &lt; sLen:
			progress = i
			ch = s[i]
			if state == string3State:
				&lt;&lt; continue python triple string &gt;&gt;
				continue
			elif state == docState:
				&lt;&lt; continue doc part &gt;&gt;
				continue
			elif state == nocolorState:
				&lt;&lt; continue nocolor state &gt;&gt;
				continue
			elif state == blockCommentState:
				&lt;&lt; continue block comment &gt;&gt;
				continue
			else: assert(state == normalState)

			if has_string and ch == '"' or ch == "'":
				&lt;&lt; handle string &gt;&gt;
			elif single_comment_start and match(s,i,single_comment_start):
				&lt;&lt; handle single-line comment &gt;&gt;
			elif block_comment_start and match(s,i,block_comment_start):
				&lt;&lt; start block comment &gt;&gt;
			elif ch == '#' and language in [c_language,cweb_language]:
				&lt;&lt; handle C preprocessor line &gt;&gt;
			elif match(s,i,lb) or (language==cweb_language and match(s,i,"@(")):
				&lt;&lt; handle possible section ref or def &gt;&gt;
			elif ch == '@':
				&lt;&lt; handle possible @keyword &gt;&gt;
			elif ch in string.letters:
				&lt;&lt; handle possible keyword &gt;&gt;
			elif ch == ' ':
				&lt;&lt; handle blank &gt;&gt;
			elif ch == '\t':
				&lt;&lt; handle tab &gt;&gt;
			else:
				&lt;&lt; handle normal character &gt;&gt;
			assert(progress &lt; i)</t>
<t tx="edream.110203163054.1084">config = app().config
assert(config)

for name in default_colors_dict:
	option_name,default_color = default_colors_dict[name]
	option_color = config.getColorsPref(option_name)
	color = choose(option_color,option_color,default_color)
	# Must use foreground, not fg.
	try:
		body.tag_config(name, foreground=color)
	except: # Recover after a user error.
		body.tag_config(name, foreground=default_color)

underline_undefined = config.getBoolColorsPref("underline_undefined_section_names")
use_hyperlinks      = config.getBoolColorsPref("use_hyperlinks")
self.use_hyperlinks = use_hyperlinks

# underline=var doesn't seem to work.
if use_hyperlinks: 
	body.tag_config("link",underline=1) # defined
	body.tag_config("name",underline=0) # undefined
else:
	body.tag_config("link",underline=0)
	if underline_undefined:
		body.tag_config("name",underline=1)
	else:
		body.tag_config("name",underline=0)

if self.showInvisibles:
	if 1: # Very poor, and vaguely usable.
		body.tag_config("blank",background="black",bgstipple="gray25")
		body.tag_config("tab",background="black",bgstipple="gray50")
	else: # Doesn't work, but does increase the spacing ;-)
		body.tag_config("blank",font="Symbol")
		body.tag_config("tab",font="Symbol")
else:
	body.tag_config("blank",background="white")
	body.tag_config("tab",background="white")</t>
<t tx="edream.110203163054.1085"></t>
<t tx="edream.110203163054.1086">if language == cweb_language:
	&lt;&lt; handle cweb doc part &gt;&gt;
else:
	&lt;&lt; handle noweb doc part &gt;&gt;</t>
<t tx="edream.110203163054.1087">word = self.getCwebWord(s,i)
if word and len(word) &gt; 0:
	j = i + len(word)
	if word in ("@&lt;","@(","@c","@d","@f","@p"):
		state = normalState # end the doc part and rescan
	else:
		# The control code does not end the doc part.
		body.tag_add("keyword", index(n,i), index(n,j))
		i = j
		if word in ("@^","@.","@:","@="): # Ended by "@&gt;"
			j = string.find(s,"@&gt;",i)
			if j &gt; -1:
				body.tag_add("cwebName", index(n,i), index(n,j))
				body.tag_add("nameBrackets", index(n,j), index(n,j+2))
				i = j + 2
else:
	# Everthing up to the next "@" is in the doc part.
	j = string.find(s,"@",i+1)
	if j == -1: j = len(s)
	body.tag_add("docPart", index(n,i), index(n,j))
	i = j</t>
<t tx="edream.110203163054.1088">if i == 0 and match(s,i,lb):
	# Possible section definition line.
	state = normalState # rescan the line.
	continue
if i == 0 and ch == '@':
	j = self.skip_id(s,i+1)
	word = s[i:j]
	word = string.lower(word)
else:
	word = ""

if word in ["@c","@code","@unit","@root","@color","@nocolor"]:
	# End of the doc part.
	body.tag_remove("docPart", index(n,i), index(n,j))
	body.tag_add("leoKeyword", index(n,i), index(n,j))
	i = j ; state = normalState
else:
	# The entire line is in the doc part.
	body.tag_add("docPart", index(n,i), index(n,sLen))
	i = sLen # skipt the rest of the line.</t>
<t tx="edream.110203163054.1089">delim = self.delim
if delim=="'''":
	j = string.find(s,"'''",i)
elif delim=='"""':
	j = string.find(s,'"""', i)
else:
	state=normalState ; self.delim = None ; continue

if j == -1:
	# The entire line is part of the triple-quoted string.
	body.tag_add("string", index(n,i), index(n,"end"))
	i = sLen # skipt the rest of the line.
else:
	# End the string
	body.tag_add("string", index(n,i), index(n,j+3))
	i = j + 3 ; state = normalState ; self.delim = None</t>
<t tx="edream.110203163054.1090">j = string.find(s,block_comment_end,i)
if j == -1:
	# The entire line is part of the block comment.
	body.tag_add("comment", index(n,i), index(n,"end"))
	i = sLen # skipt the rest of the line.
else:
	# End the block comment.
	k = len(block_comment_end)
	body.tag_add("comment", index(n,i), index(n,j+k))
	i = j + k ; state = normalState</t>
<t tx="edream.110203163054.1091">if i == 0 and ch == '@':
	j = self.skip_id(s,i+1)
	word = s[i:j]
	word = string.lower(word)
else:
	word = ""

if word == "@color" and language != plain_text_language:
	# End of the nocolor part.
	body.tag_add("leoKeyword", index(n,0), index(n,j))
	i = j ; state = normalState
else:
	# The entire line is in the nocolor part.
	# Add tags for blanks and tabs to make "Show Invisibles" work.
	for ch in s[i:]:
		if ch == ' ':
			body.tag_add("blank", index(n,i))
		elif ch == '\t':
			body.tag_add("tab", index(n,i))
		i += 1</t>
<t tx="edream.110203163054.1092">if language == python_language:
	j, state = self.skip_python_string(s,i)
	body.tag_add("string", index(n,i), index(n,j))
	i = j
else:
	j = self.skip_string(s,i)
	body.tag_add("string", index(n,i), index(n,j))
	i = j</t>
<t tx="edream.110203163054.1093">k = len(block_comment_start)
body.tag_add("comment", index(n,i), index(n,i+k))
i += k ; state = blockCommentState</t>
<t tx="edream.110203163054.1094">body.tag_add("comment", index(n,i), index(n,"end"))
i = sLen</t>
<t tx="edream.110203163054.1095">body.tag_add("pp", index(n,i), index(n,"end"))
i = sLen</t>
<t tx="edream.110203163054.1096">body.tag_add("nameBrackets", index(n,i), index(n,i+2))

# See if the line contains the rb
j = string.find(s,rb+"=",i+2) ; k = 3
if j == -1:
	j = string.find(s,rb,i+2) ; k = 2
if j == -1:
	i += 2
else:
	if language != cweb_language:
		searchName = body.get(index(n,i),   index(n,j+k)) # includes brackets
		ref = findReference(searchName,v)
	
	if language == cweb_language:
		body.tag_add("cwebName", index(n,i+2), index(n,j))
	elif ref:
		body.tag_add("link", index(n,i+2), index(n,j))
		if self.use_hyperlinks:
			&lt;&lt; set the hyperlink &gt;&gt;
	elif k == 3: # a section definition
		body.tag_add("link", index(n,i+2), index(n,j))
	else:
		body.tag_add("name", index(n,i+2), index(n,j))
	body.tag_add("nameBrackets", index(n,j), index(n,j+k))
	i = j + k</t>
<t tx="edream.110203163054.1097"># Set the bindings to vnode callbacks.
# Create the tag.
# Create the tag name.
tagName = "hyper" + `hyperCount`
hyperCount += 1
body.tag_delete(tagName)
body.tag_add(tagName, index(n,i+2), index(n,j))
ref.tagName = tagName
body.tag_bind(tagName,"&lt;Control-1&gt;",ref.OnHyperLinkControlClick)
body.tag_bind(tagName,"&lt;Any-Enter&gt;",ref.OnHyperLinkEnter)
body.tag_bind(tagName,"&lt;Any-Leave&gt;",ref.OnHyperLinkLeave)</t>
<t tx="edream.110203163054.1098">word = None
if language == cweb_language:
	&lt;&lt; Handle all cweb control codes &gt;&gt;
if not word:
	&lt;&lt; Handle non-cweb @keywords &gt;&gt;</t>
<t tx="edream.110203163054.1099">word = self.getCwebWord(s,i)
if word:
	# Color and skip the word.
	j = i + len(word)
	body.tag_add("keyword",index(n,i),index(n,j))
	i = j

	if word in ("@ ","@\t","@\n","@*","@**"):
		state = docState
		continue ;

	if word in ("@^","@.","@:","@="): # Ended by "@&gt;"
		j = string.find(s,"@&gt;",i)
		if j &gt; -1:
			body.tag_add("cwebName", index(n,i), index(n,j))
			body.tag_add("nameBrackets", index(n,j), index(n,j+2))
			i = j + 2
</t>
<t tx="edream.110203163054.1100">j = self.skip_id(s,i+1)
word = s[i:j]
word = string.lower(word)
if i != 0 and word != "@others":
	word = "" # can't be a Leo keyword, even if it looks like it.

# 7/8/02: don't color doc parts in plain text.
if language != plain_text_language and (word == "@" or word == "@doc"):
	# at-space starts doc part
	body.tag_add("leoKeyword", index(n,i), index(n,j))
	# Everything on the line is in the doc part.
	body.tag_add("docPart", index(n,j), index(n,sLen))
	i = sLen ; state = docState
elif word == "@nocolor":
	# Nothing on the line is colored.
	body.tag_add("leoKeyword", index(n,i), index(n,j))
	i = j ; state = nocolorState
elif word in leoKeywords:
	body.tag_add("leoKeyword", index(n,i), index(n,j))
	i = j
else:
	i = j</t>
<t tx="edream.110203163054.1101">j = self.skip_id(s,i)
word = s[i:j]
if word in keywords:
	body.tag_add("keyword", index(n,i), index(n,j))
i = j</t>
<t tx="edream.110203163054.1102">body.tag_add("blank", index(n,i)) ; i += 1</t>
<t tx="edream.110203163054.1103">body.tag_add("tab", index(n,i)) ; i += 1</t>
<t tx="edream.110203163054.1104"># body.tag_add("normal", index(n,i))
i += 1
</t>
<t tx="edream.110203163054.1105">def getPrefs (self):

	c = self.commands ; config = app().config
	
	self.getTag("&lt;preferences")
	while 1:
		if self.matchTag("allow_rich_text="):
			self.getDquote() ; self.getBool() ; self.getDquote() #ignored
		elif self.matchTag("tab_width="):
			self.getDquote() ; c.tab_width = self.getLong() ; self.getDquote()
		elif self.matchTag("page_width="):
			self.getDquote() ; c.page_width = self.getLong() ; self.getDquote()
		elif self.matchTag("tangle_bat="):
			self.getDquote() ; c.tangle_batch_flag = self.getBool() ; self.getDquote()
		elif self.matchTag("untangle_bat="):
			self.getDquote() ; c.untangle_batch_flag = self.getBool() ; self.getDquote()
		# New in version 0.10
		elif self.matchTag("output_doc_chunks="):
			self.getDquote() ; c.output_doc_flag = self.getBool() ; self.getDquote()
		elif self.matchTag("noweb_flag="):
			# New in version 0.19: Ignore this flag.
			self.getDquote() ; self.getBool() ; self.getDquote()
		elif self.matchTag("extended_noweb_flag="):
			# New in version 0.19: Ignore this flag.
			self.getDquote() ; self.getBool() ; self.getDquote()
		elif self.matchTag("defaultTargetLanguage="):
			# New in version 0.15
			self.getDquote()
			&lt;&lt; check for syntax coloring prefs &gt;&gt;
		elif self.matchTag("use_header_flag="):
			self.getDquote() ; c.use_header_flag = self.getBool() ; self.getDquote()
		else: break
	self.getTag("&gt;")
	while 1:
		if self.matchTag("&lt;defaultDirectory&gt;"):
			# New in version 0.16.
			c.tangle_directory = self.getEscapedString()
			self.getTag("&lt;/defaultDirectory&gt;")
			if not os.path.exists(c.tangle_directory):
				es("default tangle directory not found:" + c.tangle_directory)
		elif self.matchTag("&lt;TSyntaxMemo_options&gt;"):
			self.getEscapedString() # ignored
			self.getTag("&lt;/TSyntaxMemo_options&gt;")
		else: break
	self.getTag("&lt;/preferences&gt;")
	
	# Override .leo file's preferences if settings are in leoConfig.txt.
	if config.configsExist:
		config.setCommandsIvars(c)</t>
<t tx="edream.110203163054.1106">@color
@language tcl/tk
@root "c:\prog\test\tcltktest.txt"

after # 'after' is a keyword
all # 'all' is not a keyword

&lt;&lt; stuff &gt;&gt;

# A comment
// Not a comment
"A string"
'A string'</t>
<t tx="edream.110203163054.1107">@ This is a tcl/tk doc part

This is code</t>
<t tx="edream.110203163054.1108">Question:

It would be nice if Leo could open empty files. I tend to be "document
oriented" rather than "application oriented" in my thinking and prefer "create
empty file at location -&gt; open it with program" to "start program -&gt; create new
file -&gt; save it at location".

Answer by Paul Paterson

If you are on Windows 98/2000/XP then the procedure is as follows...

1. Start Leo
2. Click New
3. Click Save as...
4. Save the file as "c:\windows\shellnew\leofile.leo" (or c:\winnt for 2000/XP)
5. Open regedit "start...run...regedit"
6. Open HKEY_CLASSES_ROOT and find the ".leo" extension type
7. Go New ... Key from the context menu 
8. Call the new key ShellNew 
9. Select the new key, right-click, choose New ... String Value from the contextmenu
10. Call it FileName 
11. Double-click on the string, and modify it to be the filename of the leofile.leo
file you created, including the extension
12. Exit the registry editor and restart Windows Explorer (or you may need to
reboot on Windows 98)

Now you should have a New.. Leo File option in Explorer. This creates a
duplicate of the file you saved. This can be useful because you could make a
template Leo file containing some standard nodes that you always have and then
save this.</t>
<t tx="edream.110203163054.1158">@ The following is part of Leo's actual source code.  The code is written in C++ and uses Borland's Delphi classes.

For @root trees:  The Tangle command will generate derived files from @root trees.  The Untangle command will update outlines based on changes made to files derived from @root trees.

For @file trees:  The Save command will generate the derived files from @file trees.  The Open command will update outlines based on changes made to files derived from @file trees.

When looking through this outline pay particular attention to:

a) How the outline organizes classes, methods and chunks.
b) How the @root and @unit directives are used in @root trees.
c) How the @file and @others directives are used in @file trees.

If you actually want to create files you must remove the @ignore directive below.
@c

@ignore
@language c</t>
<t tx="edream.110203163054.1162">@ To create the file hello.c in the current directory.

1. Remove the @ignore directive from the parent of this node.
2. Save this file.  This will create hello.c automatically.

When you look at hello.c you will see that it contains comments starting with //@.  Leave these comments alone!  They are needed to recreate the outline when reading this .leo file.</t>
<t tx="edream.110203163054.1163">@ This shows how to use Leo to create source files for Leo2.  
@c

&lt;&lt; includes &gt;&gt;

@others</t>
<t tx="edream.110203163054.1164">#include "stdio.h"</t>
<t tx="edream.110203163054.1165">void main ( void )
{
	printf("Hello World!\n");
}</t>
<t tx="edream.110203163054.1653">@killcolor</t>
<t tx="edream.110203163054.1654">100 Series: Leaps that apply to the Leap process itself. 

Leap 101: How to administer Leaps. 

- Assigned to nobody. 
- No formality needed yet. </t>
<t tx="edream.110203163054.1655">

- Assigned to nobody. 
- Create, plan, promote &amp; administer a gathering of Leo enthusiasts. 
- Part of the planning would be to create a date and setting for the conferences. </t>
<t tx="edream.110203163054.1656"></t>
<t tx="edream.110203163054.1657">Project finished in Leo 4.2.

- Cloned vnodes share the same tnode.  That tnode forms the root of a shared tree of vnodes.

- Code must use positions to traverse the tree.

- c.rootVnode and c.currentPosition return positions, not vnodes.

- Positions are proxies for vnodes.

For more details, see leoNodes.py in LeoPy.leo.
</t>
<t tx="edream.110203163054.1658">Project finished in Leo 4.2.

The new file format uses gnx's (global node indices) to represent nodes uniquely.</t>
<t tx="edream.110203163054.1659">- More flexible and more powerful than present hand-drawn code. 
- Ideally, it would be a path to anygui. </t>
<t tx="edream.110203163054.1661"></t>
<t tx="edream.110203163054.1662">Produce a plugin (with related design) that allows people to share all or part of .leo files via a
central server. 

- Assigned to nobody. 
- This plugin need _not_ address itself to issues raised in Leap 302: it is a prototype for experimentation. The
initial aim of this Leap would be to produce a starting point design that would be incorporated into this Leap
for review. 

</t>
<t tx="edream.110203163054.1663">- Assigned to nobody 
- This plugin need _not_ address itself to issues raised in Leap 301: it is a prototype for experimentation. The
initial aim of this Leap would be to produce a starting point design that would be incorporated into this Leap
for review.</t>
<t tx="edream.110203163054.1664">Open Discussion

 RE: Status report: ten breakthroughs
2003-05-30 12:50  
About merging / CVS etc: 

Perhaps it helps to think about the big picture a bit, I mean about what do we really want / is practical. 

CVS is a de facto standard on the internet for collaboration, so being compatible is highly desirable. Unfortunately CVS has a series of shortcomings, particularly for Leo. 

CVS merges on a line-by-line basis, so interdependencies of code are ignored (I think all other tools I know of do the same). Now, I believe this is ok for large sets of files, where multiple changes to the same function or file are rare. Using CVS to merge only single Leo nodes (body text) would be rather silly though: Mostly these texts are short (a page or so) and one single function (or less). Multiple changes in such a code snippet are likely to be interdependent, and I would rather like to look at the different texts rather than have them merged automatically. 

On the other hand, I don't mind if the versioning or merging tool at hand allows me to update any nodes I did not touch myself. So rather than CVS-like merging, I would like to see which nodes are being affected by the change, then have it done automatically for those nodes I don't worry about, but by hand (or interactively) for those I changed myself too, or for those I worry about, because they are related to my own changes. 

In other words, I would like to see a merge tool, that understands versions, can tell me which nodes in a Leo file have changed, remembers which changes I made myself, and gives me the choice, tree branch by tree branch, to automatically accept the changes, or screen them interactively. 

I think Leo should have such a tool built-in. 

- Josef</t>
<t tx="edream.110303182253.3">Leo does an auto-save only if something has actually been changed.</t>
<t tx="edream.110303182253.39"></t>
<t tx="edream.110303182719">The config_encoding setting controls the encoding of non-ascii characters in leoConfig.txt.

The use_gnx setting in leoConfig.txt determines whether uses gnx's (cvs friendly) or ints.  No version of Leo before 4.1 can read .leo files containing gnx.   Only gnx's are immutable.  Leo recomputes all non-gnx indices from scratch whenever writing a .leo file. It is possible to convert between 3.x and 4.1 file formats by changing the use_gnx setting.
</t>
<t tx="edream.110603185805">Leo 4.1 beta 5                   December 5, 2003

This is the fifth release of the reorganized 4.1 code base.

For the first time in months there are no serious bugs outstanding.

Warning: By default Leo 4.1 creates .leo files that can not be read by older versions of Leo.

Warning: Use the __wx_gui.py plugin with extreme caution until further notice:
bugs in this plugin could cause body text to be cleared improperly when changing nodes.

Beta 5:
  * Leo runs in batch mode when invoked with --script aScriptFile.py
    - Created "null gui" classes that do not use any gui code.
  * Leo supports Unicode characters (e.g. Chinese) in path and file names.
  * Fixed several long-standing bugs:
    - Fixed several minor problems with the Extract Section and Import commands.
    - Fixed problem that prevent the Find panel from working on the Mac.
    - Improved @url handling so that @url file:\\path\x.leo works properly.
    - Improved support for @lineending platform.
    - Leo honors outline/body pane ratio when opening .leo files.
    - Leo now ensures that newly-opened windows fit entirely on the screen.
    - Fixed a crasher when Undoing a Change All command when searching headlines.
  - Fixed other bugs resulting from the 4.1 reorg:
    - Fixed problem loading plugins on Linux.
    - Fixed crashers in the Extract Section and Extract commands.
    - Fixed a crasher when writing a file containing an undefined section.
    - Removed duplicate bindings in popup menus.
    - Made sure to show Leo's windows in wx gui plugin.

Beta 4:
  - Fixed several "reorg" bugs, some of which affected plugins.
  - Allow @directives and section references when executing scripts!
  - More than one section reference may now appear on the same line.
  - Use "utf-8" encoding for filenames under MacOS (Darwin)
  - Allow command or cmnd prefix for menu shortcuts under Darwin.
	  
Beta 3:
  - Completed the reorg, making many changes to the code base.
  - Fixed a LaTeX coloring bug

Beta 2:
  - Fixed a startup problem on Linux: the "mbcs" text encoding is not valid on Linux.

Beta 1:
  * Script-based find/change commands.
  - Hoist &amp; DeHoist commands for viewing parts of an outline.
  - Check Outline command finds user clone mistakes.
  * New configuration settings:
    - use_gnx specifies whether .leo files use integers as indices:
      use_gnx = 0 makes .leo files compatible with previous versions of Leo.
      use_gnx = 1 makes .leo files cvs-friendly
    - config_encoding specifies the encoding of leoConfig.txt.
  * Several significant code-level changes:
    - The 4.1 code base has been reorganized to support gui plugins.
    - An example wx_gui plugin is partly functional.
    - Created a flexible framework for creating &amp; running regression tests.
    - app.forceShutdown now works when called from plugins.</t>
<t tx="edream.110603190125.1">Leo 4.1 uses immutable gnx's (id:timestamp:n) by default to associate tnodes with vnodes in .leo files.  This makes Leo as cvs friendly as possible.  From now on .leo files will be checked in to cvs with the -ko (text/keywords off) option.</t>
<t tx="edream.110603190125.3">The file test.leo in the test directory contains real regression tests for syntax coloring.   Regression testing scripts create regression tests dynamically from data in Leo's outline.  Very cool, very easy, very general.  In particular, regression tests may use temporary nodes in test.leo rather than creating separate Tk windows for testing.</t>
<t tx="edream.110603190125.4">The 4.1 code base has been reorganized to support gui's other than tkinter.  Leo's src directory contains several new source files.

This reorg affects almost all plugins.  Considerably more work and testing will be done before 4.1 final.

The __wx_gui.py plugin is uses the newly reorganized code.  It is functional except for gui-dependent commands like Toggle-Split Direction.  WARNING: treat the this plugin with extreme caution until further notice.  The possibility exists that bugs in the code could cause body text to be cleared improperly when changing nodes.</t>
<t tx="edream.110603190234.1"></t>
<t tx="edream.110603190322.3">This involved fixing a bug in idle_body_key so that the oldText param is honored if present.</t>
<t tx="edream.110603190322.6">@nocolor

New in 4.1: Leo now supports scripts in Leo's Find/Change dialog.

Leo's find panel now contains the Script Search radio button and the Script
Change checkbox. When the Script Search radio button is selected Leo treats the
contents of the Search Text as a script to execute whenever any kind of Find
command is executed. Similarly, when the Script Change checkbox is selected Leo
treats the context of the Change Text as a script to execute whenever any kind
of Change command is executed. See below for just how this works.

Script-based find-change is extremely powerful. In effect, Leo's Find/Change
panel becomes a new platform for running scripts interactively. Leo now has all
the find/change capability of pattern matching languages like Snobol and Icon,
just by using the capabilities of the plain Python language. Moreover, Leo can
deliver these capabilities interactively or not depending which buttons you push
in Leo's Find/Change panel.

Script-based find/change frees the user from having to control script-based
searches interactively. Rather than forcing find/change scripts to implement
their own interactive controls, it is much easier to use what Leo already has.</t>
<t tx="edream.110603190322.8">Undoing Change All cleared the body pane or the headline pane.

The fix was simple: call setUndoParams instead of setUndoTypingParams in batchChange.</t>
<t tx="edream.110603190322.9"></t>
<t tx="edream.110603190322.10"></t>
<t tx="edream.110603190322.11">The node-only option wasn't working due to a bug in createFrame.

There still may be a problem with the interaction between Node-only,Change All and Undo.</t>
<t tx="edream.110603190322.13">The fix was to open files with 'rb' instead of 'r'.  This probably should be done in more places.</t>
<t tx="edream.110603190322.14">This command checks for unused tnodeLists and checks the topology of all clones.</t>
<t tx="edream.110603190322.15">The Hoist command redraws the screen so presently selected tree becomes the only visible part of the outline.  Leo prevents the you from moving nodes outside the hoisted outline.  The De-hoist command restores the outline.  Hoist commands may be nested.</t>
<t tx="edream.110603190404"></t>
<t tx="edream.110603192009"></t>
<t tx="edream.110603192009.1"></t>
<t tx="edream.111803060152"></t>
<t tx="edream.111803060152.1">Leo dedicates a Python dictionary called app.searchDict for communication
between Leo and the search and change scripts. The search and change scripts may
also use app.searchDict for communication between themselves. Leo sets
app.searchDict["type"] to "find", "change", "findAll" or "changeAll" to indicate
the kind of command being executed. Scripts may use all other entries in
app.searchDict as they please.

Leo executes the find script once when you press the Find button (or the Change
then Find button) in Leo's Find/Change dialog. Typically, the find script would
traversing the tree and highlight the found text or otherwise indicate to the
user that the find operation has succeeded. However, the script can do anything
it pleases.

Leo executes the the find script repeatedly when you press the Find All button.
Leo keeps executing the find script until app.searchDict["continue"] evaluates
to false. Initially there is no entry for app.searchDict["continue"], so the
find script must set app.searchDict["continue"] = true if it wants Leo to keep
executing it.

Leo executes the change script once when you press the Change button. Typically,
the change script would change the selected text. Usually the change script will
compute the new value of body text and call v.setBodyStringOrPane(newText) to
make that change permanent. 

The change script also may handle undo, typically by calling
c.frame.onBodyChanged(v,"Change",oldText=oldText). Leo does not handle undo
automatically. Indeed, Leo makes no assumptions whatever about what the change
script really does.

Leo executes the the change script repeatedly when you press the Change All
button. Just as with the Find All command, Leo keeps executing the change script
until app.searchDict["continue"] evaluates to false.

Most find and change scripts will ignore settings in the Find Panel like "whole
word", "pattern match", and "reverse". However, these settings are available to
the scripts via ivars such as c.whole_word_flag, etc. if desired.</t>
<t tx="edream.111803060152.2">@nocolor

Some ideas for using scripts:
	
Either the find and change scripts may use Python's re module.  For
example, the find script could set app.searchDict["m"] to the match object
returned by re's match method.  The change script would then compute the
result, change the text and set the undo info as usual.

There is no reason to confine find/change scripts to operate on data only
within a Leo outline. These scripts could as easily traverse your file system
as the Leo outline. But notice: scripts could pull data from the file system
into the outline so that you can see the effects of changes as the scripts
operate. Again, this can all happen interactively if you like.</t>
<t tx="edream.111803060643"></t>
<t tx="edream.111803062437"></t>
<t tx="edream.112303173638">@color
@  New in version 4.1: On startup, Leo looks for two arguments of the form --script scriptFile.  If found, Leo enters batch mode.

In batch mode Leo does not show any windows.  Leo assumes the scriptFile contains a Python script and executes the contents of that file using Leo's Execute Script command.  By default, Leo sends all output to Leo's log pane to the console window.  Scripts in the scriptFile may disable or enable this output by calling app.log.disable() or app.log.enable()

Scripts in the scriptFile may execute any of Leo's commands except the Edit Body and Edit Headline commands.  Those commands require interaction with the user.

For example, the following batch script reads a Leo file and prints all the headlines in that file.
@c

import leoGlobals as g

path = r"c:\prog\leoCVS\leo\test\test.leo"

g.app.log.disable() # disable reading messages while opening the file
flag,newFrame = g.openWithFileName(path,None)
g.app.log.enable() # re-enable the log.

for p in newFrame.c.allNodes_iter():
	g.es(g.toEncodedString(p.headString(),"utf-8"))</t>
<t tx="edream.120403174147"></t>
<t tx="edream.120403174147.30">Another 4.1 reorg bug.</t>
<t tx="edream.120403174147.33">This was due to a missing activate event.</t>
<t tx="edream.120403174147.36">Continuation lines caused the import command to terminate functions, methods and classes prematurely.</t>
<t tx="edream.120403174147.56"></t>
<t tx="edream.120403174147.61">This was causing Leo not to load plugins properly on Linux.  The problem was that the imp module does not handle Unicode file names properly.</t>
<t tx="edream.120403174147.63">This was a reorg bug.</t>
<t tx="edream.120403174147.65">Another bug caused by the 4.1 reorg.</t>
<t tx="edream.120403174147.94">- Leo now properly enables and disables the Extract Section menu item.
- Leo no longer removes leading forward slashes in section names in headlines.
- Corrected the documentation for the Extract Section command.</t>
<t tx="edream.120403174147.102">Another 4.1 reorg bug.</t>
<t tx="edream.120403174147.105">This bug has been around for a long time.</t>
<t tx="edream.120403174147.109">The new code attempts to use bitmap files only on Windows.</t>
<t tx="edream.120403174147.112">Leo makes sure that opened files or newly-created outlines fit entirely on the screen.  The Cascade commands leaves the sizes of windows unchanged: it merely ensures that the top left corner of a window is visible on the screen.</t>
<t tx="edream.120403174147.119"></t>
<t tx="edream.120403174147.128">@ A problem: the new window gets put behind the old.  This is probably because Tk thinks that the mouse-down event should select then new window...</t>
<t tx="edream.120403174241"></t>
<t tx="edream.120403180443"></t>
<t tx="edream.120403180443.1"></t>
<t tx="edream.120503073304">This is a very useful piece of software that has enabled me to use
Literate Programming in production for the first time.

When I figured out I could do it in plain text and export to
DocBook for automated typesetting, I was on my way. Because I only
do business and utility software, I don't need the sophistication of
LaTeX markup.

Writing the documentation and the code in the same outline at
the same time improves the whole product. Being able to
automatically export both with just two key presses (tangle and
export-to-DocBook) is a real luxury. -- Michael Dawson</t>
<t tx="edream.120703073611">Plugins may create (or add to) v.tempAttributes (for vnodes) or t.tempAttributes (for tnodes).  These will work just like the corresponding unknownAttributes dicts except that Leo will _not_ read or write these dictionaries when reading or writing files.  Note: nothing needs to change in Leo to support this convention.</t>
<t tx="edream.120703073611.1">@nocolor

We wish to avoid the possibility that two plugins might unwittingly choose the same name for attributes in the unknownAttributes or tempAttributes dictionaries.  The following convention eliminates that possibility.

Each plugin should create its own dictionary _inside_ any tempAttributes or unknownAttributes dictionaries that it intends to create or modify.  Something like this:

@color

# Create the tempAttributes dict for this vnode.
if not v.hasattr("tempAttributes"):
	v.tempAttributes = {}

# Create a subdictionary for the private use of my plugin.
d = v.tempAttributes.get("myPluginName")
if d is None:
	v.tempAttributes["myPluginName"] = d = {}

@nocolor

Now the plugin can set and get fields in d.  Similar code would be used for the t.tempAttributes, v.unknownAttributes and t.unknownAttributes dictionaries.</t>
<t tx="edream.120703081642">ED, you continue to push the envelope. the amazing thing is that the footprint
isn't doubling every few months like it would be in another designers hands.
adding features by removing constraints, hot refactoring while adding unit tests.
forget the book. I would pay to see the movie.</t>
<t tx="edream.120903151103"></t>
<t tx="edream.120903151103.1">@nocolor

New in Leo 4.2:  The Import Files dialog allows you to select multiple files provided you are running Python 2.3 or above.

There is also an importFiles script in LeoPy.leo.  You can use that script as follows:

@color

import leoImport
leoImport.importFiles(aDirectory, ".py")

@nocolor

This will import all .py files from aDirectory, which should be a full path to a particular directory.  You could use ".c" to import all .c files, etc.</t>
<t tx="edream.121403160546">Leo 4.1 Release Candidate 3              December 19, 2003

This release fixes a serious bug in the logic that reads old-style derived files.

There are no known bugs in this version of Leo.

The highlights of this release:

- Leo runs in batch mode when invoked with --script aScriptFile.py
- Leo supports Unicode characters (e.g. Chinese) in path and file names.
- @directives and section references are now valid when executing scripts.
- @ignored and orphan nodes now valid in @file-nosent trees.
- Script-based find/change commands.
- Check Outline command.
- Hoist &amp; DeHoist commands.
- A new gui-agnostic architecture: useful for batch mode and unit tests.
- Several new configuration settings.
- Many new unit tests.
- A host of bug fixes.</t>
<t tx="edream.121403161017">See previous release notes for more details:

- Fixed several minor problems with the Extract Section and Import commands.
- Fixed problem that prevent the Find panel from working on the Mac.
- Improved @url handling so that @url file:\\path\x.leo works properly.
- Improved support for @lineending platform.
- Leo honors outline/body pane ratio when opening .leo files.
- Leo now ensures that newly-opened windows fit entirely on the screen.
- Fixed a crasher when Undoing a Change All command when searching headlines.
- Fixed other bugs resulting from the 4.1 reorg:
- Fixed problem loading plugins on Linux.
- Fixed crashers in the Extract Section and Extract commands.
- Fixed a crasher when writing a file containing an undefined section.
- Removed duplicate bindings in popup menus.
- Made sure to show Leo's windows in wx gui plugin.
- More than one section reference may now appear on the same line.
- Use "utf-8" encoding for filenames under MacOS (Darwin)
- Allow command or cmnd prefix for menu shortcuts under Darwin.
- Fixed a LaTeX coloring bug
</t>
<t tx="edream.121403161017.1">- The 4.1 code base has been reorganized to support gui plugins.
- Created a flexible framework for creating &amp; running regression tests.
- app.forceShutdown now works when called from plugins.
- Created app.unitTestDict for communication between tests and between tests and code.

- An example wx_gui plugin is partly functional.

	Warning: Use the __wx_gui.py plugin with extreme caution until further notice:
	bugs in this plugin could cause body text to be cleared improperly when changing nodes.
</t>
<t tx="edream.121403161017.2">- use_gnx specifies whether .leo files use integers as indices:
  
	use_gnx = 0 makes .leo files compatible with previous versions of Leo.
	use_gnx = 1 makes .leo files cvs-friendly

- config_encoding specifies the encoding of leoConfig.txt.</t>
<t tx="edream.121403161340">- Import Derived File command now uses a file dialog.

	This is much more natural than using @file nodes.

- Leo now loads all plugins listed in pluginsManager.text.

	It is no longer necessary to edit plugin files to enable or disable plugins.</t>
<t tx="edream.121403162622">New in 4.1: The plugins test suite creates a new convention: if a plugin has a
function at the outer (module) level called unitTest, Leo will call that
function when doing unit testing for plugins. So it would be good if writers of
plugins would create such a unitTest funcion. The unitTest function should run
some tests. All unitTest needs to do to indicate failure is throw an exception
or cause an assert to fail. Leo's plugins test suite takes care of the rest.</t>
<t tx="edream.121403165221">- Corrected counts when replacing tabs/blanks.
- Don't write tnodeList when executing scripts.
- Fixed long-standing clone-drag bug.
- Fixed inconsistency between how 4.x and 3.x handle @others.
  The code now works as it did in all 3.x versions, namely
  @others does not terminate doc parts.
- Leo now properly sets clone marks when when cutting and pasting nodes.
- Only double-quotes delimit strings in html files.
  This bug prevented Leo from untangling some valid html/xml files.
- Leo now puts class docstrings in class nodes when importing .py files.
- Fixed several reorg bugs.</t>
<t tx="edream.121503192354.1">&lt;humanreadablestuff&gt;
&lt;&lt; thanks,&gt;&gt;
@doc
for bringing Literate Programming to the unwashed masses, and helping me enjoy writing
@code
again
&lt;/humanreadablestuff&gt;</t>
<t tx="ekr.20031219090156">Wow, wow, and wow. I just started using Leo about a month ago (I had looked
at it about a year ago but didn't quite "get it" yet). Now I finally understand
how to use clones and I realized that this is exactly how I want to organize
my information. Multiple views on my data, fully interlinkable just like my
thoughts.

The excellent ideas which are already implemented and the new ideas mentioned
above make this a very exciting time for Leo. Thanks for a great tool, and I'm
sure I'm not alone when I say I look forward to great things with Leo!</t>
<t tx="ekr.20040118085921">I *LIKE* it; After coding a larger-than-normal DOS (sometimes one doesn't have
the luxury of choice:) batchfile with Leo (my first Leo project, auto-emailing
based on filename substring... trivial but ugly in DOS, since no string/email
functions), I was amazed at how different the experience was compared to flat-filing.
It was almost Forth-like in the way that it was possible to work top-down or
bottom-up at will (I believe this is the key to its strength, btw).

Also, I think that Leo has intrinsic qualities that make it work better than
other things.  For example:
* the ideal comprehensible code/module size (at least for small-brains like
mine) seems to be roughly what fits (with a largish font and default-sized window
split) in the bottom pane; It is probably a good chunk size for non-programming
tasks, also.
*  @ documentation is much cleaner than inline comments in a text file.
* the fact that it is Python-based gives a feeling of freedom 
* The simplicity of text-only. For example,the MS-Word97 outliner is great,
but how much time is wasted trying to un-screwup your text formatting. At first,
I thought that I wanted rich-text, html-ish panes (like TreePad Plus, for example)
for non-programming use of Leo; but on second thought,  it would be probably
be a distraction ~80% of the time.

Thanks for sharing! I hope to be able to contribute something (besides commentary),
once I get more comfortable using Python.

Thanks again,
Tarvin Rhodes
</t>
<t tx="ekr.20040129074732">I'm a newbie to Leo( a couple of weeks ) and I feel addicted to programming again...in fact it has resurrected a dead project of mine :) The Outline has proven most liberating in terms of testing ideas out...Thanks a lot!  
</t>
<t tx="ekr.20040131040356">Leo 4.1 Release Candidate 4              February 3, 2004

This release fixes numerous bugs reported since 4.1 rc3 and makes several other
minor improvements, including several nifty new plugins.

The highlights of Leo 4.1:

- Leo runs in batch mode when invoked with --script aScriptFile.py
- Leo supports Unicode characters (e.g. Chinese) in path and file names.
- @directives and section references are now valid when executing scripts.
- @ignored and orphan nodes now valid in @file-nosent trees.
- Script-based find/change commands.
- Check Outline command.
- Hoist &amp; DeHoist commands.
- A new gui-agnostic architecture: useful for batch mode and unit tests.
- Several new configuration settings.
- Many new unit tests.
- Excellent new plugins.
- A host of bug fixes.</t>
<t tx="ekr.20040131040356.1"></t>
<t tx="ekr.20040131040356.2">See previous release notes for more details:

4.1 rc3:

- Corrected counts when replacing tabs/blanks.
- Don't write tnodeList when executing scripts.
- Fixed long-standing clone-drag bug.
- Fixed inconsistency between how 4.x and 3.x handle @others.
  The code now works as it did in all 3.x versions, namely
  @others does not terminate doc parts.
- Leo now properly sets clone marks when when cutting and pasting nodes.
- Only double-quotes delimit strings in html files.
  This bug prevented Leo from untangling some valid html/xml files.
- Leo now puts class docstrings in class nodes when importing .py files.
- Fixed several reorg bugs.

4.1 rc2, rc1, betas, alphas:

- Fixed several minor problems with the Extract Section and Import commands.
- Fixed problem that prevent the Find panel from working on the Mac.
- Improved @url handling so that @url file:\\path\x.leo works properly.
- Improved support for @lineending platform.
- Leo honors outline/body pane ratio when opening .leo files.
- Leo now ensures that newly-opened windows fit entirely on the screen.
- Fixed a crasher when Undoing a Change All command when searching headlines.
- Fixed other bugs resulting from the 4.1 reorg:
- Fixed problem loading plugins on Linux.
- Fixed crashers in the Extract Section and Extract commands.
- Fixed a crasher when writing a file containing an undefined section.
- Removed duplicate bindings in popup menus.
- Made sure to show Leo's windows in wx gui plugin.
- More than one section reference may now appear on the same line.
- Use "utf-8" encoding for filenames under MacOS (Darwin)
- Allow command or cmnd prefix for menu shortcuts under Darwin.
- Fixed a LaTeX coloring bug
</t>
<t tx="ekr.20040131040356.3">- The 4.1 code base has been reorganized to support gui plugins.
- Created a flexible framework for creating &amp; running regression tests.
- app.forceShutdown now works when called from plugins.
- Created app.unitTestDict for communication between tests and between tests and code.

- An example wx_gui plugin is partly functional.

	Warning: Use the __wx_gui.py plugin with extreme caution until further notice:
	bugs in this plugin could cause body text to be cleared improperly when changing nodes.
</t>
<t tx="ekr.20040131040356.4">- use_gnx specifies whether .leo files use integers as indices:
  
	use_gnx = 0 makes .leo files compatible with previous versions of Leo.
	use_gnx = 1 makes .leo files cvs-friendly

- config_encoding specifies the encoding of leoConfig.txt.</t>
<t tx="ekr.20040131040356.5">- Import Derived File command now uses a file dialog.

	This is much more natural than using @file nodes.

- Leo now loads all plugins listed in pluginsManager.text.

	It is no longer necessary to edit plugin files to enable or disable plugins.</t>
<t tx="ekr.20040131040544.2"></t>
<t tx="ekr.20040131040544.5"></t>
<t tx="ekr.20040131040544.10">This allows plugins to draw the status area in the icon area.</t>
<t tx="ekr.20040131040544.18">The old code was concatenating strings; the new code uses list.append.</t>
<t tx="ekr.20040131040544.21">- ESC closes the Find panel.

- Hitting the Return key is now equivalent to hitting the Find button.</t>
<t tx="ekr.20040131040544.32"></t>
<t tx="ekr.20040131040544.55">Leo now reports the parent of the orphan node.</t>
<t tx="ekr.20040131040544.73">This bug happened when a move up command would cause a node to become the sibling of (a clone of) itself.  In such cases, Leo simply selects the other cloned copy of the moved node.</t>
<t tx="ekr.20040131040544.81">The bug was causing Leo not to remember the comment delimiters in the @+leo sentinel.  As a result, Leo was recognizing no sentinels and the command complained about missing @-leo sentinels.</t>
<t tx="ekr.20040131040544.146">- Leo now does a better job of checking and reporting read-only violations.

- Leo now clears the file-dirty mark only if the file was successfully saved.

</t>
<t tx="ekr.20040131040544.169"></t>
<t tx="ekr.20040131040544.178">Leo sets only ancestor @file nodes dirty (not nodes themselves) when altering outline structure, i.e., when moving, inserting, deleting, cloning and sorting nodes.</t>
<t tx="ekr.20040131040544.222">That is, when preprocessing the script (expanding section references, etc.) Leo now ensures that child nodes effectively end in a newline.  This prevents unintended concatenation of lines.</t>
<t tx="ekr.20040131040544.227">A contained a space before a tab in the leading whitespace of the line.</t>
<t tx="ekr.20040131040544.228">- These commands did not properly count the number of changed nodes.
- These commands now mark only changed nodes as dirty.</t>
<t tx="ekr.20040131040544.258"></t>
<t tx="ekr.20040131040754">Fixed crashers in:

- Insert Headline Time/Date commands.
- Change headline command.
- Write Dirty/Missing @file Nodes commands.
- Batch mode.</t>
<t tx="ekr.20040131041015"></t>
<t tx="ekr.20040131044136">- Fixed a bug that caused cut and paste operations in headlines to revert when those commands were chosen from the Edit menu.

- Extended control-v bug fix to "darwin","freebsd4","freebsd5"

- Cut and paste are now always enabled when not editing the body pane.  This isn't perfect, and is an improvement.</t>
<t tx="ekr.20040131044727">1. Fixed a bug that caused improper indentation of sections.

The bug happened in some cases when a section reference occurred following non-whitespace.

2. Leo ensures that leading whitespace is not added when writing empty lines.

This might fix the "Zope Sprint" bug: "blank" lines in the expansion of @others got leading whitespace.</t>
<t tx="ekr.20040131100557">Previously, if you hoist a node with no children and then insert a node (CTRL-I)
then the child is created as a sibling of the hoisted node and consequently is
not displayed.

Leo now creates the new node as the first child of the hoisted node. 

Also, Leo disables the Clone command when the presently selected node is the root of a hoist.</t>
<t tx="ekr.20040201061329">This creates a status area at the bottom of the Leo Window.  Plugins may write to this area using the status area convenience routines in leoTkinterFrame.py.</t>
<t tx="ekr.20040201113232">@nocolor

The Scripts node in LeoPy.leo contains a script called initScriptFind.  This script makes it easy to set up script based searches as follows:

1. Put the following code in the root of a tree that will contain your script search:

@color
# Initialize Leo's find panel using the named children of this node.
from leoGlobals import *
initScriptFind("Find script","Change script") # Second argument is optional.
# Start searching at the top.
top().selectVnode(c.rootVnode())
@nocolor

2. Put the search script in a child node called "Find script" (no quotes).

3. (Optional) Put the change script in a child node called "Change script"

4.  Execute the code above.  Leo does the following:

- Puts the body of the "Find script" into the find text of Leo's Find/Change dialog.
- Puts the body of the "Change script" into the change text of Leo's Find/Change dialog.
- Selects the Script Find radio button.
- Selects the Script Change checkbox if the change script exists.
- Selects the root of the entire outline.

Presto!  Leo is ready for a script search.</t>
<t tx="ekr.20040201114855"></t>
<t tx="ekr.20040201114855.3">This plugin uses Leo and docutils to mix program code and reST documentation.

The Python docutils package must be installed.http://docutils.sourceforge.net

If SilverCity is installed (http://silvercity.sourceforge.net) the plugin
produces HTML output that is syntax colored.

The basic approach is that any Leo node that contains program code that needs
documentation (in an ideal world it would be every node) has an associated child
node whose headline is simply '@rst', that contains reST-style documentation.
While this means that a typical program may have dozens (if not hundreds) of
these @rst nodes, it produces documentation that I think is as close as I have
ever seen to useful, easy-to-read documentation that is easy to create at the
same time as an application is being coded.

There are several interrelated aspects to this work:

- The reST plugin (renamed rst2) was hacked to manage Leo outlines that were a
combination of normal code nodes and reSt nodes.

- The plugin now recognizes a @rst directive (that has no associated file name)
in the headline of a node.

- When it encounters such a @rst Headline node, it writes the contents of the
body of the @rst node's *parent* (which generally contains program code) to the
reST output file (HTML) and then adds the reST content that is contained in the
body of the @rst documentation node to the output HTML file,

- These @rst nodes are used in @file-nosent trees and the @rst nodes have an 
@ignore directive (plus @nocolor directive and @wrap directives) so that 
when the @file is updated the application code does not contain the reST-style
documentation contained in the body of the @rst nodes. (This was the reason I
had asked you in the Leo Forum to allow @file-nosent trees to work appropriately
with @ignore nodes - Thank you for doing this right away.) There is no reason
that the reST content couldn't be written to the 
@file as documentation other than I personally believe in a volume of 
documentation (including musings, failed ideas, questions, etc.) that is 
probably best kept separate from the actual *.py files.

- When you double-click on a plain rst node (no associated filename) Leo opens
both the @rst documentation node and the parent node containing code in an
external editor *simultaneously*. I happen to use Textpad and so the code is
opened with python syntax coloring in one Textpad window and right next to it is
the reST documentation. This makes it much much easier to code and do
documentation at the same time. (Note that the plugin assumes that the python
extension is '.tp' since that is what I use with TextPad.)

So why is this a big deal?

For the first time in my experience the documentation process:

1) is completely in sync with the process of code development.

2) allows the programmer to write as much documentation as he/she wants without
the programming code becoming unreadable because of what would be considered
excessive or intrusive documentation. (This applies whether documentation is
intended for external consumption or just so a solo programmer can remember what
he/she was thinking...)

My conclusion is that Leo + reST/docutils provides the perfect platform for
optimal documentation. I have never completely understood what is meant by
Literate Programming but in my mind this is practical Literate Programming.

Frankly, I think this is all a minor miracle but maybe I've lost perspective.

Steve Zatz</t>
<t tx="ekr.20040201114855.13">Adds a quick search to the toolbar in Leo.

A search box which behaves like a web site search is added, along with a "GO"
button to do quick searches right from the main Leo window. All the current
search options are retained except that "search body text" is explicitly set -
mainly because this is by far the most common use case.

Pressing &lt;CR&gt; while editing the text automatically does a search. Repeated
searches can be done by clicking the "GO" button.

The combo box also stores a list of previous searches, which can be selected to
quickly repeat a search. When activating a previous search the original search
mode is used.

Still to do:

- incremental search
- reverse search
- persist recent searches across Leo sessions
- use INI file to set options for list size, etc.</t>
<t tx="ekr.20040201114855.29">Adds a node navigator to the toolbar. The navigator allows quick access to
marked nodes. You can either go to the marked node or hoist the marked node.</t>
<t tx="ekr.20040201114855.36">Adds row/column indicators to the toolbar at the top of Leo Windows.</t>
<t tx="ekr.20040201114855.42">A minimal http plugin for LEO, based on AsyncHttpServer.py.

Use this plugin is as follows:

1. Start Leo with the plugin enabled. You will see a purple message that says
something like: "http serving enabled on port 8080, version 0.9"

2. Start a web browser, and enter the following url: http://localhost:8080/
You will see a a "top" level page containing one link for every open .leo file.
Start clicking :-)

You can use the browser's refresh button to update the top-level view in the
browser after you have opened or closed files.</t>
<t tx="ekr.20040201114855.91">Automatically add nodes for common tasks. This can be used to generate boiler
plate code to quickly build an outline.</t>
<t tx="ekr.20040201114855.105"></t>
<t tx="ekr.20040201114855.106"></t>
<t tx="ekr.20040201114855.107">This bug happened when executing the initScriptFind script.  This bug could cause Leo not to be able to save files.</t>
<t tx="ekr.20040201114855.108">Here is a posting which might be helpful:

http://sourceforge.net/forum/message.php?msg_id=2300457

The "@first" directive is the key to output useable code in unsupported
languages.  For example, to use Leo with the Basic language:

-&gt;body of a "@file" header:
-----------------------------Snippet
@first $IFDEF LEOHEADER
@delims '
@c
$ENDIF
-----------------------------End of snippet

So this would enable a basic compiler to "jump" over the "true"
LEO-header-lines; which gives you:

-----------------------Derived file begins with:
$IFDEF LEOHEADER &lt;-conditionnal compilation directive 
#@+leo-ver=4 &lt;-these lines not compiled
#@+node:@file QParser005.INC
#@@first
#@delims ' 
'@@c
$ENDIF &lt;-... Until here!
&lt;rest of derived code file ... &gt;
-----------------------end of snippet

This changes the comment symbol to " ' " apostrophe... making comments parseable
by a BASIC (or other language.)</t>
<t tx="ekr.20040201120903">Adds a status line to the bottom of Leo windows.</t>
<t tx="ekr.20040203084228">The Change All command was looping when the find pattern was '\n'.</t>
<t tx="ekr.20040216151748">Leo 4.1 Final              February 20, 2004

Leo 4.1 Final is the culmination of four months of work. No significant bugs
have been reported since 4.1 rc4. Several people have contributed nifty plugins
recently. See leoPlugins.leo for full details.

The highlights of Leo 4.1:

- Leo runs in batch mode when invoked with --script aScriptFile.py
- Leo supports Unicode characters (e.g. Chinese) in path and file names.
- @directives and section references are now valid when executing scripts.
- @ignored and orphan nodes now valid in @file-nosent trees.
- Script-based find/change commands.
- Check Outline command.
- Hoist &amp; DeHoist commands.
- A new gui-agnostic architecture: useful for batch mode and unit tests.
- Several new configuration settings.
- Many new unit tests.
- Excellent new plugins.
- A host of bug fixes.</t>
<t tx="ekr.20040216152948"></t>
<t tx="ekr.20040216153725">Changed Undo/Redo messages:

- Insert Outline to Insert Node.
- Delete Outline to Delete Node.
- Clone to Clone Node.

This is a real code change: it affects the undo/redo logic.</t>
<t tx="ekr.20040217075627">Clone bits could be improperly set in some cases.  This bug would not have caused serious long-term problems.

Steps to reproduce:

1. Create a parent node (named 'cloned').
2. Create two children nodes (one named 'dummy' and another named 'bottom') under the parent node 'cloned'.
3. Move the 'bottom' node below the 'dummy' node.
4. Clone node 'cloned'.
5. Copy node 'dummy'.
6. Paste node 'dummy' in between 'dummy' and 'bottom'.
7. After pasting you'll see that 'bottom' is now marked as a cloned node.</t>
<t tx="ekr.20040217085036">See leoPlugins.leo for full details.</t>
<t tx="ekr.20040217085036.1">Here is the bug report I submitted to Python:

The documentation for encoding lines at

C:\Python23\Doc\Python-Docs-2.3.1\whatsnew\section-encodings.html

states:

"Encodings are declared by including a specially formatted comment in the
first or second line of the source file."

In fact, contrary to the implication, the Python 2.3 parser does not look
for lines of the form:

# -*- coding: &lt;encoding&gt; -*-

For example, Python improperly scans the following line for an encoding

#@+leo-ver=4-encoding=iso-8859-1.

and reports that iso-8859-1. (note trailing dot) is an invalid encoding!

The workaround for my app is to precede this line with the following line:

# -*- coding: iso-8859-1 -*-

This makes Python 2.3 happy.

To make myself perfectly clear: Python has absolutely no right to complain
about comment lines that do not have the form:

# -*- coding: &lt;encoding&gt; -*-</t>
<t tx="ekr.20040219100738">Leo works reliably only on MacOS X 10.3 (Panther).

For complete installation instructions see:

http://www.teti.ch/share/leo.php

Many thanks to Gaspard Bucher for these instructions.

Another set of instructions:

MacOS 10.3 comes with a near-complete version of MacPython 2.3. Instead of
installing a full MacPython 2.3, get the "MacPython 2.3 for Panther addons"
(from http://homepages.cwi.nl/~jack/macpython/), which add the package manager
and the Mac-specific Python IDE. After installing TclTkAcqua (8.4.7 BI works
fine for me), you can use the package manager to install tkinter. Then you have
everything needed for Leo, you can just download Leo and run leo.py from
wherever it happens to be, or install it to wherever you would like it to have.</t>
<t tx="ekr.20040403051340">@color

# The g.es method prints its arguments to the log pane.
import leoGlobals as g
g.es("Hello world")

# g.es prints multiple arguments separated by commas.
g.es("Hello","world")

# g.es converts non-string arguments using repr.
g.es(g.top())</t>
<t tx="ekr.20040403103655">@color
@ Iterators are defined only by the position class;  vnodes can not have iterators because vnodes may appear in multiple places in an outline.

All iterators take an optional copy keyword argument.  You should use copy=true if your script actually alters the position returned by the iterator, say by calling p.moveToThreadNext().</t>
<t tx="ekr.20040403121641.1">@ The c.allNodes_iter returns a list of all positions in the outline.

See the children of this node for more examples.
@c

# Here is how to create a list of all positions in an outline.

import leoGlobals as g
c = g.top()

nodes = [p for p in c.allNodes_iter()]
g.es("This outline contains %d nodes" % len(nodes))</t>
<t tx="ekr.20040403121641.4">@
The p.subtree_iter returns a list of all positions in p's subtree, excluding p.
The p.self_and_subtree_iter returns a list of all positions in p's subtree, including p.
@c

import leoGlobals as g
c = g.top()
p = c.currentPosition()
parent = p.parent()

g.es("inclusive subtree of %s" % parent.headString(),color="purple")
for p in parent.self_and_subtree_iter():
	g.es(p.headString())
	
g.es("exclusive subtree of %s" % parent.headString(),color="purple")
for p in parent.subtree_iter():
	g.es(p.headString())</t>
<t tx="ekr.20040403121641.7">@ The p.children_iter returns a list of all children of position p.
@c

import leoGlobals as g
c = g.top()
p = c.currentPosition()
parent = p.parent()

g.es("children of %s" % parent.headString(),color="purple")
for p in parent.children_iter():
	g.es(p.headString())</t>
<t tx="ekr.20040403121641.10">@
The p.parents_iter returns a list of all parents of position p, excluding p.
The p.self_and_parents_iter returns a list of all parents of position p, including p.
@c

import leoGlobals as g
c = g.top()
current = c.currentPosition()

print '-'*40

g.es("inclusive parents of %s" % current.headString(),color="purple")
for p in current.self_and_parents_iter():
	g.es(p.headString())

g.es("exclusive of %s" % current.headString(),color="purple")
for p in current.parents_iter():
	g.es(p.headString())</t>
<t tx="ekr.20040403121641.13">@
The p.siblings_iter returns a list of all siblings of position p.
The p.following_siblings_iter returns a list of all siblings that follow position p
@c

import leoGlobals as g
c = g.top()
current = c.currentPosition()

g.es("all siblings of %s" % current.headString(),color="purple")
for p in current.self_and_siblings_iter():
	g.es(p.headString())

g.es("following siblings of %s" % current.headString(),color="purple")
for p in current.following_siblings_iter():
	g.es(p.headString())</t>
<t tx="ekr.20040403123631.1"># Here is one way to count the nodes of an outline.

import leoGlobals as g
c = g.top()

count = 0
for p in c.allNodes_iter():
	count += 1
g.es("This outline contains %d nodes" % count)</t>
<t tx="ekr.20040403123631.2"># Here is one way to count the distinct vnodes of an outline.

import leoGlobals as g
c = g.top()

positions = 0 ; tnodes = {}
for p in c.allNodes_iter():
	positions += 1
	if not tnodes.get(p.v.t):
		tnodes[p.v.t] = p.v.t

g.es("%8s" % "positions",positions)
g.es("%8s" % "vnodes",len(tnodes.keys()))</t>
<t tx="ekr.20040403171740">####################################
Chapter 7: Scripting Leo with Python
####################################

|prev| |leo| |next|

.. contents::

.. _front:     http://webpages.charter.net/edreamleo/front.html
.. _chapter6:  http://webpages.charter.net/edreamleo/design.html
.. _chapter8:  http://webpages.charter.net/edreamleo/customizing.html

.. |prev| image:: arrow_lt.gif
	:target: chapter6_

.. |next| image:: arrow_rt.gif
	:target: chapter8_

.. |leo|   image:: leo.gif
	:target: front_</t>
<t tx="ekr.20040403173920.3"></t>
<t tx="ekr.20040403173920.5"></t>
<t tx="ekr.20040403173920.6"></t>
<t tx="ekr.20040403173920.9"></t>
<t tx="ekr.20040403173920.10"></t>
<t tx="ekr.20040403173920.13"></t>
<t tx="ekr.20040403173920.14"></t>
<t tx="ekr.20040403173920.15"></t>
<t tx="ekr.20040403173920.16"></t>
<t tx="ekr.20040403173920.17"></t>
<t tx="ekr.20040403173920.18"></t>
<t tx="ekr.20040403173920.19"></t>
<t tx="ekr.20040403173920.21"></t>
<t tx="ekr.20040403173920.22">@ignore
@wrap

The findall function returns a list of tuples (v,pos) describing matches in c's entire tree.

.. code-block:: Python

    import leoGlobals as g
    import leoFindScript
    c = g.top()

    pattern="import leoGlobals as g"
    result = leoFindScript.findAll(c,pattern,bodyFlag=1)
    
    g.es("%-3d instances of: '%s'...\n" % (len(result),pattern),color="purple")
    
    for v,pos in result:
        body = v.bodyString()
        g.es('\n%-4d %s' % (pos,v.headString()))
        g.es(g.get_line_after(body,pos))</t>
<t tx="ekr.20040403173920.23">@ignore
@wrap

The reFindall function returns a list of tuples (v,mo,pos),
where mo is a "Match Object".
The reFlags argument are flags to re.search().

.. code-block:: Python

    import leoGlobals as g
    import leoFindScript
    c = g.top()

    pattern="from .* import"
    result = leoFindScript.reFindAll(c,pattern,bodyFlag=1,reFlags=None)

    g.es("%-3d instances of: '%s'...\n" % (len(result),pattern),color="purple")
    for v,mo,pos in result:
        body = v.bodyString()
        g.es('\n%-4d %s' % (pos,v.headString()))
        g.es(g.get_line_after(body,pos))</t>
<t tx="ekr.20040403173920.24"></t>
<t tx="ekr.20040403173920.25"></t>
<t tx="ekr.20040403173920.26"></t>
<t tx="ekr.20040403173920.27"></t>
<t tx="ekr.20040403173920.28"></t>
<t tx="ekr.20040403175011"></t>
<t tx="ekr.20040403175011.1">@ignore
@nocolor
@wrap

The g.top() function returns the Commands object of the top Leo window:

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    g.es(c)
    g.es(c.rootPosition())</t>
<t tx="ekr.20040403175157.1"></t>
<t tx="ekr.20040403175157.2">@ignore
@wrap

The windowlist attribute of the application instance contains the list of the
frames of all open windows. The commands ivar of the frame gives the commander
for that frame. Execute this code now with the Execute Script command.

.. code-block:: Python

    import leoGlobals as g
    windows = g.app.windowList # get the list of all open frames.
    g.es("windows...")
    for f in windows:
        c = f.c # c is f's commander
        g.es(f)
        g.es(f.shortFileName())
        g.es(c)
        g.es(c.rootPosition())</t>
<t tx="ekr.20040403175257">@ignore
@wrap

The g.es method prints its arguments to the log pane.

.. code-block:: Python

    import leoGlobals as g
    g.es("Hello world")

g.es converts non-string arguments using repr.

.. code-block:: Python

    g.es("Hello","world")

g.es prints multiple arguments separated by commas.

.. code-block:: Python

    g.es(g.top())</t>
<t tx="ekr.20040403180217">@ignore
@wrap

Here is how to access the data of a Leo window.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    p = c.currentPosition() # get the current position.
    g.es(p)
    g.es("head:",p.headString())
    g.es("body:",p.bodyString())

The following show how to access data at a given position.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    p = c.currentPosition()
    body = p.bodyString()
    head = p.headString()
    p.setBodyStringOrPane(body)     # set body text of p to body.
    p.setHeadStringOrHeadline(head) # set headline text of p to head.

BTW, these methods will work whether or not p is the current position.</t>
<t tx="ekr.20040403183229"></t>
<t tx="ekr.20040403183229.1">@ignore
@nocolor
@wrap

This chapter describes only the most useful functions, classes and methods in leo.py.  However, keep in mind the following: **Your scripts have complete access to all of Leo's source code.**  Therefore, the most complete documentation for scripting is Leo's source code itself, that is, the file LeoPy.leo.  In particular, see the node called "Overview of the Code", the first child of the node called "Code".

Leo's source code is a collection of classes, along with utility functions in leoGlobals.py.  The preferred way of accessing the functions and data in leoGlobals.py is as follows.

.. code-block:: Python

    import leoGlobals as g

After these imports you may call function x in leoGlobals with g.x()

**g.app** refers to the **application object** representing the entire Leo application.
The ivars (instance variables) of g.app represent Leo's global variables.

A **commander** (an instance of the Commands class) represents the operations
that can be performed on a *particular* window.
Each open Leo window has its own commander.
**g.top()** returns the commander of the top window.
By convention, any variable named c refers to a commander.

A **frame** (an instance of the leoFrame class) contains all the internal data needed to manage a Leo window.  Given a commander c, c.frame refers to the commanders frame.
Given a frame f, f.c refers to the frame's commander.

A **vnode** represents an outline node.
You can use vnode methods to get and set headline text, body text and properties such as whether the node is dirty or marked.
By convention, any variable named v,v1 or v2 refers to a vnode.

A **tnode** represents the actual data in a vnode, including headline and body text.  Vnodes that are joined to each other have the same tnode.  For any vnode v, v.t is v's tnode.

Leo updates **joined vnodes** together.  Cloned nodes are joined, as are corresponding nodes in the subtrees of cloned nodes.

*New in Leo 4.2*: Cloned vnodes use a *single* subtree to represent their common descendant trees.
A **shared subtree** is a tree of vnodes shared by multiple cloned nodes.  Therefore, all joined nodes are represented by the *same* vnode.  Thus, in version 4.2 vnodes no longer represent a unique location on the screen, nor do vnodes represent a particular position in a traversal of a tree.

*New in Leo 4.2*: A **position** object represents the location of a particular node in a tree traversal or on the screen.  By convention, any variable named p or p1 or p2 refers to a position.  For any position p, p.v is the vnode at that position and p.v.t is the tnode at that position.

Leo's code uses position objects very much like vnodes were used in pre-4.2 versions of Leo.  In particular:

- In Leo 4.2 the c.currentVnode and c.rootVnode methods return *positions* not vnodes.
- position objects support all the common vnode methods that were used in scripts prior to Leo 4.2.

As a result, most scripts written before Leo 4.2 will continue to work in Leo 4.2.
*Aside*: the preferred way of get the position of the root node and the presently select node is c.rootPosition and c.currentPosition respectively.  The c.currentVnode and c.rootVnode methods exist only for compatibility with old code.
</t>
<t tx="ekr.20040403183718">@ignore
@wrap

leoGlobal.py defines 6 convenience methods for redirecting stdout and stderr.

.. code-block:: Python

    g.redirectStderr() # Redirect stderr to the current log pane.
    g.redirectStdout() # Redirect stdout to the current log pane.
    g.restoreStderr()  # Restores stderr so it prints to the console window.
    g.restoreStdout()  # Restores stdout so it prints to the console window.
    g.stdErrIsRedirected() # Returns True if the stderr stream is redirected to the log pane.
    g.stdOutIsRedirected() # Returns True if the stdout stream is redirected to the log pane.

Calls need _not_ be paired. Redundant calls are ignored and the last call made
controls where output for each stream goes.

Note: you must execute Leo in a console window to see non-redirected output from the print statement.

.. code-block:: Python

    import leoGlobals as g
    print "stdout isRedirected:", g.stdOutIsRedirected()
    print "stderr isRedirected:", g.stdErrIsRedirected()

    g.redirectStderr()
    print "stdout isRedirected:", g.stdOutIsRedirected()
    print "stderr isRedirected:", g.stdErrIsRedirected()

    g.redirectStdout()
    print "stdout isRedirected:", g.stdOutIsRedirected()
    print "stderr isRedirected:", g.stdErrIsRedirected()

    g.restoreStderr()
    print "stdout isRedirected:", g.stdOutIsRedirected()
    print "stderr isRedirected:", g.stdErrIsRedirected()

    g.restoreStdout()
    print "stdout isRedirected:", g.stdOutIsRedirected()
    print "stderr isRedirected:", g.stdErrIsRedirected()</t>
<t tx="ekr.20040403183934">@ignore
@wrap

*New in Leo 4.2*.  The preferred way to traverse an outline is with an iterator.

Iterators are defined only by the position class;
vnodes can not have iterators because vnodes may appear in multiple places in an outline.

All iterators take an optional copy keyword argument.  You should use copy=True if your script actually alters the position returned by the iterator, say by calling p.moveToThreadNext().</t>
<t tx="ekr.20040403183934.1">@ignore
@wrap

Leo's commands use c.beginUpdate() and c.endUpdate() to reduce flicker.
c.beginUpdate suppresses all drawing in the outline pane until the matching c.endUpdate is seen.
These methods can be nested; each c.beginUpdate() must have a corresponding c.endUpdate.

c.endUpdate takes an optional parameter.  If this parameter is False, no redrawing is done.  This can sometimes be useful; inner code can tell other code whether redrawing is actually required.

c.redraw() forces an update of the entire screen.
c.endUpdate() calls c.redraw() as needed.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()

    # Force a screen redraw
    c.redraw()

    # Typical way to redraw the screen:
    c.beginUpdate()
    ...code that alters the screen...
    c.endUpdate()

    # Typical way to conditionally redraw the screen:
    c.beginUpdate()
    ...code sets flag if the screen needs redrawing.
    flag = True
    c.endUpdate(flag)s
    </t>
<t tx="ekr.20040403183934.2">@ignore
@wrap

Leo dispatches commands using c.doCommand,
which calls the "command1" and "command2" hook routines for the given label.
c.doCommand catches all exceptions thrown by the command.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    c.doCommand(c.markHeadline,label="markheadline")

You can also call command handlers directly so that hooks will not be called.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    c.markHeadline()</t>
<t tx="ekr.20040403183934.3">@ignore
@wrap

Each commander maintains its own preferences.  Your scripts can get the following ivars.

.. code-block:: Python

    c.output_doc_flag
    c.page_width
    c.tab_width
    c.tangle_batch_flag
    c.tangle_directory
    c.target_language
    c.untangle_batch_flag
    c.use_header_flag

leoPrefs.leoPrefs.ivars is a list of the _names_ of these ivars.

Your script may get the values of these ivars as follows.

.. code-block:: Python

    import leoPrefs
    import leoGlobals as g
    c = g.top()
    g.es("Prefs ivars...\n",color="purple")
    for ivar in leoPrefs.leoPrefs.ivars:
        exec("val=c."+ivar) # do val = c.ivar
        g.es("c."+ivar,val)

Your script may update the prefs panel as follows.

.. code-block:: Python

    import leoPrefs
    import leoGlobals as g
    c = g.top()
    c.tab_width = 4 # Change this and see what happens.
    if c.frame.prefsPanel:
        c.frame.prefsPanel.init(c)
        c.frame.prefsPanel.setWidgets()

If your script sets c.tab_width your script may call f.setTabWidth to redraw the screen.

.. code-block:: Python

    c.frame.setTabWidth(c.tab_width)</t>
<t tx="ekr.20040403184306.1">@ignore
@wrap

The file leoFindScript.py contains functions for finding and changing text from within scripts. The children of this node show two examples of using the functions.  See the @file leoFindScript.py tree in LeoPy.leo for full details.</t>
<t tx="ekr.20040403184306.2">@ignore
@wrap

**New in version 4.1**: On startup, Leo looks for two arguments of the form --script scriptFile.
If found, Leo enters batch mode.

In batch mode Leo does not show any windows.
Leo assumes the scriptFile contains a Python script and executes the contents of that file using Leo's Execute Script command.
By default, Leo sends all output to Leo's log pane to the console window.  Scripts in the scriptFile may disable or enable this output by calling app.log.disable() or app.log.enable()

Scripts in the scriptFile may execute any of Leo's commands except the Edit Body and Edit Headline commands.
Those commands require interaction with the user.

For example, the following batch script reads a Leo file and prints all the headlines in that file.

.. code-block:: Python

    import leoGlobals as g
    
    path = r"c:\prog\leoCVS\leo\test\test.leo"
    
    g.app.log.disable() # disable reading messages while opening the file
    flag,newFrame = g.openWithFileName(path,None)
    g.app.log.enable() # re-enable the log.
    
    for p in newFrame.c.allNodes_iter():
        g.es(g.toEncodedString(p.headString(),"utf-8"))
</t>
<t tx="ekr.20040403184306.3">@ignore
@wrap

leoGlobals.py contains many "utility" functions and other names.  The following script prints all the names defined in leoGlobals.py.

.. code-block:: Python

    import leoGlobals as g
    
    g.es("Names defined in leoGlobals.py",color="purple")
    names = g.__dict__.keys()
    names.sort()
    for name in names:
        g.es(name)</t>
<t tx="ekr.20040403184306.4">@ignore

Most scripts will use methods of the position class to access information in an outline.
The following section summarizes the most useful methods that your scripts can use.
For a complete list, see the @file leoNodes.py tree of LeoPy.leo.
</t>
<t tx="ekr.20040403185643">@ignore
@wrap

The c.allNodes_iter iterator returns a list of all positions in the outline.
This script makes a list of all the nodes in an outline.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    nodes = [p for p in c.allNodes_iter()]
    g.es("This outline contains %d nodes" % len(nodes))

Here is one way to count the nodes of an outline.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    count = 0
    for p in c.allNodes_iter():
        count += 1
    g.es("This outline contains %d nodes" % count)

Here is one way to count the *distinct* vnodes of an outline.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    positions = 0 ; tnodes = {}
    for p in c.allNodes_iter():
        positions += 1
        if not tnodes.get(p.v.t):
            tnodes[p.v.t] = p.v.t
    g.es("%8s" % "positions",positions)
    g.es("%8s" % "vnodes",len(tnodes.keys()))</t>
<t tx="ekr.20040403185803">@ignore
@wrap

The p.children_iter iterator returns a list of all children of position p.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    p = c.currentPosition()
    parent = p.parent()
    g.es("children of %s" % parent.headString(),color="purple")
    for p in parent.children_iter():
        g.es(p.headString())</t>
<t tx="ekr.20040403185803.1">@ignore
@wrap

The p.parents_iter iterator returns a list of all parents of position p, excluding p.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    current = c.currentPosition()
    g.es("inclusive parents of %s" % current.headString(),color="purple")
    for p in current.self_and_parents_iter():
        g.es(p.headString())

The p.self_and_parents_iter iterator returns a list of all parents of position p, including p.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    current = c.currentPosition()
    g.es("exclusive of %s" % current.headString(),color="purple")
    for p in current.parents_iter():
        g.es(p.headString())</t>
<t tx="ekr.20040403185803.2">@ignore
@wrap

The p.siblings_iter iterator returns a list of all siblings of position p.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    current = c.currentPosition()
    g.es("all siblings of %s" % current.headString(),color="purple")
    for p in current.self_and_siblings_iter():
        g.es(p.headString())

The p.following_siblings_iter iterator returns a list of all siblings that follow position p.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    current = c.currentPosition()
    g.es("following siblings of %s" % current.headString(),color="purple")
    for p in current.following_siblings_iter():
        g.es(p.headString())</t>
<t tx="ekr.20040403185803.3">@ignore
@wrap

The p.subtree_iter iterator returns a list of all positions in p's subtree, excluding p.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    p = c.currentPosition()
    parent = p.parent()
    g.es("inclusive subtree of %s" % parent.headString(),color="purple")
    for p in parent.self_and_subtree_iter():
        g.es(p.headString())

The p.self_and_subtree_iter iterator returns a list of all positions in p's subtree, including p.

.. code-block:: Python

    import leoGlobals as g
    c = g.top()
    p = c.currentPosition()
    parent = p.parent()
    g.es("exclusive subtree of %s" % parent.headString(),color="purple")
    for p in parent.subtree_iter():
        g.es(p.headString())</t>
<t tx="ekr.20040403191729"></t>
<t tx="ekr.20040403191729.1"></t>
<t tx="ekr.20040403192653">@ignore
@nocolor
@wrap

This section lists the most useful ivars and methods for getting information from vnodes or positions.
Returning commanders.

.. code-block:: Python

    p.c # The commander for p.
    
Returning strings.

.. code-block:: Python

    p.bodyString() # the body string of p.
    p.headString() # the headline string of p.
    
Returning ints.

.. code-block:: Python

    p.childIndex()
    p.numberOfChildren()
    p.level()
    
Returning bools representing property bits.

.. code-block:: Python

    p.hasChildren()
    p.isAncestorOf(v2) # True if v2 is a child, grandchild, etc. of p.
    p.isCloned()
    p.isDirty()
    p.isExpanded()
    p.isMarked()
    p.isVisible()
    p.isVisited()</t>
<t tx="ekr.20040403192653.1">@ignore

This section lists the most useful methods for setting data or properties of positions.

These work whether or not p is the presently selected position.

.. code-block:: Python

    p.setBodyTextOrPane(s)       # Sets the body text of p.
    p.setHeadStringOrHeadline(s) # Sets the headline text of p.

Moving nodes.

.. code-block:: Python

    p.moveAfter(v2)           # move p after v2
    p.moveToNthChildOf(v2,n)  # move p to the n'th child of v2
    p.moveToRoot()            #  make p the root position

The "visited bit" may be used by commands or scripts for any purpose.
Many commands use this bits for tree traversal, so these bits do not persist.

.. code-block:: Python

    c.clearAllVisited() # Clears all visited bits in c's tree.
    p.clearVisited()
    p.setVisited()</t>
<t tx="ekr.20040411074926">There is a trick that makes it very easy to develop Leo using Leo itself.  The trick is to create a workflow that separates editing from testing.

Putting test code in LeoPy.leo would waste a lot of time.  To run tests you would have to exit Leo and reload LeoPy. A much quicker way is to put all test code in a test.leo file.  So to change and test code, do the following:

1. Save LeoPy.leo but do NOT exit Leo. 

2. Quit the copy of Leo running test.leo, then reload test.leo.

3. Run test scripts from test.leo.

That's all. Python will recompile any changed .py files in the new copy of Leo.

BTW, I create a batch file called t.bat that runs test.leo, so to the "edit-reload-test" cycle is just:

1. Control-S (in LeoPy.leo: saves the .leo file)
2. t         (in a console window: runs test.leo, compiling all changed .py files as a side effect)
3. Control-E (in test.leo: runs the test script)

The benefits of the new workflow:

- test.leo loads  _much_ more quickly than LeoPy.leo does.  This new approach can increase the speed of the edit-reload-test cycle by more than a factor of 10.  Hitting Control-S, t, Control-E takes about 5 seconds.

- LeoPy.leo runs with the _old_ code, so it is much easier to fix syntax errors or exceptions in the _new_ code: just fix the problem and save LeoPy.leo _without_ closing LeoPy.leo., then restart test.leo. Tests are run on new code; editing is done on old, stable code.

- test.leo is the perfect place to develop test.  I can create and organize those tests and when I am done, test.leo is a log of my work.</t>
<t tx="ekr.20040411151245"></t>
<t tx="ekr.20040411151245.1">@ignore
@nocolor
@wrap

Iterators exist only in the position class:

.. code-block:: Python

	c.allNodes_iter            # returns all positions in c's outline.
	p.children_iter            # returns all children of p.
	p.parents_iter             # returns all parents of p.
	p.self_and_parents_iter    # returns p and all parents of p.
	p.siblings_iter            # returns all siblings of p, including p.
	p.following_siblings_iter  # returns all siblings following p.
	p.subtree_iter             # returns all positions in p's subtree, excluding p.
	p.self_and_subtree_iter    # returns all positions in p's subtree, including p.</t>
<t tx="ekr.20040414161647">@nocolor
@ignore

Double-click the @rst x.html nodes to generate the files</t>
<t tx="ekr.20040414162124">###################
Leo's Users Guide
###################

|leo| |next|

.. _front:                                     http://webpages.charter.net/edreamleo/front.html
.. _Front Matter:                              http://webpages.charter.net/edreamleo/frontMatter.html
.. _FAQ:                                       http://webpages.charter.net/edreamleo/FAQ.html
.. _Chapter 1\: Introducing Leo:               http://webpages.charter.net/edreamleo/intro.html
.. _Chapter 2\: Installing Leo:                http://webpages.charter.net/edreamleo/Install.html
.. _Chapter 3\: Using Leo's Outlines:          http://webpages.charter.net/edreamleo/outlines.html
.. _Chapter 4\: Writing Programs in Leo:       http://webpages.charter.net/edreamleo/directives.html
.. _Chapter 5\: Using Leo's Commands:          http://webpages.charter.net/edreamleo/commands.html
.. _Chapter 6\: Leo and Literate Programming:  http://webpages.charter.net/edreamleo/design.html
.. _Chapter 7\: Scripting Leo with Python:     http://webpages.charter.net/edreamleo/scripting.html
.. _Chapter 8\: Customizing Leo:               http://webpages.charter.net/edreamleo/customizing.html
.. _Chapter 9\: History of Leo:                http://webpages.charter.net/edreamleo/history.html
.. _Chapter 10\: Theory of Operation:          http://webpages.charter.net/edreamleo/theory.html
.. _Appendices:                                http://webpages.charter.net/edreamleo/appendices.html

.. |leo|  image:: leo.gif
	:target: front_

.. |next| image:: arrow_rt.gif
	:target: `front Matter`_
</t>
<t tx="ekr.20040414163815"></t>
<t tx="ekr.20040414163815.1">@ignore

- `Front Matter`_
- FAQ_
- `Chapter 1: Introducing Leo`_
- `Chapter 2: Installing Leo`_
- `Chapter 3: Using Leo's Outlines`_
- `Chapter 4: Writing Programs in Leo`_
- `Chapter 5: Using Leo's Commands`_
- `Chapter 6: Leo and Literate Programming`_
- `Chapter 7: Scripting Leo with Python`_
- `Chapter 8: Customizing Leo`_
- `Chapter 9: History of Leo`_
- `Chapter 10: Theory of Operation`_
- `Appendices`_

------------

|leo| |next|
</t>
<t tx="ekr.20040414172212">############
Front Matter
############

|prev| |leo| |next|

.. contents::

.. _front:   http://webpages.charter.net/edreamleo/front.html
.. _toc:     http://webpages.charter.net/edreamleo/leo_TOC.html
.. _FAQ:     http://webpages.charter.net/edreamleo/FAQ.html

.. |leo|  image:: leo.gif
	:target: front_

.. |prev| image:: arrow_lt.gif
	:target: toc_

.. |next| image:: arrow_rt.gif
	:target: FAQ_</t>
<t tx="ekr.20040414172218.2"></t>
<t tx="ekr.20040414172218.4"></t>
<t tx="ekr.20040414172218.5"></t>
<t tx="ekr.20040414172336">@ignore

Leo has thousands of users. They use Leo to create programs in all kinds of languages and for all kinds of projects.  Leo's users write programs in assembly language, C and C++, Java, Python Tk, PHP, XML and XSLT and many more.  They use Leo to build and maintain web sites and to manage large amounts of other data.  Managers use Leo to organize projects and to communicate general ideas to programmers.

I would never again willingly program without Leo; many of Leo's users say the same.
What makes Leo so special?  The general answer is that Leo creates a new way of programming, a new way of organizing data, and a new way of managing projects.  One can speak of good or bad style in using Leo.  That there could *be* such a thing as proper "Leonine" style shows that Leo does, in fact, create a rich new environment for design.
</t>
<t tx="ekr.20040414172617">@ignore

Leo owes much of its visual design to MORE, possibly the most elegant computer program ever written. Leo's clone nodes are inspired by MORE.

The following people have made generous donations to the Leo project:
Robert Low, Nic Cave-Lynch.

The following people reported bugs, answered questions, and made suggestions for improving Leo: Alex Abacus, Shakeeb Alireze, Bruce Arnold, Chris Barker, Eric Brown, Darius Clarke, Bill Drissel, Wenshan Du, Allen Edwards, Chris Elliot, Mark Engleberg, Dethe Elza, Stephen Ferg, Tom Fetherston, Tomaz Ficko, Niklas Frykholm, Fred Gansevles, Jonathan M. Gilligan, Thomas Guettler, Zak Greant, Thomas Guettler, Romain Guy, Dave Hein, Tiago Castro Henriques, Gary Herron, Steve Holden, Klass Holwerda, Matthias Huening, Robert Hustead, John Jacob, Christopher P. Jobling, Eric S. Johansson, Garold Johnson, James Kerwin, Nicola Larosa, David LeBlanc, Chris Liechti, Steve Litt, Martin v. Loewis, Robert Low, Fredrik Lundh, Alex Martelli,  Marcus A. Martin, Gidion May, David McNab, Chad Netzer, Naud Olivier, Joe Orr, Marc-Antoine Parent, Paul Paterson, Davide Salomoni, Sean Shaleh Perry, Tim Peters, Scott Powell, Bruce Rafnel, Walter H. Rauser, David Speed Ream, Rich Ries, Aharon Robbins, Guido van Rossum, David Rowe, Steven Schaefer, Wolfram Schwenzer, Gil Shwartz, Paul Snively, Phil Straus, Jurjen Stellingwerff,  Jeffrey Thompson, Gabriel Valiente, Tom van Vleck, Jim Vickroy, Tony Vignaux, Ying-Chao Wang, Cliff Wells, Dan Wharton, Wim Wijnders, Vadim Zeitlin.
</t>
<t tx="ekr.20040414172617.1">@ignore

All parts of Leo are distributed under the following copyright.  This is intended to be the same as the Python license, namely that Leo is absolutely free, even for commercial use, including resale.  There is no GNU-like "copyleft" restriction.  This license is compatible with the GPL.
	
Copyright 1997-2004 by Edward K. Ream.  All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Edward K. Ream or Leo may not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission from Edward K. Ream.</t>
<t tx="ekr.20040414174439"></t>
<t tx="ekr.20040414174439.1">@ignore

**EDWARD K. REAM (REAM) SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESSED OR IMPLIED, WITH RESPECT TO THIS COMPUTER SOFTWARE, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL REAM BE LIABLE FOR ANY LOSS OF PROFIT OR ANY COMMERCIAL DAMAGE, INCLUDING BUT NOT LIMITED TO SPECIAL, INCIDENTAL, CONSEQUENTIAL OR OTHER DAMAGES.**

----------------

|prev| |leo| |next|</t>
<t tx="ekr.20040416070800">More specifically, there are several reasons why Leo "works". First, and most importantly, outlines clarify and make explicit the relationships between parts of a project, regardless of whether those parts are computer programs, pages in a web site, pages in a document or tasks of a project.   Leo excels in handling complex projects: it shows you the big picture at all times, while providing unlimited places to hide details.  This aspect of Leo quickly becomes completely addicting.   

Second, a single outline can contain multiple kinds of data: programs, documentation, project management tasks, test data, whatever.  This means, for example, that the relationships between a program, its documentation and its tests suites can be shown directly within the same outline.  Clones provide a way of relating and organizing all these kinds of data, and clones can create multiple views of these data within the *same* outline.

Third, Leo's users can use plugins to add literally any conceivable feature to Leo.  Leo's plugins provide excellent test beds for experimentation and development.  Several significant improvements to Leo started out as started out as plugins and later migrated into Leo's core.  In fact, Leo's core is "Gui-agnostic".  The code that draws the screen is separated from the rest of Leo. The present version of Leo users Tk/Tkinter to draw the screen.  Leo presently supports batch mode operation using a "Null-gui" module in Leo's core.  A wxWindows plugin is in development, and a Swing/SWT plugin would be possible using Jython.

Fourth, Python programs have full access to the outline structure and data contained within the outline itself.  This has great theoretical and practical consequences.  From a theoretical point of view, computer programs are powerful because there is no inherent distinction between code and data; a computer program is simply data that is passed to the hardware and interpreted by the central processing unit as instructions.  In other words, computers *unify* code and data.  Code *is* data, and data *is* code.

Leo extends the unification of code and data by allowing outline structure to be "first-class" data and "first-class" code:

- Outlines organize the code and data within them.
- Leo's markup language (noweb) understands and uses outline structure.
- Leo's Execute script command understands outline structure, section references and Leo's directives.
- Scripts have full access to the outline structure of the outlines in which the are embedded.

These last two points complete the unification of code, data and outline structure.
The outline structure *is* data, scripts are data *within* this structure, and scripts may *use* this structure to access their *own* data.
The unification of code, data and outline structure is much more than a theoretical curiosity.
It has great practical significance.
For example, test.leo contains the following kinds of nodes:

- The @file leoTest.py node defines all of Leo's test classes used for unit testing.
- The "Unit Tests" node contains the actual unit testing scripts.
- The subnodes of the "Unit Tests" node contain both scripts and *data for those scripts*.

The individual scripts use functions in leoGlobals.py to access the data in child nodes of the nodes that contain the scripts.  (leoGlobals.py contain several utility functions that find nodes within an outline.)  So the outline contains both the script and its data, and moreover, *scripts can access data organized by the same outline that contains the script itself.*  The possibilities are endless.  For example, some test scripts create, test and then destroy subtrees of the same outline that contains those scripts!</t>
<t tx="ekr.20040416070800.1">Inventing and reinventing Leo has been the happiest and most creative part of my professional life.  Work on Leo accelerated significantly when a community of Leo's users became established on SourceForge.  For that I am truly grateful.  Suggestions (and plugins!) from users continue to drive Leo in excellent new directions.  Leo has come a long way since the early prototypes more than 9 years ago.  But in all that time, Leo's look and feel have remained almost completely unchanged--there has been no need to do so.

Leo grew out of my attempts to understand and use Donald Knuth's CWEB system of "literate programming".  Leo greatly simplifies and extends Knuth's original idea.  Leo shows how to make literate program truly useful.  Indeed, I had great difficulty the original CWEB. The design and organization of my own literate programs were a mystery to me. I couldn't keep the parts of a literate program clear in my mind.  I easily became confused about what I had done or what remained to do.  It was too difficult to remember the names of sections or where I had defined functions and variables.

I started using the MORE outlining program to organize literate programs on March 5, 1996.  I had been lead to do this by the (gradual!) realization that webs are "outlines in disguise".  Within an hour of writing code in MORE, I knew that using outlines to organize literate programs would work spectacularly well.  This day changed my programming life forever.

Leo continues to evolve and grow.  Who knows what the next plugin will bring?

Edward K. Ream, April, 2004</t>
<t tx="ekr.20040416075437">The following have contributed plugins to Leo:
Felix Breuer,
Josef Dalcolmo,
Timo Honkasalo,
Andrea Galimberti,
Frédéric Momméja
Bernhard Mulder,
Paul Paterson,
Davide Salomoni,
Ed Taekema,
Steve Zatz.
</t>
<t tx="ekr.20040416080538">The following deserve special mention:
David Brock wrote TSyntaxMemo.
The late Bob Fitzwater kept me focused on design. Donald Knuth invented literate programming and the CWEB language.
Joe Orr created XSLT stylesheets for Leo; see http://www.jserv.com/jk_orr/xml/leo.htm.
Joe Orr also created an outstanding set of tutorials for Leo; see http://www.evisa.com/e/sb.htm.
Bernhard Mulder proposed a new way of untangling derived files.
John K. Ousterhout created tcl/Tk. Neal Norwitz wrote PyChecker.
Marc-Antoine Parent urged me to use XML for Leo's file format and helped improve it.
Paul Paterson suggested the plugin architecture, suggested an approach to spell checking and has contributed many excellent plugins.
Norman Ramsey created noweb and gave permission to quote from the noweb web documentation.
Rich Ries has contributed a huge number of suggestions.
Steven P. Schaefer pointed out major security problems lurking in hooks.
Gil Shwartz helped with unicode support.
Phil Straus has been a great friend and constant support.
Guido van Rossum created Python, Tkinter and the Python License.
Dave Winer created MORE.
Dan Winkler helped support Leo on the Mac.

Special thanks to my family.
My brother, David Speed Ream, tested Leo and made many useful suggestions.
Rebecca, James and Linda make it all worthwhile.
It was during a conversation with Rebecca that I realized that MORE could be used as a prototype for Leo.
That was a crucial first step.</t>
<t tx="ekr.20040705111716"></t>
<t tx="ekr.20040705111716.1">Leo will write only t.unknownAttributes to the .leo file when writing the &lt;v&gt; element corresponding to the root of an @thin tree.  Leo will do this by writing a new xml attribute, say descendentTnodeUnknownAttributes, in &lt;v&gt; element.

The reason that Leo will only write t.unknownAttributes and not v.unknownAttributes is that only tnodes have gnx's in thin derived files.  In effect, vnodes are anonymous.  We could attempt to get around this by identifying vnodes by their corresponding tnodes, but that's not a general solution and it is, in effect, equivalent to writing only t.unknownAttributes.  This being so, it seems pointless to "pretend" to be writing v.unknownAttributes.

The effect of this is to make all vnodes identical, as far as using unknownAttributes is concerned.  As I've stated in the past, this won't do if, for example, a plugin is trying create an arbitrary directed graph between vnodes.  In that case, the plugin should confine itself to @file trees, or just vnodes in .leo files, for that matter.

7/1/04:

- Leo now writes "marks" and "expanded" attributes in the root &lt;v&gt; element for @thin trees.

- VERY IMPORTANT.  Leo now writes entire tree of @ignored @thin nodes.  This fixes a major bug.</t>
<t tx="ekr.20040705111716.45">Leo marks as dirty all @file nodes when they become "newly unignored".</t>
<t tx="ekr.20040705111716.126"></t>
<t tx="ekr.20040705112148"></t>
<t tx="ekr.20040705150130">Leo now generates no warnings with all significant tests enabled.  Some tests have been disabled in bases classes, and in a few cases pychecker gives erroneous warnings that have been suppressed directly in the source code using the __pychecker__ = arg syntax.</t>
<t tx="ekr.20040713110718">Leo 4.2 beta 3           August 10, 2004

This version of Leo is feature complete.  Leo's core code has been stable for several months.

To do: most plugins work with the new code base, but other plugins need some more work.

The highlights of Leo 4.2:

- @thin trees make Leo much more friendly to cvs. Files derived from @thin can
be committed to cvs and updated from cvs without having to commit or update the
corresponding .leo file. There is no longer any need to keep .leo files and
derived files in synch.

- Leo's data structures have been reorganized. As a result, all outline
operations are much faster. To support this organization, scripts that traverse
Leo's data structures must now use a positions rather than vnodes. Old scripts
that appear to use vnodes will still work because methods like c.currentVnode
that appear to return vnodes actually return positions.

- A new mod_scripting plugin is a big advance in scripting and testing.
test.leo now uses @test and @script nodes to define unit tests without
explicitly creating subclasses of unittest.TestCase. Converting scripts to unit
tests now takes a few seconds!

- A much faster and more robust spell checker plugin. (requires Python 2.3)

- Leo is now much more friendly to using spaces instead of tabs.

- The Execute Script command reports erroneous lines more clearly.

- The Perfect Import feature guarantee that Leo imports file exactly.</t>
<t tx="ekr.20040804164600.16">Leo now vetoes the shutdown logic if saving a dirty file fails.

Leo prints in red the warning about not being able save the read-only file. The
user can use the Save To command to save the file. The Save To command does not
clear the file's dirty bit, so Leo will prompt again to save the file. The user
will have to ignore this prompt in order to exit. This is correct: the
_original_ file has not been saved.</t>
<t tx="ekr.20040804164600.36">- g.getScript implicitly assumed that p == c.currentPosition.
  I removed that assumption.

- The scriptButton callback in the scripting.py plugin no longer calls c.executeScript.
  It's simpler and easier to call exec directly.

- Improved c.checkOutline:
    - Added full keyword arg.
    - Print more if verbose is on.</t>
<t tx="ekr.20040804164600.56"></t>
<t tx="ekr.20040804164600.98"></t>
<t tx="ekr.20040804164600.102">Spurious entries in a tnodeList for @thin trees wiped out all the headlines in the @thin tree.</t>
<t tx="ekr.20040804164600.265"></t>
<t tx="ekr.20040804164600.275"># The new code only writes tnodes for the current tree when pasting to the clipboard.</t>
<t tx="ekr.20040804164600.377">There was a big performance bug in the nodenavigator plugin.</t>
<t tx="ekr.20040804164600.394">@nocolor

As a result, the minimal .leo file is:

@color
@language html

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;leo_file&gt;
&lt;leo_header/&gt;
&lt;globals/&gt;
&lt;preferences/&gt;
&lt;find_panel_settings/&gt;
&lt;vnodes/&gt;
&lt;tnodes/&gt;
&lt;/leo_file&gt;

@nocolor

The empty_leo_file plugin now uses this code. The minimal .leo file that Leo
might actually write is more like this:

@color

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;leo_file&gt;
&lt;leo_header/&gt;
&lt;globals/&gt;
&lt;preferences/&gt;
&lt;find_panel_settings&gt;
    &lt;find_string/&gt;
    &lt;change_string/&gt;
&lt;/find_panel_settings&gt;
&lt;vnodes/&gt;
&lt;tnodes/&gt;
&lt;/leo_file&gt;</t>
<t tx="ekr.20040804164600.406"></t>
<t tx="ekr.20040804164600.419"></t>
<t tx="ekr.20040804164600.421">This is required to make @thin work properly.</t>
<t tx="ekr.20040804164600.424">This makes the command more useful.</t>
<t tx="ekr.20040804164600.470"></t>
<t tx="ekr.20040804164600.471">A major change: putVnode doesn't put tnodeLists for @thin nodes.

Instead it issues an informational message and deletes the tnodeList.</t>
<t tx="ekr.20040804164600.515">Leo used to allocate more positions than necessary.  This unnecessarily stressed the garbage collector.</t>
<t tx="ekr.20040804165258.1"></t>
<t tx="ekr.20040804165258.2"></t>
<t tx="ekr.20040804165258.3">Leo now allows you to select multiple files in the dialogs for all Import
commands. This fixes a major annoyance. However, you must be running Python 2.3
or above to get this feature.
</t>
<t tx="ekr.20040804165258.4">Added the Check submenu of the Outline menu. This contains the Check Outline and
Dump Outline commands, as well as four new commands:

The Check All Python Code and Check Python Code commands report any syntax errors or tabnanny errors.  These commands mark erroneous nodes.  These commands work on the selected Node and its descendants.  These commands ignore any nodes for which a) @ignore is in effect or b) @language python is in not effect.

The Check Python Code and Pretty Print Python Code commands replace nodes with their pretty-printed alternative.  No doubt everyone will have their own favorite style.  You could implement alternate pretty printers in a plugin merely by overriding the following methods of class prettyPrinter in leoCommands.py:
    
---- putOperator:      puts whitespace around operators.
---- putNormalToken:   puts whitespace around everything else.</t>
<t tx="ekr.20040804170531"></t>
<t tx="ekr.20040804170657">Leo now reuses all widgets used to draw the outline pane.  This improves performance and ends leaks of bindings and widgets.</t>
<t tx="ekr.20040804170846">@thin bad-directory caused excessive and confusing tracebacks.</t>
<t tx="ekr.20040804171818"></t>
<t tx="ekr.20040804172113"></t>
<t tx="ekr.20040804172113.1"></t>
<t tx="ekr.20040804173200.6">@thin can eliminate most problems with using Leo in cvs environments:

- Developers should use @thin to create almost all derived files.

- The cvs repository contains "reference" .leo files. These reference files
should containing nothing but @thin nodes. Reference files will change only when
new derived files get added to the project.

- Developers will use local copies of reference files for their own work. For
example, instead of using LeoPyRef.leo directly, I use a copy call LeoPy.leo. My
local copy can contain nodes other than @thin nodes.</t>
<t tx="ekr.20040805102623">@nocolor
@
Just run Leo in a console window.  At the point you want to drop into the debugger, execute this line:
@c

@color

# You can execute this here provided you are running Leo in a console window.
import pdb ; pdb.set_trace() # Drop into pdb.

@nocolor
@
All output from pdb goes to stdout, which is the console window.

It would be good to create a subclass of pdb.Pdb that uses Leo's log pane rather than a console window, but I haven't done that.  It could be done easily enough in a plugin...</t>
<t tx="ekr.20040828084113">Leo is the best IDE that I have had the pleasure to use. I have been using it
now for about 2 -- 3 months. It has totally changed not only the way that I
program, but also the way that I store and organise all of the information that
I need for the job that I do. -- Ian Mulvany
</t>
<t tx="ekr.20040903095817">The tests:

@color
if p:
    
or

if not p:
@nocolor

are the _only_ correct ways to test whether a position p is valid. In particular, the following will not work:
    
@color
if p is None: # Wrong

if p is not None:  # Wrong
</t>
<t tx="ekr.20040903100514"></t>
<t tx="ekr.20040903100514.1">@ignore
@wrap

The tests:
    
.. code-block:: Python

    if p:
        
or

.. code-block:: Python
    
    if not p:

are the _only_ correct ways to test whether a position p is valid. In particular, the following will not work:

.. code-block:: Python

    if p is None: # Wrong
    
    if p is not None:  # Wrong</t>
<t tx="ekr.20040906100024">@nocolor

New in 4.2:  Leo now makes it trivial to convert ordinary scripts to unit tests.  You put script for an individual unit test in a node whose headline starts with @test.  Similarly, nodes whose headlines start with @suite denote a script that when executed will create and run a suite of unit tests.  This is a big step forward.  See test.leo for complete examples.

Using @test nodes

- Enable the mod_scripting.py plugin. This plugin creates two buttons in the
icon area called "run Script" and "script Button".

- Start with a test script that you want to convert to a unit test. Change its
headline from test x to @test x.

- Select the node called "Do @test" in test.leo and click the scriptButton
button. This reate a button called "Do @test".

- Click on this button to run all @test and @suite nodes in the presently
selected headline. Leo now executes the script (in the @test or @suite node!) as
a unit test! That's all there is to it!


Using @suite nodes

Such nodes create a suite of tests. Leo executes the script in these nodes
similar to @test nodes, but Leo assumes that the script in an @suite node will
do the following:

- Create a suite of unit tests
- Put the suite in g.app.scriptDict["suite"]

The difference between @test and @suite is:

- Leo creates a unit test from script in an @test node by creating an instance of generalTestCase, a subclass of unittest.TestCase.
- The script in an @suite node creates the test suite.

@suite nodes allow us to create "legacy" unit tests simply. For example, rather than rewriting all the reformatParagraph unit tests to use @test nodes, I simply wrote an @suite node with the following body.

@color
import leoGlobals as g
import leoTest ; reload(leoTest)
suite = leoTest.makeReformatParagraphSuite()
g.app.scriptDict['suite'] = suite
@nocolor

Notes:
    
- @test nodes dramatically simplifies the test code. There is no need for
explicit unit testing classes and methods. Nor is there any need for setUp and
tearDown methods; scripts can use try/finally instead.

- leoTest.doTests performs its own kind of setUp/tearDown code. It ensures that
the script being executed is the presently selected node. This makes it trivial
for a test script to find its own data: the script can just look in a sibling or
descendent node. There is hardly any need for testUtils.findNodeAnywhere.
leoTest.doTests also saves and restores the "changed" state of test.leo.

- Test scripts can't use @others if descendent nodes hold data. In practice this
doesn't matter. I recommend putting lengthy shared code in leoTest.py.</t>
<t tx="ekr.20040906100201"></t>
<t tx="ekr.20040906100201.1">@ignore
@wrap

New in 4.2:  Leo now makes it trivial to convert ordinary scripts to unit tests.  You put script for an individual unit test in a node whose headline starts with @test.  Similarly, nodes whose headlines start with @suite denote a script that when executed will create and run a suite of unit tests.  This is a big step forward.  See test.leo for complete examples.

Using @test nodes

- Enable the mod_scripting.py plugin. This plugin creates two buttons in the icon area called "run Script" and "script Button".
- Start with a test script that you want to convert to a unit test. Change its headline from test x to @test x.
- Select the node called "Do @test" in test.leo and click the scriptButton button. This reate a button called "Do @test".
- Click on this button to run all @test and @suite nodes in the presently selected headline. Leo now executes the script (in the @test or @suite node!) as a unit test! That's all there is to it!

Using @suite nodes

Such nodes create a suite of tests. Leo executes the script in these nodes similar to @test nodes, but Leo assumes that the script in an @suite node will do the following:

- Create a suite of unit tests
- Put the suite in g.app.scriptDict["suite"]

The difference between @test and @suite is:

- Leo creates a unit test from script in an @test node by creating an instance of generalTestCase, a subclass of unittest.TestCase.
- The script in an @suite node creates the test suite.

An @suite nodes allows us to create "legacy" unit tests simply. For example, rather than rewriting all the reformatParagraph unit tests to use @test nodes, I simply wrote an @suite node with the following body.

.. code-block:: Python

    import leoGlobals as g
    import leoTest ; reload(leoTest)
    suite = leoTest.makeReformatParagraphSuite()
    g.app.scriptDict['suite'] = suite

Notes:
    
- @test nodes dramatically simplifies the test code. There is no need for explicit unit testing classes and methods. Nor is there any need for setUp and tearDown methods; scripts can use try/finally instead.
- leoTest.doTests performs its own kind of setUp/tearDown code. It ensures that the script being executed is the presently selected node. This makes it trivial for a test script to find its own data: the script can just look in a sibling or descendent node. There is hardly any need for testUtils.findNodeAnywhere. leoTest.doTests also saves and restores the "changed" state of test.leo.
- Test scripts can't use @others if descendent nodes hold data. In practice this doesn't matter. I recommend putting lengthy shared code in leoTest.py.

-----------------

|prev| |leo| |next|
</t>
<t tx="ekr.20040908100113">Many thanks to Dave Hein for this FAQ entry.

The cause of the keymapping problem is a issue with the X11 keyboard mapping, not with Tk.

If you have this problem on your system, issue the command:

xmodmap -pke 

and look in the results for the line for keycode 22. I'll bet it shows something like:

keycode 22 = BackSpace Terminate_Server

That second token ("Terminate_Server") is what is supposed to be mapped to Shift-Backspace. You want this second token to be either not present or to be BackSpace.

To fix this, create a file (e.g. .Xmodmap) and give it the content:

keycode 22 = BackSpace

then run the command:

xmodmap .Xmodmap

And you'll have fixed the problem.

Now, on my system this also disables the ability to terminate the X server using Ctrl-Alt-BackSpace ... this is because of some conflict with xdb (xdb is the newer keyboard mapping facility in XFree86 ... xmodmap is the old original X11 keyboard mapping facility). I'm still working on that.

I'm also not able to get xmodmap to make this change during X11 startup (again because of conflicts with xdb). But I'm working on that as well.</t>
<t tx="ekr.20040914103359">Leo 4.2 release candidate 1        September 14, 2004

This version fixes a number of minor bugs reported since the last release. See
the children of this node for details.

The highlights of Leo 4.2:

- @thin trees make Leo much more friendly to cvs. Files derived from @thin can
be committed to cvs and updated from cvs without having to commit or update the
corresponding .leo file. There is no longer any need to keep .leo files and
derived files in synch.

- Leo's data structures have been reorganized. As a result, all outline
operations are much faster. To support this organization, scripts that traverse
Leo's data structures must now use a positions rather than vnodes. Old scripts
that appear to use vnodes will still work because methods like c.currentVnode
that appear to return vnodes actually return positions.

- A new mod_scripting plugin is a big advance in scripting and testing.
test.leo now uses @test and @script nodes to define unit tests without
explicitly creating subclasses of unittest.TestCase. Converting scripts to unit
tests now takes a few seconds!

- A much faster and more robust spell checker plugin. (requires Python 2.3)

- Leo is now much more friendly to using spaces instead of tabs.

- The Execute Script command reports erroneous lines more clearly.

- The Perfect Import feature guarantee that Leo imports file exactly.</t>
<t tx="ekr.20040914103359.2"></t>
<t tx="ekr.20040914103359.4"></t>
<t tx="ekr.20040914103359.7">With TclTkAqua on the Mac (but *not* with tcltk installed via Fink), the tab
problem doesn't exist there), the tab, return, and backspace keys did not generate
ASCII codes, i.e. event.char is an empty string. So when I press the tab key,
Tk inserts a tab character and Leo isn't even aware of it.</t>
<t tx="ekr.20040914103359.12">If only one file was specified Leo gave an error for every character of the file name!
</t>
<t tx="ekr.20040914103359.15"></t>
<t tx="ekr.20040914103359.19"></t>
<t tx="ekr.20040914103359.20">@killcolor

From Dan Winkler:

On a couple of occasions, I tried to paste in a long @url node and got 
this message:

	Truncating headline to 250 characters

I wonder if the 250 character limit on headline length should be 
rethought in light of the @url directive and long web addresses.</t>
<t tx="ekr.20040914103359.21">def idle_head_key (self,p,ch=None):
    
    """Update headline text at idle time."""
    
    c = self.c

    if not p or not p.isCurrentPosition():
        return "break"
        
    edit_text = self.edit_text(p)
    index = edit_text.index("insert")

    if g.doHook("headkey1",c=c,p=p,ch=ch):
        return "break" # The hook claims to have handled the event.
        
    &lt;&lt; set head to vnode text &gt;&gt;
    done = ch in ('\r','\n')
    if done:
        &lt;&lt; set the widget text to head &gt;&gt;
    &lt;&lt; set s to the widget text &gt;&gt;
    changed = s != head
    if changed:
        c.undoer.setUndoParams("Change Headline",p,newText=s,oldText=head)
        &lt;&lt; update p &gt;&gt;
    if done or changed:
        &lt;&lt; reconfigure p and all nodes joined to p &gt;&gt;
        &lt;&lt; update the screen &gt;&gt;

    g.doHook("headkey2",c=c,p=p,ch=ch)
    return "break"</t>
<t tx="ekr.20040914103359.22">head = p.headString()
if head == None:
    head = u""
head = g.toUnicode(head,"utf-8")</t>
<t tx="ekr.20040914103359.23">self.setText(edit_text,head,tag="idle_head_key")
edit_text.mark_set("insert",index)</t>
<t tx="ekr.20040914103359.24">s = edit_text.get("1.0","end")

# Don't truncate if the user is hitting return.
# That should just end editing.
if 1:
    # Truncate headline text to workaround Tk problems...
    # Another kludge: remove one or two trailing newlines before warning of truncation.
    if s and s[-1] == '\n': s = s[:-1]
    if s and s[-1] == '\n': s = s[:-1]
    i = s.find('\n')
    if i &gt; -1:
        # g.trace(i,len(s),repr(s))
        g.es("Truncating headline to one line",color="blue")
        s = s[:i]
    limit = 1000
    if len(s) &gt; limit:
        g.es("Truncating headline to %d characters" % (limit),color="blue")
        s = s[:limit]

s = g.toUnicode(s,g.app.tkEncoding)

if not s:
    s = u""
    
if 0: # 6/10/04: No longer needed.  This was stressing Tk needlessly.
    s = s.replace('\n','')
    s = s.replace('\r','')</t>
<t tx="ekr.20040914103359.25">c.beginUpdate()
if 1: # update...
    # Update changed bit.
    if not c.changed:
        c.setChanged(True)
    # Update all dirty bits.
    # Bug fix 8/2/04: must call p.setDirty even if p is dirty!
    p.setDirty()
    # Update p.
    p.initHeadString(s)
    self.setText(edit_text,s,tag="idle_head_key2")
    edit_text.mark_set("insert",index)
c.endUpdate(False) # do not redraw now.</t>
<t tx="ekr.20040914103359.26"># Reconfigure p's headline.
if done:
    self.setDisabledLabelState(p)

edit_text.configure(width=self.headWidth(p))</t>
<t tx="ekr.20040914103359.27">if done:
    # g.trace("done")
    c.beginUpdate()
    self.endEditLabel()
    c.endUpdate()

elif changed:
    # g.trace("changed")
    # Update p immediately.  Joined nodes are redrawn later by endEditLabel.
    # Redrawing the whole screen now messes up the cursor in the headline.
    self.drawIcon(p) # just redraw the icon.</t>
<t tx="ekr.20040914103359.28"></t>
<t tx="ekr.20040914103359.31"></t>
<t tx="ekr.20040914103359.37"></t>
<t tx="ekr.20040914103359.47">There were too many problems with this feature.  In the future Leo will have a Check Import command.</t>
<t tx="ekr.20040914103359.110"></t>
<t tx="ekr.20040914103359.127">Leo wasn't always traversing the outline correctly when looking for @root nodes.</t>
<t tx="ekr.20040914103359.129">http://sourceforge.net/forum/message.php?msg_id=2742238
By: hinsen

The shortcut definitions in Leo are quite inconvenient on the Mac, as those
using the Alt key don't work. Alt is used for entry of additional characters.
On the other hand, ctrl is available for shortcuts but not used in Leo, since
the ctrl-based shortcuts are shifted to the command key (following standard
Mac practice).

The patch at the end of this message simply shifts all Alt-shortcuts to Ctrl
on the Mac.

That leaves one minor clash: Command-` is used for CloneNode in Leo, although
it canonical MacOS function (switching between the windows of an application)
would be very useful in Leo as well. Removing the CloneNode binding is easy
enough, but it seems that I must implement a window switching function myself.
Not today :-)

Konrad.
</t>
<t tx="ekr.20040914103359.137"></t>
<t tx="ekr.20040914103743"></t>
<t tx="ekr.20040914103743.1"></t>
<t tx="ekr.20040922074200">Leo 4.2 Final       September 20, 2004

The highlights of Leo 4.2:

- @thin trees make Leo much more friendly to cvs. Files derived from @thin can
be committed to cvs and updated from cvs without having to commit or update the
corresponding .leo file. There is no longer any need to keep .leo files and
derived files in synch.

- Leo's data structures have been reorganized. As a result, all outline
operations are much faster. To support this organization, scripts that traverse
Leo's data structures must now use a positions rather than vnodes. Old scripts
that appear to use vnodes will still work because methods like c.currentVnode
that appear to return vnodes actually return positions.

- A new mod_scripting plugin is a big advance in scripting and testing.
test.leo now uses @test and @script nodes to define unit tests without
explicitly creating subclasses of unittest.TestCase. Converting scripts to unit
tests now takes a few seconds!

- A much faster and more robust spell checker plugin. (requires Python 2.3)

- Leo is now much more friendly to using spaces instead of tabs.

- The Execute Script command reports erroneous lines more clearly.</t>
</tnodes>
</leo_file>
