code wiki / _hdl_build / nx_math_render_page.nx

nx_math_render_page.nx source

↩ module page · 127 lines · 10417 B

1// nx_math_render_page.nx -- GENERATE the live "/wiki/math_render.html" page (IMS Thrust D, rung 1): 2// the VISIBLE proof of the sovereign "arXiv PDF->HTML / LaTeX" capability. A walkable Diataxis 3// REFERENCE page built through the reusable typed generator nx_ims_page (full walk furniture: 4// head/nav/breadcrumb/tree/prev-next/related/backlinks/infobox/toc/footer, nav read from 5// wiki_links.tsv by slug=math_render). The page's OWN content (body_html) embeds REAL presentation 6// MathML produced AT BUILD TIME by nx_tex (tx_render) -- the snippets are rendered, not hand-written: 7// 8// 1. the BM25 term-saturation factor f / (f + k) (the heart of the wiki's own ranker), 9// 2. the full BM25 single-term score IDF * f(k1+1) / (f + k1(1 - b + b|D|/avgdl)), 10// 3. the DLMF Gamma-function integral Gamma(z) = int_0^inf t^{z-1} e^{-t} dt, 11// 4. a quadratic & the quadratic formula (msqrt + mfrac showcase), 12// 5. a relations / greek line. 13// 14// Each formula is shown with its LaTeX source (escaped, in <code>) next to the rendered MathML, so a 15// reader sees input -> output. ADDITIVE: writes web_assets/math_render.html only (the publish step 16// pushes it live + fetch-verifies). REUSE (nothing reinvented): nx_ims_page ims_page (typed walkable 17// generator) + nx_tex tx_render (the sovereign renderer). license_tier: ORIGINAL 18import "nx_ims_page.nx" 19import "nx_tex.nx" 20 21const MR_BODY_CAP: i64 = 131072 // body_html scratch (>> the few KB this page needs) 22const MR_MML_CAP: i64 = 65536 // per-formula MathML scratch 23 24func mr_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 25func mr_num(v: i64) -> i64 { 26 let bb: *u8 = sys_mmap(28); var m: i64 = v 27 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 28 let t: *u8 = sys_mmap(28); var k: i64 = 0 29 if m == 0 { t[0] = 48 as u8; k = 1 } 30 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 31 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 32 sys_write(1, bb, k); return 0 33} 34func mr_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 } 35func mr_catb(dst: *u8, off: i64, s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { dst[off + i] = s[i]; i = i + 1 } return off + i } 36func mr_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 37 38// append a source LaTeX string into dst, HTML-escaping the few special bytes so the backslashes and 39// braces show literally in the <code> block (& < > stay safe). Returns new off. 40func mr_cat_escaped(dst: *u8, off: i64, s: *u8) -> i64 { 41 var o: i64 = off 42 var i: i64 = 0 43 while s[i] != (0 as u8) { 44 let c: i64 = s[i] as i64 45 if c == 38 { o = mr_cat(dst, o, "&amp;" as *u8) } else { 46 if c == 60 { o = mr_cat(dst, o, "&lt;" as *u8) } else { 47 if c == 62 { o = mr_cat(dst, o, "&gt;" as *u8) } else { 48 dst[o] = c as u8; o = o + 1 49 } 50 } 51 } 52 i = i + 1 53 } 54 return o 55} 56 57// render ONE formula card: a <figure> with the escaped LaTeX source in <code> + the rendered MathML 58// (block display) + a caption. The MathML is produced by tx_render at build time. Returns new off. 59func mr_card(dst: *u8, off: i64, latex: *u8, caption: *u8) -> i64 { 60 let mml: *u8 = sys_mmap(MR_MML_CAP) 61 let nb: i64 = tx_render(latex, mml) 62 var o: i64 = off 63 o = mr_cat(dst, o, "<figure class=\"formula\">\n" as *u8) 64 o = mr_cat(dst, o, "<figcaption>" as *u8); o = mr_cat(dst, o, caption); o = mr_cat(dst, o, "</figcaption>\n" as *u8) 65 o = mr_cat(dst, o, "<p class=\"tex-src\">LaTeX: <code>" as *u8) 66 o = mr_cat_escaped(dst, o, latex) 67 o = mr_cat(dst, o, "</code></p>\n" as *u8) 68 if nb >= 0 { 69 o = mr_catb(dst, o, mml, nb) // the rendered MathML (already valid + balanced) 70 dst[o] = 0x0A as u8; o = o + 1 71 mr_w(" rendered '"); mr_w(latex); mr_w("' -> "); mr_num(nb); mr_w(" bytes MathML\n") 72 } else { 73 o = mr_cat(dst, o, "<p class=\"tex-err\"><em>(render error)</em></p>\n" as *u8) 74 mr_w(" FAILED '"); mr_w(latex); mr_w("' rc="); mr_num(nb); mr_w("\n") 75 } 76 o = mr_cat(dst, o, "</figure>\n" as *u8) 77 return o 78} 79 80func main() -> i64 { 81 let b: *u8 = sys_mmap(MR_BODY_CAP) 82 var o: i64 = 0 83 84 // ---- lede ---- 85 o = mr_cat(b, o, "<p class=\"lede\"><strong>Sovereign LaTeX-math &rarr; MathML, rendered right here.</strong> Every formula below was turned from its LaTeX source into <a href=\"https://www.w3.org/Math/\">presentation MathML</a> by <code>nx_tex</code> &mdash; a pure, deterministic Nishi organ &mdash; <em>at the moment this page was built</em>. No JavaScript, no external math service: the markup your browser is laying out was emitted by sovereign code and verified well-formed by <code>nx_tex_gate</code>. This is the core of the arXiv-style &ldquo;PDF&rarr;HTML&rdquo; math capability.</p>\n" as *u8) 86 o = mr_cat(b, o, "<p class=\"why\">Why MathML and not an image? MathML is real, selectable, accessible, reflowable math that scales with the reader's font &mdash; the same reason modern arXiv HTML uses it instead of rasterized equations. The renderer covers a useful subset (fractions, roots, sub/superscripts, big operators with limits, Greek, and the common relations); unsupported input degrades to a visible <code>&lt;merror&gt;</code> rather than breaking the page.</p>\n" as *u8) 87 88 // ---- 1. BM25 saturation factor (the heart of the wiki's own ranker) ---- 89 o = mr_cat(b, o, "<h3 id=\"bm25\">The ranker behind this wiki's search</h3>\n" as *u8) 90 o = mr_cat(b, o, "<p>The <a href=\"/wiki/search.html\">instant-answer search</a> ranks pages with BM25. Its defining feature is <em>term-frequency saturation</em> &mdash; the 10th occurrence of a word matters far less than the 1st. That saturation is exactly this shape:</p>\n" as *u8) 91 o = mr_card(b, o, "\\frac{f}{f + k}" as *u8, "Term-frequency saturation: as the raw count f grows, the score approaches 1 and flattens." as *u8) 92 o = mr_cat(b, o, "<p>The full single-term BM25 contribution, with document-length normalization, is:</p>\n" as *u8) 93 o = mr_card(b, o, "\\frac{f \\cdot (k_1 + 1)}{f + k_1 \\cdot (1 - b + b \\cdot \\frac{|D|}{avgdl})}" as *u8, "BM25 single-term weight: f = term frequency, |D| = document length, avgdl = average document length, k_1 and b are tuning constants." as *u8) 94 95 // ---- 2. DLMF Gamma integral ---- 96 o = mr_cat(b, o, "<h3 id=\"gamma\">A special function from the DLMF</h3>\n" as *u8) 97 o = mr_cat(b, o, "<p>The Gamma function &mdash; the continuous extension of the factorial that the <a href=\"/wiki/nist_stem.html\">NIST DLMF</a> catalogs &mdash; is defined by Euler's integral:</p>\n" as *u8) 98 o = mr_card(b, o, "\\Gamma(z) = \\int_{0}^{\\infty} t^{z - 1} e^{-t} dt" as *u8, "Euler integral of the second kind (DLMF 5.2.1): the integral form of the Gamma function." as *u8) 99 o = mr_cat(b, o, "<p>Note the integral's limits render as <code>msubsup</code> (sub/super on the operator) &mdash; the integral convention &mdash; while a summation's limits render under/over (<code>munderover</code>):</p>\n" as *u8) 100 o = mr_card(b, o, "\\sum_{n=1}^{\\infty} \\frac{1}{n^2} = \\frac{\\pi^2}{6}" as *u8, "The Basel sum: limits under/over the summation sign, a fraction with a squared denominator, and the closed form." as *u8) 101 102 // ---- 3. quadratic showcase (msqrt + mfrac + sub/sup) ---- 103 o = mr_cat(b, o, "<h3 id=\"quadratic\">Roots, fractions, and scripts together</h3>\n" as *u8) 104 o = mr_cat(b, o, "<p>The quadratic formula exercises a square root over a fraction with sub/superscripts &mdash; the pieces that make real math typesetting hard:</p>\n" as *u8) 105 o = mr_card(b, o, "x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}" as *u8, "The quadratic formula: msqrt nested inside the numerator of an mfrac." as *u8) 106 107 // ---- 4. relations + greek line ---- 108 o = mr_cat(b, o, "<h3 id=\"symbols\">Greek and relations</h3>\n" as *u8) 109 o = mr_card(b, o, "\\alpha + \\beta \\le \\gamma \\neq \\delta \\approx \\epsilon \\cdot \\omega" as *u8, "Greek letters and comparison operators map to their proper Unicode glyphs." as *u8) 110 111 // ---- how it works ---- 112 o = mr_cat(b, o, "<h3 id=\"how\">How it works</h3>\n" as *u8) 113 o = mr_cat(b, o, "<ol>\n" as *u8) 114 o = mr_cat(b, o, "<li><strong>Tokenize + recursive-descent parse.</strong> <code>nx_tex</code> scans the LaTeX byte by byte and builds the MathML tree directly &mdash; numbers to <code>&lt;mn&gt;</code>, identifiers to <code>&lt;mi&gt;</code>, operators to <code>&lt;mo&gt;</code>, <code>\\frac</code> to <code>&lt;mfrac&gt;</code>, <code>^</code>/<code>_</code> to <code>&lt;msup&gt;</code>/<code>&lt;msub&gt;</code>/<code>&lt;msubsup&gt;</code>, big operators to <code>&lt;munderover&gt;</code> or <code>&lt;msubsup&gt;</code>.</li>\n" as *u8) 115 o = mr_cat(b, o, "<li><strong>Well-formed by construction.</strong> Every open tag is closed; a single-element argument drops its redundant <code>&lt;mrow&gt;</code> to match what reference renderers emit.</li>\n" as *u8) 116 o = mr_cat(b, o, "<li><strong>Gated.</strong> <code>nx_tex_gate</code> asserts the exact MathML for hand-verified known-answer tests and runs a balanced-tag check on every output; a 3rd-party structural cross-check (LaTeXML / MathJax) is the next rigor step.</li>\n" as *u8) 117 o = mr_cat(b, o, "<li><strong>Graceful.</strong> An unsupported command becomes a visible <code>&lt;merror&gt;</code> &mdash; the page never breaks.</li>\n" as *u8) 118 o = mr_cat(b, o, "</ol>\n" as *u8) 119 o = mr_cat(b, o, "<p>Related: <a href=\"/wiki/search.html\">wiki search</a> (the BM25 ranker) &middot; <a href=\"/wiki/nist_stem.html\">NIST STEM / DLMF</a> &middot; <a href=\"/wiki/formats_uxf.html\">the format family</a>.</p>\n" as *u8) 120 b[o] = 0 as u8 121 122 mr_w("=== nx_math_render_page: rendering /wiki/math_render.html (reference, walkable, live MathML) ===\n"); 123 let bytes: i64 = ims_page("math_render" as *u8, "reference" as *u8, "Math Rendering &mdash; Sovereign LaTeX to MathML" as *u8, b) 124 if bytes < 0 { mr_w("FATAL: ims_page failed rc="); mr_num(bytes); mr_w("\n"); sys_exit(2); return 2 } 125 mr_w("=== wrote web_assets/math_render.html bytes="); mr_num(bytes); mr_w(" ===\n") 126 sys_exit(0); return 0 127}