mweave

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

npm install mweave
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