code wiki / (root) / nx_html_emit.nx

nx_html_emit.nx source

↩ module page · 218 lines · 6967 B

1// nx_html_emit.nx -- minimal substrate-native HTML5 writer. 2// 3// Layer 5 of the sovereign-log roadmap: dashboard visibility. Renders 4// query-layer projections to a tail-able HTML page. Pure NishiLang, 5// fd-write based, no template engine. 6// 7// Per the user's "live fire testing + see how its testing, innovating, 8// improving" directive: this primitive is what makes the substrate's 9// audit data VISIBLE without leaving NishiLang. Caller composes a 10// page from these primitives like Lego bricks: 11// 12// nx_html_doc_open(fd, "Batch 42 audit") 13// nx_html_h1(fd, "Pool utilization") 14// nx_html_table_open(fd, "n_scenes | n_violations | outfit_band") 15// nx_html_tr3_int(fd, n_scenes, n_violations, outfit_band) 16// nx_html_table_close(fd) 17// nx_html_doc_close(fd) 18// 19// HTML5 minimal: <!doctype html> + <meta charset="utf-8">, no CSS 20// dependency (inline classes only). Output is human-readable and 21// browser-renderable end-to-end. 22// 23// genealogy_id: html5_w3c_2014 + tufte_dashboards 24// lineage_id: substrate_html_emit_v1 25 26// nx_safety_envelope: 27// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 28// sil_target: SIL1 29// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 30// verdict: NOT_YET_EVALUATED 31 32import "nx_syscalls.nx" 33import "nx_runtime.nx" 34import "nx_tier.nx" 35 36// ===== Raw byte writes ============================================ 37// 38// Direct sys_write helpers. No buffering; caller can wrap in a 39// nx_io buffered writer if they want batching. 40 41func _html_write_z(fd: nx_int, s: *u8) -> nx_int { 42 return sys_write(fd, s, strlen(s)) 43} 44 45func _html_write_byte(fd: nx_int, b: nx_int) -> nx_int { 46 let buf: *u8 = sys_mmap(8) 47 buf[0] = b 48 return sys_write(fd, buf, 1) 49} 50 51func _html_write_i64(fd: nx_int, n: nx_int) -> nx_int { 52 let buf: *u8 = sys_mmap(32) 53 let len: nx_int = itoa(n, buf) 54 return sys_write(fd, buf, len) 55} 56 57// ===== Escape text for HTML body context ========================== 58// 59// Replaces &, <, >, " with their entity references. Single quotes 60// not escaped (HTML5 attribute values quoted with double quotes by 61// our convention). 62 63func _html_write_escaped_z(fd: nx_int, s: *u8) -> nx_int { 64 let n: nx_int = strlen(s) 65 var i: nx_int = 0 66 let one: *u8 = sys_mmap(8) 67 while i < n { 68 let c: nx_int = s[i] 69 if c == 0x26 { _html_write_z(fd, "&amp;" as *u8) } 70 if c == 0x3C { _html_write_z(fd, "&lt;" as *u8) } 71 if c == 0x3E { _html_write_z(fd, "&gt;" as *u8) } 72 if c == 0x22 { _html_write_z(fd, "&quot;" as *u8) } 73 if c != 0x26 { 74 if c != 0x3C { 75 if c != 0x3E { 76 if c != 0x22 { 77 one[0] = c 78 sys_write(fd, one, 1) 79 } 80 } 81 } 82 } 83 i = i + 1 84 } 85 return n 86} 87 88// ===== Document open/close ======================================== 89 90func nx_html_doc_open(fd: nx_int, title: *u8) -> nx_int { 91 _html_write_z(fd, "<!doctype html>\n" as *u8) 92 _html_write_z(fd, "<html lang=\"en\"><head>" as *u8) 93 _html_write_z(fd, "<meta charset=\"utf-8\">" as *u8) 94 _html_write_z(fd, "<title>" as *u8) 95 _html_write_escaped_z(fd, title) 96 _html_write_z(fd, "</title></head><body>\n" as *u8) 97 return 0 98} 99 100func nx_html_doc_close(fd: nx_int) -> nx_int { 101 _html_write_z(fd, "</body></html>\n" as *u8) 102 return 0 103} 104 105// ===== Headings =================================================== 106 107func nx_html_h1(fd: nx_int, text: *u8) -> nx_int { 108 _html_write_z(fd, "<h1>" as *u8) 109 _html_write_escaped_z(fd, text) 110 _html_write_z(fd, "</h1>\n" as *u8) 111 return 0 112} 113 114func nx_html_h2(fd: nx_int, text: *u8) -> nx_int { 115 _html_write_z(fd, "<h2>" as *u8) 116 _html_write_escaped_z(fd, text) 117 _html_write_z(fd, "</h2>\n" as *u8) 118 return 0 119} 120 121// ===== Paragraph ================================================== 122 123func nx_html_p(fd: nx_int, text: *u8) -> nx_int { 124 _html_write_z(fd, "<p>" as *u8) 125 _html_write_escaped_z(fd, text) 126 _html_write_z(fd, "</p>\n" as *u8) 127 return 0 128} 129 130// ===== Table primitives =========================================== 131// 132// We emit minimal <table> with a single header row built from a 133// pipe-delimited header string. Cells take an int or string. 134// No CSS dependency; the dashboard renders fine in any browser. 135 136func nx_html_table_open(fd: nx_int) -> nx_int { 137 return _html_write_z(fd, "<table border=\"1\" cellpadding=\"4\">\n" as *u8) 138} 139 140func nx_html_table_close(fd: nx_int) -> nx_int { 141 return _html_write_z(fd, "</table>\n" as *u8) 142} 143 144// Header row: caller passes individual column labels. 145func nx_html_thead_open(fd: nx_int) -> nx_int { 146 return _html_write_z(fd, "<thead><tr>" as *u8) 147} 148 149func nx_html_thead_close(fd: nx_int) -> nx_int { 150 return _html_write_z(fd, "</tr></thead>\n" as *u8) 151} 152 153func nx_html_th(fd: nx_int, label: *u8) -> nx_int { 154 _html_write_z(fd, "<th>" as *u8) 155 _html_write_escaped_z(fd, label) 156 _html_write_z(fd, "</th>" as *u8) 157 return 0 158} 159 160// Body row: open / cells / close 161func nx_html_tr_open(fd: nx_int) -> nx_int { 162 return _html_write_z(fd, "<tr>" as *u8) 163} 164 165func nx_html_tr_close(fd: nx_int) -> nx_int { 166 return _html_write_z(fd, "</tr>\n" as *u8) 167} 168 169func nx_html_td_int(fd: nx_int, n: nx_int) -> nx_int { 170 _html_write_z(fd, "<td>" as *u8) 171 _html_write_i64(fd, n) 172 _html_write_z(fd, "</td>" as *u8) 173 return 0 174} 175 176func nx_html_td_text(fd: nx_int, s: *u8) -> nx_int { 177 _html_write_z(fd, "<td>" as *u8) 178 _html_write_escaped_z(fd, s) 179 _html_write_z(fd, "</td>" as *u8) 180 return 0 181} 182 183// ===== Bands as colored badges (no CSS framework) ================ 184// 185// Maps a utilization or continuity band code to a coloured inline 186// <span>. Caller passes the band int + a label table. This is 187// where the dashboard becomes scannable: green = GOOD, yellow = 188// DRIFT, red = BROKEN. 189 190const NX_HTML_BADGE_GOOD: nx_int = 0 191const NX_HTML_BADGE_DRIFT: nx_int = 1 192const NX_HTML_BADGE_BROKEN: nx_int = 2 193const NX_HTML_BADGE_NEUTRAL: nx_int = 3 194const NX_HTML_BADGE_N_KINDS: nx_int = 4 195 196func nx_html_badge(fd: nx_int, kind: nx_int, label: *u8) -> nx_int { 197 var color: *u8 = "#888" as *u8 198 if kind == NX_HTML_BADGE_GOOD { color = "#3a3" as *u8 } 199 if kind == NX_HTML_BADGE_DRIFT { color = "#cc6" as *u8 } 200 if kind == NX_HTML_BADGE_BROKEN { color = "#d33" as *u8 } 201 202 _html_write_z(fd, "<span style=\"background:" as *u8) 203 _html_write_z(fd, color) 204 _html_write_z(fd, ";color:#fff;padding:2px 6px;border-radius:3px;\">" as *u8) 205 _html_write_escaped_z(fd, label) 206 _html_write_z(fd, "</span>" as *u8) 207 return 0 208} 209 210// ===== Pre-formatted code block (for raw JSON / span dumps) ======= 211 212func nx_html_pre_open(fd: nx_int) -> nx_int { 213 return _html_write_z(fd, "<pre>" as *u8) 214} 215 216func nx_html_pre_close(fd: nx_int) -> nx_int { 217 return _html_write_z(fd, "</pre>\n" as *u8) 218}