Skip to content

Lurk/yamd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

415 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

yamd

codecov crates.io Released API docs

YAMD - Yet Another Markdown Document (flavour)

Simplified version of CommonMark.

For formatting check YAMD struct documentation.

Quick start

use yamd::deserialize;

let input = "# Hello\n\nA paragraph with **bold** text.";
let yamd = deserialize(input);

// Access the AST
assert_eq!(yamd.body.len(), 2);

// Round-trip back to markdown
assert_eq!(yamd.to_string(), input);

Two APIs

  • [deserialize] returns a nested Yamd document — a tree of typed nodes, suitable for walking, pattern-matching, or round-tripping back to markdown via Display. The AST makes invalid nestings unrepresentable, and deserialize is fuzz-tested for panic-freedom and property-tested for round-trip fidelity.
  • [parse] returns a flat Vec<Op> of Start/End/Value events, where Content borrows from the source when possible. Reach for it when you want streaming rendering or zero-copy text processing without materializing the full tree. [to_yamd] promotes an event stream to the tree form. Fuzz-tested for panic-freedom (transitively, via deserialize); the AST's type-level invariants and round-trip property do not apply at this layer.

Reasoning

YAMD exchanges CommonMark's context-dependent rules for a uniform set: every node is treated the same, and escaping is resolved at the lexer. The goal is a parser that's easier to reason about locally, with fewer special cases to remember.

Rendering is out of scope; Yamd is an AST you walk and render however you like. With the serde feature enabled, the AST is also serde-serializable.

Difference from CommonMark

YAMD reuses most of CommonMark's syntax but diverges in a few places.

Escaping

Escaping is handled at the [lexer] level: any character following \ is treated as a literal.

Example:

YAMD HTML equivalent
\**foo** <p>**foo**</p>

Precedence

CommonMark distinguishes container blocks from leaf blocks and gives container-block markers higher precedence. YAMD does not distinguish block types — every node is treated the same, so there are no precedence rules to remember.

Example:

YAMD HTML equivalent
- `one\n- two` <ol><li><code>one\n- two</code></li></ol>

To get two separate ListItems, escape the backticks:

YAMD HTML equivalent
- \`one\n- two\` <ol><li>`one</li><li>two`</li><ol>

The reasoning: issues like this should be caught by tooling such as linters or language servers — that tooling doesn't exist yet.

Nodes

See [nodes] for the full list of supported nodes and their formatting. Start with YAMD.

MSRV

YAMD minimal supported Rust version is 1.87.

About

yet another markdown document flavor

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages