nx_doc_render_mermaid.nx source
↩ module page · 135 lines · 3882 B
1// nx_doc_render_mermaid.nx -- D10 first stone of V4 docs doctrine.
2//
3// Emits Mermaid 'graph LR' or 'graph TD' syntax representing
4// substrate's doc-link graph. Caller provides node + edge data;
5// this primitive writes Mermaid-formatted text to fd 1.
6//
7// Bits-up: no mermaid.js dependency. Substrate-owned emitter per
8// the V4 living-docs cardinal + [[feedback-bits-up-shell-replace-
9// linux-brother-tools]] applied to doc rendering.
10//
11// **Quadrant:** REFERENCE (Diátaxis)
12// **Topic Type:** REFERENCE (DITA)
13// **Status:** DRAFT (D10 first stone)
14// **Trust State:** WRITTEN_UNTESTED
15// **Competitive State:** UNCLASSIFIED
16
17import "nx_syscalls.nx"
18import "nx_string_ops.nx"
19
20// ===== Direction sealed enum =====================================
21
22const NX_MERMAID_LR: i64 = 0 // left-to-right
23const NX_MERMAID_TD: i64 = 1 // top-down
24const NX_MERMAID_N: i64 = 2
25
26func nx_mermaid_dir_is_valid(d: i64) -> i64 {
27 if d < 0 { return 0 }
28 if d >= NX_MERMAID_N { return 0 }
29 return 1
30}
31
32// ===== Header emitter ===========================================
33
34func nx_doc_mermaid_emit_header(dir: i64) {
35 if dir == NX_MERMAID_TD {
36 sys_write(1, "graph TD\n", 9)
37 } else {
38 sys_write(1, "graph LR\n", 9)
39 }
40}
41
42// ===== Node emitter ==============================================
43//
44// Emits a Mermaid node declaration: ' <id>["<label>"]\n'.
45// Caller-provided id (alphanumeric, no spaces) + label (free-text).
46
47func nx_doc_mermaid_emit_node(
48 id: *u8, n_id: i64,
49 label: *u8, n_label: i64
50) {
51 sys_write(1, " ", 2)
52 sys_write(1, id, n_id)
53 sys_write(1, "[\"", 2)
54 sys_write(1, label, n_label)
55 sys_write(1, "\"]\n", 3)
56}
57
58// ===== Edge emitter ==============================================
59//
60// Emits a Mermaid edge: ' <from> --> <to>\n'.
61// Plus a labeled-edge variant: ' <from> -- <label> --> <to>\n'.
62
63func nx_doc_mermaid_emit_edge(
64 from_id: *u8, n_from: i64,
65 to_id: *u8, n_to: i64
66) {
67 sys_write(1, " ", 2)
68 sys_write(1, from_id, n_from)
69 sys_write(1, " --> ", 5)
70 sys_write(1, to_id, n_to)
71 sys_write(1, "\n", 1)
72}
73
74func nx_doc_mermaid_emit_edge_labeled(
75 from_id: *u8, n_from: i64,
76 label: *u8, n_label: i64,
77 to_id: *u8, n_to: i64
78) {
79 sys_write(1, " ", 2)
80 sys_write(1, from_id, n_from)
81 sys_write(1, " -- ", 4)
82 sys_write(1, label, n_label)
83 sys_write(1, " --> ", 5)
84 sys_write(1, to_id, n_to)
85 sys_write(1, "\n", 1)
86}
87
88// ===== Footer =====================================================
89//
90// Mermaid graphs don't require a footer (text auto-terminates).
91// Helper for callers that want a trailing comment.
92
93func nx_doc_mermaid_emit_footer(comment: *u8, n_comment: i64) {
94 if n_comment > 0 {
95 sys_write(1, " %% ", 5)
96 sys_write(1, comment, n_comment)
97 sys_write(1, "\n", 1)
98 }
99}
100
101// ===== Node ID escaping ==========================================
102//
103// Mermaid node IDs must be alphanumeric (plus _ and -). Substrate
104// doc names often have dots, slashes, parens. This helper writes
105// an escaped ID by replacing problematic chars with underscores.
106
107func nx_doc_mermaid_escape_id(
108 src: *u8, n_src: i64,
109 dst: *u8, dst_cap: i64
110) -> i64 {
111 var i: i64 = 0
112 var written: i64 = 0
113 while i < n_src {
114 if written >= dst_cap { return -1 }
115 let c: i64 = src[i] as i64
116 var safe: i64 = 0
117 // a-z (97-122)
118 if c >= 97 { if c <= 122 { safe = 1 } }
119 // A-Z (65-90)
120 if c >= 65 { if c <= 90 { safe = 1 } }
121 // 0-9 (48-57)
122 if c >= 48 { if c <= 57 { safe = 1 } }
123 // _ (95) and - (45)
124 if c == 95 { safe = 1 }
125 if c == 45 { safe = 1 }
126 if safe == 1 {
127 dst[written] = src[i]
128 } else {
129 dst[written] = 95 // '_'
130 }
131 written = written + 1
132 i = i + 1
133 }
134 return written
135}