nx_wiki_toc.nx
buildroot/runtime/wiki/nx_wiki_toc.nx
about
nx_wiki_toc.nx -- wiki R4: auto table-of-contents + heading anchor ids.
COMPOSES: nx_syscalls (sys_mmap scratch). No markdown library needed -- it
reads ATX heading LINES directly from the markdown source (the same #/##/###
the renderer turns into <hN>), so the TOC and the rendered anchors share one
definition of "what a heading is".
TWO halves:
1. nx_wiki_toc_build(src,n) -> <nav class="nx-toc"><ol>...<li><a
href="#<anchor>">heading text</a></li>...</ol></nav> (one <li> per
ATX heading, in document order). Empty <nav> elided -> "" when a doc
has no headings.
2. nx_wiki_toc_inject_ids(html,n) -> a COPY of rendered HTML with
id="<anchor>" added to every <hN ...> open tag that lacks one. The
anchor for an <hN> is derived from that tag's INNER TEXT, computed by
the SAME nx_wiki_toc_slugify the TOC links use -> the "#section-a"
links in (1) jump to the id="section-a" stamped here.
ANCHOR RULE: lowercase the heading text; every run of non-[a-z0-9] bytes ->
a single '-'; trim leading/trailing '-'. Deterministic + collision-tolerant
(duplicate headings get duplicate ids -- browsers jump to the first, which
is the documented, acceptable behavior; a -2/-3 disambiguator is a follow-on).
Hygiene: M1 out-params; M3 capped loops; M5 bounded indexing; M6 real
semantics; M7 named constants; M8 propagated verdicts.
Status: V1 (wiki R4). 2026-06-15. license_tier: ORIGINAL
dependencies 1 imports · 3 importers
imports: nx_syscalls.nx
imported by: _wiki_backlinks_gate.nxnx_wiki_doc_handler.nxnx_wiki_doc_render.nx
structs
| none |
consts
| 31 | const NX_WTOC_OK: i64 = 0 |
| 32 | const NX_WTOC_BAD_INPUT: i64 = 2660 |
| 33 | const NX_WTOC_OVERFLOW: i64 = 2661 |
| 34 | const NX_WTOC_LOOP_BUDGET: i64 = 2662 |
| 37 | const NX_WTOC_MAX_HEADINGS: i64 = 256 // headings per document cap |
| 38 | const NX_WTOC_MAX_HEAD_LEN: i64 = 512 // single heading text cap |
| 39 | const NX_WTOC_SCAN_BUDGET: i64 = 8000000 // per-doc byte-scan cap (M3) |
| 40 | const NX_WTOC_ANCHOR_DASH: i64 = 0x2D // '-' |
| 42 | const NX_WTOC_HASH: i64 = 0x23 // '#' |
| 43 | const NX_WTOC_SP: i64 = 0x20 // ' ' |
| 44 | const NX_WTOC_LF: i64 = 0x0A // '\n' |
| 45 | const NX_WTOC_CR: i64 = 0x0D // '\r' |
| 46 | const NX_WTOC_LT: i64 = 0x3C // '<' |
| 47 | const NX_WTOC_GT: i64 = 0x3E // '>' |
functions
| 55 | func nx_wiki_toc_slugify(src: *u8, n: i64, out: *u8, cap: i64) -> i64 |
| 100 | func nx_wtoc_emit(out: *u8, off: i64, cap: i64, s: *u8) -> i64 |
| 109 | func nx_wtoc_emit_bytes(out: *u8, off: i64, cap: i64, src: *u8, n: i64) -> i64 |
| 120 | func nx_wiki_toc_build(src: *u8, n: i64, out: *u8, cap: i64, called by 2: mainnx_wiki_doc_render calls 4: sys_mmapnx_wiki_toc_slugifynx_wtoc_emitnx_wtoc_emit_bytes |
| 223 | func nx_wiki_toc_inject_ids(html: *u8, n: i64, out: *u8, cap: i64, called by 2: mainnx_wiki_doc_render calls 4: sys_mmapnx_wiki_toc_slugifynx_wtoc_emitnx_wtoc_emit_bytes |