md-pipe
v0.7.0
Published
A rendering engine that transforms Markdown to HTML/PDF via directive-driven pipelines
Maintainers
Readme
md-pipe
A rendering engine that transforms Markdown manuscripts into HTML/PDF through HTML-comment directives and DOM transformations — without polluting the Markdown source.
Why
- Keep Markdown clean — no
<div>tags or framework-specific syntax in your source - HTML comments are invisible on GitHub, so your docs stay readable
- Full HTML/CSS power for rendering: themes, custom layouts, print styles
- Pipeline architecture lets you stop, inspect, and resume at any stage
Install
npm install -g md-pipeQuick Start
# Markdown → HTML
md-pipe report.md -o report.html
# Markdown → PDF
md-pipe report.md --pipeline .pdf -o report.pdf
# Initialize a project config
md-pipe initHow It Works
md-pipe uses HTML comments as directives. They're invisible on GitHub but control rendering:
<!--md-pipe: .feature-cards .compact-->
| title | description | status |
|---|---|---|
| Auth | Login & permissions | Done |
| Notifications | Email & Push | WIP |
<!--/md-pipe-->This renders as a normal table on GitHub, but md-pipe wraps it in a styled <div class="feature-cards compact"> for HTML/PDF output.
Directives
| Syntax | Description |
|---|---|
| <!--name: .class #id key=value--> | Block start |
| <!--/name--> | Block end |
| <!--name: .class /--> | Self-closing |
Directive-to-element mapping is defined in config:
# md-pipe.config.yml
directives:
md-pipe: div
page-break: div
note: aside .note-block
feature-cards: div feature_cards()Pipeline
Processing flows through five stages:
preprocess → render → transform → html → pdfUse --pipeline to control the range:
| Flag | Stages | Description |
|---|---|---|
| .html | all except pdf | Source to final HTML (default) |
| .pdf | all | Source to PDF |
| .render | preprocess + render | Stop after Markdown→HTML |
| render.html | render → html | Resume from intermediate HTML |
| transform.pdf | transform → pdf | Resume from transformed HTML |
Pipe Chaining
cat report.md | md-pipe --pipeline .transform | md-pipe --pipeline transform.pdf -o report.pdfConfiguration
Frontmatter
---
title: Monthly Report
theme: business-report
template: ./templates/report.hbs
pipeline: .pdf
output: ./dist/report.pdf
---Project Config (md-pipe.config.yml)
theme: business-report
template: ./templates/report.hbs
themes:
business-report:
template: ./templates/business.hbs
styles:
- ./styles/base.css
- ./styles/report.css
directives:
md-pipe: div
page-break: div
feature-cards: div feature_cards()
transforms:
- ./transforms/feature-cards.ts
pipeline: .pdfPrecedence
CLI args > frontmatter > project config > tool defaultCustom HTML Template
By default, md-pipe wraps the rendered body in a minimal HTML shell. Use --template to provide your own Handlebars template for full control over the HTML structure.
md-pipe report.md --template ./templates/report.hbs -o report.htmlTemplate Variables
| Variable | Description |
|---|---|
| {{{body}}} | Rendered HTML body (unescaped) |
| {{{styles}}} | Concatenated <style> blocks from resolved CSS (unescaped) |
| {{{scripts}}} | Concatenated <script> blocks from resolved JS (unescaped) |
| {{title}} | Document title from frontmatter (escaped) |
Use triple-stash {{{ }}} for body, styles, and scripts since they contain raw HTML.
Template Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{{#if title}}<title>{{title}}</title>{{/if}}
{{{styles}}}
</head>
<body>
<header><h1>{{title}}</h1></header>
<main>{{{body}}}</main>
<footer>© 2026 Company Name</footer>
{{{scripts}}}
</body>
</html>The template can also be specified via frontmatter (template:), project config, or theme config. Paths are resolved relative to the input file.
CLI Reference
md-pipe [input] [options]
Options:
-o, --output <file> Output file path
-p, --pipeline <range> Pipeline range ([start.]end)
-t, --theme <name> Theme name
-c, --config <file> Config file path
--template <file> Handlebars template for the html stage
--styles <files...> Additional CSS files
--scripts <files...> Additional JS files
--paper-size <size> PDF paper size (A4, A3, Letter, Legal, Tabloid)
--landscape PDF landscape orientation
--header <text> PDF header text
--margin <size> PDF page margin (e.g. 16mm)
--strict Error on undefined directives
-v, --verbose Verbose logging
Commands:
init [options] Generate md-pipe.config.yml
extract [commands...] Extract embedded CLI contract specificationContract Extraction
The extract command outputs the embedded CLI contract specification for use by external tooling (AI agents, documentation generators, etc.):
md-pipe extract --all # Full contract (YAML)
md-pipe extract --all --format json # Full contract (JSON)
md-pipe extract render init # Specific commands onlyTransform Plugins
Custom DOM transforms are TypeScript modules:
import type { TransformFn } from "md-pipe";
export default {
feature_cards({ $, el, helpers }) {
const table = $(el).find("table").first();
const rows = helpers.tableToObjects(table);
const html = rows.map(row =>
`<article class="feature-card">
<h3>${helpers.escapeHtml(row.title ?? "")}</h3>
<p>${helpers.escapeHtml(row.description ?? "")}</p>
</article>`
).join("");
$(el).replaceWith(`<section class="feature-cards">${html}</section>`);
}
} satisfies Record<string, TransformFn>;Register in config:
directives:
feature-cards: div feature_cards()
transforms:
- ./transforms/feature-cards.tsLicense
MIT
