Everything this module knows how to read out of a note's markdown: YAML front
matter, tags, [[wiki-links]], and the rendered HTML.
The markdown is the single source of truth. title_key, frontmatter, tags
and the whole link index are derived from it on save, which is what keeps
notes portable — the database holds nothing you could not recover by
re-reading the text.
Code is not scanned
Tags and wiki-links are only read from outside code, so a [[Foo]] inside a
fenced block or a backtick span stays literal instead of quietly becoming a
link and a phantom entry in the vault's unresolved list. Fenced blocks
(```, ~~~) and inline spans are handled; four-space indented code
blocks are not, because telling one apart from a wrapped list item needs a
real block parser.
Summary
Types
One parsed [[wiki-link]].
Functions
A short plain-text excerpt for note lists — front matter, markdown syntax and wiki-link brackets removed.
All tags for a note: front matter tags: merged with inline #tags in the
body, downcased, de-duplicated and sorted.
The canonical form of a note title — downcased with runs of whitespace collapsed.
Parses the inside of one [[...]] into a wiki_link/0, or nil if there
is no target left after trimming.
Splits YAML front matter off the top of a note.
Renders a note to sanitized HTML, with [[wiki-links]] turned into real
links.
Every distinct [[wiki-link]] in a body, in order of first appearance.
Types
Functions
@spec excerpt(String.t() | nil, pos_integer()) :: String.t()
A short plain-text excerpt for note lists — front matter, markdown syntax and wiki-link brackets removed.
Cosmetic only: it is never stored, and never used for search (that is the
tsvector column's job).
All tags for a note: front matter tags: merged with inline #tags in the
body, downcased, de-duplicated and sorted.
Front matter accepts either a list (tags: [a, b]) or a single string
(tags: a, b), which are the two spellings Obsidian itself accepts.
Tags are downcased so #Project and #project are one tag — they are a
filtering key here, not a display string.
The canonical form of a note title — downcased with runs of whitespace collapsed.
This is what the per-vault unique index constrains and what [[wiki-links]]
match on, so "My Note", "my note" and " My Note " are all the same note.
Parses the inside of one [[...]] into a wiki_link/0, or nil if there
is no target left after trimming.
[[Target#Heading|Alias]] keeps Alias as the label and resolves against
Target — the heading anchor is dropped, since this module has no
heading-level addressing yet.
Splits YAML front matter off the top of a note.
Returns {properties, body}. A note with no front matter returns {%{}, note}
unchanged — and so does one whose front matter is invalid YAML, deliberately:
a typo in a property block must not swallow the writing underneath it. The
broken block stays visible in the body, where the author can see and fix it.
@spec to_html(String.t() | nil, (wiki_link() -> {:resolved | :unresolved, String.t()})) :: String.t()
Renders a note to sanitized HTML, with [[wiki-links]] turned into real
links.
No caller in the UI, on purpose
There is one editing surface — Leaf — and it renders markdown itself, so
nothing in the LiveView calls this today. It is kept because it is the
server half of wiki-link rendering: when Leaf learns to display [[…]],
this is the function that tells it which links resolve, where they point,
and which are dangling. Its tests pin that contract, which is the thing
worth not losing.
resolver is called once per distinct link with a wiki_link/0 and must
return {:resolved, href} or {:unresolved, href}. Unresolved links get a
muted, dotted-underline style so a vault's gaps are visible while reading —
the class survives sanitization, which allows class on any tag.
Front matter is stripped rather than rendered; the properties are shown by the UI, not by the prose.
Every distinct [[wiki-link]] in a body, in order of first appearance.
De-duplicated by :key, because writing [[Foo]] five times in one note is
one link, not five — the same thing the (source_note_uuid, target_key)
unique index enforces in the database.