base-markdown 0.1.3

CommonMark compliant markdown parser in Rust with ASTs and extensions
Documentation

base-markdown

A CommonMark-compliant Markdown parser for Rust with pull events, a source-backed AST, extensions, and HTML and Markdown renderers. It builds on markdown-rs, with compact CommonMark parsing and a single source-backed document representation.

Build Coverage

Motivation

Socketry's documentation tooling needs to inspect, edit, and render Markdown sections as structured data. This fork builds on markdown-rs with a pull-based event parser, a single source-backed document AST with editing helpers, shared HTML and Markdown renderers, and optional syntax extensions for richer documentation.

Usage

cargo add base-markdown

The library supports Rust 1.73 and later.

For direct conversion from Markdown source to HTML:

let html = base_markdown::to_html("## Hello, *world*!");
assert_eq!(html, "<h2>Hello, <em>world</em>!</h2>");

Enable GFM constructs with Options::gfm():

use base_markdown::{to_html_with_options, Options};

let html = to_html_with_options("* [x] done", &Options::gfm());

See the API documentation for pull events, document editing, parser options, and frontmatter, the architecture guide for the parser design, and the performance comparison for benchmarks against other Markdown engines.

Releasing

Prepare a release with cargo bake cargo:version:patch (or minor, major, or bump --version X.Y.Z), commit it with a Release: vVERSION trailer, then run cargo bake cargo:release and open a pull request. After review and merge, GitHub Actions publishes the release when the configured crates-io environment approves it, then creates or updates the matching GitHub Release from releases.md. Follow the shared Releasing skill for the standard process.

Releases

See releases.md for the full release history.

v0.1.3

  • Add normalize_markdown and normalize_markdown_with_options, which parse Markdown with GFM, frontmatter, and math and serialize it with default formatting and soft line breaks unwrapped. This is the normalization bake-markdown applies, so tools that generate Markdown can produce output it leaves unchanged.
  • Add ParseOptions::normalize, the syntax normalize_markdown parses, so tools can inspect a document with the same structure the normalizer sees.
  • Indent the content of GFM task list items to the list marker's content column rather than past the checkbox. Nested lists, paragraphs, and code in a task item were previously re-parsed as paragraph text or indented code, so repeated serialization changed or grew the document.
  • Keep the blank line between a nested list and a following paragraph, table, definition, or setext heading in the same list item. Without it, the next parse continued the nested list's last paragraph, merging the two.
  • Write a heading with soft line breaks as an ATX heading when soft breaks are unwrapped. It was previously written as a setext heading, which the next normalization turned into an ATX heading.
  • Leave underscores between letters or digits unescaped when serializing Markdown, as mdast-util-to-markdown does, so io_uring and snake_case no longer become io\_uring and snake\_case. Such underscores cannot open or close emphasis, so the rendered output is unchanged.

v0.1.2

  • Replace a line ending before inline HTML only when the HTML could start an HTML block there, as mdast-util-to-markdown does. Line endings before other tags, such as <span> or </span>, are now kept, and a hard break before them is no longer lost.
  • Keep a hard break before inline HTML that could start an HTML block by indenting the next line four spaces, so it continues the paragraph. Previously the break's line ending was replaced with a space, leaving a literal backslash.

v0.1.1

  • Keep inline HTML after text unchanged when serializing Markdown. Previously each serialization added a space before inline HTML in paragraphs, including those in block quotes and list items, so repeated normalization kept growing the gap. Only a line ending directly before inline HTML is now replaced with a space.
  • Write every line ending in serialized Markdown as LF. CRLF and lone CR line endings inside code, HTML, math, front matter and titles were previously copied through, which left mixed line endings in otherwise LF output.
  • Return inline subtrees from to_markdown_node without a trailing line ending, as cmark does. Text, emphasis, links, code and other phrasing content, including inline opaque nodes, serialize as *b* rather than *b*\n; non-empty documents and block subtrees still end with a line ending. This changes output for callers serializing inline fragments.

See Also

Contributing

Please open an issue or pull request on GitHub.

Agent Context

Run cargo bake agent:context:install to install shared context and skills. Use cargo bake agent:context:list and cargo bake agent:context:show to discover relevant guides, follow agents.md if present, and apply skills under .agents/skills/. The installer preserves repository-owned agents.md; it does not create or regenerate that file.