Skip to content

Commit

Permalink
Docco 0.2.0, with and NPM installer.
Browse files Browse the repository at this point in the history
  • Loading branch information
jashkenas committed Sep 10, 2010
1 parent b2d97bc commit 948a172
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 22 deletions.
8 changes: 6 additions & 2 deletions Cakefile
@@ -1,7 +1,11 @@
exec = require('child_process').exec
{spawn, exec} = require 'child_process'

option '-p', '--prefix [DIR]', 'set the installation prefix for `cake install`'

task 'build', 'build the docco library', ->
coffee = spawn 'coffee', ['-cw', '-o', 'lib', 'src']
coffee.stdout.on 'data', (data) -> print data.toString()

task 'install', 'install the `docco` command into /usr/local (or --prefix)', (options) ->
base = options.prefix or '/usr/local'
lib = base + '/lib/docco'
Expand All @@ -15,7 +19,7 @@ task 'install', 'install the `docco` command into /usr/local (or --prefix)', (op

task 'doc', 'rebuild the Docco documentation', ->
exec([
'bin/docco docco.coffee'
'bin/docco src/docco.coffee'
'sed "s/docco.css/resources\\/docco.css/" < docs/docco.html > index.html'
'rm -r docs'
].join(' && '), (err) ->
Expand Down
10 changes: 4 additions & 6 deletions bin/docco
@@ -1,10 +1,8 @@
#!/usr/bin/env node

var path = require('path');
var fs = require('fs');
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../');
var cmd = 'coffee ' + path.join(lib, 'docco.coffee') + ' -- ' + process.ARGV.slice(2).join(' ');
var fs = require('fs');
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

require('child_process').exec(cmd, function(err, stdout, stderr) {
if (err) process.stdio.writeError(stderr.read());
});
process.ARGV = process.argv = process.argv.slice(2, process.argv.length);
require(lib + '/docco.js');
14 changes: 7 additions & 7 deletions index.html
Expand Up @@ -16,10 +16,9 @@
<p>To install Docco, first make sure you have <a href="http://nodejs.org/">Node.js</a>,
<a href="http://pygments.org/">Pygments</a> (install the latest dev version of Pygments
from <a href="http://dev.pocoo.org/hg/pygments-main">its Mercurial repo</a>), and
<a href="http://coffeescript.org/">CoffeeScript</a>. Then, to install system-wide in
<code>/usr/local</code>:</p>
<a href="http://coffeescript.org/">CoffeeScript</a>. Then, with NPM:</p>

<pre><code>sudo cake install
<pre><code>sudo npm install docco
</code></pre>

<p>If <strong>Node.js</strong> doesn't run on your platform, or you'd prefer a more convenient
Expand Down Expand Up @@ -95,12 +94,13 @@
<span class="nv">html = </span><span class="nx">docco_template</span> <span class="p">{</span>
<span class="nx">title</span><span class="o">:</span> <span class="nx">title</span><span class="p">,</span> <span class="nx">sections</span><span class="o">:</span> <span class="nx">sections</span><span class="p">,</span> <span class="nx">sources</span><span class="o">:</span> <span class="nx">sources</span><span class="p">,</span> <span class="nx">path</span><span class="o">:</span> <span class="nx">path</span><span class="p">,</span> <span class="nx">destination</span><span class="o">:</span> <span class="nx">destination</span>
<span class="p">}</span>
<span class="nx">puts</span> <span class="s2">&quot;docco: $source -&gt; $dest&quot;</span>
<span class="nx">puts</span> <span class="s2">&quot;docco: #{source} -&gt; #{dest}&quot;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">writeFile</span> <span class="nx">dest</span><span class="p">,</span> <span class="nx">html</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <h3>Helpers &amp; Setup</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Require our external dependencies, including <strong>Showdown.js</strong>
(the JavaScript implementation of Markdown).</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">fs = </span><span class="nx">require</span> <span class="s1">&#39;fs&#39;</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s1">&#39;path&#39;</span>
<span class="nv">showdown = </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./vendor/showdown&#39;</span><span class="p">).</span><span class="nx">Showdown</span>
<span class="p">{</span><span class="nx">spawn</span><span class="p">,</span> <span class="nx">exec</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s1">&#39;child_process&#39;</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>A list of the languages that Docco supports, mapping the file extension to
<span class="nv">showdown = </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./../vendor/showdown&#39;</span><span class="p">).</span><span class="nx">Showdown</span>
<span class="p">{</span><span class="nx">spawn</span><span class="p">,</span> <span class="nx">exec</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s1">&#39;child_process&#39;</span>
<span class="p">{</span><span class="nx">puts</span><span class="p">,</span> <span class="nx">print</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s1">&#39;sys&#39;</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>A list of the languages that Docco supports, mapping the file extension to
the name of the Pygments lexer and the symbol that indicates a comment. To
add another language to Docco's repertoire, add it here.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">languages =</span>
<span class="s1">&#39;.coffee&#39;</span><span class="o">:</span>
Expand All @@ -125,7 +125,7 @@
<span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/&lt;%=(.+?)%&gt;/g</span><span class="p">,</span> <span class="s2">&quot;&#39;,$1,&#39;&quot;</span><span class="p">)</span>
<span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;&lt;%&#39;</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;&#39;);&quot;</span><span class="p">)</span>
<span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;%&gt;&#39;</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;p.push(&#39;&quot;</span><span class="p">)</span> <span class="o">+</span>
<span class="s2">&quot;&#39;);}return p.join(&#39;&#39;);&quot;</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Create the template that we will use to generate the Docco HTML page.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">docco_template = </span><span class="nx">template</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">__dirname</span> <span class="o">+</span> <span class="s1">&#39;/resources/docco.jst&#39;</span><span class="p">).</span><span class="nx">toString</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>The CSS styles we'd like to apply to the documentation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">docco_styles = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">__dirname</span> <span class="o">+</span> <span class="s1">&#39;/resources/resources/docco.css&#39;</span><span class="p">).</span><span class="nx">toString</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>The start of each Pygments highlight block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">highlight_start = </span><span class="s1">&#39;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&#39;</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>The end of each Pygments highlight block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">highlight_end = </span><span class="s1">&#39;&lt;/pre&gt;&lt;/div&gt;&#39;</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>Run the script.
<span class="s2">&quot;&#39;);}return p.join(&#39;&#39;);&quot;</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Create the template that we will use to generate the Docco HTML page.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">docco_template = </span><span class="nx">template</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">__dirname</span> <span class="o">+</span> <span class="s1">&#39;/../resources/docco.jst&#39;</span><span class="p">).</span><span class="nx">toString</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>The CSS styles we'd like to apply to the documentation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">docco_styles = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">__dirname</span> <span class="o">+</span> <span class="s1">&#39;/../resources/resources/docco.css&#39;</span><span class="p">).</span><span class="nx">toString</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>The start of each Pygments highlight block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">highlight_start = </span><span class="s1">&#39;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&#39;</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>The end of each Pygments highlight block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">highlight_end = </span><span class="s1">&#39;&lt;/pre&gt;&lt;/div&gt;&#39;</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>Run the script.
For each source file passed in as an argument, generate the documentation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">sources = </span><span class="nx">process</span><span class="p">.</span><span class="nx">ARGV</span><span class="p">.</span><span class="nx">sort</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">ensure_directory</span> <span class="o">-&gt;</span>
Expand Down
160 changes: 160 additions & 0 deletions lib/docco.js
@@ -0,0 +1,160 @@
(function() {
var _a, _b, _c, destination, docco_styles, docco_template, ensure_directory, exec, ext, fs, generate_documentation, generate_html, get_language, highlight, highlight_end, highlight_start, l, languages, parse, path, print, puts, showdown, sources, spawn, template;
var __hasProp = Object.prototype.hasOwnProperty;
generate_documentation = function(source, callback) {
return fs.readFile(source, "utf-8", function(error, code) {
var sections;
if (error) {
throw error;
}
sections = parse(source, code);
return highlight(source, sections, function() {
generate_html(source, sections);
return callback();
});
});
};
parse = function(source, code) {
var _a, _b, _c, code_text, docs_text, has_code, language, line, lines, save, sections;
lines = code.split('\n');
sections = [];
language = get_language(source);
has_code = (docs_text = (code_text = ''));
save = function(docs, code) {
return sections.push({
docs_text: docs,
code_text: code
});
};
_b = lines;
for (_a = 0, _c = _b.length; _a < _c; _a++) {
line = _b[_a];
if (line.match(language.comment_matcher)) {
if (has_code) {
save(docs_text, code_text);
has_code = (docs_text = (code_text = ''));
}
docs_text += line.replace(language.comment_matcher, '') + '\n';
} else {
has_code = true;
code_text += line + '\n';
}
}
save(docs_text, code_text);
return sections;
};
highlight = function(source, sections, callback) {
var _a, _b, _c, _d, language, output, pygments, section;
language = get_language(source);
pygments = spawn('pygmentize', ['-l', language.name, '-f', 'html', '-O', 'encoding=utf-8']);
output = '';
pygments.stderr.addListener('data', function(error) {
if (error) {
return puts(error);
}
});
pygments.stdout.addListener('data', function(result) {
if (result) {
return output += result;
}
});
pygments.addListener('exit', function() {
var _a, _b, fragments, i, section;
output = output.replace(highlight_start, '').replace(highlight_end, '');
fragments = output.split(language.divider_html);
_a = sections;
for (i = 0, _b = _a.length; i < _b; i++) {
section = _a[i];
section.code_html = highlight_start + fragments[i] + highlight_end;
section.docs_html = showdown.makeHtml(section.docs_text);
}
return callback();
});
pygments.stdin.write((function() {
_a = []; _c = sections;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
section = _c[_b];
_a.push(section.code_text);
}
return _a;
})().join(language.divider_text));
return pygments.stdin.end();
};
generate_html = function(source, sections) {
var dest, html, title;
title = path.basename(source);
dest = destination(source);
html = docco_template({
title: title,
sections: sections,
sources: sources,
path: path,
destination: destination
});
puts("docco: " + (source) + " -> " + (dest));
return fs.writeFile(dest, html);
};
fs = require('fs');
path = require('path');
showdown = require('./../vendor/showdown').Showdown;
_a = require('child_process');
spawn = _a.spawn;
exec = _a.exec;
_b = require('sys');
puts = _b.puts;
print = _b.print;
languages = {
'.coffee': {
name: 'coffee-script',
symbol: '#'
},
'.js': {
name: 'javascript',
symbol: '//'
},
'.rb': {
name: 'ruby',
symbol: '#'
}
};
_c = languages;
for (ext in _c) {
if (!__hasProp.call(_c, ext)) continue;
l = _c[ext];
l.comment_matcher = new RegExp('^\\s*' + l.symbol + '\\s?');
l.divider_text = '\n' + l.symbol + 'DIVIDER\n';
l.divider_html = new RegExp('\\n*<span class="c1">' + l.symbol + 'DIVIDER<\\/span>\\n*');
}
get_language = function(source) {
return languages[path.extname(source)];
};
destination = function(filepath) {
return 'docs/' + path.basename(filepath, path.extname(filepath)) + '.html';
};
ensure_directory = function(callback) {
return exec('mkdir -p docs', function() {
return callback();
});
};
template = function(str) {
return new Function('obj', 'var p=[],print=function(){p.push.apply(p,arguments);};' + 'with(obj){p.push(\'' + str.replace(/[\r\t\n]/g, " ").replace(/'(?=[^<]*%>)/g, "\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g, "',$1,'").split('<%').join("');").split('%>').join("p.push('") + "');}return p.join('');");
};
docco_template = template(fs.readFileSync(__dirname + '/../resources/docco.jst').toString());
docco_styles = fs.readFileSync(__dirname + '/../resources/docco.css').toString();
highlight_start = '<div class="highlight"><pre>';
highlight_end = '</pre></div>';
sources = process.ARGV.sort();
if (sources.length) {
ensure_directory(function() {
var files, next_file;
fs.writeFile('docs/docco.css', docco_styles);
files = sources.slice(0);
next_file = function() {
if (files.length) {
return generate_documentation(files.shift(), next_file);
}
};
return next_file();
});
}
})();
21 changes: 21 additions & 0 deletions package.json
@@ -0,0 +1,21 @@
{
"name": "docco",
"description": "The Quick and Dirty Literate Programming Documentation Generator",
"keywords": ["documentation", "docs", "generator", "coffeescript"],
"author": "Jeremy Ashkenas",
"version": "0.2.0",
"licenses": [{
"type": "MIT",
"url": "http://opensource.org/licenses/mit-license.php"
}],
"engines": {
"node": ">=0.2.0"
},
"directories": {
"lib" : "./lib"
},
"main" : "./lib/docco",
"bin": {
"docco": "./bin/docco",
}
}

0 comments on commit 948a172

Please sign in to comment.