Contents
Details
- Applies to
MoinMoin macro (TableOfContents.py) v1.8.2 and v1.9.3 (2 patches submitted)
- Purpose
To make TableOfContents numbering hierarchical
- Description
This patch enables TableOfContents to produce hierarchical headers numbering. Example below
Old style:
1. Header 1 1. Sub Header 1 2. Sub Header 2 1. Sub Sub Header 1 1. Sub Sub Header 2 2. Header 2
New style:
1. Header 1 1.1. Sub Header 1 1.2. Sub Header 2 1.2.1. Sub Sub Header 1 1.2.2. Sub Sub Header 2 2. Header 2
Patch
1 --- TableOfContents.old.py 2009-02-08 01:27:07.000000000 +0100
2 +++ TableOfContents.py 2009-03-27 02:28:16.000000000 +0100
3 @@ -149,11 +149,6 @@
4
5 tocfm = TOCFormatter(macro.request)
6 p = Page(macro.request, pname, formatter=tocfm, rev=macro.request.rev)
7 -
8 - # this is so we get a correctly updated TOC if we just preview in the editor -
9 - # the new content is not stored on disk yet, but available as macro.parser.raw:
10 - p.set_raw_body(macro.parser.raw, modified=1)
11 -
12 output = macro.request.redirectedOutput(p.send_page,
13 content_only=True,
14 count_hit=False,
15 @@ -162,66 +157,88 @@
16 _ = macro.request.getText
17
18 result = [
19 - macro.formatter.div(1, css_class="table-of-contents"),
20 + macro.formatter.div(1, css_class="table-of-contents", id="toc"),
21 macro.formatter.paragraph(1, css_class="table-of-contents-heading"),
22 macro.formatter.text(_('Contents')),
23 macro.formatter.paragraph(0),
24 ]
25
26 + lastlvl = 0
27 +
28 + # variables needed to provide with nice, leveled prefixes
29 + levelnumbers = None
30 + levelnumbers = {}
31 + counter = 1
32 + lowest_lvl = None
33
34 - # find smallest used level and use that as the outer-most indentation,
35 - # to fix pages like HelpOnMacros that only use h2 and lower levels.
36 - lastlvl = 100
37 for lvl, id, txt in macro.request._tocfm_collected_headings:
38 +
39 if txt is None:
40 incl_id = id
41 continue
42 if lvl > maxdepth or id is None:
43 continue
44 - if lvl < lastlvl:
45 - lastlvl = lvl
46
47 - # headings are 1-based, lastlvl needs to be one less so that one is closed
48 - lastlvl -= 1
49 + # determine the lowest level available
50 + if lowest_lvl is None or lowest_lvl > lvl:
51 + lowest_lvl = lvl
52 +
53 + # determine number prefix for the TOC line
54 + if lvl > lastlvl:
55 + levelnumbers[lastlvl] = counter
56 + counter = 0
57 + elif lvl < lastlvl:
58 + counter = levelnumbers[lvl]
59 +
60 + counter = counter + 1
61 + levelnumbers[lvl] = counter
62 +
63 + line_number = ""
64 + for i in range(lowest_lvl, lvl):
65 + line_number = line_number + str(levelnumbers[i]) + "."
66 + line_number = line_number + str(counter) + "."
67
68 - for lvl, id, txt in macro.request._tocfm_collected_headings:
69 - if txt is None:
70 - incl_id = id
71 - continue
72 - if lvl > maxdepth or id is None:
73 - continue
74
75 # will be reset by pop_unique_ids below
76 macro.request.include_id = incl_id
77
78 need_li = lastlvl >= lvl
79 - while lastlvl > lvl:
80 - result.extend([
81 - macro.formatter.listitem(0),
82 - macro.formatter.number_list(0),
83 - ])
84 - lastlvl -= 1
85 +
86 +
87 + # adjust lastlvl so that we can start lists from the lowest_lvl
88 + if lastlvl < lvl and lastlvl < lowest_lvl: lastlvl = lvl - 1
89 + if lastlvl > lvl and lastlvl < lowest_lvl: lastlvl = lvl + 1
90 +
91 +
92 + # open and close corresponding lists
93 while lastlvl < lvl:
94 result.extend([
95 - macro.formatter.number_list(1),
96 + macro.formatter.bullet_list(1, type="none"),
97 macro.formatter.listitem(1),
98 ])
99 lastlvl += 1
100 + while lastlvl > lvl:
101 + result.extend([
102 + macro.formatter.listitem(0),
103 + macro.formatter.bullet_list(0),
104 + ])
105 + lastlvl -= 1
106 if need_li:
107 result.extend([
108 macro.formatter.listitem(0),
109 macro.formatter.listitem(1),
110 ])
111 +
112 result.extend([
113 '\n',
114 macro.formatter.anchorlink(1, id),
115 - macro.formatter.text(txt),
116 + macro.formatter.text(line_number + " " + txt),
117 macro.formatter.anchorlink(0),
118 ])
119
120 - while lastlvl > 0:
121 + while lastlvl > lvl:
122 result.append(macro.formatter.listitem(0))
123 - result.append(macro.formatter.number_list(0))
124 + result.append(macro.formatter.bullet_list(0))
125 lastlvl -= 1
126
127 macro.request.pop_unique_ids()
1 --- TableOfContents.py.dist 2010-06-26 23:46:42.000000000 +0200
2 +++ TableOfContents.py 2010-09-01 18:57:24.000000000 +0200
3 @@ -167,7 +167,7 @@
4 _ = macro.request.getText
5
6 result = [
7 - macro.formatter.div(1, css_class="table-of-contents"),
8 + macro.formatter.div(1, css_class="table-of-contents", id="toc"),
9 macro.formatter.paragraph(1, css_class="table-of-contents-heading"),
10 macro.formatter.text(_('Contents')),
11 macro.formatter.paragraph(0),
12 @@ -181,21 +181,48 @@
13 if txt is None:
14 incl_id = id
15 continue
16 - if lvl < mindepth or lvl > maxdepth or id is None:
17 + if lvl > maxdepth or id is None:
18 continue
19 if lvl < lastlvl:
20 lastlvl = lvl
21
22 # headings are 1-based, lastlvl needs to be one less so that one is closed
23 + # variables needed to provide with nice, leveled prefixes
24 + # (part of the hierarhical TOC prefix code)
25 + levelnumbers = None
26 + levelnumbers = {}
27 + counter = 1
28 + lowest_lvl = None
29 lastlvl -= 1
30
31 for lvl, id, txt in macro.request._tocfm_collected_headings:
32 if txt is None:
33 incl_id = id
34 continue
35 - if lvl < mindepth or lvl > maxdepth or id is None:
36 + if lvl > maxdepth or id is None:
37 continue
38
39 +
40 + # determine the lowest level available
41 + # (part of the hierarhical TOC prefix)
42 + if lowest_lvl is None or lowest_lvl > lvl:
43 + lowest_lvl = lvl
44 +
45 + # determine number prefix for the TOC line
46 + # (part of the hierarhical TOC prefix)
47 + if lvl > lastlvl:
48 + levelnumbers[lastlvl] = counter
49 + counter = 0
50 + elif lvl < lastlvl:
51 + counter = levelnumbers[lvl]
52 + counter = counter + 1
53 + levelnumbers[lvl] = counter
54 +
55 + line_number = ""
56 + for i in range(lowest_lvl, lvl):
57 + line_number = line_number + str(levelnumbers[i]) + "."
58 + line_number = line_number + str(counter) + "."
59 +
60 # will be reset by pop_unique_ids below
61 macro.request.uid_generator.include_id = incl_id
62
63 @@ -203,12 +230,12 @@
64 while lastlvl > lvl:
65 result.extend([
66 macro.formatter.listitem(0),
67 - macro.formatter.number_list(0),
68 + macro.formatter.bullet_list(0),
69 ])
70 lastlvl -= 1
71 while lastlvl < lvl:
72 result.extend([
73 - macro.formatter.number_list(1),
74 + macro.formatter.bullet_list(1, type="none"),
75 macro.formatter.listitem(1),
76 ])
77 lastlvl += 1
78 @@ -220,13 +247,13 @@
79 result.extend([
80 '\n',
81 macro.formatter.anchorlink(1, id),
82 - macro.formatter.text(txt),
83 + macro.formatter.text(line_number + " " + txt),
84 macro.formatter.anchorlink(0),
85 ])
86
87 while lastlvl > 0:
88 result.append(macro.formatter.listitem(0))
89 - result.append(macro.formatter.number_list(0))
90 + result.append(macro.formatter.bullet_list(0))
91 lastlvl -= 1
92
93 macro.request.uid_generator.pop()
Complete macro
Both macros are attached below:
Discussion
- don't overwrite id
- counter += 1
py.test will cry on
50 + if lowest_lvl is None or lowest_lvl > lvl: 51 + lowest_lvl = lvl
Plan
- Priority:
- Assigned to:
- Status: