linktitle: toc.py
parent: Plugins
ctime: 2010-06-23
+change: make get_toc() work like get_recently()
This plugin analyzes the HTML header statements (h1, h2, h3 ...) and
generates a table of contents based on this information.
If not specified, this defaults to 30.
-= Usage example =
+= Internal representation =
-with this HTML:
+Given this HTML ...
<h2>Calling macros</h2>
<h3>Example</h3>
- <h3>Defining macros</h2>
+ <h2>Defining macros</h2>
-the table-of-contents will be like this:
- <ul id="toc">
- <li><a href="#calling_macros">Calling macros</a></li>
- <ul>
- <li><a href="#example">Example</a></li>
- </ul>
- <li><a href="#defining_macros">Defining macros</a></li>
- </ul>
+... the plugin populates the variable "`_toc`" like this:
+
+ _toc = [
+ (2, "Calling macros", "calling_macros"),
+ (3, "Example", "example"),
+ (2, "Defining macros", "defining_macros"),
+ ]
+
+... where the first item is the level (h1, h2, etc). The
+second item is the headline and the last element is a so-called
+[[slug|http://en.wikipedia.org/wiki/Slug_(web_publishing)]], used for
+local anchors.
+
-While doing this, it also modifies the HTML file contents to look like this:
+= Generation of a table-of-contents =
- <h2>Calling macros<a name="calling_macros"> </a></h2>
- <h3>Example<a name="example"> </a></h3>
- <h2>Defining macros<a name="defining_macros"> </a></h2>
+This again is done via a suitable [[template_mako]]. The template uses
+the function "`get_toc()`" and returns (level, headline, slug) tuples.
-== Accessing the TOC ==
+* "`level`" is the indendation level, starting with 0. You can use
+ this for CSS "`id=`" or "`class`" attributes
+* "`headline`" is the headline (the text inside <hX>..</hX>)
+* "`slug`" is the
+ [[slug|http://en.wikipedia.org/wiki/Slug_(web_publishing)]] that can
+ be used for link creation
-Use "`${get_toc()}`" in your [[template|template_mako]] to access
-the generated HTML.
+== Example template ==
+
+Here's a sample [[Mako template|template_mako]] excerpt that converts
+this into a HTML:
+
+ <ul id="toc">
+ % for level, headline, link in toc:
+ <li class="toc${level}"><a href="${link}">${headline | entity}</a></li>
+ % endfor
+ </ul>
== Example CSS ==
width: 100%;
text-align: right;
}
+
+ .toc1 { padding-left: 1em; }
+ .toc2 { padding-left: 2em; }
reHeader = re.compile(r'<h(\d)(.*)>(.*)</h\1>', re.IGNORECASE | re.MULTILINE)
-toc = []
-labels = {}
+_toc = []
+_labels = {}
toc_min_lines = 30
def repl(m):
- global toc
+ """
+ Function used for re.sub() to find all header elements (h1, h2, ...).
+ Data from those elements (level, headline) are stored in the global
+ array `toc`.
+
+ This function also modifies the text by adding a anchor to the
+ header.
+ """
+ global _toc
label = slugify(m.group(3), "_")
- if labels.has_key(label):
+ if _labels.has_key(label):
n = 0
while True:
l = "%s_%d" % (label, n)
- if not labels.has_key(l):
+ if not _labels.has_key(l):
label = l
break
n += 1
- toc.append( (label, int(m.group(1))-1, m.group(3)) )
+ _toc.append( (int(m.group(1)), m.group(3), label) )
+ _labels[label] = 1
return '<h%s%s>%s<a name="%s"> </a></h%s>' % (
m.group(1),
m.group(2),
m.group(3),
label,
m.group(1))
- """
- Function used for re.sub() to find all header elements (h1, h2, ...).
- Data from those elements (level, headline) are stored in the global
- array `toc`.
-
- This function also modifies the text by adding a anchor to the
- header.
- """
@set_hook("linkify")
def linkify(params):
- global toc
- global labels
- toc = []
- labels = {}
+ global _toc
+ global _labels
+ _toc = []
+ _labels = {}
# Very small pages don't need a table-of-contents
if params.file.contents.count("\n") < toc_min_lines:
@set_function("get_toc")
def get_toc():
- level = 1
- res = []
- for (label, lvl, txt) in toc:
- while lvl > level:
- res.append("%s<ul>" % (" "*level))
- level += 1
- while lvl < level:
- level -= 1
- res.append("%s</ul>" % (" "*level))
- res.append('%s<li><a href="#%s">%s</a></li>' %
- (" " * level, label, txt))
- while level > 1:
- level -= 1
- return "\n".join(res)
+ return _toc