mweave

This is an experiment in using Markdown and some concepts from literate programming.

npm install mweave
3 downloads in the last week
12 downloads in the last month

Markdown Weave

What is mw.js?

An experiment in using Markdown and Donald Knuth's literate programming concept.

Bootstraping mw.js

I like the idea of writing mw.js using mw.js. To do that I wrote a very simple implementation of mv.js which I'm calling mw-bootstrap.js. I'm leveraging Markdown syntax via JavaScript to generate the vi commands to extract the code. The source for mw.js will be generate by running mw-bootstrap.js on Markdown-Weave.md.

Here is code to bootstrap this whole thing ---

mw-bootstrap.js

    #!/usr/bin/env node
    /**
     * mw-bootstrap.js - an experiment in literate style programming in a 
     * markdown file.
     * @author R. S. Doiel, <rsdoiel@gmail.com>
     * copyright (c) 2013 all rights reserved
     * Licensed under the BSD 2-clause license. See http://opensource.org/licenses/BSD-2-Clause
     */
    require("shelljs/global"); 
    var fs = require("fs"),
        lines = [],
        line = "",
        check = "",
        outputs = {},
        i = 0,
        markdownFilename = "Markdown-Weave.md",
        filename,
        start = 0,
        end = 0;

    function exportLines(outFilename, start, end, lines) {
        var i = 0;
        console.log("# Output Filename: " + outFilename);
        for (i = start; i < lines.length  && i < end; i += 1) {
            lines[i] = lines[i].replace(/\t/g, "    ").replace(/^    /, "");
        }
        fs.writeFile(outFilename, lines.slice(start, end).join("\n"), function (err) {
            if (err) {
                console.error(err);
                process.exit(1);
            }
        });
    }

    if (process.argv.length === 3) {
        markdownFilename = process.argv[2];
    }
    lines = fs.readFileSync(markdownFilename).toString().split(/\n|\r\n/);
    for (i = 0; i < lines.length; i += 1) {
        line = lines[i];
        check = line.trim();
        if (i < lines.length - 2 &&
                lines[i + 1].indexOf("```") === 0 &&
                check[0] === '[' && check[check.length - 1] === ')') {
            i += 2;
            start = check.lastIndexOf('(') + 1;
            end = check.lastIndexOf(')');
            filename = line.substr(start, end - start);
            console.log("# Found Filename: " + filename);
            outputs[filename] = {start: i, end: -1};
        } else if (typeof outputs[filename] !== "undefined" &&
                outputs[filename].end < 0 &&
                line.indexOf("```") === 0) {
            outputs[filename].end = i;
            filename = "";
        }
    };
    Object.keys(outputs).forEach(function (outFilename) {
        exportLines(outFilename, outputs[outFilename].start, outputs[outFilename].end, lines);
    });

You can bootstrap with a few Unix commands (vi, sed, chmod, and node).

bootstrap.sh

    #!/bin/bash
    npm install shelljs
    vi -e -c "20,79wq! mw-bootstrap.js" README.md
    sed -e "s/    //" -i mw-bootstrap.js
    chmod 770 mw-bootstrap.js
    ./mw-bootstrap.js
    npm install
    npm test

Further reading

  • Markdown-Weave.md is the source to mw.js and cli.js (i.e. command line tool). Since this is process by mw-bootstrap.js it is not quiet literate yet.
  • HelloWorld.md - A simple hello world example.
  • Example-1.md - An example of writing multiple code blocks that form a single JavaScript file.
npm loves you