code wiki / _hdl_build / nx_wiki_workstream_page.nx
nx_wiki_workstream_page.nx source
↩ module page · 201 lines · 10941 B
1// nx_wiki_workstream_page.nx -- the AUTONOMOUS per-workstream page generator. Reads ONE real workstream
2// record (a memory project-*.md -- our actual work, NOT a hand-kept TSV) and emits an S-class wiki page
3// in the canonical anatomy the Nishi researcher found in Wikipedia's MoS/Layout:
4// LEAD (standalone summary) -> INFOBOX (structured metadata) -> BODY (sections/lists, [[wikilinks]]) ->
5// SEE ALSO (related pages) -> CATEGORY. All on the shared GitBook skin (nx_wiki_skin_lib).
6// Usage: nx_wiki_workstream_page <record.md> (default = a sample record). Emits /tmp/nx_ws_page.html.
7// Sovereign: nx_syscalls + nx_wiki_skin_lib only. license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_wiki_skin_lib.nx"
10const WP_MAGIC_4194304: i64 = 4194304
11const WP_MAGIC_2048: i64 = 2048
12const WP_MAGIC_8388608: i64 = 8388608
13
14const WP_DEFAULT: *u8 = "/mnt/c/Users/elder/.claude/projects/C--Users-elder/memory/project-temporal-work-coverage-2026-06-19.md"
15const WP_OUT: *u8 = "/tmp/nx_ws_page.html"
16
17func wp_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
18func wp_slurp(path: *u8, buf: *u8, cap: i64) -> i64 {
19 let fd: i64 = sys_openat_rd(path)
20 if fd < 0 { return 0 }
21 var total: i64 = 0
22 var nrd: i64 = sys_read(fd, buf, cap)
23 while nrd > 0 { total = total + nrd; if total >= cap { nrd = 0 } else { nrd = sys_read(fd, ((buf as i64) + total) as *u8, cap - total) } }
24 sys_close(fd)
25 return total
26}
27func wp_find_from(buf: *u8, len: i64, from: i64, pat: *u8) -> i64 {
28 var pl: i64 = 0; while pat[pl] != (0 as u8) { pl = pl + 1 }
29 if pl == 0 { return 0 - 1 }
30 var i: i64 = from
31 while i + pl <= len { var j: i64 = 0; var ok: i64 = 1; while j < pl { if buf[i + j] != pat[j] { ok = 0; j = pl } else { j = j + 1 } } if ok == 1 { return i } i = i + 1 }
32 return 0 - 1
33}
34func wp_line_end(buf: *u8, len: i64, s: i64) -> i64 { var e: i64 = s; while e < len { if buf[e] == (10 as u8) { return e } e = e + 1 } return len }
35
36// extract the value of a frontmatter "key:" line into out (NUL-terminated, trimmed). returns length.
37func wp_fm_field(buf: *u8, len: i64, key: *u8, out: *u8, cap: i64) -> i64 {
38 let p: i64 = wp_find_from(buf, len, 0, key)
39 if p < 0 { out[0] = 0 as u8; return 0 }
40 var s: i64 = p
41 while s < len {
42 if buf[s] == (58 as u8) { // the ':' after the key
43 s = s + 1
44 if s < len { if buf[s] == (32 as u8) { s = s + 1 } } // skip one space
45 var o: i64 = 0
46 while s < len { if buf[s] == (10 as u8) { s = len } else { if buf[s] == (13 as u8) { s = len } else { if o < cap - 1 { out[o] = buf[s]; o = o + 1 } s = s + 1 } } }
47 out[o] = 0 as u8
48 return o
49 }
50 s = s + 1
51 }
52 out[0] = 0 as u8
53 return 0
54}
55
56func wp_esc1(dst: *u8, o: i64, c: i64) -> i64 {
57 if c == 60 { return sk_cat(dst, o, "<" as *u8) }
58 if c == 62 { return sk_cat(dst, o, ">" as *u8) }
59 if c == 38 { return sk_cat(dst, o, "&" as *u8) }
60 dst[o] = c as u8; return o + 1
61}
62func wp_esc(dst: *u8, o: i64, buf: *u8, a: i64, b: i64) -> i64 { var oo: i64 = o; var i: i64 = a; while i < b { oo = wp_esc1(dst, oo, buf[i] as i64); i = i + 1 } return oo }
63func wp_find2(buf: *u8, i: i64, end: i64, a: u8, b: u8) -> i64 { var k: i64 = i; while k + 1 < end { if buf[k] == a { if buf[k + 1] == b { return k } } k = k + 1 } return end }
64func wp_find1(buf: *u8, i: i64, end: i64, a: u8) -> i64 { var k: i64 = i; while k < end { if buf[k] == a { return k } k = k + 1 } return end }
65
66// inline render of buf[a..b): **bold** `code` [[wikilink]] + HTML-escape. returns new offset.
67func wp_inline(dst: *u8, off: i64, buf: *u8, a: i64, b: i64) -> i64 {
68 var o: i64 = off; var i: i64 = a
69 while i < b {
70 let c: i64 = buf[i] as i64
71 if c == 91 { if i + 1 < b { if buf[i + 1] == (91 as u8) {
72 let k: i64 = wp_find2(buf, i + 2, b, 93 as u8, 93 as u8)
73 o = sk_cat(dst, o, "<a href=\"" as *u8)
74 var t: i64 = i + 2; while t < k { dst[o] = buf[t]; o = o + 1; t = t + 1 }
75 o = sk_cat(dst, o, ".html\">" as *u8)
76 o = wp_esc(dst, o, buf, i + 2, k)
77 o = sk_cat(dst, o, "</a>" as *u8)
78 i = k + 2
79 } else { o = wp_esc1(dst, o, 91); i = i + 1 } } else { o = wp_esc1(dst, o, 91); i = i + 1 } }
80 else { if c == 42 { if i + 1 < b { if buf[i + 1] == (42 as u8) {
81 let k: i64 = wp_find2(buf, i + 2, b, 42 as u8, 42 as u8)
82 o = sk_cat(dst, o, "<strong>" as *u8); o = wp_esc(dst, o, buf, i + 2, k); o = sk_cat(dst, o, "</strong>" as *u8)
83 i = k + 2
84 } else { o = wp_esc1(dst, o, 42); i = i + 1 } } else { o = wp_esc1(dst, o, 42); i = i + 1 } }
85 else { if c == 96 {
86 let k: i64 = wp_find1(buf, i + 1, b, 96 as u8)
87 o = sk_cat(dst, o, "<code>" as *u8); o = wp_esc(dst, o, buf, i + 1, k); o = sk_cat(dst, o, "</code>" as *u8)
88 i = k + 1
89 }
90 else { o = wp_esc1(dst, o, c); i = i + 1 } } }
91 }
92 return o
93}
94
95// block render: headings (## -> h2/h3/h4), "- " lists, paragraphs. returns new offset.
96func wp_body(dst: *u8, off: i64, buf: *u8, start: i64, len: i64) -> i64 {
97 var o: i64 = off; var in_list: i64 = 0; var ls: i64 = start
98 while ls < len {
99 let le: i64 = wp_line_end(buf, len, ls)
100 var blank: i64 = 1; var j: i64 = ls
101 while j < le { if buf[j] != (32 as u8) { blank = 0; j = le } else { j = j + 1 } }
102 if blank == 1 { if in_list == 1 { o = sk_cat(dst, o, "</ul>\n" as *u8); in_list = 0 } }
103 else {
104 if buf[ls] == (35 as u8) {
105 if in_list == 1 { o = sk_cat(dst, o, "</ul>\n" as *u8); in_list = 0 }
106 var h: i64 = 0; var p: i64 = ls
107 while p < le { if buf[p] == (35 as u8) { h = h + 1; p = p + 1 } else { p = le } }
108 var cs: i64 = ls + h
109 if cs < le { if buf[cs] == (32 as u8) { cs = cs + 1 } }
110 var tag: *u8 = "h2" as *u8
111 if h == 3 { tag = "h3" as *u8 }
112 if h >= 4 { tag = "h4" as *u8 }
113 o = sk_cat(dst, o, "<" as *u8); o = sk_cat(dst, o, tag); o = sk_cat(dst, o, ">" as *u8)
114 o = wp_inline(dst, o, buf, cs, le)
115 o = sk_cat(dst, o, "</" as *u8); o = sk_cat(dst, o, tag); o = sk_cat(dst, o, ">\n" as *u8)
116 }
117 else { var islist: i64 = 0
118 if buf[ls] == (45 as u8) { if ls + 1 < le { if buf[ls + 1] == (32 as u8) { islist = 1 } } }
119 if islist == 1 {
120 if in_list == 0 { o = sk_cat(dst, o, "<ul>\n" as *u8); in_list = 1 }
121 o = sk_cat(dst, o, "<li>" as *u8); o = wp_inline(dst, o, buf, ls + 2, le); o = sk_cat(dst, o, "</li>\n" as *u8)
122 } else {
123 if in_list == 1 { o = sk_cat(dst, o, "</ul>\n" as *u8); in_list = 0 }
124 o = sk_cat(dst, o, "<p>" as *u8); o = wp_inline(dst, o, buf, ls, le); o = sk_cat(dst, o, "</p>\n" as *u8)
125 }
126 }
127 }
128 ls = le + 1
129 }
130 if in_list == 1 { o = sk_cat(dst, o, "</ul>\n" as *u8) }
131 return o
132}
133
134// SEE ALSO: emit each distinct [[wikilink]] in [start,len) as a list item. returns new offset.
135func wp_seealso(dst: *u8, off: i64, buf: *u8, start: i64, len: i64) -> i64 {
136 var o: i64 = off; var count: i64 = 0
137 o = sk_cat(dst, o, "<ul>\n" as *u8)
138 var i: i64 = start
139 while i + 1 < len {
140 if buf[i] == (91 as u8) { if buf[i + 1] == (91 as u8) {
141 let k: i64 = wp_find2(buf, i + 2, len, 93 as u8, 93 as u8)
142 o = sk_cat(dst, o, "<li><a href=\"" as *u8)
143 var t: i64 = i + 2; while t < k { dst[o] = buf[t]; o = o + 1; t = t + 1 }
144 o = sk_cat(dst, o, ".html\">" as *u8); o = wp_esc(dst, o, buf, i + 2, k); o = sk_cat(dst, o, "</a></li>\n" as *u8)
145 count = count + 1
146 i = k + 2
147 } else { i = i + 1 } } else { i = i + 1 }
148 }
149 if count == 0 { o = sk_cat(dst, o, "<li class=\"sub\">no linked workstreams</li>\n" as *u8) }
150 o = sk_cat(dst, o, "</ul>\n" as *u8)
151 return o
152}
153
154func main(argc: i64, argv: *i64) -> i64 {
155 var rec: *u8 = WP_DEFAULT
156 if argc >= 2 { rec = argv[1] as *u8 }
157 let src: *u8 = sys_mmap(WP_MAGIC_4194304)
158 let slen: i64 = wp_slurp(rec, src, WP_MAGIC_4194304)
159 if slen <= 0 { sys_write(2, "WS-PAGE: record not found\n" as *u8, 26); sys_exit(1); return 1 }
160
161 // frontmatter fields
162 let name: *u8 = sys_mmap(256); wp_fm_field(src, slen, "name:" as *u8, name, 256)
163 let desc: *u8 = sys_mmap(WP_MAGIC_2048); wp_fm_field(src, slen, "description:" as *u8, desc, WP_MAGIC_2048)
164 let typ: *u8 = sys_mmap(64); wp_fm_field(src, slen, "\n type:" as *u8, typ, 64)
165
166 // body = after the closing frontmatter fence "\n---"
167 var body_start: i64 = 0
168 let close: i64 = wp_find_from(src, slen, 3, "\n---" as *u8)
169 if close >= 0 { var bs: i64 = close + 4; while bs < slen { if src[bs] == (10 as u8) { bs = bs + 1; body_start = bs; bs = slen } else { bs = bs + 1 } } }
170
171 let h: *u8 = sys_mmap(WP_MAGIC_8388608)
172 var w: i64 = 0
173 w = skin_open(h, w, name, "board" as *u8)
174 // H1 (the workstream name)
175 w = sk_cat(h, w, "<h1>" as *u8); w = wp_inline(h, w, name, 0, wp_slen(name)); w = sk_cat(h, w, "</h1>\n" as *u8)
176 // LEAD (the description = standalone summary)
177 w = sk_cat(h, w, "<p class=\"sub\">" as *u8); w = wp_inline(h, w, desc, 0, wp_slen(desc)); w = sk_cat(h, w, "</p>\n" as *u8)
178 // INFOBOX
179 w = sk_cat(h, w, "<table><thead><tr><th colspan=2>Workstream</th></tr></thead><tbody>" as *u8)
180 w = sk_cat(h, w, "<tr><td>Name</td><td><code>" as *u8); w = wp_esc(h, w, name, 0, wp_slen(name)); w = sk_cat(h, w, "</code></td></tr>" as *u8)
181 w = sk_cat(h, w, "<tr><td>Type</td><td>" as *u8); w = wp_esc(h, w, typ, 0, wp_slen(typ)); w = sk_cat(h, w, "</td></tr>" as *u8)
182 w = sk_cat(h, w, "<tr><td>Source</td><td class=\"sub\">memory record (live work, not a TSV)</td></tr>" as *u8)
183 w = sk_cat(h, w, "</tbody></table>\n" as *u8)
184 // BODY
185 w = sk_cat(h, w, "<h2>Detail</h2>\n" as *u8)
186 w = wp_body(h, w, src, body_start, slen)
187 // SEE ALSO
188 w = sk_cat(h, w, "<h2>See also</h2>\n" as *u8)
189 w = wp_seealso(h, w, src, body_start, slen)
190 // CATEGORY
191 w = sk_cat(h, w, "<h2>Category</h2>\n<p><a href=\"index.html\">" as *u8); w = wp_esc(h, w, typ, 0, wp_slen(typ)); w = sk_cat(h, w, "</a></p>\n" as *u8)
192 w = skin_close(h, w, sys_now_realtime_sec())
193
194 let fd: i64 = sys_openat_wr(WP_OUT, 420)
195 if fd < 0 { sys_write(2, "WS-PAGE: open out failed\n" as *u8, 25); sys_exit(1); return 1 }
196 sys_write(fd, h, w); sys_close(fd)
197 let r: *u8 = sys_mmap(128); var ro: i64 = 0
198 ro = sk_cat(r, ro, "WS-PAGE-OK bytes=" as *u8); ro = sk_catn(r, ro, w); ro = sk_cat(r, ro, " out=/tmp/nx_ws_page.html\n" as *u8)
199 sys_write(1, r, ro)
200 sys_exit(0); return 0
201}