Defined in [[hierarchy.py|hierarchy]], where you find an example.
+== get_toc() ==
+
+Returns an unsorted list with the hierarchy of the table-of-contents.
+
+Defined in [[toc.py|toc]], where you find an example.
== func ==
== linkify ==
-This hook should contain any link to html. Implemented by the plugin
-[[link]].
+Functions that are called by this hook receive a pre-rendered HTML page.
+They can now modify this HTML further, e.g. py converting links to HTML.
+
+They can directly modify params.file.contents and don't need to return anything.
+
+Implemented by the plugin [[link]] and [[toc]].
* "`params.direc`" contains a "`class Directory`" object
* "`params.file`" has a "`class File`" object
= Support in the template =
-You [[templates]] should mention your rss feed. One possible solution
+Your [[template|Mako template]] should mention your rss feed. One possible solution
is this:
<head>
--- /dev/null
+title: Generate table of contents
+linktitle: toc.py
+parent: Plugins
+ctime: 2010-06-23
+
+This plugin analyzes the HTML header statements (h1, h2, h3 ...) and
+generates a table of contents based on this information.
+
+= Configuration =
+
+== toc_min_lines ==
+
+A page needs with less lines than specified won't get a table-of-contents.
+
+You can use this if you paste the table-of-contents to some screen
+corner, and don't want the clutter the display if the HTML page is
+very short anyway.
+
+If not specified, this defaults to 30.
+
+
+= Usage example =
+
+with this HTML:
+
+ <h2>Calling macros</h2>
+ <h3>Example</h3>
+ <h3>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>
+
+While doing this, it also modifies the HTML file contents to look like this:
+
+ <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>
+
+== Accessing the TOC ==
+
+Use "`${get_toc()}`" in your [[template|template_mako]] to access
+the generated HTML.
+
+
+== Example CSS ==
+
+Finally, you use some CSS to format the table-of-contents to your
+liking, e.g. with this:
+
+ #toc, #toc ul {
+ list-style-type: none;
+ overflow: hidden;
+ padding: 0;
+ margin: 0;
+ }
+ #toc {
+ font-size: 90%;
+ }
+ #toc li {
+ width: 100%;
+ text-align: right;
+ }
"read_markdown",
"template_mako",
"google_sitemap",
+ "toc",
]
exclude_dir: [
]
res = reLink.sub(do_link, s)
print "", res
-#test_link()
-#test_sub()
-
-
-
@set_hook("linkify")
def linkify(params):
- return reLink.sub(do_link, params.file.contents)
+ params.file.contents = reLink.sub(do_link, params.file.contents)
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+from webber import *
+import htmlentitydefs, re
+
+
+reHeader = re.compile(r'<h(\d)(.*)>(.*)</h\1>', re.IGNORECASE | re.MULTILINE)
+toc = []
+labels = {}
+
+
+toc_min_lines = 30
+
+
+@set_hook("checkconfig")
+def checkconfig(params):
+ if cfg.has_key("toc_min_lines"):
+ global toc_min_lines
+ toc_min_lines = int(cfg.toc_min_times)
+
+
+def slugify(text, separator):
+ """Based on http://snipplr.com/view/26266/create-slugs-in-python/"""
+
+ ret = ""
+ for c in text.lower():
+ try:
+ ret += htmlentitydefs.codepoint2name[ord(c)]
+ except:
+ ret += c
+ ret = re.sub("([a-zA-Z])(uml|acute|grave|circ|tilde|cedil)", r"\1", ret)
+ ret = re.sub("\W", " ", ret)
+ ret = re.sub(" +", separator, ret)
+ return ret.strip()
+
+
+def repl(m):
+ global toc
+ label = slugify(m.group(3), "_")
+ if labels.has_key(label):
+ n = 0
+ while True:
+ l = "%s_%d" % (label, n)
+ if not labels.has_key(l):
+ label = l
+ break
+ n += 1
+
+ toc.append( (label, int(m.group(1))-1, m.group(3)) )
+ return '<h%s%s>%s<a name="%s"> </a></h%s>' % (
+ m.group(1),
+ m.group(2),
+ m.group(3),
+ label,
+ m.group(1))
+
+
+@set_hook("linkify")
+def linkify(params):
+ 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:
+ return
+
+ params.file.contents = reHeader.sub(repl, params.file.contents)
+
+
+
+@set_function("get_toc")
+def get_toc():
+ level = 1
+ res = []
+ res.append('<ul id="toc">')
+ 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:
+ level -= 1
+ res.append("%s</ul>" % (" "*level))
+ return "\n".join(res)
continue
direc = directories[file.direc]
- contents = run_hooks("linkify",
+ run_hooks("linkify",
direc=direc,
file=file,
- return_holder=False)
+ return_holder=True)
#print "contents after 'linkify':", contents
- if not contents:
+ if not file.contents:
continue
- file.contents = contents
# TODO: einige Fragmente sollen u.U. in eine andere
# Webseite eingebaut werden und sollten daher nicht in