Conceptually, a markdown file can be divided into a hierarchical structure by its headers:
# Level 1
|--- ## Level 2
| |--------- Paragraph
| +-------- Paragraph
+--- ## Level 2
I also found that in the ATXHeading
implementation of lezer-parser/markdown
. We can actually fold markdown base on this tree-like structure.
I wonder if there is a way to access this tree-like structure without custom plugins. (I’m struggling to implement this via my plugin (>_<)).
/// Parse Section as Composite Blocks
const sectionParserPlugin: MarkdownConfig = {
defineNodes: (() => {
let nodes = new Array<NodeSpec>();
for (let i = 1; i <= 10; ++i) {
nodes.push({
name: `SectionHead${i}`,
block: true,
style: banyanTags[`sectionHead${i}`]
}, {
name: `Section${i}`,
style: banyanTags[`section${i}`],
block: true,
composite(_, line): boolean {
let level = line.text.trimStart().match(/^#*/)?.[0].length || 0;
console.log(level, i, line.text);
return (level == 0) || (level > i);
}
});
}
return nodes;
})(),
parseBlock: (() => {
let blockParsers = new Array<BlockParser>();
for (let i = 1; i <= 10; ++i) {
blockParsers.push({
name: `Section${i}`,
parse(cx, line): boolean | null {
// Nothing happens
let level = line.text.trimStart().match(/^#*/)?.[0].length || 0;
if (level != i) { return false; }
// Process the header
let start = cx.lineStart;
let lineElements = cx.parser.parseInline(line.text.slice(level), start + level);
// Start composite block
cx.startComposite(`Section${i}`, cx.lineStart);
// Add next current element
cx.nextLine();
cx.addElement(cx.elt(`SectionHead${i}`, start, cx.lineStart, lineElements));
return null;
}
});
}
return blockParsers;
})(),
}