code wiki / (root) / nx_paper_native.nx

nx_paper_native.nx source

↩ module page · 855 lines · 40567 B

1// nx_paper_native.nx -- PAPERS AS NATIVE NISHI DOCS, NOT PDF (operator 2026-08-13: "i dont want 2// the papers in 3rd party formats like pdf ... ingested into html or whatever from the first bit 3// up we can do in nishi that makes it native to nishi os and browser"). 4// 5// NXPAP2 (2026-08-14) -- v1 was a readable DIGEST, measured NOT sota. Against the real LaTeXML 6// source of one paper (arXiv 2411.15205, 242,460 B) v1 preserved: 0 of 82 <math>, 0 of 8 <figure>, 7// 0 of 84 bibitems, and collapsed all 10 <h3> subsections into their parent section. It also 8// DECODED source entities (&lt; -> <) and then copied section text into HTML unescaped, so decoded 9// markup reached the page raw. NXPAP2 fixes all of it, and REFUSES rather than drop silently. 10// 11// FORMAT: line-oriented, greppable, sovereign. Header `KEY\tVALUE` lines, then typed blocks: 12// .SEC <level>\t<id>\t<title> sectioning, level 1..3, id = the source anchor 13// .PARA <inline> one paragraph of SAFE inline html (see below) 14// .MATH <id>\t<mathml> display equation, MathML subtree VERBATIM 15// .FIG <id> figure open | .TBL <id> table open 16// .IMG <url> one image of the current figure (absolute url) 17// .CAP <inline> caption of the current figure/table 18// .ROW <cell>\t<cell>... one table row, cells are inline 19// .REF <key>\t<label>\t<text> one parsed reference 20// 21// SAFE INLINE is the load-bearing invariant: source entities are kept VERBATIM (never decoded), 22// every tag is dropped except (a) <math>..</math> copied byte-for-byte so MathML survives to the 23// browser natively, and (b) fragment links rebuilt as anchors so citations and cross-references 24// stay real links. Nothing else reaches the output, so the emitted page cannot carry injected 25// markup -- escaping is by construction, not by a filter that must be remembered. 26// 27// FIDELITY IS ENFORCED, NOT HOPED FOR: the ingest counts <math>, <figure> and bibitems in the 28// SOURCE and in what it EMITTED, prints both, and REFUSES (exit 3) if it emitted fewer. A silent 29// drop -- the v1 defect -- is impossible by construction. 30// 31// nx_paper_native abs <cvf-abstract.raw> <out.nxpap> [arxiv-html.raw] 32// nx_paper_native view <in.nxpap> <out.html> 33// exit: 0 ok | 1 io | 2 usage | 3 refuse (named). license_tier: ORIGINAL. No hw writes (Rule 26). 34import "nx_syscalls.nx" 35const PN_MAGIC_1048576: i64 = 1048576 36 37// NO READ CAP EXISTS HERE BY DESIGN. Reads compose sys_read_file, which sizes its buffer from the 38// file itself (lseek END) and therefore cannot short-read; the estate fixed that defect class on 39// 2026-07-15 and this organ had been hand-rolling a capped reader beside it. A buffer ceiling that 40// has to be guessed is a defect generator either way -- too small truncates in silence, too large 41// wastes memory -- so the constant is removed, not raised. Output buffers are DERIVED from input 42// size (below), and mmap faults pages in on demand, so headroom costs address space, not memory. 43const PN_ARXBASE: *u8 = "https://arxiv.org/html/" 44 45func pn_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 46func pn_puts(s: *u8) -> i64 { sys_write(1, s, pn_len(s)); return 0 } 47func pn_num(v: i64) -> i64 { 48 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 49 var m: i64 = v 50 let t: *u8 = sys_mmap(32) 51 var k: i64 = 0 52 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 53 let o: *u8 = sys_mmap(32) 54 var i: i64 = 0 55 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 56 sys_write(1, o, k) 57 return 0 58} 59func pn_app(d: *u8, off: i64, s: *u8) -> i64 { 60 var i: i64 = 0 61 var o: i64 = off 62 while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } 63 return o 64} 65func pn_appn(d: *u8, off: i64, src: *u8, a: i64, b: i64) -> i64 { 66 var o: i64 = off 67 var i: i64 = a 68 while i < b { d[o] = src[i]; o = o + 1; i = i + 1 } 69 return o 70} 71func pn_find(src: *u8, a: i64, b: i64, pat: *u8) -> i64 { 72 let pl: i64 = pn_len(pat) 73 if pl == 0 { return 0 - 1 } 74 var i: i64 = a 75 var hit: i64 = 0 - 1 76 var run: i64 = 1 77 while run == 1 { 78 if i + pl > b { run = 0 } else { 79 var j: i64 = 0 80 var ok: i64 = 1 81 var scan: i64 = 1 82 while scan == 1 { 83 if j >= pl { scan = 0 } else { 84 if src[i + j] != pat[j] { ok = 0; scan = 0 } else { j = j + 1 } 85 } 86 } 87 if ok == 1 { hit = i; run = 0 } else { i = i + 1 } 88 } 89 } 90 return hit 91} 92func pn_count(src: *u8, a: i64, b: i64, pat: *u8) -> i64 { 93 var c: i64 = 0 94 var p: i64 = a 95 var run: i64 = 1 96 while run == 1 { 97 let h: i64 = pn_find(src, p, b, pat) 98 if h < 0 { run = 0 } else { c = c + 1; p = h + 1 } 99 } 100 return c 101} 102func pn_num_to(d: *u8, off: i64, v: i64) -> i64 { 103 var o: i64 = off 104 if v == 0 { d[o] = 48 as u8; return o + 1 } 105 var m: i64 = v 106 let t: *u8 = sys_mmap(32) 107 var k: i64 = 0 108 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 109 while k > 0 { k = k - 1; d[o] = t[k]; o = o + 1 } 110 return o 111} 112// start of the value of `attr` (which must include the opening quote) inside src[a..b); -1 if none 113func pn_attr_s(src: *u8, a: i64, b: i64, attr: *u8) -> i64 { 114 let p: i64 = pn_find(src, a, b, attr) 115 if p < 0 { return 0 - 1 } 116 return p + pn_len(attr) 117} 118func pn_write(path: *u8, buf: *u8, n: i64) -> i64 { 119 let fd: i64 = sys_openat_wr(path, 0x1a4) 120 if fd < 0 { return 0 - 1 } 121 sys_write(fd, buf, n) 122 sys_close(fd) 123 return 0 124} 125 126// ---- text: drop tags, KEEP entities verbatim, collapse whitespace ---- 127func pn_txt(d: *u8, off: i64, src: *u8, a: i64, b: i64) -> i64 { 128 var o: i64 = off 129 var i: i64 = a 130 var sp: i64 = 1 131 while i < b { 132 let c: i64 = src[i] as i64 133 if c == 60 { 134 let te: i64 = pn_find(src, i, b, ">" as *u8) 135 if te < 0 { i = b } else { i = te + 1 } 136 } else { 137 var ch: i64 = c 138 if ch == 9 { ch = 32 } 139 if ch == 10 { ch = 32 } 140 if ch == 13 { ch = 32 } 141 if ch == 32 { 142 if sp == 0 { d[o] = 32 as u8; o = o + 1; sp = 1 } 143 } else { 144 d[o] = ch as u8 145 o = o + 1 146 sp = 0 147 } 148 i = i + 1 149 } 150 } 151 return o 152} 153// ---- inline: safe html. entities verbatim, <math> verbatim, fragment links rebuilt, 154// every other tag dropped. cnt[0] += maths copied. THIS is the escaping invariant. ---- 155func pn_inline(d: *u8, off: i64, src: *u8, a: i64, b: i64, cnt: *i64) -> i64 { 156 var o: i64 = off 157 var i: i64 = a 158 var sp: i64 = 1 159 while i < b { 160 let c: i64 = src[i] as i64 161 if c == 60 { 162 var done: i64 = 0 163 if pn_find(src, i, b, "<math" as *u8) == i { 164 let me: i64 = pn_find(src, i, b, "</math>" as *u8) 165 if me >= 0 { 166 let end: i64 = me + 7 167 var k: i64 = i 168 while k < end { 169 var ch2: i64 = src[k] as i64 170 if ch2 == 10 { ch2 = 32 } 171 if ch2 == 13 { ch2 = 32 } 172 if ch2 == 9 { ch2 = 32 } 173 d[o] = ch2 as u8 174 o = o + 1 175 k = k + 1 176 } 177 cnt[0] = cnt[0] + 1 178 sp = 0 179 i = end 180 done = 1 181 } 182 } 183 if done == 0 { 184 if pn_find(src, i, b, "<a " as *u8) == i { 185 let te: i64 = pn_find(src, i, b, ">" as *u8) 186 if te > 0 { 187 let hs: i64 = pn_attr_s(src, i, te, "href=\"" as *u8) 188 if hs > 0 { 189 let he: i64 = pn_find(src, hs, te, "\"" as *u8) 190 if he > hs { 191 if src[hs] == (35 as u8) { 192 let ae: i64 = pn_find(src, te, b, "</a>" as *u8) 193 if ae > te { 194 o = pn_app(d, o, "<a href=\"" as *u8) 195 o = pn_appn(d, o, src, hs, he) 196 o = pn_app(d, o, "\">" as *u8) 197 o = pn_txt(d, o, src, te + 1, ae) 198 o = pn_app(d, o, "</a>" as *u8) 199 sp = 0 200 i = ae + 4 201 done = 1 202 } 203 } 204 } 205 } 206 } 207 } 208 } 209 if done == 0 { 210 let te2: i64 = pn_find(src, i, b, ">" as *u8) 211 if te2 < 0 { i = b } else { i = te2 + 1 } 212 } 213 } else { 214 var ch: i64 = c 215 if ch == 9 { ch = 32 } 216 if ch == 10 { ch = 32 } 217 if ch == 13 { ch = 32 } 218 if ch == 32 { 219 if sp == 0 { d[o] = 32 as u8; o = o + 1; sp = 1 } 220 } else { 221 d[o] = ch as u8 222 o = o + 1 223 sp = 0 224 } 225 i = i + 1 226 } 227 } 228 return o 229} 230 231// ---- one figure/table region [a..b) -> .FIG/.TBL + .IMG* + .CAP (+ .ROW* for tables) ---- 232func pn_figure(d: *u8, off: i64, src: *u8, a: i64, b: i64, istbl: i64, cnt: *i64) -> i64 { 233 var o: i64 = off 234 let ids: i64 = pn_attr_s(src, a, b, "id=\"" as *u8) 235 if istbl == 1 { o = pn_app(d, o, ".TBL " as *u8) } else { o = pn_app(d, o, ".FIG " as *u8) } 236 if ids > 0 { 237 let ide: i64 = pn_find(src, ids, b, "\"" as *u8) 238 if ide > ids { o = pn_appn(d, o, src, ids, ide) } 239 } 240 o = pn_app(d, o, "\n" as *u8) 241 // images -- absolute so the document is self-describing 242 var p: i64 = a 243 var run: i64 = 1 244 while run == 1 { 245 let im: i64 = pn_find(src, p, b, "<img " as *u8) 246 if im < 0 { run = 0 } else { 247 let ss: i64 = pn_attr_s(src, im, b, "src=\"" as *u8) 248 if ss > 0 { 249 let se: i64 = pn_find(src, ss, b, "\"" as *u8) 250 if se > ss { 251 o = pn_app(d, o, ".IMG " as *u8) 252 if pn_find(src, ss, se, "http" as *u8) != ss { o = pn_app(d, o, PN_ARXBASE) } 253 o = pn_appn(d, o, src, ss, se) 254 o = pn_app(d, o, "\n" as *u8) 255 } 256 } 257 p = im + 5 258 } 259 } 260 // caption 261 let cs: i64 = pn_find(src, a, b, "<figcaption" as *u8) 262 if cs >= 0 { 263 let ce: i64 = pn_find(src, cs, b, "</figcaption>" as *u8) 264 if ce > cs { 265 let cb: i64 = pn_find(src, cs, ce, ">" as *u8) 266 if cb > cs { 267 o = pn_app(d, o, ".CAP " as *u8) 268 o = pn_inline(d, o, src, cb + 1, ce, cnt) 269 o = pn_app(d, o, "\n" as *u8) 270 } 271 } 272 } 273 // table rows -- cells carry math, so they go through pn_inline or the count is short 274 if istbl == 1 { 275 var rp: i64 = a 276 var rr: i64 = 1 277 while rr == 1 { 278 let tr: i64 = pn_find(src, rp, b, "<tr " as *u8) 279 if tr < 0 { rr = 0 } else { 280 var tre: i64 = pn_find(src, tr, b, "</tr>" as *u8) 281 if tre < 0 { tre = b } 282 o = pn_app(d, o, ".ROW " as *u8) 283 var cp: i64 = tr 284 var nc: i64 = 0 285 var cr: i64 = 1 286 while cr == 1 { 287 var cell: i64 = pn_find(src, cp, tre, "<td " as *u8) 288 let cellh: i64 = pn_find(src, cp, tre, "<th " as *u8) 289 if cell < 0 { cell = cellh } else { 290 if cellh >= 0 { if cellh < cell { cell = cellh } } 291 } 292 if cell < 0 { cr = 0 } else { 293 let cb2: i64 = pn_find(src, cell, tre, ">" as *u8) 294 var cend: i64 = pn_find(src, cell, tre, "</t" as *u8) 295 if cend < 0 { cend = tre } 296 if cb2 > cell { 297 if nc > 0 { o = pn_app(d, o, "\t" as *u8) } 298 o = pn_inline(d, o, src, cb2 + 1, cend, cnt) 299 nc = nc + 1 300 } 301 cp = cend + 3 302 } 303 } 304 o = pn_app(d, o, "\n" as *u8) 305 rp = tre + 5 306 } 307 } 308 } 309 return o 310} 311 312// ---- the bibliography region -> one .REF per bibitem ---- 313// the refnum span repeats the authors that the bibblocks also carry -- taking ONLY the bibblocks 314// is what kills the v1 duplication ("Achlioptas et al. 2018; Achlioptas et al. 2018"). 315func pn_refs(d: *u8, off: i64, src: *u8, a: i64, b: i64, nref: *i64) -> i64 { 316 var o: i64 = off 317 var p: i64 = a 318 var run: i64 = 1 319 while run == 1 { 320 // ANCHOR ON THE ELEMENT, THEN TEST IT -- never scan backwards a guessed distance. 321 // This used to find class="ltx_bibitem" and then look BACK a fixed 40 bytes for the id, 322 // which is a magic number wearing arithmetic: one bibitem whose opening tag is longer 323 // than the window and the reference key comes out wrong or empty, silently. Finding the 324 // <li first means the id is read FORWARD inside the tag and no window exists to guess. 325 let li: i64 = pn_find(src, p, b, "<li " as *u8) 326 if li < 0 { run = 0 } else { 327 let lt: i64 = pn_find(src, li, b, ">" as *u8) 328 var le: i64 = pn_find(src, li, b, "</li>" as *u8) 329 if le < 0 { le = b } 330 var isbib: i64 = 0 331 if lt > li { if pn_find(src, li, lt, "ltx_bibitem" as *u8) > 0 { isbib = 1 } } 332 if isbib == 1 { 333 o = pn_app(d, o, ".REF " as *u8) 334 let ks: i64 = pn_attr_s(src, li, lt, "id=\"" as *u8) 335 if ks > 0 { 336 let ke: i64 = pn_find(src, ks, lt, "\"" as *u8) 337 if ke > ks { o = pn_appn(d, o, src, ks, ke) } 338 } 339 o = pn_app(d, o, "\t" as *u8) 340 // label: the refnum span 341 let ts: i64 = pn_find(src, li, le, "ltx_tag_bibitem" as *u8) 342 var afterlabel: i64 = li 343 if ts >= 0 { 344 let t1: i64 = pn_find(src, ts, le, ">" as *u8) 345 if t1 > 0 { 346 let t2: i64 = pn_find(src, t1, le, "</span></span>" as *u8) 347 if t2 > t1 { 348 o = pn_txt(d, o, src, t1 + 1, t2) 349 afterlabel = t2 + 14 350 } 351 } 352 } 353 o = pn_app(d, o, "\t" as *u8) 354 // text: the bibblocks only -- the refnum span above repeats the authors these 355 // carry, and emitting both is exactly the v1 duplication defect 356 var q: i64 = afterlabel 357 var qr: i64 = 1 358 while qr == 1 { 359 let bb: i64 = pn_find(src, q, le, "class=\"ltx_bibblock\"" as *u8) 360 if bb < 0 { qr = 0 } else { 361 let b1: i64 = pn_find(src, bb, le, ">" as *u8) 362 var b2: i64 = pn_find(src, bb, le, "</span>\n</span>" as *u8) 363 if b2 < 0 { b2 = pn_find(src, bb, le, "</span></span>" as *u8) } 364 if b2 < 0 { b2 = le } 365 if b1 > 0 { o = pn_txt(d, o, src, b1 + 1, b2) } 366 q = b2 + 7 367 } 368 } 369 o = pn_app(d, o, "\n" as *u8) 370 nref[0] = nref[0] + 1 371 } 372 p = le + 5 373 } 374 } 375 return o 376} 377 378// the first structural block. Skips the abstract (already taken from the CVF metadata) while 379// keeping the teaser figure that precedes section 1. The fidelity counts use the SAME start, so 380// the denominator is exactly the region that was walked -- an aggregate assertion bound to a 381// wider denominator than its subject is how a conversion "passes" while dropping content. 382func pn_bodystart(src: *u8, n: i64) -> i64 { 383 var start: i64 = pn_find(src, 0, n, "<section id=\"" as *u8) 384 let f0: i64 = pn_find(src, 0, n, "<figure id=\"" as *u8) 385 if f0 >= 0 { if start < 0 { start = f0 } else { if f0 < start { start = f0 } } } 386 return start 387} 388// ---- the LaTeXML body walk: emit typed blocks in document order ---- 389func pn_body(d: *u8, off: i64, src: *u8, n: i64, cnt: *i64, nfig: *i64, nref: *i64, nsec: *i64) -> i64 { 390 var o: i64 = off 391 let start: i64 = pn_bodystart(src, n) 392 if start < 0 { return o } 393 var p: i64 = start 394 var run: i64 = 1 395 while run == 1 { 396 let sec: i64 = pn_find(src, p, n, "<section id=\"" as *u8) 397 let fig: i64 = pn_find(src, p, n, "<figure id=\"" as *u8) 398 let par: i64 = pn_find(src, p, n, "<p id=\"" as *u8) 399 let eqt: i64 = pn_find(src, p, n, "<table id=\"" as *u8) 400 // earliest marker wins 401 var best: i64 = 0 - 1 402 var kind: i64 = 0 403 if sec >= 0 { best = sec; kind = 1 } 404 if fig >= 0 { if best < 0 { best = fig; kind = 2 } else { if fig < best { best = fig; kind = 2 } } } 405 if par >= 0 { if best < 0 { best = par; kind = 3 } else { if par < best { best = par; kind = 3 } } } 406 if eqt >= 0 { if best < 0 { best = eqt; kind = 4 } else { if eqt < best { best = eqt; kind = 4 } } } 407 if best < 0 { run = 0 } else { 408 let te: i64 = pn_find(src, best, n, ">" as *u8) 409 if te < 0 { run = 0 } else { 410 if kind == 1 { 411 // bibliography section -> references, not prose 412 if pn_find(src, best, te, "ltx_bibliography" as *u8) > 0 { 413 o = pn_refs(d, o, src, best, n, nref) 414 run = 0 415 } else { 416 var lvl: i64 = 1 417 if pn_find(src, best, te, "ltx_subsubsection" as *u8) > 0 { lvl = 3 } else { 418 if pn_find(src, best, te, "ltx_subsection" as *u8) > 0 { lvl = 2 } 419 } 420 let ids: i64 = pn_attr_s(src, best, te, "id=\"" as *u8) 421 // the heading that opens this section 422 var hs: i64 = pn_find(src, te, n, "<h" as *u8) 423 if hs >= 0 { 424 let h1: i64 = pn_find(src, hs, n, ">" as *u8) 425 var h2e: i64 = pn_find(src, hs, n, "</h" as *u8) 426 if h2e < 0 { h2e = n } 427 if h1 > 0 { 428 o = pn_app(d, o, ".SEC " as *u8) 429 o = pn_num_to(d, o, lvl) 430 o = pn_app(d, o, "\t" as *u8) 431 if ids > 0 { 432 let ide: i64 = pn_find(src, ids, te, "\"" as *u8) 433 if ide > ids { o = pn_appn(d, o, src, ids, ide) } 434 } 435 o = pn_app(d, o, "\t" as *u8) 436 o = pn_txt(d, o, src, h1 + 1, h2e) 437 o = pn_app(d, o, "\n" as *u8) 438 nsec[0] = nsec[0] + 1 439 p = h2e 440 } else { p = te + 1 } 441 } else { p = te + 1 } 442 } 443 } 444 if kind == 2 { 445 var fe: i64 = pn_find(src, best, n, "</figure>" as *u8) 446 if fe < 0 { fe = n } 447 var istbl: i64 = 0 448 if pn_find(src, best, te, "ltx_table" as *u8) > 0 { istbl = 1 } 449 o = pn_figure(d, o, src, best, fe, istbl, cnt) 450 nfig[0] = nfig[0] + 1 451 p = fe + 9 452 } 453 if kind == 3 { 454 var pe: i64 = pn_find(src, best, n, "</p>" as *u8) 455 if pe < 0 { pe = n } 456 o = pn_app(d, o, ".PARA " as *u8) 457 o = pn_inline(d, o, src, te + 1, pe, cnt) 458 o = pn_app(d, o, "\n" as *u8) 459 p = pe + 4 460 } 461 if kind == 4 { 462 var qe: i64 = pn_find(src, best, n, "</table>" as *u8) 463 if qe < 0 { qe = n } 464 if pn_find(src, best, te, "ltx_eqn_table" as *u8) > 0 { 465 let ids2: i64 = pn_attr_s(src, best, te, "id=\"" as *u8) 466 var mp: i64 = best 467 var mr: i64 = 1 468 while mr == 1 { 469 let m0: i64 = pn_find(src, mp, qe, "<math" as *u8) 470 if m0 < 0 { mr = 0 } else { 471 let m1: i64 = pn_find(src, m0, qe, "</math>" as *u8) 472 if m1 < 0 { mr = 0 } else { 473 o = pn_app(d, o, ".MATH " as *u8) 474 if ids2 > 0 { 475 let ide2: i64 = pn_find(src, ids2, te, "\"" as *u8) 476 if ide2 > ids2 { o = pn_appn(d, o, src, ids2, ide2) } 477 } 478 o = pn_app(d, o, "\t" as *u8) 479 var k2: i64 = m0 480 let end2: i64 = m1 + 7 481 while k2 < end2 { 482 var c3: i64 = src[k2] as i64 483 if c3 == 10 { c3 = 32 } 484 if c3 == 13 { c3 = 32 } 485 if c3 == 9 { c3 = 32 } 486 d[o] = c3 as u8 487 o = o + 1 488 k2 = k2 + 1 489 } 490 o = pn_app(d, o, "\n" as *u8) 491 cnt[0] = cnt[0] + 1 492 mp = end2 493 } 494 } 495 } 496 } 497 p = qe + 8 498 } 499 if p <= best { p = best + 1 } 500 if p >= n { run = 0 } 501 } 502 } 503 } 504 return o 505} 506 507// ---- CVF abstract-page metadata ---- 508func pn_meta(src: *u8, a: i64, b: i64, key: *u8, r: *i64) -> i64 { 509 let kp: i64 = pn_find(src, a, b, key) 510 if kp < 0 { return 0 - 1 } 511 let cp: i64 = pn_find(src, kp, b, "content=" as *u8) 512 if cp < 0 { return 0 - 1 } 513 let vs: i64 = cp + 9 514 let ve: i64 = pn_find(src, vs, b, "\"" as *u8) 515 if ve < 0 { return 0 - 1 } 516 r[0] = vs 517 r[1] = ve 518 r[2] = ve 519 return 0 520} 521func pn_hdr(out: *u8, off: i64, fb: *u8, n: i64, key: *u8, label: *u8, r: *i64) -> i64 { 522 var o: i64 = off 523 if pn_meta(fb, 0, n, key, r) == 0 { 524 o = pn_app(out, o, label) 525 o = pn_txt(out, o, fb, r[0], r[1]) 526 o = pn_app(out, o, "\n" as *u8) 527 } 528 return o 529} 530 531// ---- INGEST: CVF abstract page (+ optional arXiv LaTeXML full text) -> NXPAP2 ---- 532func pn_ingest(inp: *u8, outp: *u8, axp: *u8) -> i64 { 533 let ln: *i64 = sys_mmap(16) as *i64 534 let fb: *u8 = sys_read_file(inp, ln) 535 if (fb as i64) == 0 { pn_puts("PAPER-NATIVE REFUSE: cannot read source\n" as *u8); return 3 } 536 let n: i64 = ln[0] 537 if n <= 0 { pn_puts("PAPER-NATIVE REFUSE: cannot read source\n" as *u8); return 3 } 538 // the full text is read UP FRONT so the output buffer can be sized from the REAL inputs 539 var ab: *u8 = 0 as *u8 540 var an: i64 = 0 541 if (axp as i64) != 0 { 542 let l2: *i64 = sys_mmap(16) as *i64 543 ab = sys_read_file(axp, l2) 544 if (ab as i64) != 0 { an = l2[0] } 545 } 546 // DERIVED from the real inputs, never a fixed ceiling. Every emit path copies a SUBSET of the 547 // source plus bounded per-block markup, so output cannot approach 8x input; the reservation is 548 // deliberately generous because mmap faults pages in on demand, so headroom costs address 549 // space and not resident memory. outcap is kept because an unchecked bound is worse than a 550 // magic number -- the tripwire below turns a violated derivation into a loud refusal. 551 let outcap: i64 = (n + an) * 8 + PN_MAGIC_1048576 552 let out: *u8 = sys_mmap(outcap) 553 let r: *i64 = sys_mmap(32) as *i64 554 var o: i64 = 0 555 o = pn_app(out, o, "NXPAP2\n" as *u8) 556 if pn_meta(fb, 0, n, "citation_title" as *u8, r) != 0 { pn_puts("PAPER-NATIVE REFUSE: no citation_title (broken parse, not an empty paper)\n" as *u8); return 3 } 557 o = pn_app(out, o, "TITLE\t" as *u8) 558 o = pn_txt(out, o, fb, r[0], r[1]) 559 o = pn_app(out, o, "\n" as *u8) 560 var scan: i64 = 0 561 var nau: i64 = 0 562 var more: i64 = 1 563 while more == 1 { 564 if pn_meta(fb, scan, n, "citation_author" as *u8, r) != 0 { more = 0 } else { 565 o = pn_app(out, o, "AUTHOR\t" as *u8) 566 o = pn_txt(out, o, fb, r[0], r[1]) 567 o = pn_app(out, o, "\n" as *u8) 568 scan = r[2] 569 nau = nau + 1 570 } 571 } 572 o = pn_hdr(out, o, fb, n, "citation_publication_date" as *u8, "YEAR\t" as *u8, r) 573 o = pn_hdr(out, o, fb, n, "citation_conference_title" as *u8, "VENUE\t" as *u8, r) 574 o = pn_hdr(out, o, fb, n, "citation_pdf_url" as *u8, "SOURCE\t" as *u8, r) 575 let ax: i64 = pn_find(fb, 0, n, "arxiv.org/abs/" as *u8) 576 if ax >= 0 { 577 let ae: i64 = pn_find(fb, ax, n, "\"" as *u8) 578 if ae > ax { 579 o = pn_app(out, o, "ARXIV\t" as *u8) 580 o = pn_appn(out, o, fb, ax + 14, ae) 581 o = pn_app(out, o, "\n" as *u8) 582 } 583 } 584 let cnt: *i64 = sys_mmap(16) as *i64 585 let nfig: *i64 = sys_mmap(16) as *i64 586 let nref: *i64 = sys_mmap(16) as *i64 587 let nsec: *i64 = sys_mmap(16) as *i64 588 cnt[0] = 0 589 nfig[0] = 0 590 nref[0] = 0 591 nsec[0] = 0 592 let abs0: i64 = pn_find(fb, 0, n, "id=\"abstract\"" as *u8) 593 if abs0 < 0 { pn_puts("PAPER-NATIVE REFUSE: no abstract block\n" as *u8); return 3 } 594 let abs1: i64 = pn_find(fb, abs0, n, ">" as *u8) + 1 595 let abs2: i64 = pn_find(fb, abs1, n, "</div>" as *u8) 596 if abs2 < 0 { pn_puts("PAPER-NATIVE REFUSE: unterminated abstract block\n" as *u8); return 3 } 597 o = pn_app(out, o, ".SEC 1\tabstract\tAbstract\n" as *u8) 598 nsec[0] = 1 599 o = pn_app(out, o, ".PARA " as *u8) 600 o = pn_inline(out, o, fb, abs1, abs2, cnt) 601 o = pn_app(out, o, "\n" as *u8) 602 var smath: i64 = 0 603 var sfig: i64 = 0 604 var sref: i64 = 0 605 var bodyb: i64 = 0 606 if an > 0 { 607 bodyb = an 608 let st: i64 = pn_bodystart(ab, an) 609 if st >= 0 { 610 smath = pn_count(ab, st, an, "<math" as *u8) 611 sfig = pn_count(ab, st, an, "<figure" as *u8) 612 sref = pn_count(ab, st, an, "class=\"ltx_bibitem\"" as *u8) 613 } 614 o = pn_body(out, o, ab, an, cnt, nfig, nref, nsec) 615 } 616 if o >= outcap { pn_puts("PAPER-NATIVE REFUSE: emitted output reached its derived reservation, so the size derivation is WRONG and this document may be corrupt. Do not widen the reservation without first finding which emit path expands its source.\n" as *u8); return 3 } 617 if pn_write(outp, out, o) != 0 { pn_puts("PAPER-NATIVE REFUSE: cannot write\n" as *u8); return 1 } 618 pn_puts("PAPER-NATIVE-OK authors=" as *u8); pn_num(nau) 619 pn_puts(" sections=" as *u8); pn_num(nsec[0]) 620 pn_puts(" math=" as *u8); pn_num(cnt[0]); pn_puts("/" as *u8); pn_num(smath) 621 pn_puts(" figs=" as *u8); pn_num(nfig[0]); pn_puts("/" as *u8); pn_num(sfig) 622 pn_puts(" refs=" as *u8); pn_num(nref[0]); pn_puts("/" as *u8); pn_num(sref) 623 pn_puts(" fulltext_src_bytes=" as *u8); pn_num(bodyb) 624 pn_puts(" nxpap_bytes=" as *u8); pn_num(o); pn_puts("\n" as *u8) 625 var lost: i64 = 0 626 if cnt[0] < smath { lost = 1 } 627 if nfig[0] < sfig { lost = 1 } 628 if nref[0] < sref { lost = 1 } 629 if lost == 1 { 630 pn_puts("PAPER-NATIVE REFUSE: FIDELITY LOSS -- the source carries more math, figures or references than were emitted (see the emitted/source pairs above). Silently dropping them is exactly the v1 defect, so this run FAILS. The document was still written so the gap can be inspected; it is not fit to publish.\n" as *u8) 631 return 3 632 } 633 return 0 634} 635 636// ---- VIEW: NXPAP1 or NXPAP2 -> the reader page (Nishi bytes rendering Nishi bytes) ---- 637func pn_field(fb: *u8, p: i64, e: i64, idx: i64, r: *i64) -> i64 { 638 var s: i64 = p 639 var k: i64 = 0 640 var run: i64 = 1 641 while run == 1 { 642 if k == idx { 643 var t: i64 = pn_find(fb, s, e, "\t" as *u8) 644 if t < 0 { t = e } 645 r[0] = s 646 r[1] = t 647 return 0 648 } 649 let t2: i64 = pn_find(fb, s, e, "\t" as *u8) 650 if t2 < 0 { run = 0 } else { s = t2 + 1; k = k + 1 } 651 } 652 return 0 - 1 653} 654func pn_view(inp: *u8, outp: *u8) -> i64 { 655 let ln: *i64 = sys_mmap(16) as *i64 656 let fb: *u8 = sys_read_file(inp, ln) 657 if (fb as i64) == 0 { pn_puts("PAPER-VIEW REFUSE: cannot read nxpap\n" as *u8); return 3 } 658 let n: i64 = ln[0] 659 if n <= 0 { pn_puts("PAPER-VIEW REFUSE: cannot read nxpap\n" as *u8); return 3 } 660 var v2: i64 = 0 661 if pn_find(fb, 0, n, "NXPAP2" as *u8) == 0 { v2 = 1 } 662 if v2 == 0 { if pn_find(fb, 0, n, "NXPAP1" as *u8) != 0 { pn_puts("PAPER-VIEW REFUSE: not an NXPAP document\n" as *u8); return 3 } } 663 let outcap: i64 = n * 8 + PN_MAGIC_1048576 664 let out: *u8 = sys_mmap(outcap) 665 let r: *i64 = sys_mmap(32) as *i64 666 var o: i64 = 0 667 var ti: i64 = pn_find(fb, 0, n, "TITLE\t" as *u8) 668 var te: i64 = n 669 if ti >= 0 { te = pn_find(fb, ti, n, "\n" as *u8) } 670 o = pn_app(out, o, "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>" as *u8) 671 if ti >= 0 { o = pn_appn(out, o, fb, ti + 6, te) } 672 o = pn_app(out, o, " - Nishi Papers</title><style>body{margin:0;background:#0b0e16;color:#e8ecf6;font:16px/1.7 system-ui,sans-serif}main{max-width:78ch;margin:0 auto;padding:26px 18px 90px}a{color:#c9a0ff}h1{font-size:25px;line-height:1.25;margin:0 0 8px}h2{font-size:12px;letter-spacing:.13em;text-transform:uppercase;color:#c9a0ff;margin:32px 0 8px;border-bottom:1px solid #222c44;padding-bottom:6px}h3{font-size:15px;color:#e8ecf6;margin:22px 0 6px}h4{font-size:13px;color:#b9c4d8;margin:18px 0 6px}p{margin:0 0 14px}.meta{color:#8a97ad;font-size:.9rem;margin:0 0 18px}.eq{overflow-x:auto;margin:16px 0;padding:6px 0;text-align:center}figure{margin:20px 0;padding:0}figure img{max-width:100%;height:auto;border-radius:6px;background:#111827}figcaption{color:#8a97ad;font-size:.86rem;margin-top:8px}table{border-collapse:collapse;width:100%;font-size:.9rem;display:block;overflow-x:auto}td,th{border:1px solid #222c44;padding:5px 9px;text-align:left}ol.refs{font-size:.88rem;color:#b9c4d8;padding-left:22px}ol.refs li{margin:0 0 8px}.k{color:#c9a0ff}.note{color:#8a97ad;font-size:.82rem;border-top:1px solid #222c44;margin-top:34px;padding-top:12px}</style></head><body><main>\n" as *u8) 673 o = pn_app(out, o, "<p class=\"meta\"><a href=\"/papers\">Nishi Papers</a> &rsaquo; native document</p>\n<h1>" as *u8) 674 if ti >= 0 { o = pn_appn(out, o, fb, ti + 6, te) } 675 o = pn_app(out, o, "</h1>\n<p class=\"meta\">" as *u8) 676 var p: i64 = 0 677 var nau: i64 = 0 678 var run: i64 = 1 679 while run == 1 { 680 let a: i64 = pn_find(fb, p, n, "AUTHOR\t" as *u8) 681 if a < 0 { run = 0 } else { 682 let e: i64 = pn_find(fb, a, n, "\n" as *u8) 683 if nau > 0 { o = pn_app(out, o, " &middot; " as *u8) } 684 o = pn_appn(out, o, fb, a + 7, e) 685 nau = nau + 1 686 p = e 687 } 688 } 689 let vi: i64 = pn_find(fb, 0, n, "VENUE\t" as *u8) 690 if vi >= 0 { 691 let ve2: i64 = pn_find(fb, vi, n, "\n" as *u8) 692 o = pn_app(out, o, "<br>" as *u8) 693 o = pn_appn(out, o, fb, vi + 6, ve2) 694 } 695 let yi: i64 = pn_find(fb, 0, n, "YEAR\t" as *u8) 696 if yi >= 0 { 697 let ye: i64 = pn_find(fb, yi, n, "\n" as *u8) 698 o = pn_app(out, o, ", " as *u8) 699 o = pn_appn(out, o, fb, yi + 5, ye) 700 } 701 o = pn_app(out, o, "</p>\n" as *u8) 702 var nsec: i64 = 0 703 var nmath: i64 = 0 704 var nfig: i64 = 0 705 var nref: i64 = 0 706 var figopen: i64 = 0 707 var refopen: i64 = 0 708 var tblopen: i64 = 0 709 var lp: i64 = 0 710 var lr: i64 = 1 711 while lr == 1 { 712 if lp >= n { lr = 0 } else { 713 var e: i64 = pn_find(fb, lp, n, "\n" as *u8) 714 if e < 0 { e = n } 715 if pn_find(fb, lp, e, ".SEC " as *u8) == lp { 716 if tblopen == 1 { o = pn_app(out, o, "</table>" as *u8); tblopen = 0 } 717 if figopen == 1 { o = pn_app(out, o, "</figure>\n" as *u8); figopen = 0 } 718 if refopen == 1 { o = pn_app(out, o, "</ol>\n" as *u8); refopen = 0 } 719 var lvl: i64 = 1 720 if fb[lp + 5] == (50 as u8) { lvl = 2 } 721 if fb[lp + 5] == (51 as u8) { lvl = 3 } 722 if pn_field(fb, lp + 5, e, 1, r) == 0 { 723 let ids: i64 = r[0] 724 let ide: i64 = r[1] 725 if pn_field(fb, lp + 5, e, 2, r) == 0 { 726 if lvl == 1 { o = pn_app(out, o, "<h2 id=\"" as *u8) } 727 if lvl == 2 { o = pn_app(out, o, "<h3 id=\"" as *u8) } 728 if lvl == 3 { o = pn_app(out, o, "<h4 id=\"" as *u8) } 729 o = pn_appn(out, o, fb, ids, ide) 730 o = pn_app(out, o, "\">" as *u8) 731 o = pn_appn(out, o, fb, r[0], r[1]) 732 if lvl == 1 { o = pn_app(out, o, "</h2>\n" as *u8) } 733 if lvl == 2 { o = pn_app(out, o, "</h3>\n" as *u8) } 734 if lvl == 3 { o = pn_app(out, o, "</h4>\n" as *u8) } 735 nsec = nsec + 1 736 } 737 } 738 } else { 739 if pn_find(fb, lp, e, ".PARA " as *u8) == lp { 740 o = pn_app(out, o, "<p>" as *u8) 741 o = pn_appn(out, o, fb, lp + 6, e) 742 o = pn_app(out, o, "</p>\n" as *u8) 743 } else { 744 if pn_find(fb, lp, e, ".MATH " as *u8) == lp { 745 if pn_field(fb, lp + 6, e, 0, r) == 0 { 746 o = pn_app(out, o, "<div class=\"eq\" id=\"" as *u8) 747 o = pn_appn(out, o, fb, r[0], r[1]) 748 o = pn_app(out, o, "\">" as *u8) 749 if pn_field(fb, lp + 6, e, 1, r) == 0 { o = pn_appn(out, o, fb, r[0], r[1]) } 750 o = pn_app(out, o, "</div>\n" as *u8) 751 nmath = nmath + 1 752 } 753 } else { 754 if pn_find(fb, lp, e, ".FIG " as *u8) == lp { 755 if figopen == 1 { o = pn_app(out, o, "</figure>\n" as *u8) } 756 o = pn_app(out, o, "<figure id=\"" as *u8) 757 o = pn_appn(out, o, fb, lp + 5, e) 758 o = pn_app(out, o, "\">" as *u8) 759 figopen = 1 760 nfig = nfig + 1 761 } else { 762 if pn_find(fb, lp, e, ".TBL " as *u8) == lp { 763 if figopen == 1 { o = pn_app(out, o, "</figure>\n" as *u8) } 764 o = pn_app(out, o, "<figure id=\"" as *u8) 765 o = pn_appn(out, o, fb, lp + 5, e) 766 o = pn_app(out, o, "\"><table>" as *u8) 767 figopen = 1 768 tblopen = 1 769 nfig = nfig + 1 770 } else { 771 if pn_find(fb, lp, e, ".IMG " as *u8) == lp { 772 o = pn_app(out, o, "<img loading=\"lazy\" alt=\"\" src=\"" as *u8) 773 o = pn_appn(out, o, fb, lp + 5, e) 774 o = pn_app(out, o, "\">" as *u8) 775 } else { 776 if pn_find(fb, lp, e, ".CAP " as *u8) == lp { 777 if tblopen == 1 { o = pn_app(out, o, "</table>" as *u8); tblopen = 0 } 778 o = pn_app(out, o, "<figcaption>" as *u8) 779 o = pn_appn(out, o, fb, lp + 5, e) 780 o = pn_app(out, o, "</figcaption>" as *u8) 781 } else { 782 if pn_find(fb, lp, e, ".ROW " as *u8) == lp { 783 o = pn_app(out, o, "<tr>" as *u8) 784 var ci: i64 = 0 785 var cr: i64 = 1 786 while cr == 1 { 787 if pn_field(fb, lp + 5, e, ci, r) == 0 { 788 o = pn_app(out, o, "<td>" as *u8) 789 o = pn_appn(out, o, fb, r[0], r[1]) 790 o = pn_app(out, o, "</td>" as *u8) 791 if r[1] >= e { cr = 0 } else { ci = ci + 1 } 792 } else { cr = 0 } 793 } 794 o = pn_app(out, o, "</tr>" as *u8) 795 } else { 796 if pn_find(fb, lp, e, ".REF " as *u8) == lp { 797 if tblopen == 1 { o = pn_app(out, o, "</table>" as *u8); tblopen = 0 } 798 if figopen == 1 { o = pn_app(out, o, "</figure>\n" as *u8); figopen = 0 } 799 if refopen == 0 { o = pn_app(out, o, "<h2 id=\"bib\">References</h2>\n<ol class=\"refs\">\n" as *u8); refopen = 1 } 800 o = pn_app(out, o, "<li id=\"" as *u8) 801 if pn_field(fb, lp + 5, e, 0, r) == 0 { o = pn_appn(out, o, fb, r[0], r[1]) } 802 o = pn_app(out, o, "\"><span class=\"k\">" as *u8) 803 if pn_field(fb, lp + 5, e, 1, r) == 0 { o = pn_appn(out, o, fb, r[0], r[1]) } 804 o = pn_app(out, o, "</span> " as *u8) 805 if pn_field(fb, lp + 5, e, 2, r) == 0 { o = pn_appn(out, o, fb, r[0], r[1]) } 806 o = pn_app(out, o, "</li>\n" as *u8) 807 nref = nref + 1 808 } else { 809 if pn_find(fb, lp, e, ".SECTION " as *u8) == lp { 810 // NXPAP1 compatibility: the legacy corpus is still on disk and must stay readable 811 var nx: i64 = pn_find(fb, e, n, ".SECTION " as *u8) 812 if nx < 0 { nx = n } 813 o = pn_app(out, o, "<h2>" as *u8) 814 o = pn_appn(out, o, fb, lp + 9, e) 815 o = pn_app(out, o, "</h2>\n<p>" as *u8) 816 o = pn_appn(out, o, fb, e + 1, nx) 817 o = pn_app(out, o, "</p>\n" as *u8) 818 nsec = nsec + 1 819 e = nx - 1 820 } } } } } } } } } } 821 lp = e + 1 822 } 823 } 824 if tblopen == 1 { o = pn_app(out, o, "</table>" as *u8) } 825 if figopen == 1 { o = pn_app(out, o, "</figure>\n" as *u8) } 826 if refopen == 1 { o = pn_app(out, o, "</ol>\n" as *u8) } 827 o = pn_app(out, o, "<p class=\"note\">Rendered by <code>nx_paper_native</code> from an NXPAP sovereign document held on the Nishi estate &mdash; no PDF, no third-party reader, and the equations are browser-native MathML. Text, figures and copyright belong to the authors; the source link is preserved in the document header.</p>\n</main></body></html>\n" as *u8) 828 if o >= outcap { pn_puts("PAPER-VIEW REFUSE: emitted page reached its derived reservation, so the size derivation is WRONG and this page may be corrupt. Find the expanding emit path; do not just widen the reservation.\n" as *u8); return 3 } 829 if pn_write(outp, out, o) != 0 { pn_puts("PAPER-VIEW REFUSE: cannot write\n" as *u8); return 1 } 830 pn_puts("PAPER-VIEW-OK sections=" as *u8); pn_num(nsec) 831 pn_puts(" authors=" as *u8); pn_num(nau) 832 pn_puts(" math=" as *u8); pn_num(nmath) 833 pn_puts(" figs=" as *u8); pn_num(nfig) 834 pn_puts(" refs=" as *u8); pn_num(nref) 835 pn_puts(" html_bytes=" as *u8); pn_num(o); pn_puts("\n" as *u8) 836 return 0 837} 838 839func main(argc: i64, argv: *i64) -> i64 { 840 if argc < 4 { 841 pn_puts("usage: nx_paper_native abs <cvf-abstract.raw> <out.nxpap> [arxiv-html.raw] | nx_paper_native view <in.nxpap> <out.html>\n" as *u8) 842 sys_exit(2) 843 return 2 844 } 845 let v: *u8 = argv[1] as *u8 846 var rc: i64 = 2 847 if v[0] == (97 as u8) { 848 var ax: *u8 = 0 as *u8 849 if argc > 4 { ax = argv[4] as *u8 } 850 rc = pn_ingest(argv[2] as *u8, argv[3] as *u8, ax) 851 } 852 if v[0] == (118 as u8) { rc = pn_view(argv[2] as *u8, argv[3] as *u8) } 853 sys_exit(rc) 854 return rc 855}