code wiki / _hdl_build / nx_docx_html_gate.nx
nx_docx_html_gate.nx source
↩ module page · 140 lines · 7530 B
1// nx_docx_html_gate.nx -- gate for the .docx -> HTML PREVIEW renderer (nx_docx html). Browsers can't render a
2// raw .docx (they download it); this proves nx_docx turns OOXML into a clean, sovereign, 0-JS HTML page the Nishi
3// browser shows INLINE -- headings, bold/italic runs, tables, and a "Download .docx" interop link. Evidence: it
4// writes a rich .docx (writerich), renders it (html), and greps the produced HTML for real structural markup.
5// Rows: 1 render-ok 2 valid-html 3 heading 4 bold+italic 5 table+cell 6 download-link 7 sovereign-0-JS 8 neg-missing[neg]
6// license_tier: ORIGINAL
7import "nx_syscalls.nx"
8import "nx_gate_verdict.nx"
9
10func hg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8) { n=n+1 } return n }
11func hg_p(s: *u8) -> i64 { sys_write(1, s, hg_slen(s)); return 0 }
12
13func hg_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8) { dst[off+i]=s[i]; i=i+1 } return off+i }
14func hg_catn(dst: *u8, off: i64, v: i64) -> i64 {
15 var o: i64=off; var m: i64=v; if m<0 { dst[o]=45 as u8; o=o+1; m=0-m }
16 let t: *u8=sys_mmap(28); var k: i64=0; if m==0 { t[0]=48 as u8; k=1 }
17 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
18 var i: i64=0; while i<k { dst[o+i]=t[k-1-i]; i=i+1 } return o+k
19}
20
21func hg_write(path: *u8, content: *u8) -> i64 {
22 let fd: i64=sys_openat_wr(path, 0x1a4); if fd<0 { return 0-1 }
23 sys_write(fd, content, hg_slen(content)); sys_close(fd); return 0
24}
25
26func hg_readall(path: *u8, szout: *i64) -> *u8 {
27 let fd: i64=sys_openat_rd(path); if fd<0 { szout[0]=0-1; return 0 as *u8 }
28 let buf: *u8=sys_mmap(4194304); var got: i64=0; var n: i64=1
29 while n>0 { n=sys_read(fd,(buf as i64+got) as *u8,131072); if n>0 { got=got+n } }
30 sys_close(fd); szout[0]=got; return buf
31}
32
33func hg_runv(elf: *u8, args: *i64, outpath: *u8) -> i64 {
34 let pid: i64=sys_fork()
35 if pid==0 {
36 if (outpath as i64)!=0 { let ofd: i64=sys_openat_wr(outpath,0x1a4); if ofd>=0 { sys_dup3(ofd,1,0); sys_dup3(ofd,2,0) } }
37 let argv: *i64=sys_mmap(128) as *i64
38 argv[0]=elf as i64; var i: i64=0; var go: i64=1
39 while go==1 { if args[i]==0 { go=0 } else { argv[i+1]=args[i]; i=i+1 } }
40 argv[i+1]=0
41 let envp: *i64=sys_mmap(16) as *i64; envp[0]=0
42 sys_execve(elf, argv, envp); sys_exit(127)
43 }
44 let st: *i64=sys_mmap(16) as *i64; sys_wait4(pid, st, 0)
45 let sig: i64=st[0]&0x7f; if sig!=0 { return 128+sig }
46 return (st[0]>>8)&0xff
47}
48
49func hg_has(path: *u8, needle: *u8) -> i64 {
50 let szp: *i64=sys_mmap(16) as *i64; let b: *u8=hg_readall(path, szp); let sz: i64=szp[0]
51 let n: i64=hg_slen(needle); if sz<n { return 0 }
52 var i: i64=0
53 while i+n<=sz { var ok: i64=1; var j: i64=0; while j<n { if b[i+j]!=needle[j] { ok=0; j=n } else { j=j+1 } } if ok==1 { return 1 } i=i+1 }
54 return 0
55}
56
57func hg_args4(a1: *u8, a2: *u8, a3: *u8, a4: *u8) -> *i64 {
58 let a: *i64=sys_mmap(64) as *i64; a[0]=a1 as i64; a[1]=a2 as i64; a[2]=a3 as i64; a[3]=a4 as i64; a[4]=0; return a
59}
60
61func hg_row(name: *u8, pass: i64) -> i64 {
62 hg_p("ROW " as *u8); hg_p(name); if pass==1 { hg_p(" PASS\n" as *u8) } else { hg_p(" FAIL\n" as *u8) } return pass
63}
64
65func main(argc: i64, argv: *i64) -> i64 {
66 hg_p("=== DOCX -> HTML PREVIEW GATE: inline document viewer (headings/bold/italic/tables) + download link ===\n" as *u8)
67 let docx: *u8="buildroot/_build/nx_docx.sov.elf" as *u8
68 let pr: i64=sys_openat_rd(docx)
69 if pr>=0 { sys_close(pr) } else {
70 hg_p(" instrument missing -> rebuilding via durable runner\n" as *u8)
71 hg_runv("_offc/nx_sov_build_run.elf" as *u8, hg_args4("nx_docx" as *u8, "--build-only" as *u8, 0 as *u8, 0 as *u8), "/tmp/dh_rebuild.out" as *u8)
72 }
73
74 hg_write("/tmp/dh_spec.txt" as *u8, "H Venue Booking Agreement\nB Parties\nI confidential draft\nP Nishi Family and Lakeside Pavilion\nT Field|Value\nT Date|2026-08-15\nT Cost|USD 350.00\nP Signed on the day of booking.\n" as *u8)
75
76 var pass: i64=0; var r: i64=0
77
78 // build the rich .docx to preview
79 hg_runv(docx, hg_args4("writerich" as *u8, "/tmp/dh.docx" as *u8, "/tmp/dh_spec.txt" as *u8, 0 as *u8), "/tmp/dh_w.txt" as *u8)
80
81 // row 1: render to HTML (with a download link)
82 let rc1: i64=hg_runv(docx, hg_args4("html" as *u8, "/tmp/dh.docx" as *u8, "/tmp/dh.html" as *u8, "/vizsla_agreement.docx" as *u8), "/tmp/dh_r1.txt" as *u8)
83 r=0; if rc1==0 { if hg_has("/tmp/dh_r1.txt" as *u8, "DOCX-HTML-OK path=/tmp/dh.html bytes=" as *u8)==1 { r=1 } }
84 pass=pass+hg_row("html-render-ok" as *u8, r)
85
86 // row 2: valid HTML document
87 r=0; if hg_has("/tmp/dh.html" as *u8, "<!DOCTYPE html>" as *u8)==1 { if hg_has("/tmp/dh.html" as *u8, "</html>" as *u8)==1 { r=1 } }
88 pass=pass+hg_row("valid-html" as *u8, r)
89
90 // row 3: heading rendered as <h2> (b + sz=32 -> heading)
91 r=hg_has("/tmp/dh.html" as *u8, "<h2>Venue Booking Agreement</h2>" as *u8)
92 pass=pass+hg_row("heading-h2" as *u8, r)
93
94 // row 4: bold + italic runs
95 r=0; if hg_has("/tmp/dh.html" as *u8, "<b>Parties</b>" as *u8)==1 { if hg_has("/tmp/dh.html" as *u8, "<i>confidential draft</i>" as *u8)==1 { r=1 } }
96 pass=pass+hg_row("bold-italic-runs" as *u8, r)
97
98 // row 5: table + cell content
99 r=0; if hg_has("/tmp/dh.html" as *u8, "<table>" as *u8)==1 { if hg_has("/tmp/dh.html" as *u8, "<tr>" as *u8)==1 { if hg_has("/tmp/dh.html" as *u8, "<td>USD 350.00</td>" as *u8)==1 { r=1 } } }
100 pass=pass+hg_row("table-cells" as *u8, r)
101
102 // row 6: interop download link
103 r=0; if hg_has("/tmp/dh.html" as *u8, "href=\"/vizsla_agreement.docx\"" as *u8)==1 { if hg_has("/tmp/dh.html" as *u8, "Download .docx" as *u8)==1 { r=1 } }
104 pass=pass+hg_row("download-link" as *u8, r)
105
106 // row 7: sovereign 0-JS (no script, no external http load)
107 r=1; if hg_has("/tmp/dh.html" as *u8, "<script" as *u8)==1 { r=0 } if hg_has("/tmp/dh.html" as *u8, "http" as *u8)==1 { r=0 }
108 pass=pass+hg_row("sovereign-0js" as *u8, r)
109
110 // row 8 (neg): missing .docx must loud-fail
111 let rc8: i64=hg_runv(docx, hg_args4("html" as *u8, "/tmp/dh_nope.docx" as *u8, "/tmp/dh_x.html" as *u8, 0 as *u8), "/tmp/dh_r8.txt" as *u8)
112 r=0; if rc8==1 { r=1 }
113 pass=pass+hg_row("loud-fail-missing" as *u8, r)
114
115 let permil: i64=(pass*1000)/8
116 let logfd: i64=sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4)
117 var fdi: i64=0
118 while fdi<2 {
119 var fd: i64=1; if fdi==1 { fd=logfd }
120 if fd>0 {
121 let line: *u8=sys_mmap(256); var o: i64=0
122 o=hg_cat(line,o,"DOCX-HTML-GATE epoch=" as *u8); o=hg_catn(line,o,sys_now_realtime_sec())
123 o=hg_cat(line,o," rows=8 pass=" as *u8); o=hg_catn(line,o,pass)
124 o=hg_cat(line,o," permil=" as *u8); o=hg_catn(line,o,permil)
125 if pass==8 { o=hg_cat(line,o," verdict=GREEN\n" as *u8) } else { o=hg_cat(line,o," verdict=RED\n" as *u8) }
126 sys_write(fd, line, o)
127 }
128 fdi=fdi+1
129 }
130 if logfd>0 { sys_close(logfd) }
131 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
132 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
133 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
134 let ctr__dry: *i64 = gv_ctr()
135 ctr__dry[0] = pass
136 ctr__dry[1] = 8
137 let rc__dry: i64 = gv_verdict("DOCX-HTML-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
138 sys_exit(rc__dry)
139 return rc__dry
140}