The last two days mark a milestone in Leo's history. It's taken a while to process the implications. This post will summarize what has happened and what it means.
This post will be pre-writing for new words in Leo's customization chapter. These words will completely replace Leo's dreadful "rst3 Command Reference" chapter.
Note: The work described here exists only in the ekr-new-rst branch. PR
#1870 shows the latest code.
Supporting filters in leoRst.py
leoRst.py now supports user-defined filters for headline and body text. The new code is much more general and powerful than the old.
plugins/example_rst_filter.py
Yesterday I wrote the example_rst_filter plugin. The entire plugin is about one page of code, yet it illustrates how to get the effect of half clones! Here are the guts of the plugin:
def has_cloned_parent(c, p):
"""
Return True if p has a cloned parent within the @rst tree.
"""
root = c.rstCommands.root
p = p.parent()
while p and p != root:
if p.isCloned():
return True
p.moveToParent()
return False
def body_filter(c, p):
return '' if has_cloned_parent(c, p) else p.b
def headline_filter(c, p):
return '' if has_cloned_parent(c, p) else p.h
Folks, this sends a shiver down my spine. The has_cloned_parent helper filters out all the children of all clones in the @rst tree. We have the effect of half clones, with no changes to Leo's core!
Note 1:
c.rstCommands.root is the parent @rst node. has_cloned_parent stops the scan at the root, ensuring that the rst3 command includes "top-level" clones themselves.
Note 2: As shown above, the rst3 code passes both c and p to each filter. There is no need for a filter to set c = p.v.context.
Endless customization possibilities
"...a
filter can use p.b, p.h, p.u, or p.gnx for p itself, but the filter can
use p (and c = p.v.context) to access any ancestor or descendant node,
or indeed any other node in the outline.
Nothing could be simpler or more general."
I forgot to mention two other sources of data:
1. Special-format comments embedded in p.b, or even special-purpose headlines.
2. Filters could use data from anywhere in the outline, not just the data in node p.
Using uAs in filters
Yesterday I spent considerable time digesting the implications of using uAs (p.u) in filters. The question is, "how easy would it be in practice for a documentation writer to use uAs in rst filters?"
Happily, Leo already has several easy ways to use uAs. I have just created Info Item #1871 to record my researches. The takeaway is that documentation writers can use tags (nodetags.py plugin) and icons to "mark" nodes. There is no urgent need to use uAs directly, though writers could do so if they choose.
#1873 suggests a few new commands that would help manage uAs and tags. Adding aliases that start with "uas" or "tags" will help Leonistas find those commands.
Summary
For the first time in Leo's history, it is now dead easy to get the effect of half-clones in @rst trees. Similar techniques could filter any Leo data.
Power users of the rst3 command could extend the code in example_filter.py to create more sophisticated filters. For example, it would be dead easy to scan body text for special purpose comments. The filter could update rst3 settings (or filter-specific settings) and then delete the special-purpose comments.
I'll soon update the "Customizing Leo" chapter with new sections about rst3 filters.
A few new commands will make it easier to use uAs, tags, and icons.
In short, the new rst3 command is more than an important milestone. For the first time, it is clear that Leo's core is complete as it is.
Edward