Parse SDK

Tree Utilities

Query, filter, split, and serialize the AST without writing raw loops.

The tree-utils module provides utilities for working with the AST. Most functions operate on Node and recurse into the entire tree automatically.

find / findAll

Find the first or all nodes matching a predicate anywhere in the tree:

import { find, findAll, isHeading } from "datamark/parse";

const firstH2 = find(doc.root, (n) => isHeading(n, 2));
const allCodeBlocks = findAll(doc.root, (n) => n.type === "code");

filter

Top-level filter on a Node[] array (does not recurse):

import { filter } from "datamark/parse";

const paragraphs = filter(doc.root.children, (n) => n.type === "paragraph");

sectionsAtDepth / sectionsByHeading

Find sections by depth or heading text:

import { sectionsAtDepth, sectionsByHeading } from "datamark/parse";

const h2s = sectionsAtDepth(doc.root, 2);
const introSection = sectionsByHeading(doc.root, "Introduction");

splitBy

Split a flat array of block nodes by a predicate. Separator nodes are discarded:

import { splitBy, isHeading } from "datamark/parse";

const groups = splitBy(flatBlocks, (n) => isHeading(n, 2));
// BlockNode[][] — each group is nodes between H2s

between / after / before

import { between, after, before } from "datamark/parse";

const intro = between(flatBlocks, isHeading(1), isHeading(2));
const rest = after(flatBlocks, (n) => isHeading(n, 1));
const preamble = before(flatBlocks, (n) => isHeading(n, 1));

codeBlocks

Extract all code blocks recursively from any node:

import { codeBlocks } from "datamark/parse";

const blocks = codeBlocks(doc.root);
// CodeNode[]

textContent / inlineText

Extract plain text from nodes:

import { textContent, inlineText } from "datamark/parse";

const bodyText = textContent(doc.root); // from any Node
const linkLabel = inlineText(linkNode.children); // from InlineNode[]

toMarkdown

Serialize nodes back to a Markdown string:

import { toMarkdown } from "datamark/stringify";

const markdown = toMarkdown(doc.root); // from SectionNode
const markdown2 = toMarkdown(blocks); // from BlockNode[]

toMarkdown is the reverse of parsing. It handles headings, paragraphs, code blocks, lists, blockquotes, tables, and inline formatting.

flatten

Convert a section tree back to a flat array of block nodes:

import { flatten } from "datamark/parse";

const blocks = flatten(doc.root);
// BlockNode[]

isHeading / isCodeBlock / isTodoItem

Type guards for common node types:

import { isHeading, isCodeBlock, isTodoItem, extractTodoItems } from "datamark/parse";

if (isHeading(node, 1)) { /* ... */ }
if (isCodeBlock(node, "typescript")) { /* ... */ }
if (isTodoItem(node)) { /* ... */ }

const todos = extractTodoItems(doc.root);
// [{ text: "Buy milk", completed: false, raw: "[ ] Buy milk" }]

Type guards

import { isSection, isBlockNode, isInlineNode, isParentNode } from "datamark/parse";

if (isSection(node)) {
  console.log(node.heading?.depth);
}

if (isParentNode(node)) {
  console.log(node.children.length);
}

On this page