summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMicheil Smith <micheil@brandedcode.com>2010-11-18 12:26:37 +1100
committerRyan Dahl <ry@tinyclouds.org>2010-11-17 17:38:54 -0800
commit8d27393aa20afe9e0cba211e08957183587540e4 (patch)
tree5fb8e96cd44ccf4177273e7e8469ce35cebf3008 /tools
parent8591057fa3b141da61849ebbb310bed96e0d03de (diff)
downloadnode-8d27393aa20afe9e0cba211e08957183587540e4.tar.gz
Generate Table of Contents at compile time.
Diffstat (limited to 'tools')
-rw-r--r--tools/doctool/doctool.js127
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);