/mmd-js

Node.js interface to the MultiMarkdown parsing library

Primary LanguageTypeScriptISC LicenseISC

mmd-js npm version

This project is a lightweight wrapper around multimarkdown-6's C library. Node.js scripts use it to parse Multimarkdown documents and walk their ASTs.

Demo / Context

mmd-js demo

Installation

npm install mmd-js
# or `yarn add mmd-js`
# or `pnpm add mmd-js`

Usage

mmd-js currently exposes a very small interface:

import * as mmd from "mmd-js";

// Usually you'd read a file, or maybe stdin
const buf = Buffer.from("Title: My Document\n\n# Header\n\nSome body text");

// Parse the MultiMarkdown document's root token from the buffer
const rootToken = mmd.parse(buf);

// Now you can walk the token tree
mmd.walk(rootToken, console.log);

// You can also render any node's text as a string
const text = mmd.read(buf, rootToken);
// const title = mmd.readTitle(buf, aTitleToken);

console.log(text);
// Title: My Document
//
// # Header
//
// Some body text

This API powers the bin/demo.ts script, which takes a MultiMarkdown file and:

  • Creates a directory for each "Part" (header level-1)
  • Creates a file for each "Section" within a part (header level-2)
  • Prints the Section's content into the file, after stripping:
    • The section title itself;
    • Any footnotes or footnote anchors within the section's text; and
    • Any whitespace before / after the section's text

If you would like to do something mmd-js does not yet support, please open an issue.

Wasm Notes

mmd-js also exposes a WebAssembly interface, with a few minor differences:

// Import the `/wasm.js` JS module instead of the default one
import * as mmd from "mmd-js/wasm.js";

// Load and instantiate the WebAssembly `.wasm` module.
// You may optionally pass a string (or string-returning function) to tell
// the JS where to find the `.wasm` file, if it is having trouble.
await mmd.load();

// Now you can use the same `mmd.*` APIs as above, albeit with
// browser-friendly `ArrayBuffer`s instead of Node.js `Buffer`s.
const buf = new TextEncoder().encode(
  "Title: My Document\n\n# Header\n\nSome body text"
);

// ...

Development

Installation

Tested with pnpm, but npm should work fine.

# you can skip the `git submodule` steps by using the `--recurse-submodules` flag while cloning:
# $ git clone --recurse-submodules git@github.com:anulman/mmd-js.git

# install `packages/MultiMarkdown-6`
git submodule init
git submodule update

# install emscripten, for wasm builds
brew install emscripten

# install js/ts deps
pnpm install

# configure wasm before building
pnpm run wasm:configure

Build && Run

pnpm build:napi # builds a node.js addon
pnpm build:wasm # builds a wasm module
pnpm build:js # compiles and emits typescript to js
pnpm build # runs all of the above

pnpm demo:bin # invokes `bin/demo.ts`; pass it a filepath
pnpm demo:web # starts the `demo/` dir's next.js dev server

Publishing

pnpm version [patch|minor|major] # uptick the version
pnpm publish # publish to the npm registry