Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Created the ultimate TOC generator in javascript, build stylesheet fr…
…om sass, improve rakefile by using rules
- Loading branch information
Showing
3 changed files
with
429 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,70 +1,145 @@ | |||
/* Author: Mihai Bazon, September 2002 | TOCCreator = { | ||
* http://students.infoiasi.ro/~mishoo | Header: function(level, text, visible, id){ | ||
* | var obj = { | ||
* Table Of Content generator | level: level, | ||
* Version: 0.4 | text: text, | ||
* | id: id, | ||
* Feel free to use this script under the terms of the GNU General Public | visible: visible, | ||
* License, as long as you do not remove or alter this notice. | childs: [], | ||
*/ | mother: null, | ||
|
|||
/* modified by Troy D. Hanson, September 2006. License: GPL */ | |||
/* modified by Stuart Rackham, October 2006. License: GPL */ | |||
/* modified by Michael Fellinger, April 2009. License: GPL */ | |||
|
|||
function getText(el) { | |||
var text = ""; | |||
for (var i = el.firstChild; i != null; i = i.nextSibling) { | |||
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants. | |||
text += i.data; | |||
else if (i.firstChild != null) | |||
text += getText(i); | |||
} | |||
return text; | |||
} | |||
|
|
||
function TocEntry(el, text, toclevel) { | add_child: function(child){ | ||
this.element = el; | this.childs.push(child); | ||
this.text = text; | child.mother = this; | ||
this.toclevel = toclevel; | }, | ||
} |
|
||
to_html: function(out){ | |||
var ol, li, a; | |||
|
|||
if(this.visible){ | |||
li = document.createElement('li'); | |||
a = document.createElement('a'); | |||
a.innerHTML = this.text; | |||
a.href = '#' + this.id; | |||
li.appendChild(a); | |||
out.appendChild(li); | |||
|
|||
if(this.childs.length > 0){ | |||
ol = document.createElement('ol'); | |||
li.appendChild(ol); | |||
|
|||
this.each_child_to_html(ol); | |||
} | |||
} else { | |||
ol = document.createElement('ol'); | |||
out.appendChild(ol); | |||
this.each_child_to_html(ol); | |||
} | |||
|
|||
return(out); | |||
}, | |||
|
|||
each_child_to_html: function(root){ | |||
for(child_i in this.childs){ | |||
this.childs[child_i].to_html(root); | |||
} | |||
} | |||
}; | |||
|
|||
return(obj); | |||
}, | |||
|
|||
elements_by_tag_names: function(list, given_doc){ | |||
var doc = (doc || document); | |||
var tag_names = list.split(','); | |||
var tags = []; | |||
|
|
||
function tocEntries(el, toclevels) { | for(tag_names_i in tag_names){ | ||
var result = new Array; | var partials = doc.getElementsByTagName(tag_names[tag_names_i]); | ||
var re = new RegExp('[hH]([1-'+(toclevels+1)+'])'); |
|
||
// Function that scans the DOM tree for header elements (the DOM2 | for(i = 0; i < partials.length; i++){ | ||
// nodeIterator API would be a better technique but not supported by all | tags.push(partials[i]); | ||
// browsers). | |||
var iterate = function (el) { | |||
for (var i = el.firstChild; i != null; i = i.nextSibling) { | |||
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) { | |||
var mo = re.exec(i.tagName) | |||
if (mo) | |||
result[result.length] = new TocEntry(i, getText(i), mo[1]-1); | |||
iterate(i); | |||
} | } | ||
} | } | ||
} | |||
iterate(el); | |||
return result; | |||
} | |||
|
|
||
// This function does the work. toclevels = 1..4. | var test_node = tags[0]; | ||
function generateToc(toclevels) { |
|
||
var toc = document.getElementById("toc"); | if(!test_node){ | ||
var entries = tocEntries(document.getElementsByTagName("body")[0], toclevels); | return([]); | ||
for (var i = 0; i < entries.length; ++i) { | } else if(test_node.sourceIndex){ | ||
var entry = entries[i]; | tags.sort(function(a, b){ return(a.sourceIndex - b.sourceIndex); }); | ||
if (entry.element.id == "") | } else if(test_node.compareDocumentPosition){ | ||
entry.element.id = "toc" + i; | tags.sort(function(a, b){ return(3 - (a.compareDocumentPosition(b) & 6)); }); | ||
var a = document.createElement("a"); | } | ||
a.href = "#" + entry.element.id; |
|
||
a.appendChild(document.createTextNode(entry.text)); | return(tags); | ||
var div = document.createElement("div"); | }, | ||
div.appendChild(a); |
|
||
div.className = "toclevel" + entry.toclevel; | collect_headers: function(given_levels, doc){ | ||
toc.appendChild(div); | var levels = (given_levels || 'h1,h2,h3,h4,h5'); | ||
var headers = []; | |||
var tags = this.elements_by_tag_names(levels, doc); | |||
|
|||
for(tag_i in tags){ | |||
var tag, level, text, id | |||
|
|||
tag = tags[tag_i]; | |||
level = tag.nodeName.match('H(\\d+)')[1]; | |||
text = tag.innerHTML; | |||
|
|||
if(tag.id){ | |||
id = tag.id; | |||
} else { | |||
id = 'toc_' + tag_i; | |||
tag.id = id; | |||
} | |||
|
|||
headers.push({toclevel: level, text: text, id: id}); | |||
} | |||
|
|||
return(headers); | |||
}, | |||
|
|||
generate_ast: function(doc){ | |||
var headers = this.collect_headers(doc); | |||
var original_root = new this.Header(1, 'ROOT', false); | |||
var root = original_root; | |||
root.mother = root; | |||
|
|||
for(header_i in headers){ | |||
var element = headers[header_i]; | |||
var header = new this.Header(element.toclevel, element.text, true, element.id); | |||
var temp = root; | |||
var i; | |||
|
|||
if(header.level == root.level){ | |||
root.mother.add_child(header); | |||
} else if(header.level > root.level){ | |||
for(i = (header.level - 1); i > root.level; i--){ | |||
var temp_child = new this.Header(i, 'TEMP', false); | |||
temp.add_child(temp_child); | |||
temp = temp_child; | |||
} | |||
|
|||
temp.add_child(header); | |||
} else if(header.level < root.level){ | |||
for(i = header.level; i <= root.level; i++){ | |||
var temp_mother = temp.mother; | |||
temp = temp_mother; | |||
} | |||
|
|||
temp.add_child(header); | |||
} | |||
|
|||
root = header; | |||
} | |||
|
|||
return(original_root); | |||
} | } | ||
if (entries.length == 0) | }; | ||
document.getElementById("header").removeChild(toc); |
|
||
function generateToc(n){ | |||
var root = document.getElementById('toc'); | |||
var ast = TOCCreator.generate_ast(); | |||
ast.to_html(root); | |||
} | } |
Oops, something went wrong.