Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Generate Table of Contents at compile time.
  • Loading branch information
miksago authored and ry committed Nov 18, 2010
1 parent 8591057 commit 8d27393
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 102 deletions.
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -77,10 +77,10 @@ build/doc/api/assets/%: doc/api_assets/% build/doc/api/assets/
build/doc/%: doc/%
cp $< $@

build/doc/api/%.html: doc/api/%.markdown build/default/node $(apidoc_dirs) $(apiassets)
build/doc/api/%.html: doc/api/%.markdown build/default/node $(apidoc_dirs) $(apiassets) tools/doctool/doctool.js
build/default/node tools/doctool/doctool.js doc/template.html $< > $@

build/doc/changelog.html: ChangeLog build/default/node build/doc/ $(apidoc_dirs) $(apiassets)
build/doc/changelog.html: ChangeLog build/default/node build/doc/ $(apidoc_dirs) $(apiassets) tools/doctool/doctool.js
build/default/node tools/doctool/doctool.js doc/template.html $< \
| sed 's|assets/|api/assets/|g' \
| sed 's|<body>|<body id="changelog">|g' > $@
Expand Down
70 changes: 10 additions & 60 deletions doc/api_assets/core.js
@@ -1,63 +1,13 @@
$(function(){
highlight(undefined, undefined, 'pre');
var $headings = $("h2, h3, h4, h5, h6");

if(! $("body").hasClass("index") && $headings.size() > 2){
var current_level
, last_level = 0
, toc = [
'<div id="toc">',
'<h2>Table Of Contents <a id="toggler" href="#toc">Hide</a></h2>'
];

for(var i=0, hl=$headings.size()+1; i < hl; i++) {
var heading = $headings[i] || false;
if(heading) {
current_level = heading.tagName.substr(1,1);

console.log(current_level, last_level, $(heading).text());

if(last_level != 0 && current_level <= last_level) {
toc.push("</li>");
}

if(current_level > last_level) {
toc.push("<ul>");
toc.push("<li>");
} else if(current_level < last_level) {
console.log(last_level-current_level);
for(var c=last_level-current_level; 0 < c ; c-- ){
toc.push("</ul>");
toc.push("</li>");
}
}

if(current_level == last_level || current_level < last_level) {
toc.push("<li>");
}

toc.push('<a href="#'+$(heading).attr("id")+'">'+$(heading).text()+'</a>');
last_level = current_level;
} else {
toc.push("</li>");
toc.push("</ul>");
}
}

toc.push("</li>");
toc.push("</ul>");
toc.push("<hr />");
toc.push("</div>");

$("#container header").after(toc.join("\n"));
$("#toggler").toggle(function(e){
$("#toc ul").hide();
$(this).text("show");
e.preventDefault();
}, function(e){
$("#toc ul").show();
$(this).text("hide");
e.preventDefault();
});
}

$('<a href="#toc">Hide</a>').appendTo($("#toc h2")).toggle(function(e){
$("#toc ul").hide();
$(this).text("Show");
e.preventDefault();
}, function(e){
$("#toc ul").show();
$(this).text("Hide");
e.preventDefault();
});
});
127 changes: 87 additions & 40 deletions tools/doctool/doctool.js
@@ -1,9 +1,9 @@
/*
Process a single doc file
argv[2] = template file
argv[3] = input file
argv[4] = output file
argv[2] = template file
argv[3] = input file
argv[4] = output file
*/
var fs = require("fs"),
Expand All @@ -14,9 +14,8 @@ var fs = require("fs"),

var template = fs.readFileSync(argv[2], "utf8");

var ids = {};

function formatIdString(str){
function formatIdString(str) {
str = str
.replace(/\([^)}]*\)/gmi, "")
.replace(/[^A-Za-z0-9_.]+/gmi, "_");
Expand All @@ -25,59 +24,107 @@ function formatIdString(str){
}


var includeExpr = /^@include\s+([A-Za-z0-9-_]+)(?:\.)?([a-zA-Z]*)$/gmi;
function convertData(data, current_file){
// Allow including other pages in the data.
function loadIncludes(data){
return data.replace(includeExpr, function(src, name, ext){
try {
var include_path = path.join(current_file, "../", name+"."+(ext || "markdown"))
return loadIncludes(fs.readFileSync(include_path, "utf8"));
} catch(e) {
return "";
function generateToc(data) {
var last_level = 0
, first_level = 0
, toc = [
'<div id="toc">',
'<h2>Table Of Contents</h2>'
];

data.replace(/(^#+)\W+([^$\n]+)/gmi, function(src, level, text) {
level = level.length;

if (first_level == 0) first_level = level;

if (level <= last_level) {
toc.push("</li>");
}

if (level > last_level) {
toc.push("<ul>");
} else if (level < last_level) {
for(var c=last_level-level; 0 < c ; c-- ) {
toc.push("</ul>");
toc.push("</li>");
}
});
};
}

data = loadIncludes(data);
toc.push("<li>");
toc.push('<a href="#'+formatIdString(text)+'">'+text+'</a>');

// Convert it to HTML from Markdown
if(data.length == 0){
data = "Sorry, this section is currently undocumented, but we'll be working on it.";
last_level = level;
});

for(var c=last_level-first_level; 0 <= c ; c-- ) {
toc.push("</li>");
toc.push("</ul>");
}

data = markdown.toHTML(markdown.parse(data), {xhtml:true});
toc.push("<hr />")
toc.push("</div>");

return toc.join("");
}

data = data.replace(/<hr><\/hr>/g, "<hr />");

data = data.replace(/(\<h[2-6])\>([^<]+)(\<\/h[1-6]\>)/gmi, function(o, ts, c, te){
var id = formatIdString(c);
return ts+' id="'+id+'">'+c+te;
var includeExpr = /^@include\s+([A-Za-z0-9-_]+)(?:\.)?([a-zA-Z]*)$/gmi;
// Allow including other pages in the data.
function loadIncludes(data, current_file) {
return data.replace(includeExpr, function(src, name, ext) {
try {
var include_path = path.join(current_file, "../", name+"."+(ext || "markdown"))
return loadIncludes(fs.readFileSync(include_path, "utf8"), current_file);
} catch(e) {
return "";
}
});
}

return data;
};

if(argc > 3){
var filename = argv[3];
function convertData(data) {
// Convert it to HTML from Markdown
var html = markdown.toHTML(markdown.parse(data), {xhtml:true})
.replace(/<hr><\/hr>/g, "<hr />")
.replace(/(\<h[2-6])\>([^<]+)(\<\/h[1-6]\>)/gmi, function(o, ts, c, te) {
return ts+' id="'+formatIdString(c)+'">'+c+te;
});

return html;
}


fs.readFile(filename, "utf8", function(err, data){
if(err) throw err;
if (argc > 3) {
var filename = argv[3],
output = template,
html;

// do conversion stuff.
var html = convertData(data, filename);
var output = template.replace("{{content}}", html);
fs.readFile(filename, "utf8", function(err, data) {
if (err) throw err;

// go recursion.
data = loadIncludes(data, filename);
// go markdown.
html = convertData(data);
filename = path.basename(filename, '.markdown');

if(filename == "index"){
output = output.replace("{{section}}", "");
output = output.replace(/<body([^>]*)>/, '<body class="index" $1>');
} else {
if (filename != "_toc" && filename != "index") {
if (data) {
html = generateToc(data) + "\n" + html;
}

output = output.replace("{{section}}", filename+" - ")
} else {
output = output.replace("{{section}}", "");
output = output.replace(/<body([^>]*)>/, '<body class="'+filename+'" $1>');
}
if (html.length == 0) {
html = "Sorry, this section is currently undocumented, \
but we'll be working on it.";
}
output = output.replace("{{content}}", html);

if(argc > 4) {
if (argc > 4) {
fs.writeFile(argv[4], output);
} else {
process.stdout.write(output);
Expand Down

0 comments on commit 8d27393

Please sign in to comment.