diff options
author | Micheil Smith <micheil@brandedcode.com> | 2010-11-18 12:26:37 +1100 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-11-17 17:38:54 -0800 |
commit | 8d27393aa20afe9e0cba211e08957183587540e4 (patch) | |
tree | 5fb8e96cd44ccf4177273e7e8469ce35cebf3008 /tools | |
parent | 8591057fa3b141da61849ebbb310bed96e0d03de (diff) | |
download | node-8d27393aa20afe9e0cba211e08957183587540e4.tar.gz |
Generate Table of Contents at compile time.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/doctool/doctool.js | 127 |
1 files changed, 87 insertions, 40 deletions
diff --git a/tools/doctool/doctool.js b/tools/doctool/doctool.js index 4f3c6d4c5..4b4f2f07b 100644 --- a/tools/doctool/doctool.js +++ b/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"), @@ -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, "_"); @@ -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); |