Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Pretty Awesome (and Necessary) Documentation Assembly--A total documentation build system for technical writers, and those who want to be like them.
Tree: 9ebbc05f85

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.

Panda Docs

What's black and white and read all over?

Panda reading a newspaper

This is a documentation build system that takes Markdown files as sources, and produces HTML files. It runs on Node.js, and uses Jade as its templating engine.


  • Markdown syntax using NAMP.
  • Support for content references (conrefs) in Markdown
  • Pass in individual files or entire directories; exclude files and directories with glob matching
  • Embeddable metadata
  • Easy template customization
  • Automatic linking for all heading tags (h1, h2, e.t.c.), as well as automatic table of headers generation
  • Provides a JSON format


Make sure you have a recent build of Node.js (this was tested on v0.6.0). Install it using npm:

npm install panda-docs -g

Want to try a demonstration? Then clone this repository, and run

node build.js

That'll turn this README into a better looking HTML file in the /out directory.


Use panda-docs in a script! Simply define a file similar to this one:

var options = {
    title: "Panda (from script)"

panda.make(["./src/"], options, function(err, cbReturn) {
    if (err) {

You can find out more information on options you can use below:

Available Options

There are a number of arguments you can pass to Panda that affect the entire build. They are:

  • -h, --help` Show this help message and exit.
  • -v, --version Show program's version number and exit.
  • -o PATH, --output PATH Resulting file(s) location [out]
  • -oa PATH, --outputAssets PATH Resulting file(s) location for assets [out/assets]
  • -tSTRING,--title STRING` Title of the index page [Panda: Default Title Here]
  • --skin PATH The location of your primary Jade template [./templates/default/layout.jade]
  • --assets PATH The location of your asset files (CSS, Javascript, e.t.c.) [./templates/default/assets]
  • -d, --disableTests Disables the test suite that runs at the end of an HTML build. This is NOT recommended.
  • --keepFirstHeader If set, keeps the first header (<h1>) detected
  • --baseUrl STRING Base url of all links [./]
  • --keepOutDir Does not wipe output directory before building (defaults to false)
  • --safeWords An array of words not to complain about when performing a spellcheck test

Jade Templates

You have to specify at least one Jade file as a template for your pages. Within your Jade template, you have access to the following variables:

  • content is the transformed HTML content of your Markdown file
  • metadata is an object containing your document-based metadata values
  • manifest is an object containing the Manifest.json properties
  • toh is an object containing the headings for each file (h1, h2, e.t.c.). See below for more information on this object.
  • headingTable is a function you can use to generate a list of your page's table of contents. See below for more information on using this
  • fileName is the name of the resulting file (without the extension)
  • title is the title of the documentation
  • pageTitle is the title of the current page
  • mtime indicates the last modified time of your source file
  • markdown references the Markdown converter; since this is based on namp, you'll want to add .html at the end to get the actual HTML

All your passed in options are also available.

Working with a Table of Contents for a Page

The toh object has the following structure:

    rank: 1,                   // the hierarchy in the toc (based on h1, h2, ..., h6)
    name: "My first header",   // the content of the header
    link: "#my-first-header",  // a direct internal url to be used
    line: 0                    // the line number in the original markdown file
    text: "# My first header"  // the actual Markdown header text
  }, {
    rank: 2,
    name: "Subtitle",
    link: "#subtitle",
    line: 4
  }, {
    rank: 4,
    name: "Minor Header",
    link: "#minor-header",
    line: 25
    rank: 2,
    name: "Another Subtitle!",
    link: "#another-subtitle",
    line: 58

Each non-h1 header is also automatically an anchor. The resulting HTML for an H2 called "Testing Your Highlighter" looks like this:

<h2 id="testing-your-highlighter">
    <a class="heading_anchor" href="#testing-your-highlighter"></a>
    <i class="headerLinkIcon"></i>
    Testing Your Highlighter

You can add an icon for headerLinkIcon to make it more discoverable, i.e. by using something from Font Awesome.

Finally, you also have access to a function, called headingTable, that automatically generates a table of contents for each page's heading. The resulting HTML produced by this function might look like this:

<ol class="tocContainer level_1">
    <li class="tocItem level_2">
        <a href="#defining-a-mode">Defining a Mode</a>
    <li class="tocItem level_2">
        <a href="#defining-syntax-highlighting-rules">Defining Syntax Highlighting Rules</a>
        <ol class="tocContainer level_2">
            <li class="tocItem level_3">
                <a href="#defining-tokens">Defining Tokens</a>
            <li class="tocItem level_3">
                <a href="#defining-regular-expressions">Defining Regular Expressions</a>
                <ol class="tocContainer level_3">
                    <li class="tocItem level_4">
                        <a href="#groupings">Groupings</a>
    <li class="tocItem level_2">
        <a href="#defining-states">Defining States</a>
    <li class="tocItem level_2">
        <a href="#code-folding">Code Folding</a>

Basically, every sub-heading is nested underneath a parent heading of larger size. In the example above, we have a page with an <h2> tag called "Defining a Mode", followed by another <h2>, "Defining Syntax Highlighting Rules", which itself is followed by two <h3> tags, "Defining Tokens" and "Defining Regular Expressions." The last <h3> has an <h4> called "Groupings." We then go back to some regular old <h2> tags.

This generated table always ignores the <h1> tag. You can customize it by by embedding the following signature into your Jade template:

headingTable(toh, maxLevel, classes)


  • toh is your page's toh object
  • maxLevel is optional, and refers to the maximum heading number you want to display; this defaults to 4. Basically, any h tag greater than this number is ignored
  • classes is optional, and it's an array of two strings. The first is a class that applies to all the <ol> tags; the second applies to the <li> tags. Every <ol> and <li> automatically gets a level_<POSITION> class that is set to the current item's position

Thus, to generate the above, your Jade template might go:

!= headingTable(toh, 5, ['tocContainer', 'tocItem'])

Callback Results

The callback for panda returns a JSON with one key: files, which is a listing of all the files generated. files is an array of objects, containing the following keys:

  • filename: the filename (minus the suffix)
  • mtime: the last modified time of your source file
  • pageTitle: the title of the page (text only, meaning minus any # or <h1> indicators)

You could use this information to provide a list of Recently Updated content--which is exactly what the Cloud9 IDE User Documentation does.

Something went wrong with that request. Please try again.