From 05eab9e4e5a5097ddc8538f7b29841660fe7fcfc Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Thu, 23 Jul 2026 14:47:41 -0400 Subject: [PATCH 1/3] docs(web): frame HTML + CSS grammars + HTML injections (approved rev 3) Add tree-sitter HTML and CSS grammars for .html/.htm/.xhtml and .css highlighting, and light up HTML's ` parses as JavaScript and + `` parses as CSS, via HTML's crate-exported injections query + riding the #122 injection engine. CSS is registered here so the `` and `` produces a + `ParseTreeBundle` whose child layers resolve to `css` and `javascript`, and + a grid-paint asserts an injected CSS property and JS keyword paint **inside** + the embedded regions (mirroring `grid_paints_injected_child_keyword`). +6. **Paint (non-vacuous highlighting)**: parse `` and assert **both** + the `` tag (`@tag`) **and** the `href` attribute name (`@attribute`) paint + the two new non-default styles — the attribute assertion is load-bearing, since + a tag-only test could pass with `@attribute` unverified. Also assert a CSS + selector (`@tag`) paints the new `tag` style and an ordinary CSS property + (`color` → `@property`) paints non-default (an ordinary property has a single + unconditional capture, so no precedence subtlety — Q#WEB4). +7. **Full gate suite** per `CLAUDE.md`. + +## 7. Prior art in pmacs + +- **LaTeX lane #144** (`docs/latex-grammar-math-substrate-framing.md`) — the + grammar-add mechanics, the table-guard/smoke/paint test conventions, and the + compile-gate-plus-paint-test discipline. (Its overlay convention is not + needed here.) +- **Multi-language injections #122** + (`docs/multi-language-injections-framing.md`) — the `ParseTreeBundle` + + `Layer` engine HTML's injections ride. +- **markdown → rust fenced code** (`src/syntax.rs:848`, tested by + `src/highlight.rs`'s `grid_paints_injected_child_keyword`) — the working + injection precedent this lane's acceptance 5 mirrors. From 394d39942c960abc4eda20aa9055b6fe80bf56c3 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Thu, 23 Jul 2026 15:04:10 -0400 Subject: [PATCH 2/3] feat(web): bundle HTML + CSS grammars + HTML injections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register `html` (.html/.htm/.xhtml) and `css` (.css) entries in BUILTIN_LANGUAGES, backed by the official tree-sitter-html 0.23 and tree-sitter-css 0.25 grammars over the tree-sitter-language shim (ABI-fine, no overlay — both export their query constants). The single `extensions` field wires detection ahead of the LSP filetype map. HTML's crate-exported INJECTIONS_QUERY lights up — `let` (JS keyword) at col 8. + let src = b"\n\n"; + let mut buf = Buffer::new(BufferId::next(), "page.html"); + buf.apply_edit(EditOp::Insert { pos: 0, bytes: src }) + .unwrap(); + let view = ParseView::new(&buf, language, "html".to_owned()); + let handle = view.handle(); + let _vid = buf.attach_view(Box::new(view)); + let mut req = handle.make_request(); + req.injection_aliases = reg.injection_alias_snapshot(); + let bundle = crate::syntax::run_parse(req).expect("html parse"); + handle.install(reg.resolve_layer_queries(&bundle)); + + let mut hv = SyntaxHighlightView::new(handle, reg.theme()); + let (rows, cols) = (2usize, 60usize); + let mut backing: Vec = vec![Cell::default(); rows * cols]; + let mut grid = CellGrid { + cells: &mut backing, + stride: cols as u32, + size: CellSize::new(rows as u32, cols as u32), + }; + let viewport = Viewport { + buffer_start: 0, + buffer_end: u64::MAX, + cell_origin: CellCoord::new(0, 0), + cell_size: CellSize::new(rows as u32, cols as u32), + gutter_w: 0, + }; + let registry = buf; + hv.render(®istry, viewport, &mut grid); + + // Inside