code wiki / (root) / nx_doc_render_mermaid.nx

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}