Skip to content

Let comments and strings compete for the text by position - #26

Merged
liuyingjierun merged 3 commits into
mainfrom
engine/span-groups
Sep 13, 2026
Merged

liuyingjierun merged 3 commits into
mainfrom
engine/span-groups

Conversation

@liuyingjierun

Copy link
Copy Markdown
Contributor

Three commits, and the first two belong together.

Spans compete by position. No order of rules renders both "https://jsray.org" as a string and // don't stop, won't stop as a comment, and every grammar had picked one of the two failures. Measured on beta.4: 27 grammars cut a line comment holding two quotes; JavaScript, the C family and PHP took "/* x */" inside a string for a comment; a JavaScript regex holding a quote opened a string; // see @Override was cut in two; JSONC cut "https://…" at its //; and SQL's multi-line strings let -- don't run on for lines. Three forms added in beta.4 — Ruby %w[…], Perl q{…}, Elixir ~r/…/ — and heredoc openings written inside comments were part of the same failure.

A rule may now carry an optional group. Adjacent rules sharing one run as a single pass in which the earliest match wins, and listed order only breaks a tie. Grammar is still GrammarRule[], and a rule without the field runs exactly as before.

Nested template placeholders. The first commit made one pre-existing bug worse. A placeholder holding a template ended the outer template at the inner one's closing backtick; once spans compete, the outer template's real closing backtick opened a new template that inverted the rest of the file. jsray-terminal's tests/tty.test.mjs is where it showed. The second commit lets a placeholder hold one nested template and one level of braces, each alternative still beginning with its own character so the pattern keeps one parse.

Private class members — #count, this.#count — are coloured as properties instead of being plain text or split by the type rule.

Verification

  • Each commit was built and tested on its own — 183, 184 and 185 tests — with check:integrity, check:versions and check:docs-parity green at every step.
  • Every JavaScript, PHP, shell, YAML and CSS file in the four JSRay repositories and each code block in their docs, 185 in all, rendered with beta.4 and with this build, and the differences read by class transition. None was a regression.
  • A span-boundary check — strings end on their own quote, // comments stay on one line, /* comments close: beta.4 had three block comments swallowing code, this build has none.
  • 200 KB per language: no slower than beta.4.

No version bump; this accumulates under [Unreleased] for 0.0.2-beta.5.

No order of rules can render both "https://jsray.org" as a string and
// don't stop, won't stop as a comment: strings first cuts the comment at its
first apostrophe, comments first cuts the string at its //. Every grammar had
chosen one, and the choice was written beside its rules as though it were the
fix. Measured on beta.4, 27 grammars cut a line comment holding two quotes,
and JavaScript, the C family and PHP took /* x */ inside a string for a
comment.

A rule may now carry group. Adjacent rules sharing one run as a single pass in
which the match beginning earliest wins, and listed order only breaks a tie.
Positions are compared where the whole match begins, lookbehind prefix
included, so a heredoc opened by << on a line that also carries a quoted
redirect is not lost to the quoted name.

Comments, strings, heredocs, regex literals, JSON keys, C preprocessor lines
and JavaScript parameter lists are spans in every grammar that has them. The
parameter list had to be one: ahead of the comments it read a signature inside
a doc comment as code, and behind the strings it could not match a list holding
a string default.

The field is optional and Grammar is still GrammarRule[]; a rule without it
runs exactly as before.
A placeholder holding a template — ${ok ? `a ${b}` : 'c'} — ended the outer
template at the inner one's closing backtick, because the placeholder pattern
stopped at the first }. Under ordered rules that was wrong and mostly harmless.
Once spans compete by position, the outer template's real closing backtick
opens a template of its own, running to the next backtick in the file, and
everything in between renders inverted.

jsray-terminal's tests showed it: a template carrying a Python script, with a
ternary between a template and a string in one placeholder. Rendering every
source file in the four repositories with beta.4 and with this build, that
file was the one place the previous commit made worse.

A placeholder now admits one nested template and one level of braces. Every
alternative inside it begins with its own character — a brace, a backtick, or
neither — so it still has one parse, and the storm cases include nested
openings that never close.
#count, this.#count and #count in obj were plain text, and the type rule took
#Foo apart at the word boundary, colouring Foo and leaving the # bare. The rule
sits ahead of the type and constant rules for that reason. A shebang's #! is
not a name and is left alone.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
jsray 6885860 Commit Preview URL

Branch Preview URL
Sep 13 2026, 10:19 AM

@liuyingjierun
liuyingjierun merged commit 82aa19a into main Sep 13, 2026
6 checks passed
@liuyingjierun
liuyingjierun deleted the engine/span-groups branch September 13, 2026 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant