nx_unidoc_lib.nx
buildroot/runtime/nx_unidoc_lib.nx
about
nx_unidoc_lib.nx -- THE UNIFIED DOCUMENT PAGE (rung UD1 of /compare/unidoc, 2026-09-03).
Operator (2026-09-03): "we want nishi browser to handle documents like webpages securely but with full
interactivity so we dont have to have a file browser and a web browser etc but a unified portal."
ONE page per document, whatever it was born as. A .docx, .odt, .pdf, .md, .csv or .txt becomes the SAME
zero-script HTML page: the office's own document model (the H/P/T/B/I spec lines that nx_office_serve
edits, versions and signs) rendered as a page, with a Content-Security-Policy that forbids every script
and every foreign fetch, every byte of document text escaped BY CONSTRUCTION, and the portal's actions
(original bytes, versions, annotate, sign) as plain HTML forms -- no client script anywhere, so the page
is native in the Nishi browser and NishiOS first and degrades to nothing in a third-party browser.
A web page is NOT a document: .html and .htm are REFUSED here by name (UD_ERR_REFUSED_HTML). The browser
already serves a page as itself; wrapping one as a document would be the exact confusion this organ ends.
Composition, never re-implementation: .docx and .odt go through the promoted format organs' `spec` verbs
(_offc/nx_docx.elf, _offc/nx_odt.elf -- the same verbs the office import uses), .pdf through the proven
text extractor _offc/nx_pdf_text.elf, all captured with nx_tool_run. Markdown, CSV and text are folded
to the spec here because their grammar IS the spec's grammar.
Every refusal is NAMED (ud_err_name) and the input ceiling is ANNOUNCED, never a silent truncation.
license_tier: ORIGINAL
dependencies 3 imports · 2 importers
imports: nx_syscalls.nxnx_itoa_lib.nxnx_tool_run.nx
imported by: nx_unidoc.nxnx_unidoc_gate.nx
structs
| none |
consts
| 28 | const UD_KIND_UNKNOWN: i64 = 0 |
| 29 | const UD_KIND_DOCX: i64 = 1 |
| 30 | const UD_KIND_ODT: i64 = 2 |
| 31 | const UD_KIND_PDF: i64 = 3 |
| 32 | const UD_KIND_MD: i64 = 4 |
| 33 | const UD_KIND_CSV: i64 = 5 |
| 34 | const UD_KIND_TXT: i64 = 6 |
| 35 | const UD_KIND_HTML: i64 = 7 // recognised so it can be REFUSED by name, never rendered as a document |
| 38 | const UD_ERR_UNKNOWN_KIND: i64 = 0 - 1 |
| 39 | const UD_ERR_REFUSED_HTML: i64 = 0 - 2 |
| 40 | const UD_ERR_RENDERER: i64 = 0 - 3 // the format organ failed or handed back no spec |
| 41 | const UD_ERR_TOO_BIG: i64 = 0 - 4 // above UD_IN_CAP: refused by name, never cut |
| 42 | const UD_ERR_READ: i64 = 0 - 5 // the input could not be read |
| 43 | const UD_ERR_OUT_CAP: i64 = 0 - 6 // the page would not fit the caller's buffer: refused, never truncated |
| 46 | const UD_IN_CAP: i64 = 8388608 // 8 MiB of document bytes per page |
| 47 | const UD_SPEC_CAP: i64 = 4194304 // the folded spec (H/P/T lines) |
| 48 | const UD_CAPTURE_CAP: i64 = 4194320 // a format organ's captured stdout (spec + its BEGIN/END markers) |
| 49 | const UD_PATH_CAP: i64 = 4096 |
| 50 | const UD_EXT_MAX: i64 = 12 // the browser's own br_doc_ext bound |
| 51 | const UD_ARGV_SLOTS: i64 = 6 |
| 52 | const UD_PTR_BYTES: i64 = 8 |
| 53 | const UD_SLACK: i64 = 4096 // headroom the page emitter keeps before refusing UD_ERR_OUT_CAP |
| 55 | const UD_DOCX_ELF: *u8 = "_offc/nx_docx.elf" |
| 56 | const UD_ODT_ELF: *u8 = "_offc/nx_odt.elf" |
| 57 | const UD_PDFTEXT_ELF: *u8 = "_offc/nx_pdf_text.elf" |
| 58 | const UD_PDF_TXT_SCRATCH: *u8 = "/tmp/nx_unidoc_pdf.txt" |
| 61 | const UD_NL: i64 = 10 |
| 62 | const UD_CR: i64 = 13 |
| 63 | const UD_TAB: i64 = 9 |
| 64 | const UD_SP: i64 = 32 |
| 65 | const UD_HASH: i64 = 35 |
| 66 | const UD_DASH: i64 = 45 |
| 67 | const UD_STAR: i64 = 42 |
| 68 | const UD_PLUS: i64 = 43 |
| 69 | const UD_PIPE: i64 = 124 |
| 70 | const UD_SLASH: i64 = 47 |
| 71 | const UD_COMMA: i64 = 44 |
| 72 | const UD_QUOTE: i64 = 34 |
| 73 | const UD_DOT: i64 = 46 |
| 74 | const UD_LT: i64 = 60 |
| 75 | const UD_GT: i64 = 62 |
| 76 | const UD_AMP: i64 = 38 |
| 77 | const UD_APOS: i64 = 39 |
| 78 | const UD_BACKTICK: i64 = 96 |
| 79 | const UD_H: i64 = 72 |
| 80 | const UD_P: i64 = 80 |
| 81 | const UD_T: i64 = 84 |
| 82 | const UD_B: i64 = 66 |
| 83 | const UD_I: i64 = 73 |
| 84 | const UD_MD_HEADING_MAX: i64 = 6 |
functions
| 86 | func ud_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 87 | func ud_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; var o: i64 = off; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o } |
| 88 | func ud_catn(dst: *u8, off: i64, v: i64) -> i64 { return nxi_buf(dst, off, v) } |
| 89 | func ud_lower(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c } called by 1: ud_ext |
| 90 | func ud_streq(a: *u8, b: *u8) -> i64 |
| 97 | func ud_find(hay: *u8, n: i64, needle: *u8) -> i64 |
| 110 | func ud_count(hay: *u8, n: i64, needle: *u8) -> i64 |
| 127 | func ud_esc_n(out: *u8, off: i64, src: *u8, a: i64, b: i64) -> i64 |
| 141 | func ud_esc(out: *u8, off: i64, s: *u8) -> i64 { return ud_esc_n(out, off, s, 0, ud_slen(s)) } |
| 144 | func ud_ext(path: *u8, ext: *u8) -> i64 |
| 168 | func ud_kind_of_ext(ext: *u8) -> i64 |
| 181 | func ud_kind_of_path(path: *u8) -> i64 |
| 187 | func ud_kind_label(kind: i64) -> *u8 called by 1: ud_page |
| 197 | func ud_kind_name(kind: i64) -> *u8 called by 1: main |
| 207 | func ud_err_name(code: i64) -> *u8 |
| 217 | func ud_check_size(n: i64) -> i64 { if n > UD_IN_CAP { return UD_ERR_TOO_BIG } return 0 } |
| 221 | func ud_spec_line(out: *u8, o0: i64, cap: i64, tag: i64, src: *u8, a: i64, b: i64, in_tbl: i64) -> i64 |
| 238 | func ud_spec_from_text(src: *u8, n: i64, out: *u8, cap: i64) -> i64 |
| 260 | func ud_spec_from_md(src: *u8, n: i64, out: *u8, cap: i64) -> i64 |
| 305 | func ud_spec_from_csv(src: *u8, n: i64, out: *u8, cap: i64) -> i64 called by 1: ud_spec_of |
| 334 | func ud_spec_from_fork(elf: *u8, path: *u8, out: *u8, cap: i64) -> i64 |
| 362 | func ud_spec_from_pdf(path: *u8, out: *u8, cap: i64) -> i64 |
| 396 | func ud_spec_of(kind: i64, path: *u8, bytes: *u8, n: i64, out: *u8, cap: i64) -> i64 |
| 408 | func ud_spec_to_html(out: *u8, off: i64, spec: *u8, sl: i64) -> i64 |
| 442 | func ud_css(out: *u8, off: i64) -> i64 |
| 457 | func ud_page(out: *u8, cap: i64, title: *u8, kind: i64, nbytes: i64, spec: *u8, sl: i64, dlurl: *u8, base: *u8, sha: *u8) -> i64 |
| 486 | func ud_title_of(path: *u8, out: *u8) -> i64 |
| 499 | func ud_render_path(path: *u8, dlurl: *u8, base: *u8, out: *u8, cap: i64, kind_out: *i64) -> i64 called by 2: mainug_render calls 7: ud_kind_of_pathsys_mmapsys_read_fileud_check_sizeud_spec_ofud_title_of+1 |