Expand description
Source-line anchor injection for the HTML renderer.
When Options::source_line_anchors is true, top-level block
elements in the rendered HTML get a data-afm-source-line="N"
attribute (1-based) pointing back at the source line where the
block began. The afm-obsidian document-mode adapter (Pillar 6)
relies on this to map Obsidian’s per-block post-processor calls
back to slices of the full rendered fragment.
Algorithm:
- Walk comrak’s top-level AST children (
root.children()) and collect each child’s source position fromnode.data.borrow().sourcepos.start.line. - After comrak emits the HTML string, scan it once and inject
data-afm-source-line="N"into the first opening tag at each top-level block boundary. Top-level blocks are identified positionally — the Nth top-level element in the HTML corresponds to the Nth child of the comrak root.
Why string-level injection rather than custom rendering: comrak’s
format_html doesn’t expose a per-node attribute hook on every
block kind we care about. A scan-and-inject pass is O(html) and
deterministic; the per-element overhead is dwarfed by the comrak
formatter’s own cost.
Functions§
- collect_
top_ 🔒level_ lines - 1-based source line for each top-level child, in document order.
- find_
tag_ 🔒end - inject_
anchors 🔒 - Insert
data-afm-source-line="N"into the first opening tag at each top-level block boundary. Tags considered top-level are<p>,<h1..h6>,<ul>,<ol>,<blockquote>,<pre>,<table>,<hr>,<div>(containers). - inject_
attribute 🔒 - is_
top_ 🔒level_ tag - is_
void_ 🔒tag - tag_
name 🔒