1 var asciidoc
= { // Namespace.
3 /////////////////////////////////////////////////////////////////////
4 // Table Of Contents generator
5 /////////////////////////////////////////////////////////////////////
7 /* Author: Mihai Bazon, September 2002
8 * http://students.infoiasi.ro/~mishoo
10 * Table Of Content generator
13 * Feel free to use this script under the terms of the GNU General Public
14 * License, as long as you do not remove or alter this notice.
17 /* modified by Troy D. Hanson, September 2006. License: GPL */
18 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
21 toc: function (toclevels
) {
23 function getText(el
) {
25 for (var i
= el
.firstChild
; i
!= null; i
= i
.nextSibling
) {
26 if (i
.nodeType
== 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
28 else if (i
.firstChild
!= null)
34 function TocEntry(el
, text
, toclevel
) {
37 this.toclevel
= toclevel
;
40 function tocEntries(el
, toclevels
) {
41 var result
= new Array
;
42 var re
= new RegExp('[hH]([1-'+(toclevels
+1)+'])');
43 // Function that scans the DOM tree for header elements (the DOM2
44 // nodeIterator API would be a better technique but not supported by all
46 var iterate = function (el
) {
47 for (var i
= el
.firstChild
; i
!= null; i
= i
.nextSibling
) {
48 if (i
.nodeType
== 1 /* Node.ELEMENT_NODE */) {
49 var mo
= re
.exec(i
.tagName
);
50 if (mo
&& (i
.getAttribute("class") || i
.getAttribute("className")) != "float") {
51 result
[result
.length
] = new TocEntry(i
, getText(i
), mo
[1]-1);
61 var toc
= document
.getElementById("toc");
66 // Delete existing TOC entries in case we're reloading the TOC.
67 var tocEntriesToRemove
= [];
69 for (i
= 0; i
< toc
.childNodes
.length
; i
++) {
70 var entry
= toc
.childNodes
[i
];
71 if (entry
.nodeName
.toLowerCase() == 'div'
72 && entry
.getAttribute("class")
73 && entry
.getAttribute("class").match(/^toclevel/))
74 tocEntriesToRemove
.push(entry
);
76 for (i
= 0; i
< tocEntriesToRemove
.length
; i
++) {
77 toc
.removeChild(tocEntriesToRemove
[i
]);
80 // Rebuild TOC entries.
81 var entries
= tocEntries(document
.getElementById("content"), toclevels
);
82 for (var i
= 0; i
< entries
.length
; ++i
) {
83 var entry
= entries
[i
];
84 if (entry
.element
.id
== "")
85 entry
.element
.id
= "_toc_" + i
;
86 var a
= document
.createElement("a");
87 a
.href
= "#" + entry
.element
.id
;
88 a
.appendChild(document
.createTextNode(entry
.text
));
89 var div
= document
.createElement("div");
91 div
.className
= "toclevel" + entry
.toclevel
;
94 if (entries
.length
== 0)
95 toc
.parentNode
.removeChild(toc
);
99 /////////////////////////////////////////////////////////////////////
100 // Footnotes generator
101 /////////////////////////////////////////////////////////////////////
103 /* Based on footnote generation code from:
104 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
107 footnotes: function () {
108 // Delete existing footnote entries in case we're reloading the footnodes.
110 var noteholder
= document
.getElementById("footnotes");
114 var entriesToRemove
= [];
115 for (i
= 0; i
< noteholder
.childNodes
.length
; i
++) {
116 var entry
= noteholder
.childNodes
[i
];
117 if (entry
.nodeName
.toLowerCase() == 'div' && entry
.getAttribute("class") == "footnote")
118 entriesToRemove
.push(entry
);
120 for (i
= 0; i
< entriesToRemove
.length
; i
++) {
121 noteholder
.removeChild(entriesToRemove
[i
]);
124 // Rebuild footnote entries.
125 var cont
= document
.getElementById("content");
126 var spans
= cont
.getElementsByTagName("span");
129 for (i
=0; i
<spans
.length
; i
++) {
130 if (spans
[i
].className
== "footnote") {
132 var note
= spans
[i
].getAttribute("data-note");
134 // Use [\s\S] in place of . so multi-line matches work.
135 // Because JavaScript has no s (dotall) regex flag.
136 note
= spans
[i
].innerHTML
.match(/\s*\[([\s\S]*)]\s*/)[1];
138 "[<a id='_footnoteref_" + n
+ "' href='#_footnote_" + n
+
139 "' title='View footnote' class='footnote'>" + n
+ "</a>]";
140 spans
[i
].setAttribute("data-note", note
);
142 noteholder
.innerHTML
+=
143 "<div class='footnote' id='_footnote_" + n
+ "'>" +
144 "<a href='#_footnoteref_" + n
+ "' title='Return to text'>" +
145 n
+ "</a>. " + note
+ "</div>";
146 var id
=spans
[i
].getAttribute("id");
147 if (id
!= null) refs
["#"+id
] = n
;
151 noteholder
.parentNode
.removeChild(noteholder
);
153 // Process footnoterefs.
154 for (i
=0; i
<spans
.length
; i
++) {
155 if (spans
[i
].className
== "footnoteref") {
156 var href
= spans
[i
].getElementsByTagName("a")[0].getAttribute("href");
157 href
= href
.match(/#.*/)[0]; // Because IE return full URL.
160 "[<a href='#_footnote_" + n
+
161 "' title='View footnote' class='footnote'>" + n
+ "</a>]";
167 install: function(toclevels
) {
170 function reinstall() {
171 asciidoc
.footnotes();
173 asciidoc
.toc(toclevels
);
177 function reinstallAndRemoveTimer() {
178 clearInterval(timerId
);
182 timerId
= setInterval(reinstall
, 500);
183 if (document
.addEventListener
)
184 document
.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer
, false);
186 window
.onload
= reinstallAndRemoveTimer
;