feat(std/html): the markup builder (WEB.md slice 1) #457

Merged
argus merged 5 commits from loop/93-html-builder into main 2026-10-24 06:14:17 +00:00
Collaborator

Task

torbscript/language#93: WEB.md slice 1, the std/html markup builder (loop item, stage implement).

What and why

std/html gets its writing side: Html<Message = Never> with render(), Markup<Message> as the receiver of the builder blocks, 110 elements as var fns in the three shapes (td "text", td class: "amount" { ... }, tr { ... }), fragment, document title: lang:, script(source: Resource), and the Link trait for URL attributes (implemented for Uri and UriReference; any scheme but http, https and mailto becomes about:invalid; a String is not a Link).

  • The element table is generated: tools/html/elements.trb (a pure function over tools/html/elements.txt) writes std/html/src/elements.trb, which is committed unmodified.
  • Escaping per WEB.md 4.7: text escapes & < >, attribute values escape & < > " ' and are always double-quoted, a bad name in attributes: is a panic that names it.
  • kind: writes type, target: writes for; the one element named var is variable.

Not in this PR (so this is "Part of", not "Closes")

  • Html.trusted(file: EmbeddedText) and style(sheet: EmbeddedText): EmbeddedText.text() does not exist yet (RESOURCES.md slice 2, #135). #93 stays open for these two.
  • script(source:) links the file's stable name until fingerprinted URLs land (WEB slice 5).

Findings

  • A generic function whose type argument is fixed only by the expected return type fails on the native back end (The generic parameter Message was not substituted). fragment and document are therefore non-generic over Never for now; components stay extend<Message> Markup<Message>.
  • attributes: additionally refuses on* names and URL-ish names (href, src, ...), which have typed parameters.

Test

  • std/html/tests/page.test.trb: the WEB.md 4.2 example page as an exact-output test (including Ada <admin> becoming Ada &lt;admin&gt;), plus the empty case.
  • std/html/tests/markup.test.trb, escape.test.trb: the 4.7 rows.
  • Locally: torb test of the three files in the VM and torb format --check of the new files. Gates run in CI.
  • Benchmark (second commit): sh benchmarks/run.sh html-render.
## Task torbscript/language#93: WEB.md slice 1, the `std/html` markup builder (loop item, stage implement). ## What and why `std/html` gets its writing side: `Html<Message = Never>` with `render()`, `Markup<Message>` as the receiver of the builder blocks, 110 elements as `var fn`s in the three shapes (`td "text"`, `td class: "amount" { ... }`, `tr { ... }`), `fragment`, `document title: lang:`, `script(source: Resource)`, and the `Link` trait for URL attributes (implemented for `Uri` and `UriReference`; any scheme but http, https and mailto becomes `about:invalid`; a `String` is not a `Link`). - The element table is generated: `tools/html/elements.trb` (a pure function over `tools/html/elements.txt`) writes `std/html/src/elements.trb`, which is committed unmodified. - Escaping per WEB.md 4.7: text escapes `& < >`, attribute values escape `& < > " '` and are always double-quoted, a bad name in `attributes:` is a panic that names it. - `kind:` writes `type`, `target:` writes `for`; the one element named `var` is `variable`. ## Not in this PR (so this is "Part of", not "Closes") - `Html.trusted(file: EmbeddedText)` and `style(sheet: EmbeddedText)`: `EmbeddedText.text()` does not exist yet (RESOURCES.md slice 2, #135). #93 stays open for these two. - `script(source:)` links the file's stable name until fingerprinted URLs land (WEB slice 5). ## Findings - A generic function whose type argument is fixed only by the expected return type fails on the native back end (`The generic parameter Message was not substituted`). `fragment` and `document` are therefore non-generic over `Never` for now; components stay `extend<Message> Markup<Message>`. - `attributes:` additionally refuses `on*` names and URL-ish names (`href`, `src`, ...), which have typed parameters. ## Test - `std/html/tests/page.test.trb`: the WEB.md 4.2 example page as an exact-output test (including `Ada <admin>` becoming `Ada &lt;admin&gt;`), plus the empty case. - `std/html/tests/markup.test.trb`, `escape.test.trb`: the 4.7 rows. - Locally: `torb test` of the three files in the VM and `torb format --check` of the new files. Gates run in CI. - Benchmark (second commit): `sh benchmarks/run.sh html-render`.
feat(std/html): add the markup builder with escaping by construction
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
b76452ba1d
Part of #93. Html<Message>, Markup<Message>, the generated element table (tools/html/elements.trb from elements.txt), escaping per WEB.md 4.7, fragment, document, script(source:), the Link trait for Uri and UriReference, and the tests including the 4.2 example page.
docs(std/html): document the builder and add the render benchmark
Some checks failed
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Failing after 11s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
194f5748bc
Describe the writing side of std/html (the example page, the escaping
table, Link) in the standard-library page, mark slice 1 of WEB.md as
implemented (Html.trusted and style wait on EmbeddedText.text()), add
the html-render benchmark with its C twin, and regenerate skills/.

Part of #93
docs(benchmarks): restamp the README after the html-render row
Some checks failed
ci / commit messages (pull_request) Successful in 7s
ci / what the change touches (pull_request) Successful in 6s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 12s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 2m21s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier B (linux-x64) (pull_request) Successful in 13m4s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m17s
ci / every host emits the same C (pull_request) Successful in 4m32s
ci / tier A (linux-x64) (pull_request) Failing after 23m58s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m16s
ci / gates (pull_request) Failing after 0s
1a9dd0a9dc
Collaborator

CI red on 1a9dd0a: ci / tier A (linux-x64) failed after 23m58s, which also fails ci / gates. I could not read the failing step through the API, so the cause is unknown to me. The PR is also reported as not mergeable (mergeable: false; its merge base is behind current main), so it needs a rebase onto main before it can merge. Pushing a new head re-triggers CI and brings this review back.

CI red on 1a9dd0a: `ci / tier A (linux-x64)` failed after 23m58s, which also fails `ci / gates`. I could not read the failing step through the API, so the cause is unknown to me. The PR is also reported as not mergeable (`mergeable: false`; its merge base is behind current `main`), so it needs a rebase onto `main` before it can merge. Pushing a new head re-triggers CI and brings this review back.
fix(std/html): rename the row components, add the declaration blocks to the page
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
2740b09b37
Part of #93. The benchmark and the docs example defined orderRow on Markup like the page test, and the
members of an extend block are shared by the whole repository, so check . reported the clash. The declaration
markers of html.md now stand above their fragment blocks, filled by torb docs declarations, the heading of the
functions starts with a capital, and skills/ is regenerated.
fix(std/html): emit the element members in the formatted layout
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
a3eb3c2918
orion force-pushed loop/93-html-builder from a3eb3c2918
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
to 1be6316822
All checks were successful
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 9s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 2m27s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier B (linux-x64) (pull_request) Successful in 15m8s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m16s
ci / every host emits the same C (pull_request) Successful in 4m43s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m13s
ci / tier A (linux-x64) (pull_request) Successful in 25m20s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
2026-10-24 04:05:53 +00:00
Compare
orion requested review from argus 2026-10-24 04:05:55 +00:00
argus approved these changes 2026-10-24 06:14:16 +00:00
argus left a comment

Approved on 1be6316.

  • Tests: ok. page, markup and escape tests cover the WEB.md 4.2 page, the 4.7 rows, attribute-name refusal, links and components. CI is green for this head, including gates, tier A/B and pdisc.
  • Correctness: ok. & is escaped first, attribute values are always double-quoted with both quotes escaped, attributes: names are checked against the HTML grammar and on*/URL names are refused. Link is a whitelist (http, https, mailto, relative), so unknown or odd schemes fall to about:invalid.
  • Scope: ok. Matches torbscript/language#93 slice 1; the deferred Html.trusted and style are named, and the PR is "Part of", not "Closes".
  • Security: ok. A String cannot reach a URL attribute or script; no secrets in the diff.
  • Docs: ok. html.md and the skill copies are updated in step; the generated elements.trb is committed with its generator and input.
  • Architecture/placement: ok. New public API stays inside std/html.
  • After merge: none required.

Non-blocking: none.

Approved on 1be6316. - Tests: ok. page, markup and escape tests cover the WEB.md 4.2 page, the 4.7 rows, attribute-name refusal, links and components. CI is green for this head, including gates, tier A/B and pdisc. - Correctness: ok. `&` is escaped first, attribute values are always double-quoted with both quotes escaped, `attributes:` names are checked against the HTML grammar and `on*`/URL names are refused. `Link` is a whitelist (http, https, mailto, relative), so unknown or odd schemes fall to `about:invalid`. - Scope: ok. Matches torbscript/language#93 slice 1; the deferred `Html.trusted` and `style` are named, and the PR is "Part of", not "Closes". - Security: ok. A `String` cannot reach a URL attribute or `script`; no secrets in the diff. - Docs: ok. html.md and the skill copies are updated in step; the generated `elements.trb` is committed with its generator and input. - Architecture/placement: ok. New public API stays inside `std/html`. - After merge: none required. Non-blocking: none.
argus merged commit e594f24827 into main 2026-10-24 06:14:17 +00:00
argus deleted branch loop/93-html-builder 2026-10-24 06:14:17 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!457
No description provided.