Pre-release Harn is pre-1.0 — the language, standard library, and CLI may change between releases. See the release notes

Markdown stdlib

std/markdown parses Markdown and MDX for documentation checks, search indexes, and prose reports. It uses the runtime's content feature, which the Harn CLI includes. Lean embedders must enable that feature.

parse(source, options)#

Returns a MarkdownDocument. options.mdx defaults to false; set it to true to recognize JSX, imports, exports, and embedded expressions. Parsing doesn't evaluate JavaScript or load imported modules. Invalid MDX structure throws.

FieldContents
headingsHeading level, rendered text, unique GitHub-style anchor, line, and offset
linksResolved destination, image flag, line, and offset
blocksProse text, heading flag, and starting line for each block
textNormalized visible text, including code and table contents

Lines start at one. Offsets count UTF-8 bytes from zero. Links include inline links, images, reference uses, and reference definitions. Code examples don't create headings or links. Repeated headings get unique anchors, including headings whose text already ends in a numbered suffix.

Prose blocks retain link labels and heading or list boundaries. They exclude frontmatter, code, images, tables, HTML comments, and bare web addresses. MDX mode also excludes import, export, and expression text. HTML extraction excludes script and style contents.

import { parse } from "std/markdown"

fn main(harness: Harness) -> nil {
  const document = parse("# Example\n\nRead the [guide](./guide.md).")
  harness.stdio.println(document.headings[0]!.anchor)
  harness.stdio.println(document.links[0]!.destination)
}

This prints example and ./guide.md.

reading_level(source, options)#

Returns a ReadingLevel, or nil when no English words remain. It uses the same parser and options as parse.

FieldMeaning
wordsEnglish word count
sentencesSentence count, with each heading treated as one unit
words_per_sentenceMean words per unit
syllables_per_wordMean estimated syllables per word
gradeFlesch-Kincaid grade level
easeFlesch reading ease
longestUnit with the most words

Scores estimate word and sentence length. They don't measure jargon, correctness, or how well a page explains its subject.

extract_text from std/document uses the same Markdown and HTML extraction. Pass {source_format: "markdown"} or {source_format: "html"} to select it.