From ab280e7cfd7871131cb739b8e612db62cfdcd414 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Mon, 11 Mar 2013 11:01:13 +0800 Subject: [PATCH] Docco can now handle literate CoffeeScript, as well as literate anything-else, with the .codeext.md convention --- bin/docco | 4 +- docco.js | 55 ++- docco.litcoffee | 47 +-- index.html | 755 +++++++++++++++++++++++++++++++-------- package.json | 3 +- resources/languages.json | 5 +- 6 files changed, 685 insertions(+), 184 deletions(-) diff --git a/bin/docco b/bin/docco index adda5f26..d8fd60f2 100755 --- a/bin/docco +++ b/bin/docco @@ -2,5 +2,5 @@ var path = require('path'); var fs = require('fs'); -var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); -require(lib + '/docco.js').run(); +var dir = path.join(path.dirname(fs.realpathSync(__filename)), '../'); +require(dir + 'docco.js').run(); diff --git a/docco.js b/docco.js index e1fb0d93..5207ae67 100644 --- a/docco.js +++ b/docco.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 1.6.1 (function() { - var commander, defaults, document, ensureDirectory, exec, ext, fs, generateDocumentation, generateHtml, getLanguage, getResource, highlight, highlightEnd, highlightStart, htmlEscape, l, languages, marked, parse, path, resolveSource, run, spawn, template, version, _ref, + var commander, defaults, document, ensureDirectory, exec, ext, fs, generateDocumentation, generateHtml, getLanguage, getResource, highlight, highlightEnd, highlightStart, htmlEscape, l, languages, marked, parse, path, resolveSource, run, spawn, version, _, _ref, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; generateDocumentation = function(source, config, callback) { @@ -19,7 +19,7 @@ }; parse = function(source, code, config) { - var codeText, docsText, hasCode, language, line, lines, save, sections, _i, _len; + var codeText, docsText, hasCode, i, language, line, lines, match, save, sections, _i, _j, _len, _len1; lines = code.split('\n'); sections = []; language = getLanguage(source, config); @@ -30,8 +30,14 @@ codeText: codeText }); }; - for (_i = 0, _len = lines.length; _i < _len; _i++) { - line = lines[_i]; + if (language.literate) { + for (i = _i = 0, _len = lines.length; _i < _len; i = ++_i) { + line = lines[i]; + lines[i] = (match = /^([ ]{4}|\t)/.exec(line)) ? line.slice(match[0].length) : '# ' + line; + } + } + for (_j = 0, _len1 = lines.length; _j < _len1; _j++) { + line = lines[_j]; if (line.match(language.commentMatcher) && !line.match(language.commentFilter)) { if (hasCode) { save(docsText, codeText); @@ -114,7 +120,7 @@ generateHtml = function(source, sections, config) { var dest, destination, html, title; destination = function(filepath) { - return path.join(config.output, path.basename(filepath, path.extname(filepath)) + '.html'); + return path.join(config.output, path.basename(filepath, config.fullExtension) + '.html'); }; title = path.basename(source); dest = destination(source); @@ -130,19 +136,21 @@ return fs.writeFileSync(dest, html); }; + _ = require('underscore'); + fs = require('fs'); path = require('path'); marked = require('marked'); - _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec; - commander = require('commander'); + _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec; + getResource = function(name) { var fullPath; - fullPath = path.join(__dirname, '..', 'resources', name); + fullPath = path.join(__dirname, 'resources', name); return fs.readFileSync(fullPath).toString(); }; @@ -159,7 +167,19 @@ } getLanguage = function(source, config) { - return languages[config.extension || path.extname(source)]; + var codeExt, codeLang, lang; + ext = config.fullExtension = config.extension || path.extname(source); + lang = languages[ext]; + if (lang.name === 'markdown') { + codeExt = path.extname(path.basename(source, ext)); + if (codeExt && (codeLang = languages[codeExt])) { + config.fullExtension = codeExt + ext; + lang = _.extend({}, codeLang, { + literate: true + }); + } + } + return lang; }; ensureDirectory = function(dir, cb, made) { @@ -185,10 +205,6 @@ }); }; - 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('');"); - }; - highlightStart = '
';
 
   highlightEnd = '
'; @@ -247,7 +263,7 @@ console.log("docco: skipped unknown type (" + m + ")"); } } - config.doccoTemplate = template(fs.readFileSync(config.template).toString()); + config.doccoTemplate = _.template(fs.readFileSync(config.template).toString()); doccoStyles = fs.readFileSync(config.css).toString(); return ensureDirectory(config.output, function() { var files, nextFile; @@ -287,4 +303,15 @@ })(); }; + module.exports = { + run: run, + document: document, + parse: parse, + resolveSource: resolveSource, + version: version, + defaults: defaults, + languages: languages, + ensureDirectory: ensureDirectory + }; + }).call(this); diff --git a/docco.litcoffee b/docco.litcoffee index adb9d122..257dbe40 100644 --- a/docco.litcoffee +++ b/docco.litcoffee @@ -79,6 +79,13 @@ follows it, and create an individual **section** for it. save = (docsText, codeText) -> sections.push {docsText, codeText} + if language.literate + for line, i in lines + lines[i] = if match = (/^([ ]{4}|\t)/).exec line + line[match[0].length..] + else + '# ' + line + for line in lines if line.match(language.commentMatcher) and not line.match(language.commentFilter) if hasCode @@ -89,6 +96,7 @@ follows it, and create an individual **section** for it. hasCode = yes codeText += line + '\n' save docsText, codeText + sections Highlights parsed sections of code, using **Pygments** over stdio, @@ -150,7 +158,7 @@ the specified output path. generateHtml = (source, sections, config) -> destination = (filepath) -> - path.join(config.output, path.basename(filepath, path.extname(filepath)) + '.html') + path.join(config.output, path.basename(filepath, config.fullExtension) + '.html') title = path.basename source dest = destination source html = config.doccoTemplate { @@ -170,16 +178,17 @@ Helpers & Setup Require our external dependencies. + _ = require 'underscore' fs = require 'fs' path = require 'path' marked = require 'marked' - {spawn, exec} = require 'child_process' commander = require 'commander' + {spawn, exec} = require 'child_process' Read resource file and return its content. getResource = (name) -> - fullPath = path.join __dirname, '..', 'resources', name + fullPath = path.join __dirname, 'resources', name fs.readFileSync(fullPath).toString() Languages are stored in JSON format in the file `resources/languages.json` @@ -218,7 +227,15 @@ Build out the appropriate matchers and delimiters for each language. Get the current language we're documenting, based on the extension. - getLanguage = (source, config) -> languages[config.extension or path.extname(source)] + getLanguage = (source, config) -> + ext = config.fullExtension = config.extension or path.extname(source) + lang = languages[ext] + if lang.name is 'markdown' + codeExt = path.extname(path.basename(source, ext)) + if codeExt and codeLang = languages[codeExt] + config.fullExtension = codeExt + ext + lang = _.extend {}, codeLang, {literate: yes} + lang Ensure that the destination directory exists. @@ -231,22 +248,6 @@ Ensure that the destination directory exists. if er then cb er, made else ensureDirectory dir, cb, made cb er, made -Micro-templating, originally by John Resig, borrowed by way of -[Underscore.js](http://documentcloud.github.com/underscore/). - - template = (str) -> - 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('');" - The start of each Pygments highlight block. highlightStart = '
'
@@ -303,7 +304,7 @@ Run Docco over a list of `sources` with the given `options`.
       config.sources = resolved.filter((source) -> getLanguage source, config).sort()
       console.log "docco: skipped unknown type (#{m})" for m in resolved when m not in config.sources
 
-      config.doccoTemplate = template fs.readFileSync(config.template).toString()
+      config.doccoTemplate = _.template fs.readFileSync(config.template).toString()
       doccoStyles = fs.readFileSync(config.css).toString()
 
       ensureDirectory config.output, ->
@@ -333,5 +334,5 @@ Resolve a wildcard `source` input to the files it matches.
 Public API
 ----------
 
-module.exports = {run, document, parse, resolveSource, version, defaults,
-  languages, ensureDirectory}
+    module.exports = {run, document, parse, resolveSource, version, defaults,
+      languages, ensureDirectory}
diff --git a/index.html b/index.html
index e8f2fc97..8b736c4d 100644
--- a/index.html
+++ b/index.html
@@ -1,4 +1,30 @@
-      docco.coffee              
  • docco.coffee

  • Docco is a quick-and-dirty, hundred-line-long, literate-programming-style + + + + + docco.litcoffee + + + + + +

    +
    + +
      +
    • +
      +

      docco.litcoffee

      +
      +
    • + + +
    • +
      +
      + +
      +

      Docco is a quick-and-dirty, hundred-line-long, literate-programming-style documentation generator. It produces HTML that displays your comments alongside your code. Comments are passed through Markdown, and code is @@ -7,10 +33,9 @@ This page is the result of running Docco against its own source file.

      -

      If you install Docco, you can run it from the command-line: +

      If you install Docco, you can run it from the command-line: docco src/*.coffee

      -
      docco src/*.coffee

      ...will generate an HTML documentation page for each of the named source files, with a menu linking to the other pages, saving it into a docs folder. @@ -22,15 +47,18 @@

      To install Docco, first make sure you have Node.js, Pygments (install the latest dev version of Pygments from its Mercurial repo), and -CoffeeScript. Then, with NPM: +CoffeeScript. + +

      +

      Then, with NPM: sudo npm install -g docco

      -
      sudo npm install -g docco

      Docco can be used to process CoffeeScript, JavaScript, Ruby, Python, or TeX files. Only single-line comments are processed -- block comments are ignored. +

      -

      Partners in Crime:

      +

      Partners in Crime:

      • If Node.js doesn't run on your platform, or you'd prefer a more convenient package, get Ryan Tomayko's @@ -56,43 +84,95 @@

        Partners in Crime:

        Nocco.

      -
    • -

      Main Documentation Generation Functions

      -
    • +

      Main Documentation Generation Functions

      Generate the documentation for a source file by reading it in, splitting it up into comment/code sections, highlighting them for the appropriate language, and merging them into an HTML template. +

      -
      generateDocumentation = (source, config, callback) ->
      +
      +            
      + +
      generateDocumentation = (source, config, callback) ->
         fs.readFile source, (error, buffer) ->
           throw error if error
           code = buffer.toString()
           sections = parse source, code, config
           highlight source, sections, config, ->
             generateHtml source, sections, config
      -      callback()
    • + callback()
+ + + + +
  • +
    +
    + +
    +

    Given a string of source code, parse out each comment and the code that follows it, and create an individual section for it. -Sections take the form: +

    -
    {
    -  docsText: ...
    -  docsHtml: ...
    -  codeText: ...
    -  codeHtml: ...
    -}
    -
    parse = (source, code, config) ->
    +
    +            
    + +
    parse = (source, code, config) ->
       lines    = code.split '\n'
       sections = []
       language = getLanguage source, config
    -  hasCode  = docsText = codeText = ''
    -
    -  save = (docsText, codeText) ->
    -    sections.push {docsText, codeText}
    -
    -  for line in lines
    +  hasCode  = docsText = codeText = ''
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      save = (docsText, codeText) ->
    +    sections.push {docsText, codeText}
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      if language.literate
    +    for line, i in lines
    +      lines[i] = if match = (/^([ ]{4}|\t)/).exec line
    +        line[match[0].length..]
    +      else
    +        '# ' + line
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      for line in lines
         if line.match(language.commentMatcher) and not line.match(language.commentFilter)
           if hasCode
             save docsText, codeText
    @@ -101,21 +181,47 @@ 

    Main Documentation Generation Functions

    else hasCode = yes codeText += line + '\n' - save docsText, codeText - sections
  • + save docsText, codeText
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      sections
    + +
  • + + +
  • +
    +
    + +
    +

    Highlights parsed sections of code, using Pygments over stdio, and runs the text of their corresponding comments through Markdown, using Marked. If Pygments is not present on the system, output the code in plain text. -

    We process all sections with single calls to Pygments and Marked, by inserting marker comments between them, and then splitting the result string wherever the marker occurs. +

    -
    highlight = (source, sections, config, callback) ->
    +
    +            
    + +
    highlight = (source, sections, config, callback) ->
       language = getLanguage source, config
       pygments = spawn 'pygmentize', [
         '-l', language.name,
    @@ -124,48 +230,124 @@ 

    Main Documentation Generation Functions

    ] output = '' code = (section.codeText for section in sections).join language.codeSplitText - docs = (section.docsText for section in sections).join language.docsSplitText - - pygments.stderr.on 'data', -> + docs = (section.docsText for section in sections).join language.docsSplitText
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      pygments.stderr.on 'data', ->
       pygments.stdin.on 'error', ->
       pygments.stdout.on 'data', (result) ->
    -    output += result if result
    -
    -  pygments.on 'exit', ->
    +    output += result if result
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      pygments.on 'exit', ->
         output = output.replace(highlightStart, '').replace(highlightEnd, '')
         if output is ''
           codeFragments = (htmlEscape section.codeText for section in sections)
         else
           codeFragments = output.split language.codeSplitHtml
    -    docsFragments = marked(docs).split language.docsSplitHtml
    -
    -    for section, i in sections
    +    docsFragments = marked(docs).split language.docsSplitHtml
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
        for section, i in sections
           section.codeHtml = highlightStart + codeFragments[i] + highlightEnd
           section.docsHtml = docsFragments[i]
    -    callback()
    -
    -  if pygments.stdin.writable
    +    callback()
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      if pygments.stdin.writable
         pygments.stdin.write code
    -    pygments.stdin.end()
  • + pygments.stdin.end()
    + +
  • + + +
  • +
    +
    + +
    +

    Escape an html string, to produce valid non-highlighted output when pygments is not present on the system. +

    -
    htmlEscape = (string) ->
    +
    +            
    + +
    htmlEscape = (string) ->
       string.replace(/&/g, '&amp;')
         .replace(/</g, '&lt;')
         .replace(/>/g, '&gt;')
         .replace(/"/g, '&quot;')
         .replace(/'/g, '&#x27;')
    -    .replace(/\//g,'&#x2F;')
  • + .replace(/\//g,'&#x2F;')
    + +
  • + + +
  • +
    +
    + +
    +

    Once all of the code is finished highlighting, we can generate the HTML file by passing the completed sections into the template, and then writing the file to the specified output path. +

    -
    generateHtml = (source, sections, config) ->
    +
    +            
    + +
    generateHtml = (source, sections, config) ->
       destination = (filepath) ->
    -    path.join(config.output, path.basename(filepath, path.extname(filepath)) + '.html')
    +    path.join(config.output, path.basename(filepath, config.fullExtension) + '.html')
       title = path.basename source
       dest  = destination source
       html  = config.doccoTemplate {
    @@ -177,124 +359,344 @@ 

    Main Documentation Generation Functions

    css : path.basename(config.css) } console.log "docco: #{source} -> #{dest}" - fs.writeFileSync dest, html
  • -

    Helpers & Setup

    -
  • + fs.writeFileSync dest, html
    + +
  • + + +
  • +
    +
    + +
    + +

    Helpers & Setup

    Require our external dependencies. +

    -
    fs            = require 'fs'
    +
    +            
    + +
    _             = require 'underscore'
    +fs            = require 'fs'
     path          = require 'path'
     marked        = require 'marked'
    -{spawn, exec} = require 'child_process'
    -commander     = require 'commander'
  • +commander = require 'commander' +{spawn, exec} = require 'child_process'
    + +
  • + + +
  • +
    +
    + +
    +

    Read resource file and return its content. +

    -
    getResource = (name) ->
    -  fullPath = path.join __dirname, '..', 'resources', name
    -  fs.readFileSync(fullPath).toString()
  • + +
    + +
    getResource = (name) ->
    +  fullPath = path.join __dirname, 'resources', name
    +  fs.readFileSync(fullPath).toString()
    + +
  • + + +
  • +
    +
    + +
    +

    Languages are stored in JSON format in the file resources/languages.json Each item maps the file extension to the name of the Pygments lexer and the symbol that indicates a comment. To add a new language, modify the file. +

    -
    languages = JSON.parse getResource 'languages.json'
  • + +
    + +
    languages = JSON.parse getResource 'languages.json'
    + +
  • + + +
  • +
    +
    + +
    +

    Build out the appropriate matchers and delimiters for each language. +

    -
    for ext, l of languages
  • + +
    + +
    for ext, l of languages
    + +
  • + + +
  • +
    +
    + +
    +

    Does the line begin with a comment?

    -
      l.commentMatcher = ///^\s*#{l.symbol}\s?///
  • + +
    + +
      l.commentMatcher = ///^\s*#{l.symbol}\s?///
    + +
  • + + +
  • +
    +
    + +
    +

    Ignore hashbangs) and interpolations...

    -
      l.commentFilter = /(^#![/]|^\s*#\{)/
  • + +
    + +
      l.commentFilter = /(^#![/]|^\s*#\{)/
    + +
  • + + +
  • +
    +
    + +
    +

    The dividing token we feed into Pygments, to delimit the boundaries between sections.

    -
      l.codeSplitText = "\n#{l.symbol}DIVIDER\n"
  • + +
    + +
      l.codeSplitText = "\n#{l.symbol}DIVIDER\n"
    + +
  • + + +
  • +
    +
    + +
    +

    The mirror of codeSplitText that we expect Pygments to return. We can split on this to recover the original sections. Note: the class is "c" for Python and "c1" for the other languages

    -
      l.codeSplitHtml = ///\n*<span\sclass="c1?">#{l.symbol}DIVIDER<\/span>\n*///
  • + +
    + +
      l.codeSplitHtml = ///\n*<span\sclass="c1?">#{l.symbol}DIVIDER<\/span>\n*///
    + +
  • + + +
  • +
    +
    + +
    +

    The dividing token we feed into markdown, to delimit the boundaries between sections.

    -
      l.docsSplitText = "\n##{l.name}DOCDIVIDER\n"
  • + +
    + +
      l.docsSplitText = "\n##{l.name}DOCDIVIDER\n"
    + +
  • + + +
  • +
    +
    + +
    +

    The mirror of docsSplitText that we expect markdown to return. We can split on this to recover the original sections.

    -
      l.docsSplitHtml = ///<h1>#{l.name}DOCDIVIDER</h1>///
  • + +
    + +
      l.docsSplitHtml = ///<h1>#{l.name}DOCDIVIDER</h1>///
    + +
  • + + +
  • +
    +
    + +
    +

    Get the current language we're documenting, based on the extension. +

    -
    getLanguage = (source, config) -> languages[config.extension or path.extname(source)]
  • + +
    + +
    getLanguage = (source, config) ->
    +  ext  = config.fullExtension = config.extension or path.extname(source)
    +  lang = languages[ext]
    +  if lang.name is 'markdown'
    +    codeExt = path.extname(path.basename(source, ext))
    +    if codeExt and codeLang = languages[codeExt]
    +      config.fullExtension = codeExt + ext
    +      lang = _.extend {}, codeLang, {literate: yes}
    +  lang
    + +
  • + + +
  • +
    +
    + +
    +

    Ensure that the destination directory exists. +

    -
    ensureDirectory = (dir, cb, made=null) ->
    +
    +            
    + +
    ensureDirectory = (dir, cb, made=null) ->
       mode = parseInt '0777', 8
       fs.mkdir dir, mode, (er) ->
         return cb null, made || dir if not er
         if er.code == 'ENOENT'
           return ensureDirectory path.dirname(dir), (er, made) ->
             if er then cb er, made else ensureDirectory dir, cb, made
    -    cb er, made
  • -

    Micro-templating, originally by John Resig, borrowed by way of -Underscore.js. - -

    -
    template = (str) ->
    -  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('');"
  • + cb er, made
    + +
  • + + +
  • +
    +
    + +
    +

    The start of each Pygments highlight block. +

    -
    highlightStart = '<div class="highlight"><pre>'
  • + +
    + +
    highlightStart = '<div class="highlight"><pre>'
    + +
  • + + +
  • +
    +
    + +
    +

    The end of each Pygments highlight block. +

    -
    highlightEnd   = '</pre></div>'
  • + +
    + +
    highlightEnd   = '</pre></div>'
    + +
  • + + +
  • +
    +
    + +
    +

    Extract the docco version from package.json +

    -
    version = JSON.parse(fs.readFileSync("#{__dirname}/../package.json")).version
  • + +
    + +
    version = JSON.parse(fs.readFileSync("#{__dirname}/package.json")).version
    + +
  • + + +
  • +
    +
    + +
    +

    Default configuration options. +

    -
    defaults =
    -  template : "#{__dirname}/../resources/docco.jst"
    -  css      : "#{__dirname}/../resources/resources/docco.css"
    +
    +            
    + +
    defaults =
    +  template : "#{__dirname}/resources/docco.jst"
    +  css      : "#{__dirname}/resources/resources/docco.css"
       output   : "docs/"
    -  extension: null
  • -

    Run from Commandline

    -
  • + extension: null
    + +
  • + + +
  • +
    +
    + +
    + +

    Run from Commandline

    Run Docco from a set of command line arguments. +Parse command line using Commander JS. +

    -
      -
    1. Parse command line using Commander JS.
    2. -
    3. Document sources, or print the usage help if none are specified.
    4. -
    -
    run = (args=process.argv) ->
    +
    +            
    + +
    run = (args=process.argv) ->
       commander.version(version)
         .usage("[options] <filePattern ...>")
         .option("-c, --css [file]","use a custom css file",defaults.css)
    @@ -306,50 +708,100 @@ 

    Run from Commandline

    if commander.args.length document(commander.args.slice(),commander) else - console.log commander.helpInformation()
  • -

    Document Sources

    -
  • + console.log commander.helpInformation()
    + +
  • + + +
  • +
    +
    + +
    + +

    Document Sources

    Run Docco over a list of sources with the given options. +

    -
      -
    1. Construct config to use by taking defaults first, then merging in options
    2. -
    3. Generate the resolved source list, filtering out unknown types.
    4. -
    5. Load the specified template and css files.
    6. -
    7. Ensure the output path is created, write out the CSS file, -document each source, and invoke the completion callback if it is specified.
    8. -
    -
    document = (sources, options = {}, callback = null) ->
    +
    +            
    + +
    document = (sources, options = {}, callback = null) ->
       config = {}
       config[key] = defaults[key] for key,value of defaults
    -  config[key] = value for key,value of options if key of defaults
    -
    -  resolved = []
    +  config[key] = value for key,value of options if key of defaults
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      resolved = []
       resolved = resolved.concat(resolveSource(src)) for src in sources
       config.sources = resolved.filter((source) -> getLanguage source, config).sort()
    -  console.log "docco: skipped unknown type (#{m})" for m in resolved when m not in config.sources
    -
    -  config.doccoTemplate = template fs.readFileSync(config.template).toString()
    -  doccoStyles = fs.readFileSync(config.css).toString()
    -
    -  ensureDirectory config.output, ->
    +  console.log "docco: skipped unknown type (#{m})" for m in resolved when m not in config.sources
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      config.doccoTemplate = _.template fs.readFileSync(config.template).toString()
    +  doccoStyles = fs.readFileSync(config.css).toString()
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
      ensureDirectory config.output, ->
         fs.writeFileSync path.join(config.output,path.basename(config.css)), doccoStyles
         files = config.sources.slice()
         nextFile = ->
           callback() if callback? and not files.length
           generateDocumentation files.shift(), config, nextFile if files.length
    -    nextFile()
  • -

    Resolve Wildcard Source Inputs

    -
  • + nextFile()
    + +
  • + + +
  • +
    +
    + +
    + +

    Resolve Wildcard Source Inputs

    Resolve a wildcard source input to the files it matches. +

    -
      -
    1. If the input contains no wildcard characters, just return it.
    2. -
    3. Convert the wildcard match to a regular expression, and return -an array of files in the path that match it.
    4. -
    -
    resolveSource = (source) ->
    +
    +            
    + +
    resolveSource = (source) ->
       return source if not source.match(/([\*\?])/)
       regex_str = path.basename(source)
         .replace(/\./g, "\\$&")
    @@ -358,20 +810,39 @@ 

    Resolve Wildcard Source Inputs

    regex = new RegExp('^(' + regex_str + ')$') file_path = path.dirname(source) files = fs.readdirSync file_path - return (path.join(file_path,file) for file in files when file.match regex)
  • -

    Exports

    -
  • -

    Information about docco, and functions for programatic usage. -

    -
    exports[key] = value for key, value of {
    -  run           : run
    -  document      : document
    -  parse         : parse
    -  resolveSource : resolveSource
    -  version       : version
    -  defaults      : defaults
    -  languages     : languages
    -  ensureDirectory: ensureDirectory
    -}
    -
    -
  • + return (path.join(file_path,file) for file in files when file.match regex) + + + + +
  • +
    +
    + +
    + +

    Public API

    + +
    + +
    module.exports = {run, document, parse, resolveSource, version, defaults,
    +  languages, ensureDirectory}
    + +
  • + + +
  • +
    +
    + +
    + + +
    + +
  • + + + + + diff --git a/package.json b/package.json index c968f209..d0b33700 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ }, "dependencies": { "commander": ">= 0.5.2", - "marked": ">= 0.2.7" + "marked": ">= 0.2.7", + "underscore":">= 1.0.0" }, "main" : "./docco", "bin": { diff --git a/resources/languages.json b/resources/languages.json index 8506761a..2ea74ab2 100644 --- a/resources/languages.json +++ b/resources/languages.json @@ -1,4 +1,5 @@ { ".coffee": {"name": "coffee-script", "symbol": "#"}, + ".litcoffee": {"name": "coffee-script", "symbol": "#", "literate": true}, ".ls": {"name": "livescript", "symbol": "#"}, ".rb": {"name": "ruby", "symbol": "#"}, ".py": {"name": "python", "symbol": "#"}, @@ -17,8 +18,8 @@ ".hs": {"name": "haskell", "symbol": "--"}, ".erl": {"name": "erlang", "symbol": "%"}, ".hrl": {"name": "erlang", "symbol": "%"}, - ".md": {"name": "text", "symbol": ""}, - ".markdown": {"name": "text", "symbol": ""}, + ".md": {"name": "markdown", "symbol": ""}, + ".markdown": {"name": "markdown", "symbol": ""}, ".less": {"name": "scss", "symbol": "//"}, ".m": {"name": "objc", "symbol": "//"}, ".scala": {"name": "scala", "symbol": "//"}