Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 227
- Log:
Added a truly automatic section numbering script derived
from Rhino (see script comments) which can be included in
Wiki pages if required. Wiki help updated to describe the
process for enabling the contents section - for the record
here, adding a DIV with ID toc_heading and closing the
tag, then another DIV with ID toc and closing the tag,
will add a "Contents" heading at level 2, then the TOC. It
is recommended that pages then use a level 2 heading after
the TOC and do not skip header levels (e.g. don't jump
from 2 to 4 without level 3 in between).Might be nice to get this server side some time, but this
works resonably in Firefox 2, Opera 9 and IE 7, degrades
gracefully in older browsers, and is better than nothing!
- Author:
- rool
- Date:
- Thu Jun 14 11:20:41 +0100 2007
- Size:
- 7779 Bytes
1 | /* Variable depth automatic section numbering implemented by automatic |
2 | * document scanning, looking for headers. |
3 | * |
4 | * This code is derived from an example in O'Reilly, "JavaScript: The |
5 | * Definitive Guide" by David Flanagan, ISBN-10: 0-596-10199-6, ISBN-13: |
6 | * 978-0-596-10199-2, 5th edition, section 15.9, p336. |
7 | * |
8 | * History |
9 | * ======= |
10 | * |
11 | * 13-Jun-2007 (ADH): Imported into Wiki structure. |
12 | */ |
13 | |
14 | /* This module defines a single maketoc() function and registers an onload |
15 | * event handler so the function is automatically run when the document |
16 | * finishes loading. When it runs, maketoc() first looks for document |
17 | * elements with IDs of "toc" and "under_toc". If there are no such elements |
18 | * maketoc() does* nothing. Otherwise, maketoc() traverses all child nodes |
19 | * of "under_toc" to find all <h2> through <h6> tags. It creates a table of |
20 | * contents, which it appends to the "toc" element. maketoc() adds section |
21 | * numbers to each section heading and inserts a link back to the table of |
22 | * contents before each heading. maketoc() generates links and anchors with |
23 | * names that begin with "TOC", so you should avoid this prefix in your own |
24 | * HTML. |
25 | * |
26 | * The entries in the generated TOC can be styled with CSS. All entries have |
27 | * a class "TOCEntry". Entries also have a class that corresponds to the level |
28 | * of the section heading. <h1> tags generate entries of class "TOCLevel1", |
29 | * <h2> tags generate entries of class "TOCLevel2", and so on. Section numbers |
30 | * inserted into headings have class "TOCSectNum" and the generated links back |
31 | * to the TOC have class "TOCBackLink". |
32 | * |
33 | * By default, the generated links back to the TOC read "Contents". |
34 | * Override this default (for internationalization, e.g.) by setting |
35 | * the maketoc.backlinkText property to the desired text. |
36 | */ |
37 | |
38 | function maketoc() { |
39 | // Find the containers. If either is missing, return silently. |
40 | var container = document.getElementById('toc'); |
41 | var searchNode = document.getElementById('under_toc'); |
42 | if (!container || !searchNode) return; |
43 | |
44 | // Traverse the document, adding all <h1>...<h6> tags to an array |
45 | var sections = []; |
46 | findSections(searchNode, sections); |
47 | |
48 | // Insert an anchor before the container element so we can link back to it |
49 | var anchor = document.createElement("a"); // Create an <a> node |
50 | anchor.name = "TOCtop"; // Give it a name |
51 | anchor.id = "TOCtop"; // And an id (IE needs this) |
52 | container.parentNode.insertBefore(anchor, container); // add before toc |
53 | |
54 | // Initialize an array that keeps track of section numbers |
55 | var sectionNumbers = [0,0,0,0,0,0]; |
56 | var found = false; |
57 | |
58 | // Now loop through the section header elements we found |
59 | for(var s = 0; s < sections.length; s++) { |
60 | var section = sections[s]; |
61 | |
62 | // Figure out what level heading it is |
63 | var level = parseInt(section.tagName.charAt(1)); |
64 | if (isNaN(level) || level < 2 || level > 6) continue; |
65 | found = true; |
66 | |
67 | // Increment the section number for this heading level |
68 | // And reset all lower heading level numbers to zero |
69 | sectionNumbers[level-1]++; |
70 | for(var i = level; i < 6; i++) sectionNumbers[i] = 0; |
71 | |
72 | // Now combine section numbers for all heading levels |
73 | // to produce a section number like 2.3.1 |
74 | var sectionNumber = ""; |
75 | for(i = 1; i < level; i++) { |
76 | sectionNumber += sectionNumbers[i]; |
77 | if (i < level-1) sectionNumber += "."; |
78 | } |
79 | |
80 | // Add the section number and a space to the section header title. |
81 | // We place the number in a <span> to make it styleable. |
82 | var frag = document.createDocumentFragment(); // to hold span and space |
83 | var span = document.createElement("span"); // span to hold number |
84 | span.className = "TOCSectNum"; // make it styleable |
85 | span.appendChild(document.createTextNode(sectionNumber)); // add sect# |
86 | frag.appendChild(span); // Add span to fragment |
87 | frag.appendChild(document.createTextNode(". ")); // Then add a full stop and space |
88 | section.insertBefore(frag, section.firstChild); // Add both to header |
89 | |
90 | // Create an anchor to mark the beginning of this section. |
91 | var anchor = document.createElement("a"); |
92 | anchor.name = "TOC"+sectionNumber; // Name the anchor so we can link |
93 | anchor.id = "TOC"+sectionNumber; // In IE generated anchors need ids |
94 | |
95 | // Wrap the anchor around a link back to the TOC |
96 | var link = document.createElement("a"); |
97 | link.href = "#TOCtop"; |
98 | link.className = "TOCBackLink"; |
99 | link.appendChild(document.createTextNode(maketoc.backlinkText)); |
100 | anchor.appendChild(link); |
101 | |
102 | // Insert the anchor and link immediately before the section header |
103 | section.parentNode.insertBefore(anchor, section); |
104 | |
105 | // Now create a link to this section. |
106 | var link = document.createElement("a"); |
107 | link.href = "#TOC" + sectionNumber; // Set link destination |
108 | link.innerHTML = section.innerHTML; // Make link text same as heading |
109 | |
110 | // Place the link in a div that is styleable based on the level |
111 | var entry = document.createElement("div"); |
112 | entry.className = "TOCEntry TOCLevel" + level; // For CSS styling |
113 | entry.appendChild(link); |
114 | |
115 | // And add the div to the TOC container |
116 | container.appendChild(entry); |
117 | } |
118 | |
119 | // If we found anything, add the 'Contents' heading. |
120 | |
121 | if (found) { |
122 | var heading = document.getElementById('toc_heading'); |
123 | |
124 | if (heading) { |
125 | var h2 = document.createElement('h2'); |
126 | h2.appendChild(document.createTextNode(maketoc.headingText)); |
127 | heading.appendChild(h2); |
128 | heading.appendChild(document.createElement('p')); |
129 | } |
130 | |
131 | container.appendChild(document.createElement('p')); |
132 | } |
133 | |
134 | // This method recursively traverses the tree rooted at node n, looking |
135 | // for <h1> through <h6> tags and appends them to the sections array. |
136 | function findSections(n, sects) { |
137 | // Loop through all the children of n |
138 | for(var m = n.firstChild; m != null; m = m.nextSibling) { |
139 | // Skip any nodes that are not elements. |
140 | if (m.nodeType != 1 /* Node.Element_NODE */) continue; |
141 | // Skip the container element since it may have its own heading |
142 | if (m == container) continue; |
143 | // As an optimization, skip <p> tags since headings are not |
144 | // supposed to appear inside paragraphs. (We could also skip |
145 | // lists, <pre> tags, etc., but <p> is the most common one.) |
146 | // XHTML documents tend to return lower case elements, HTML |
147 | // documents tend to return upper case elements. |
148 | if (m.tagName == "p" || m.tagName == "P") continue; // optimization |
149 | |
150 | // If we didn't skip the child node, check whether it is a heading. |
151 | // If so, add it to the array. Otherwise, recurse on it. |
152 | // Note that the DOM is interface-based not class-based so we |
153 | // cannot simply test whether (m instanceof HTMLHeadingElement). |
154 | if (m.tagName.length==2 && (m.tagName.charAt(0)=="h" || m.tagName.charAt(0)=="H")) sects.push(m); |
155 | else findSections(m, sects); |
156 | } |
157 | } |
158 | } |
159 | |
160 | // Default text for the Contents section heading |
161 | maketoc.headingText = "Contents"; |
162 | // This is the default text of links back to the TOC |
163 | maketoc.backlinkText = "Contents"; |
164 | |
165 | // Register maketoc() to run automatically when the document finishes loading |
166 | if (window.addEventListener) window.addEventListener("load", maketoc, false); |
167 | else if (window.attachEvent) window.attachEvent("onload", maketoc); |