idiomd
v0.1.1
Published
Parses, checks and renders a Markdown document against a type specification.
Downloads
66
Maintainers
Readme
idiomd
Parses, checks and renders a Markdown document against a type specification. One document at a time, no graph, no server.
A document is a file with YAML frontmatter and a body of ## sections. A
type is a JSON file that says which fields the frontmatter carries and what
each section holds: prose, one value, a list with prefixes, steps, a
checklist, a fenced block, or Key: value lines. idiomd check tells you
where a document departs from its type, by file and line.
npx idiomd check docs/docs/decisions/ADR-057.md:43 warn "Consequences" holds a list; the line is prose
docs/specs/S-0009.md:12 error "Status" says "draft", state is "accepted"Install
npm install idiomdNode 22 or later. One dependency, yaml.
Use the command line
idiomd check <file|dir>... [--types <dir>] [--json]
idiomd parse <file> [--types <dir>]
idiomd types [--types <dir>]check walks directories, reads every .md file that opens with ---,
and prints one line per finding. It exits with 1 when an error exists.
--json prints the findings as an array.
parse prints one document as JSON: the frontmatter, the type and kind,
the title, and every section in the form its type declares.
types lists the types in use and what their sections hold.
Types come from --types, else from the types key of the nearest
idiomd.json or aimd.json above each document, else from the six types
shipped with the package: Decision Record, Specification, Term, Work
Item (feature and bug), Scenario, and UX (flow and screen).
Use the API
import { load, parse, check } from 'idiomd';
const types = await load('./types');
const doc = parse(source, types, { file: 'docs/decisions/ADR-001.md' });
const findings = check(doc); // the types travel with the documentparse throws a ParseError only when the frontmatter cannot be read at
all. Everything else is a finding.
Write a type
{
"type": "Decision Record",
"folder": "decisions",
"states": ["draft", "proposed", "accepted", "superseded", "rejected"],
"template": {
"frontmatter": { "type": "$type", "title": "$title", "id": "$id", "state": "$state", "date": "$today" },
"sections": [
{ "heading": "Status", "holds": "value", "field": "state" },
{ "heading": "Context", "holds": "prose" },
{ "heading": "Decision", "holds": "prose" },
{ "heading": "Consequences", "holds": "list", "prefixes": ["+", "-"] }
]
}
}A value section that names a field is a projection of that field: it
has to say the same, and nothing ever reads it back into the field. The
shape is the document half of an aimd type declaration, so one file serves
both tools; keys idiomd does not read pass through. SPEC.md has the rules,
schema/type.json the schema.
Where it stands
SPEC.md is version 0.2. The renderers for html, json and gherkin
come with a later version. The repository is at
https://gitlab.com/idiomd/idiomd, the project root with the decisions and
work items is private.
