Skip to main content

Crate markdown_link

Crate markdown_link 

Source
Expand description

Parsing and resolution of Markdown and wiki-style links.

Finds [[wikilinks]], ![[embeds]] and relative markdown links in a note body or its frontmatter, and resolves a link target to a file path with LinkIndex, using a path-suffix index.

use markdown_link::{LinkIndex, body_links};

let links = body_links("See [[Target#Heading|alias]].");
assert_eq!(links[0].target, "Target");

let index = LinkIndex::build(&["notes/Target.md".to_string()]);
assert_eq!(index.resolve("Target"), Some("notes/Target.md"));

Two details that look arbitrary and are not:

  • Code is stripped before matching. A fenced block full of [[example]] would otherwise manufacture links that do not exist, and the link graph would grow edges nobody wrote.
  • A pathed miss falls back to its basename. Notes often write typed links like [[muscle-groups/glutes]] whose prefix is a collection alias, not a real folder. Dropping the prefix on a miss is what makes those resolve; without it the graph is full of ghost nodes for links that a human would call obviously correct.

Re-exports§

pub use code::strip_code;

Modules§

code
Code fences and inline code spans: finding them, and blanking them so a lexer never harvests out of them.

Structs§

BodyLink
One outgoing reference found in a body, with its span, before resolution.
LinkIndex
A suffix index: every file is reachable by any suffix of its path.
RawLink
One reference found in a note, before it is resolved.
ScanOptions
What a body scan counts as a link. ScanOptions::default is what body_links_spanned and crate::body_links use.
Size
An embed’s display size, |300 (width) or |300x200 (width and height).
TypedRef
A typed reference, [[type/slug]] or [[type/slug|Alias]]: a frontmatter value naming one note of a known type, such as location: "[[location/home]]".
WikiLink
A parsed [[target#heading|alias]].

Enums§

BodyLinkKind
What syntax produced a BodyLink.
LinkKind
What kind of reference produced a RawLink.
ResolveError
Why LinkIndex::resolve_strict did not resolve a target.

Constants§

ATTACHMENT_EXTENSIONS
Every non-markdown extension that counts as a vault ATTACHMENT (lowercase, no leading dot).

Functions§

body_links
Every wikilink, embed and relative markdown link in a note body, in the order they appear.
body_links_spanned
Every wikilink, embed and relative markdown link in a body, in encounter order, with byte spans.
body_links_spanned_with
body_links_spanned under options: which code rules apply, whether HTML comments hide links, and whether [[#Heading]] is a link.
display_text
Replace each wikilink and embed with what a reader sees for it, for snippets and search: its alias, or else its target. An embed’s trailing |300 or |300x200 is a size, not an alias, so ![[img.png|300]] shows img.png. An empty alias shows the target. Code is not skipped.
encode_uri_component
JavaScript’s encodeURIComponent: every byte of the UTF-8 text except A-Z a-z 0-9 - _ . ! ~ * ' ( ) is percent-encoded.
encode_uri_fragment
JavaScript’s encodeURI, with # also encoded, for a fragment. URI structure characters (/ ? : @ & = + $ ; ,) are kept, so a fragment such as page=2 reads back as written.
escape_label
Markdown link text with \, [ and ] escaped, so a label cannot end or nest the link it sits in.
frontmatter_links
Wikilinks hiding in frontmatter values, tagged with their top-level key.
frontmatter_paths
Frontmatter string values that name a file by path (cover: img/a.png), tagged with their top-level key. A value counts when its last segment has an extension; a URL, a wikilink or text with a line break does not. Whether the path exists is the resolver’s question.
is_size_spec
Whether spec is an image size, ^\d+(x\d+)?$: 300 or 300x200.
is_vault_link_url
Whether a markdown link’s URL is one this dialect harvests: a note, or a vault attachment.
join_relative
target joined onto from’s folder when it starts with ./ or ../, with the dot segments collapsed. None for any other target, and for one that climbs above the vault root.
may_hold_frontmatter_paths
A cheap test of raw frontmatter text: whether any token on any line could be a path frontmatter_paths keeps. False means it would find none, so a caller can skip the YAML parse. It errs toward true: a false positive costs a parse, a false negative a missed link.
md_link_target
The resolution target of a markdown link’s URL: percent-decoded, minus its trailing .md.
normalize_target
Normalise a link target to an index key.
parse_inner
Parse a single wikilink body (the text between the brackets).
parse_inner_self
parse_inner, except that a link with no target and a # fragment, such as #Heading or #^block, is a link to the note it is written in: its target is empty. This is how Obsidian reads [[#Heading]].
parse_typed_ref
Parse a whole value as a typed reference, or None.
percent_decode
Percent-decode a markdown link URL. Public for the same reason strip_md_ext is.
prefer_in_folder
Pick the winner from a shortest-first candidate field, as written in from.
relative_link
The relative URL from the file from to the file to, both vault-relative and /-separated, with an optional #fragment.
strip_md_ext
Drop a trailing .md, case-insensitively.
suffixes
a/b/c -> ["c", "b/c", "a/b/c"].
target_range
Byte range of parse_inner’s target within inner, for a caller that rewrites the target in place and must leave the rest of the link as written.
wikilink_targets
Every reference in one piece of markdown, in the order it appears, with any #heading and |alias stripped.