Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
172 commits
Select commit Hold shift + click to select a range
c183165
Restore cleared scopes before Pop on pop: N + set: X
stefanobaghino Apr 20, 2026
d1200b3
Clip captures: N span to rule's match bounds
stefanobaghino Apr 21, 2026
cd23cc9
Suppress cur meta_scope on pop: N + embed: match text
stefanobaghino Apr 21, 2026
e9c022a
Drain orphan scope atoms on outer escape fire
stefanobaghino Apr 22, 2026
b185a2c
Order apply_prototype external prototype before target main
stefanobaghino Apr 22, 2026
69cd4b3
Cover apply_prototype external-prototype precedence
stefanobaghino Apr 23, 2026
347ea76
Drop HAML-Rails from syntest baselines
stefanobaghino Apr 23, 2026
17e46c4
Wrap past-EOL syntest assertions to next-line scopes
stefanobaghino Apr 23, 2026
b1b5438
Dedup flushed_ops across multi-fail parse_line calls
stefanobaghino Apr 23, 2026
78da6c4
Anchor replay-born branches to their replay line
stefanobaghino Apr 23, 2026
715a68e
Inherit outer prefix in replay-born branch_points
stefanobaghino Apr 25, 2026
7706736
Refresh post-replay shadow and stack_before snapshots
stefanobaghino Apr 25, 2026
d31dbe3
Subtract bp.pop_count in branch_point retain predicate
stefanobaghino Apr 26, 2026
d4a7e05
Route handle_fail cross-line re-emit through push_meta_ops
stefanobaghino Apr 26, 2026
82703dc
Save flushed_ops before cross-line replay loop and prefer inner corre…
stefanobaghino Apr 26, 2026
f3e497a
Fall through to parent on branch_point exhaustion
stefanobaghino Apr 27, 2026
ed949e4
Restore cleared scopes before deeper pops in pop:N
stefanobaghino Apr 27, 2026
0a2139a
Skip inner replay correction when nested deeper than outer BP
stefanobaghino Apr 27, 2026
d36dc01
Treat pop:N + push:X as Set with pop_count=N
stefanobaghino Apr 27, 2026
b31b727
Skip cur mcs Pop in Set when wrapper has embed_scope_replaces
stefanobaghino Apr 27, 2026
4bd9272
Defer target Clear in single-context Set when cur has meta_scope
stefanobaghino Apr 27, 2026
96ae959
Drop extra parent mcs on trigger of multi-set + target clear+ms
stefanobaghino Apr 27, 2026
aca11f5
Restore deeper frame clear_scopes on pop:N + set:
stefanobaghino Apr 27, 2026
61a796e
Drop python_strings.py from syntest baselines
stefanobaghino Apr 27, 2026
3b44840
Skip embed_scope_replaces for fragment embeds
stefanobaghino Apr 27, 2026
d4b6a5b
Drop python.py from syntest baselines
stefanobaghino Apr 27, 2026
72f5ac0
Prefer own over inherited in multi-extends parent merge
stefanobaghino Apr 28, 2026
172a697
Skip non-pure assertion lines in the syntest harness
stefanobaghino Apr 28, 2026
230faae
Bypass search cache on truncated searches at embed-escape boundary
stefanobaghino Apr 28, 2026
02ac40d
Apply non-topmost set target's clear_scopes at trigger position
stefanobaghino Apr 28, 2026
c432a0c
Defer LRD blank-line pop to next-line baseline
stefanobaghino Apr 28, 2026
6ca4ebd
Treat shebang header tail as testtoken_end in syntest harness
stefanobaghino Apr 28, 2026
b3d9841
Stop propagating no_prototype mark across include boundaries past a Push
stefanobaghino Apr 28, 2026
6376028
Collapse empty atoms in scope and selector strings
stefanobaghino Apr 28, 2026
bf88dd9
Bump testdata/Packages to v4202
stefanobaghino Apr 29, 2026
82121e6
Mirror same-line rewind+skip on cross-line BP exhaustion
stefanobaghino Apr 29, 2026
ae78419
Bound prefer_inner_replay_corrections by depth_diff to substitute sib…
stefanobaghino Apr 29, 2026
610412f
Pop deeper popped meta_scope before pop:N+set: trigger token
stefanobaghino Apr 29, 2026
9bfe8a9
Collapse rule scope atoms duplicating popped meta_scope on match
stefanobaghino Apr 29, 2026
be11842
Refresh syntest baselines after qualified-annotation dedup
stefanobaghino Apr 29, 2026
c25204f
Allow immediately-pop tail-extension from deeper inner BP correction
stefanobaghino Apr 29, 2026
345072e
Refresh syntest baselines after annotation EOL-pop fix
stefanobaghino Apr 29, 2026
c849e38
Refresh syntest baselines after annotation EOL-pop fix
stefanobaghino Apr 29, 2026
3918258
Distinguish pop:N+push: from pop:N+set: at MatchOperation IR
stefanobaghino Apr 30, 2026
51e62e6
Route pop:N+branch: through Push lookahead and drop scope-dedup hack
stefanobaghino Apr 30, 2026
6ce6367
Route pop:N+embed: through Push lookahead
stefanobaghino Apr 30, 2026
e5213d9
Add line-number and effective-depth discriminators to cross-line repl…
stefanobaghino May 6, 2026
2d56cf2
Refresh syntest baselines after cross-line discriminator fix
stefanobaghino May 6, 2026
2091022
Substitute outer-side cross-line replay with inner correction when in…
stefanobaghino May 6, 2026
ff4e4d2
Refresh syntest baselines after cluster-B substitution path lands
stefanobaghino May 6, 2026
c0bc9bb
Force `class-members` alt 5 via inline alt-5 re-run on composite disc…
stefanobaghino May 6, 2026
b211904
Refresh syntest baselines after `class-members` alt-5 fix
stefanobaghino May 6, 2026
ef5a7ff
Fix non-consuming multi-context push loop guard
stefanobaghino May 6, 2026
15f9a6e
Bound zero-width escape fires per line to break Perl POD hang
stefanobaghino May 6, 2026
be18d58
Stop skipping syntax_test_perl.pl in syntest harness
stefanobaghino May 6, 2026
ff76a22
Fix exec_escape BP prune to respect pop_count like the other sites
stefanobaghino Jul 4, 2026
5a7eba0
Replace ClassedHTMLGenerator with trait-based ClassedHighlighter
stefanobaghino Apr 8, 2026
e2c6eaf
Extract generic ScopeRenderer trait into top-level renderer module
stefanobaghino Apr 8, 2026
542f361
Remove deprecated DefaultScopeRenderer type alias
stefanobaghino Apr 8, 2026
3070245
Restore ClassedHTMLGenerator as the primary name
stefanobaghino Apr 8, 2026
62032dd
Rename highlighter references to html_generator for ClassedHTMLGenerator
stefanobaghino Apr 8, 2026
cf16fa4
Remove LineHighlightingRenderer
stefanobaghino Apr 8, 2026
58b5f05
Generalize ScopeRenderer output from String to io::Write
stefanobaghino Apr 8, 2026
6d51a0b
Replace unsafe String::from_utf8_unchecked with safe conversion
stefanobaghino Apr 8, 2026
7a54d9a
Restore doc comment about CSS class matching semantics
stefanobaghino Apr 8, 2026
fb2bbe6
Rename HtmlScopeRenderer to HTMLScopeRenderer for consistency
stefanobaghino Apr 8, 2026
c8018ce
Extract generic DocumentGenerator from ClassedHTMLGenerator
stefanobaghino Apr 8, 2026
4e07b86
Revert ScopeRenderer output from io::Write back to String
stefanobaghino Apr 8, 2026
94098de
Gate generator and renderer modules behind parsing feature
stefanobaghino Apr 8, 2026
a025e87
Merge html/mod.rs and html/renderer.rs into a single html.rs file
stefanobaghino Apr 9, 2026
6882091
Remove redundant legacy output test and stale doc comment
stefanobaghino Apr 9, 2026
ac2876a
Add changelog entries for ScopeRenderer and DocumentGenerator
stefanobaghino Apr 9, 2026
b0f632e
Generalize DocumentGenerator output over io::Write
stefanobaghino Apr 9, 2026
b7d77b8
Ignore files generated by synhtml-css-classes example
stefanobaghino Apr 9, 2026
c659876
Evolve HighlightLines into unified ScopeRenderer-driven API
stefanobaghino Apr 9, 2026
36cfdfa
Add ThemeHighlight for high-level theme-based string highlighting
stefanobaghino Apr 9, 2026
838ddc8
Remove ThemeHighlight, make all high-level APIs streaming
stefanobaghino Apr 9, 2026
d9952ae
Remove StyleWriter trait, consolidate on ScopeRenderer
stefanobaghino Apr 9, 2026
c5b99d5
Remove unreleased generator/renderer modules from changelog
stefanobaghino Apr 9, 2026
5224c7e
Remove ansi-scope-renderer example
stefanobaghino Apr 9, 2026
fe7d6aa
Restore testdata to upstream/master contents
stefanobaghino Apr 9, 2026
cdd33ee
Preserve whitespace-merging behaviour in InlineHTMLScopeRenderer
stefanobaghino Apr 9, 2026
ddd9d53
Restore can_start_again_from_previous_state test
stefanobaghino Apr 9, 2026
a5c6aa4
Fix redundant explicit link targets in rustdoc comments
stefanobaghino Apr 9, 2026
f47ba1c
Introduce HighlightDriver, restore and deprecate HighlightLines/Highl…
stefanobaghino Apr 9, 2026
fc77ad1
Stream highlighted output directly to stdout in examples
stefanobaghino Apr 9, 2026
b90eacf
Fix G/B channel swap in as_latex_escaped and align LatexScopeRenderer
stefanobaghino Apr 9, 2026
4051d7a
Close LaTeX color groups at line boundaries
stefanobaghino Apr 10, 2026
810a90c
Replace HighlightDriver with syntect::io::HighlightedWriter
stefanobaghino Apr 10, 2026
ca74f99
Port bench helper to HighlightedWriter
stefanobaghino Apr 10, 2026
cd521ae
Use writeln! in latex-demo to show macro composition
stefanobaghino Apr 10, 2026
cd0ffd6
Group Unreleased changelog link references in their own block
stefanobaghino Apr 10, 2026
4828f79
Drive bench helper line-by-line via writeln!
stefanobaghino Apr 10, 2026
497963a
Rename InlineHTMLScopeRenderer to ThemedHTMLScopeRenderer
stefanobaghino Apr 10, 2026
b2c74d6
Layer the renderer trait into ScopeMarkup, StyledOutput, ScopeRenderer
stefanobaghino Apr 10, 2026
15db188
Replace HighlightedWriter constructors with a typed builder
stefanobaghino Apr 10, 2026
7506e5c
Replace HighlightedWriter::finalize with into_inner + Drop
stefanobaghino Apr 10, 2026
a0d9320
Hide render_line; deprecate line_tokens_to_classed_spans
stefanobaghino Apr 10, 2026
b438c29
Make ThemedRenderer split text on '\n' unconditionally
stefanobaghino Apr 10, 2026
0ddd68d
Harden tests via cargo-mutants for the trait-based-classed-highlighte…
stefanobaghino Apr 11, 2026
4909a2c
Replace file:line references in test comments with behaviour descript…
stefanobaghino Apr 11, 2026
b5d21a4
Refresh testdata HTML snapshots after rebase onto #692
stefanobaghino May 7, 2026
b5763fc
Restore syncat's background colour fills
stefanobaghino May 7, 2026
c06187a
Gate html-using io tests on the html feature
stefanobaghino May 7, 2026
db47dc8
Replace AnsiStyledOutput's bool toggle with an AnsiBackground enum
stefanobaghino May 7, 2026
1a36a9a
Collapse AnsiStyledOutput into a pure two-variant enum
stefanobaghino May 7, 2026
3e2aa64
Align ParseLineOutput::replayed to the last pending_ops slots
stefanobaghino May 7, 2026
a4b908a
Add scopedump differential harness example
stefanobaghino Jul 4, 2026
50eda6b
Skip hidden files and directories in the scopedump walk
stefanobaghino Jul 4, 2026
8c15d55
Move parser.rs to parser/mod.rs ahead of module split
stefanobaghino Jul 4, 2026
d30a2ce
Carve parser production code into themed submodules
stefanobaghino Jul 4, 2026
b6ef368
Split parser tests into themed submodules
stefanobaghino Jul 4, 2026
e0cef82
Point drifted parser.rs line references at stable anchors
stefanobaghino Jul 4, 2026
87987ec
Extract the pure interpreter state of ParseState into Core
stefanobaghino Jul 4, 2026
1a83739
Un-ignore embed wrapper-mcs test; CI checks out the submodule
stefanobaghino Jul 11, 2026
79ae5fd
Merge branch '631-fragment-embed-skip-replaces' into 631-multi-extend…
stefanobaghino Jul 11, 2026
9b8b713
Merge branch '631-markdown-fence-embed-scope-token-drop' into 631-bas…
stefanobaghino Jul 11, 2026
f8f0501
Merge branch '631-bash-tilde-meta-scope-leak' into 631-php-multi-set-…
stefanobaghino Jul 11, 2026
11b84a2
Merge branch '631-php-multi-set-target-clear-extra-mcs-drop' into 631…
stefanobaghino Jul 11, 2026
1ce1d05
Merge branch '631-pop-n-set-deeper-clear-scopes-restore' into 631-fra…
stefanobaghino Jul 11, 2026
2048676
Un-ignore zsh-for-markdown shebang test; CI has the submodule
stefanobaghino Jul 11, 2026
ff67ac4
Merge branch '631-zsh-range-clear-parent-string-scope' into 631-markd…
stefanobaghino Jul 11, 2026
d8bd7d2
Merge branch '631-multi-extends-own-beats-inherited' into 631-syntest…
stefanobaghino Jul 11, 2026
f2a0dea
Merge branch '631-syntest-non-pure-assertion-gating' into 631-clip-lo…
stefanobaghino Jul 11, 2026
b872bfa
Merge branch '631-clip-lookahead-at-embed-escape' into 631-zsh-range-…
stefanobaghino Jul 11, 2026
39f3a17
Un-ignore LRD blank-line test; CI has the submodule
stefanobaghino Jul 11, 2026
d91cc52
Merge branch '631-syntest-haskell-meta-function-identifier' into 631-…
stefanobaghino Jul 11, 2026
78498a6
Merge branch '631-markdown-lrd-blank-line' into 631-syntest-shebang-t…
stefanobaghino Jul 11, 2026
8f0918c
Merge branch '631-syntest-shebang-tail-as-end-token' into 631-syntest…
stefanobaghino Jul 11, 2026
2f3fee8
Track v4202 embed_scope atom rename in embed wrapper-mcs test
stefanobaghino Jul 11, 2026
2aadad9
Merge branch '631-java-qualified-annotation-dedup' into 631-java-anno…
stefanobaghino Jul 11, 2026
bbccf81
Merge branch '631-syntest-bump-packages-submodule' into 631-java-cros…
stefanobaghino Jul 11, 2026
81fd88e
Merge branch '631-java-cross-line-bp-fall-through' into 631-java-cros…
stefanobaghino Jul 11, 2026
4a2712c
Merge branch '631-java-cross-line-allexhaust-pops' into 631-java-pop-…
stefanobaghino Jul 11, 2026
a1d6b9d
Merge branch '631-java-pop-n-set-deeper-trigger' into 631-java-qualif…
stefanobaghino Jul 11, 2026
2ad2cbe
Un-ignore annotation EOL-pop replay test; CI has the submodule
stefanobaghino Jul 11, 2026
7674762
Merge branch '631-java-annotation-eol-pop' into 631-pop-n-non-set-loo…
stefanobaghino Jul 11, 2026
053d7dc
Merge branch '631-pop-n-non-set-lookahead' into 631-java-annotation-p…
stefanobaghino Jul 11, 2026
7804240
Merge branch '631-java-annotation-parameters-drift' into 631-java-fie…
stefanobaghino Jul 11, 2026
b3bfd6a
Merge branch '631-java-field-type-meta-path-drop' into 631-java-class…
stefanobaghino Jul 11, 2026
13de8c6
Merge branch '631-java-class-members-alt-cycle' into 631-non-consumin…
stefanobaghino Jul 11, 2026
5e15063
Merge branch '631-non-consuming-multi-push-guard' into 631-zero-width…
stefanobaghino Jul 11, 2026
cb7f666
Merge branch '631-zero-width-escape-loop-guard' into 627-scopedump-ha…
stefanobaghino Jul 11, 2026
12a1a99
Merge branch '627-scopedump-harness' into 627-parser-module-split
stefanobaghino Jul 11, 2026
4074376
Merge branch '627-parser-module-split' into 627-parser-core-extraction
stefanobaghino Jul 11, 2026
02210d7
Un-ignore the 630-era submodule tests too; CI has the submodule
stefanobaghino Jul 11, 2026
6fa70b9
Merge branch '631-markdown-fence-embed-scope-token-drop' into 631-bas…
stefanobaghino Jul 11, 2026
d2efa94
Merge branch '631-bash-tilde-meta-scope-leak' into 631-php-multi-set-…
stefanobaghino Jul 11, 2026
eea01f4
Merge branch '631-php-multi-set-target-clear-extra-mcs-drop' into 631…
stefanobaghino Jul 11, 2026
5944f95
Merge branch '631-pop-n-set-deeper-clear-scopes-restore' into 631-fra…
stefanobaghino Jul 11, 2026
e298261
Merge branch '631-fragment-embed-skip-replaces' into 631-multi-extend…
stefanobaghino Jul 11, 2026
e96f99f
Merge branch '631-multi-extends-own-beats-inherited' into 631-syntest…
stefanobaghino Jul 11, 2026
f954cb1
Merge branch '631-syntest-non-pure-assertion-gating' into 631-clip-lo…
stefanobaghino Jul 11, 2026
bad01ab
Merge branch '631-clip-lookahead-at-embed-escape' into 631-zsh-range-…
stefanobaghino Jul 11, 2026
4426958
Merge branch '631-zsh-range-clear-parent-string-scope' into 631-markd…
stefanobaghino Jul 11, 2026
e72786d
Merge branch '631-markdown-lrd-blank-line' into 631-syntest-shebang-t…
stefanobaghino Jul 11, 2026
c2bcd9a
Merge branch '631-syntest-shebang-tail-as-end-token' into 631-syntest…
stefanobaghino Jul 11, 2026
53bf87a
Merge branch '631-syntest-haskell-meta-function-identifier' into 631-…
stefanobaghino Jul 11, 2026
04f88dc
Merge branch '631-syntest-bump-packages-submodule' into 631-java-cros…
stefanobaghino Jul 11, 2026
5f28c20
Merge branch '631-java-cross-line-bp-fall-through' into 631-java-cros…
stefanobaghino Jul 11, 2026
ad9cee0
Merge branch '631-java-cross-line-allexhaust-pops' into 631-java-pop-…
stefanobaghino Jul 11, 2026
35cce2c
Merge branch '631-java-pop-n-set-deeper-trigger' into 631-java-qualif…
stefanobaghino Jul 11, 2026
972dced
Merge branch '631-java-qualified-annotation-dedup' into 631-java-anno…
stefanobaghino Jul 11, 2026
c9d30cf
Merge branch '631-java-annotation-eol-pop' into 631-pop-n-non-set-loo…
stefanobaghino Jul 11, 2026
8696e58
Merge branch '631-pop-n-non-set-lookahead' into 631-java-annotation-p…
stefanobaghino Jul 11, 2026
b7b813e
Merge branch '631-java-annotation-parameters-drift' into 631-java-fie…
stefanobaghino Jul 11, 2026
0827969
Merge branch '631-java-field-type-meta-path-drop' into 631-java-class…
stefanobaghino Jul 11, 2026
c449a6f
Merge branch '631-java-class-members-alt-cycle' into 631-non-consumin…
stefanobaghino Jul 11, 2026
7656e19
Merge branch '631-non-consuming-multi-push-guard' into 631-zero-width…
stefanobaghino Jul 11, 2026
3f50e9c
Merge branch '631-zero-width-escape-loop-guard' into 627-scopedump-ha…
stefanobaghino Jul 11, 2026
b22a729
Merge branch '627-scopedump-harness' into 627-parser-module-split
stefanobaghino Jul 11, 2026
23b17c9
Merge branch '627-parser-module-split' into 627-parser-core-extraction
stefanobaghino Jul 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ target/

# VS Code
.vscode/

# Generated by examples/synhtml-css-classes
synhtml-css-classes.html
synhtml-css-classes.css
theme-dark.css
theme-light.css

# cargo-mutants
mutants.out/
mutants.out.old/
master.diff
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[submodule "testdata/Packages"]
path = testdata/Packages
url = https://github.com/sublimehq/Packages
branch = v4202
[submodule "testdata/InspiredGitHub.tmtheme"]
path = testdata/InspiredGitHub.tmtheme
url = https://github.com/sethlopezme/InspiredGitHub.tmtheme.git
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### Breaking changes

- `HighlightLines` and `HighlightFile` deprecated since 6.0.0 — use `syntect::io::HighlightedWriter` instead [#627]
- `line_tokens_to_classed_spans` (`syntect::html`) deprecated since 6.0.0 — cannot correctly handle cross-line branch-point failures (the rendered output for earlier lines is already in the caller's hands when the parser retroactively replays). Use `ClassedHTMLGenerator` or `HighlightedWriter::from_markup` instead, both of which buffer rendered output during speculative parsing and replay corrected ops [#627]
- `SCOPE_REPO` removed from public API (was already deprecated since 5.3.0) [#627]
- `ParseState::parse_line` now returns `Result<ParseLineOutput, ParsingError>` instead of a bare `Vec` [#614]
- `MatchOperation` enum: new `Branch`, `Fail` [#614], and `Embed` [#615] variants
- `Pattern` enum: new `IncludeWithPrototype` variant [#610]
Expand All @@ -15,12 +18,33 @@

### Improvements

- Add `syntect::io` module containing `HighlightedWriter<'a, R, W>`, a streaming highlighter that implements `std::io::Write` and handles branch-point backtracking, generic over the output sink (`Vec<u8>` by default, or any `io::Write` for streaming). Constructed via the new `HighlightedWriterBuilder`: pick a renderer category with `HighlightedWriter::from_themed` / `from_markup` / `from_renderer`, then chain `.with_output(...)` / `.with_state(...)` and finish with `.build()`. End-of-input cleanup runs implicitly via `Drop` on a best-effort basis; call `into_inner` explicitly when you need the inner sink back or want errors propagated [#627]
- Add `syntect::rendering` module with a layered renderer trait design [#627]:
- `ScopeMarkup` — slim trait for stateless renderers that map scope structure 1:1 to output structure (e.g. CSS-classed HTML); receives only pre-resolved atom strings
- `StyledOutput` — small trait for theme-aware renderers (e.g. ANSI, inline-styled HTML, LaTeX `\textcolor`); only describes how to begin/end a styled span and write text
- `ThemedRenderer<O>` — adapter that turns any `StyledOutput` into a `ScopeRenderer` by managing the `Highlighter`, the style stack, and adjacent-token style merging
- `ScopeRenderer` — low-level engine trait kept as an escape hatch for advanced cases that need raw `Scope` / `&[Scope]` access
- `AnsiStyledOutput` — built-in 24-bit ANSI colour emitter; pair with `HighlightedWriter::from_themed` for terminal output
- Add `ClassedHTMLScopeRenderer` (`syntect::html`) implementing `ScopeMarkup` for `<span class="...">` output with CSS classes derived from scope atoms [#627]
- Add `HtmlStyledOutput` (`syntect::html`) implementing `StyledOutput` for theme-aware inline-styled `<span style="...">` HTML output with whitespace-merge optimization [#627]
- Add `Scope::with_atom_strs()` closure-based API for reading atom strings without direct repository access [#627]
- `ClassedHTMLGenerator` preserved as backward-compatible wrapper around `HighlightedWriter` (now driven by `MarkupAdapter<ClassedHTMLScopeRenderer>`) [#627]
- `highlighted_html_for_string`/`highlighted_html_for_file` reworked to use `HighlightedWriter::from_themed` and `HtmlStyledOutput` [#627]
- Implement sublime-syntax Build 4075 features: `extends` (single and multiple inheritance), `meta_prepend`/`meta_append`, `apply_prototype`, `version: 2`, and `first_line_match` variable resolution [#610] [#612]
- Implement `branch_point`/`branch`/`fail` backtracking with cross-line replay support [#614]
- Implement native `embed`/`escape` support, fixing cases where embedded context patterns could consume escape characters first [#615]
- Gracefully skip syntax files that fail to load and hide syntaxes with unresolved `extends` parents [#610]
- Add `warnings()` API on `SyntaxSetBuilder` and `SyntaxSet` to replace `eprintln!` warnings with programmatic access [#619]

[#512]: https://github.com/trishume/syntect/pull/512
[#576]: https://github.com/trishume/syntect/pull/576
[#610]: https://github.com/trishume/syntect/pull/610
[#612]: https://github.com/trishume/syntect/pull/612
[#614]: https://github.com/trishume/syntect/pull/614
[#615]: https://github.com/trishume/syntect/pull/615
[#619]: https://github.com/trishume/syntect/pull/619
[#627]: https://github.com/trishume/syntect/pull/627

## [Version 5.3.0](https://github.com/trishume/syntect/compare/v5.2.0...v5.3.0)

### Improvements
Expand Down
Binary file modified assets/default_newlines.packdump
Binary file not shown.
Binary file modified assets/default_nonewlines.packdump
Binary file not shown.
14 changes: 8 additions & 6 deletions benches/highlight_utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use syntect::easy::HighlightLines;
use std::io::Write;
use syntect::highlighting::Theme;
use syntect::io::HighlightedWriter;
use syntect::parsing::{SyntaxReference, SyntaxSet};
use syntect::rendering::AnsiStyledOutput;

/// Common helper for benchmarking highlighting.
pub fn do_highlight(
Expand All @@ -9,11 +11,11 @@ pub fn do_highlight(
syntax: &SyntaxReference,
theme: &Theme,
) -> usize {
let mut h = HighlightLines::new(syntax, theme);
let mut count = 0;
let mut highlight =
HighlightedWriter::from_themed(syntax, syntax_set, theme, AnsiStyledOutput::Transparent)
.build();
for line in s.lines() {
let regions = h.highlight_line(line, syntax_set).unwrap();
count += regions.len();
writeln!(highlight, "{}", line).unwrap();
}
count
highlight.into_inner().unwrap().len()
}
66 changes: 54 additions & 12 deletions examples/latex-demo.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,64 @@
use syntect::easy::HighlightLines;
use std::fmt::Write as FmtWrite;
use std::io::Write as IoWrite;
use syntect::highlighting::{Style, ThemeSet};
use syntect::io::HighlightedWriter;
use syntect::parsing::SyntaxSet;
use syntect::util::{as_latex_escaped, LinesWithEndings};
use syntect::rendering::StyledOutput;

/// A [`StyledOutput`] that produces LaTeX `\textcolor[RGB]{r,g,b}{...}`
/// output. Wrap with [`ThemedRenderer`] (or pass to
/// [`HighlightedWriter::with_themed`]) to plug it into a highlighter.
struct LatexStyledOutput;

impl StyledOutput for LatexStyledOutput {
fn begin_style(&mut self, style: Style, output: &mut String) {
write!(
output,
"\\textcolor[RGB]{{{},{},{}}}{{",
style.foreground.r, style.foreground.g, style.foreground.b
)
.unwrap();
}

fn end_style(&mut self, output: &mut String) {
output.push('}');
}

fn write_text(&mut self, text: &str, output: &mut String) {
// The `ThemedRenderer` adapter guarantees `text` never contains
// '\n' (line breaks are split out and emitted between styled
// spans), so we only need to escape LaTeX's three special
// characters.
for ch in text.chars() {
match ch {
'\\' => output.push_str("\\\\"),
'{' => output.push_str("\\{"),
'}' => output.push_str("\\}"),
_ => output.push(ch),
}
}
}
}

fn main() {
// Load these once at the start of your program
let ps = SyntaxSet::load_defaults_newlines();
let ts = ThemeSet::load_defaults();

let syntax = ps.find_syntax_by_extension("rs").unwrap();
let s = "pub struct Wow { hi: u64 }\nfn blah() -> u64 {}\n";

let mut h = HighlightLines::new(syntax, &ts.themes["InspiredGitHub"]);
for line in LinesWithEndings::from(s) {
// LinesWithEndings enables use of newlines mode
let ranges: Vec<(Style, &str)> = h.highlight_line(line, &ps).unwrap();
let escaped = as_latex_escaped(&ranges[..]);
println!("\n{:?}", line);
println!("\n{}", escaped);
}
// No explicit `into_inner` needed at the end: we don't need the
// `StdoutLock` back, and `Drop` runs the close-scopes / partial-line
// cleanup on a best-effort basis when `highlight` falls out of scope.
// Examples that *do* need the inner sink back (e.g. `parsyncat` collecting
// a `Vec<u8>` per file) call `into_inner` explicitly to propagate errors.
let mut highlight = HighlightedWriter::from_themed(
syntax,
&ps,
&ts.themes["InspiredGitHub"],
LatexStyledOutput,
)
.with_output(std::io::stdout().lock())
.build();
writeln!(highlight, "pub struct Wow {{ hi: u64 }}").unwrap();
writeln!(highlight, "fn blah() -> u64 {{}}").unwrap();
}
67 changes: 25 additions & 42 deletions examples/parsyncat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
//! Prints the highlighted output to stdout.

use rayon::prelude::*;
use syntect::easy::HighlightFile;
use syntect::highlighting::{Style, ThemeSet};
use syntect::highlighting::ThemeSet;
use syntect::io::HighlightedWriter;
use syntect::parsing::SyntaxSet;
use syntect::rendering::AnsiStyledOutput;

use std::fs::File;
use std::io::{BufRead, BufReader};
use std::io::{self, Write};

fn main() {
let files: Vec<String> = std::env::args().skip(1).collect();
Expand All @@ -20,51 +21,33 @@ fn main() {
let syntax_set = SyntaxSet::load_defaults_newlines();
let theme_set = ThemeSet::load_defaults();

// We first collect the contents of the files...
let contents: Vec<Vec<String>> = files
// Highlight each file in parallel, buffering each result into its own
// `Vec<u8>` so we can stream them out in order at the end.
let outputs: Vec<Vec<u8>> = files
.par_iter()
.map(|filename| {
let mut lines = Vec::new();
// We use `String::new()` and `read_line()` instead of `BufRead::lines()`
// in order to preserve the newlines and get better highlighting.
let mut line = String::new();
let mut reader = BufReader::new(File::open(filename).unwrap());
while reader.read_line(&mut line).unwrap() > 0 {
lines.push(line);
line = String::new();
}
lines
})
.collect();

// ...so that the highlighted regions have valid lifetimes...
let regions: Vec<Vec<(Style, &str)>> = files
.par_iter()
.zip(&contents)
.map(|(filename, contents)| {
let mut regions = Vec::new();
let theme = &theme_set.themes["base16-ocean.dark"];
let mut highlighter = HighlightFile::new(filename, &syntax_set, theme).unwrap();

for line in contents {
for region in highlighter
.highlight_lines
.highlight_line(line, &syntax_set)
.unwrap()
{
regions.push(region);
}
}

regions
let syntax = syntax_set
.find_syntax_for_file(filename)
.unwrap()
.unwrap_or_else(|| syntax_set.find_syntax_plain_text());
let mut f = File::open(filename).unwrap();
let mut w = HighlightedWriter::from_themed(
syntax,
&syntax_set,
theme,
AnsiStyledOutput::Transparent,
)
.build();
io::copy(&mut f, &mut w).unwrap();
w.into_inner().unwrap()
})
.collect();

// ...and then print them all out.
for file_regions in regions {
print!(
"{}",
syntect::util::as_24_bit_terminal_escaped(&file_regions[..], true)
);
let stdout = io::stdout();
let mut out = stdout.lock();
for output in outputs {
out.write_all(&output).unwrap();
}
}
Loading