turbovault-parser
An Obsidian Flavored Markdown parser, and a JSON Canvas 1.0 reader and writer, for TurboVault.
One pulldown-cmark pass finds code, links and structure; Obsidian syntax is then read outside the code ranges it found, so a [[link]] in a code block is never a link. Positions are byte offsets plus line and column.
What it reads
- Wikilinks and embeds:
[[Note]],[[Note|alias]],[[Note#Heading]],[[Note#^block]],![[image.png]], and the table-escaped[[Note\|alias]]. - Markdown links: inline (
[x](My%20Note.md),[x](<My Note.md>)), reference-style ([x][ref],[ref][],[ref]with[ref]: target), with destinations percent-decoded. - Frontmatter as YAML, bounded in size and depth; wikilinks and Markdown links in property values count as links.
- Tags (
#tag,#parent/child), tasks ([ ],[x],[/],[-], Tasks-plugin emoji, Dataview fields), callouts, headings with anchors, citations. - Blocks:
parse_blocksturns a note into a tree of paragraphs, headings, lists, quotes, tables, code and callouts, for renderers and outline tools. - JSON Canvas 1.0:
parse_canvasreads.canvasfiles into nodes and edges; canvases validate and serialize back in Obsidian's own layout.
Example
use ;
let note = "---\ntags: [project]\n---\n# Plan\n\nSee [[Roadmap|the roadmap]] and [notes][n].\n\n- [ ] Ship it\n\n[n]: Meeting%20Notes.md\n";
let parsed = parse;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Parser::new(vault_root).parse_file(path, content) returns a VaultFile with the path, metadata and every element above, which is what the rest of TurboVault works from.
License
MIT