From 1d8dc419a210d4d621b42dfa6ed292d940a08768 Mon Sep 17 00:00:00 2001 From: Ryan Atkinson Date: Tue, 25 Nov 2025 04:48:08 -0500 Subject: [PATCH 1/3] wip --- CHANGELOG.md | 4 +- CLAUDE.md | 18 +- README.md | 10 +- benchmark/benchmarks.ts | 8 +- benchmark/compare/compare.ts | 10 +- src/lib/Code.svelte | 8 +- ..._Highlight.svelte => CodeHighlight.svelte} | 18 +- src/lib/code_sample.ts | 4 +- src/lib/grammar_clike.ts | 6 +- src/lib/grammar_css.ts | 8 +- src/lib/grammar_js.ts | 4 +- src/lib/grammar_json.ts | 6 +- src/lib/grammar_markdown.ts | 30 +- src/lib/grammar_markup.ts | 26 +- src/lib/grammar_svelte.ts | 8 +- src/lib/grammar_ts.ts | 4 +- src/lib/highlight_manager.ts | 10 +- src/lib/highlight_priorities.gen.ts | 4 +- src/lib/highlight_priorities.ts | 4 +- src/lib/syntax_styler.ts | 124 +++--- src/lib/syntax_styler_global.ts | 4 +- src/lib/syntax_token.ts | 10 +- src/lib/tokenize_syntax.ts | 52 +-- src/routes/+page.svelte | 12 +- .../{Code_Tome.svelte => CodeTome.svelte} | 24 +- .../{Tome_Link.svelte => TomeLink.svelte} | 2 +- src/routes/about/+page.svelte | 14 +- src/routes/benchmark/+page.svelte | 16 +- ...Harness.svelte => BenchmarkHarness.svelte} | 16 +- ...stance.svelte => BenchmarkInstance.svelte} | 12 +- ...Results.svelte => BenchmarkResults.svelte} | 12 +- src/routes/benchmark/benchmark_fixtures.ts | 18 +- src/routes/benchmark/benchmark_results.ts | 14 +- src/routes/benchmark/benchmark_runner.ts | 48 +-- src/routes/benchmark/benchmark_stability.ts | 6 +- src/routes/benchmark/benchmark_stats.ts | 22 +- src/routes/benchmark/benchmark_types.ts | 36 +- src/routes/docs/+page.svelte | 4 +- src/routes/docs/api/+page.svelte | 4 +- .../docs/api/[...module_path]/+page.svelte | 4 +- src/routes/docs/package/+page.svelte | 10 +- src/routes/moss.css | 77 ---- src/routes/package.ts | 353 +++++++++--------- src/routes/samples/+page.svelte | 10 +- .../fixtures/generated/ts/ts_complex.html | 10 +- src/test/fixtures/generated/ts/ts_complex.txt | 22 +- src/test/fixtures/helpers.ts | 26 +- src/test/fixtures/samples/all.gen.ts | 6 +- src/test/fixtures/samples/all.ts | 16 +- src/test/fixtures/samples/sample_complex.ts | 10 +- src/test/highlight_manager.test.ts | 228 +++++------ src/test/highlight_test_helpers.ts | 20 +- src/test/syntax_styler.test.ts | 16 +- 53 files changed, 685 insertions(+), 763 deletions(-) rename src/lib/{Code_Highlight.svelte => CodeHighlight.svelte} (93%) rename src/routes/{Code_Tome.svelte => CodeTome.svelte} (83%) rename src/routes/{Tome_Link.svelte => TomeLink.svelte} (81%) rename src/routes/benchmark/{Benchmark_Harness.svelte => BenchmarkHarness.svelte} (80%) rename src/routes/benchmark/{Benchmark_Instance.svelte => BenchmarkInstance.svelte} (76%) rename src/routes/benchmark/{Benchmark_Results.svelte => BenchmarkResults.svelte} (88%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c019f89..32ff816d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,7 @@ ### Minor Changes -- rename `Syntax_Grammar_Raw` from `Syntax_Grammar` and `Syntax_Grammar` from `Normalized_Syntax_Grammar` ([#20](https://github.com/ryanatkn/fuz_code/pull/20)) +- rename `SyntaxGrammarRaw` from `SyntaxGrammar` and `SyntaxGrammar` from `NormalizedSyntaxGrammar` ([#20](https://github.com/ryanatkn/fuz_code/pull/20)) ## 0.28.0 @@ -73,7 +73,7 @@ ### Minor Changes -- rename `Grammar` to `Syntax_Grammar` ([#13](https://github.com/ryanatkn/fuz_code/pull/13)) +- rename `Grammar` to `SyntaxGrammar` ([#13](https://github.com/ryanatkn/fuz_code/pull/13)) - improve token styles ([#14](https://github.com/ryanatkn/fuz_code/pull/14)) - factor out `tokenize_syntax` into its own module ([#13](https://github.com/ryanatkn/fuz_code/pull/13)) diff --git a/CLAUDE.md b/CLAUDE.md index ed9cd276..c5151b6c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -58,9 +58,9 @@ The system uses regex-based tokenization inherited from PrismJS, maintaining com Syntax styler creates a hierarchical token tree where tokens can contain nested tokens: ```typescript -interface Syntax_Token { +interface SyntaxToken { type: string; // token type (e.g., 'keyword', 'string') - content: string | Syntax_Token_Stream; // text or nested tokens + content: string | SyntaxTokenStream; // text or nested tokens alias: string | Array; // CSS class aliases length: number; // token text length } @@ -91,10 +91,10 @@ The generated HTML uses CSS classes like `.token_keyword`, `.token_string`, etc. ## API Reference -### Syntax_Styler +### SyntaxStyler ```typescript -class Syntax_Styler { +class SyntaxStyler { // Generate HTML with syntax highlighting stylize(text: string, lang: string): string; @@ -138,11 +138,11 @@ Generated fixtures in `src/test/fixtures/{lang}/`: ### CSS Custom Highlight API Support -An experimental alternative component (`Code_Highlight.svelte`) is available that supports the CSS Custom Highlight API +An experimental alternative component (`CodeHighlight.svelte`) is available that supports the CSS Custom Highlight API for browsers that implement it. This is not recommended for general use due to limited browser support. **Components:** -- `src/lib/Code_Highlight.svelte` - Hybrid component supporting both HTML and range modes with auto-detection +- `src/lib/CodeHighlight.svelte` - Hybrid component supporting both HTML and range modes with auto-detection - `src/lib/highlight_manager.ts` - Manages CSS Custom Highlights per element **Theme:** @@ -159,10 +159,10 @@ const tokens = tokenize_syntax(code, grammar); highlight_manager.highlight_from_syntax_tokens(element, tokens); ``` -#### Highlight_Manager API +#### HighlightManager API ```typescript -const manager = new Highlight_Manager(); +const manager = new HighlightManager(); // Apply highlights from tokens manager.highlight_from_syntax_tokens(element, tokens); @@ -199,7 +199,7 @@ Results show relative performance (% of fastest) for each language and content s ### Optimization Notes - **HTML Mode** (standard): Proven PrismJS approach, works everywhere, good for SSR -- **Range Mode** (experimental): Native browser highlighting available in `Code_Highlight.svelte`, limited browser support +- **Range Mode** (experimental): Native browser highlighting available in `CodeHighlight.svelte`, limited browser support ## Color Variables diff --git a/README.md b/README.md index d45a620e..ad24afe6 100644 --- a/README.md +++ b/README.md @@ -145,15 +145,15 @@ using HTML generation is recommended for most use cases. ```svelte - + - + - + ``` When using the experimental highlight component, import the corresponding theme: @@ -165,7 +165,7 @@ import '@ryanatkn/fuz_code/theme_highlight.css'; Experimental modules: -- [@ryanatkn/fuz_code/Code_Highlight.svelte](src/lib/Code_Highlight.svelte) - +- [@ryanatkn/fuz_code/CodeHighlight.svelte](src/lib/CodeHighlight.svelte) - component supporting both HTML generation and CSS Custom Highlight API - [@ryanatkn/fuz_code/highlight_manager.js](src/lib/highlight_manager.ts) - manages browser [`Highlight`](https://developer.mozilla.org/en-US/docs/Web/API/Highlight) diff --git a/benchmark/benchmarks.ts b/benchmark/benchmarks.ts index b07c08f7..fbc4388a 100644 --- a/benchmark/benchmarks.ts +++ b/benchmark/benchmarks.ts @@ -10,14 +10,14 @@ const WARMUP_TIME = 1000; const WARMUP_ITERATIONS = 50; const LARGE_CONTENT_MULTIPLIER = 100; -export interface Benchmark_Result { +export interface BenchmarkResult { name: string; ops_per_sec: number; mean_time: number; samples: number; } -export const run_benchmark = async (filter?: string): Promise> => { +export const run_benchmark = async (filter?: string): Promise> => { const bench = new Bench({ time: BENCHMARK_TIME, warmupTime: WARMUP_TIME, @@ -58,7 +58,7 @@ export const run_benchmark = async (filter?: string): Promise = []; + const results: Array = []; for (const task of bench.tasks) { if (task.result) { @@ -74,7 +74,7 @@ export const run_benchmark = async (filter?: string): Promise): string => { +export const format_benchmark_results = (results: Array): string => { const lines: Array = [ '## Benchmark Results', '', diff --git a/benchmark/compare/compare.ts b/benchmark/compare/compare.ts index 44e144d7..099a179b 100644 --- a/benchmark/compare/compare.ts +++ b/benchmark/compare/compare.ts @@ -37,7 +37,7 @@ const WARMUP_ITERATIONS = 20; // 20 const LARGE_CONTENT_MULTIPLIER = 100; // 100 const MIN_ITERATIONS = 3; // Tiny minimum samples cause of Shiki's pathological cases with TS -export interface Comparison_Result { +export interface ComparisonResult { implementation: string; language: string; ops_per_sec: number; @@ -111,7 +111,7 @@ const getSampleContent = (lang: SupportedLanguage, large = false) => { export const run_comparison_benchmark = async ( filter?: string, -): Promise> => { +): Promise> => { const bench = new Bench({ time: BENCHMARK_TIME, warmupTime: WARMUP_TIME, @@ -187,7 +187,7 @@ export const run_comparison_benchmark = async ( await bench.run(); // Process results - const results: Array = []; + const results: Array = []; for (const task of bench.tasks) { if (task.result) { @@ -250,7 +250,7 @@ export const run_comparison_benchmark = async ( return results; }; -export const format_comparison_results = (results: Array): string => { +export const format_comparison_results = (results: Array): string => { const lines: Array = [ '# Syntax Highlighting Performance Comparison', '', @@ -263,7 +263,7 @@ export const format_comparison_results = (results: Array): st ]; // Group results by language+operation+size to find fastest in each group - const grouped: Map> = new Map(); + const grouped: Map> = new Map(); for (const result of results) { const key = `${result.language}_${result.operation}_${result.content_size}`; const group = grouped.get(key) || []; diff --git a/src/lib/Code.svelte b/src/lib/Code.svelte index fc095803..25248f93 100644 --- a/src/lib/Code.svelte +++ b/src/lib/Code.svelte @@ -4,7 +4,7 @@ import type {SvelteHTMLElements} from 'svelte/elements'; import {syntax_styler_global} from './syntax_styler_global.js'; - import type {Syntax_Styler, Syntax_Grammar} from './syntax_styler.js'; + import type {SyntaxStyler, SyntaxGrammar} from './syntax_styler.js'; const { content, @@ -52,7 +52,7 @@ * * @default undefined (uses grammar from `syntax_styler.langs[lang]`) */ - grammar?: Syntax_Grammar | undefined; + grammar?: SyntaxGrammar | undefined; /** * Whether to render as inline code or block code. * Controls display via CSS classes. @@ -75,12 +75,12 @@ */ wrap?: boolean; /** - * Custom Syntax_Styler instance to use for highlighting. + * Custom SyntaxStyler instance to use for highlighting. * Allows using a different styler with custom grammars or configuration. * * @default syntax_styler_global */ - syntax_styler?: Syntax_Styler; + syntax_styler?: SyntaxStyler; /** * Optional snippet to customize how the highlighted markup is rendered. * Receives the generated HTML string as a parameter. diff --git a/src/lib/Code_Highlight.svelte b/src/lib/CodeHighlight.svelte similarity index 93% rename from src/lib/Code_Highlight.svelte rename to src/lib/CodeHighlight.svelte index 25421693..e328f6a6 100644 --- a/src/lib/Code_Highlight.svelte +++ b/src/lib/CodeHighlight.svelte @@ -11,12 +11,12 @@ import type {SvelteHTMLElements} from 'svelte/elements'; import {syntax_styler_global} from './syntax_styler_global.js'; - import type {Syntax_Styler, Syntax_Grammar} from './syntax_styler.js'; + import type {SyntaxStyler, SyntaxGrammar} from './syntax_styler.js'; import {tokenize_syntax} from './tokenize_syntax.js'; import { - Highlight_Manager, + HighlightManager, supports_css_highlight_api, - type Highlight_Mode, + type HighlightMode, } from './highlight_manager.js'; const { @@ -63,7 +63,7 @@ * * @default 'auto' */ - mode?: Highlight_Mode; + mode?: HighlightMode; /** * Optional custom grammar object for syntax tokenization. * @@ -80,7 +80,7 @@ * * @default undefined (uses grammar from `syntax_styler.langs[lang]`) */ - grammar?: Syntax_Grammar | undefined; + grammar?: SyntaxGrammar | undefined; /** * Whether to render as inline code or block code. * Controls display via CSS classes. @@ -103,12 +103,12 @@ */ wrap?: boolean; /** - * Custom Syntax_Styler instance to use for highlighting. + * Custom SyntaxStyler instance to use for highlighting. * Allows using a different styler with custom grammars or configuration. * * @default syntax_styler_global */ - syntax_styler?: Syntax_Styler; + syntax_styler?: SyntaxStyler; /** * Optional snippet to customize how the highlighted markup is rendered. * - In HTML mode: receives the generated HTML string @@ -121,7 +121,7 @@ const supports_ranges = supports_css_highlight_api(); - const highlight_manager = supports_ranges ? new Highlight_Manager() : null; + const highlight_manager = supports_ranges ? new HighlightManager() : null; const use_ranges = $derived(supports_ranges && (mode === 'ranges' || mode === 'auto')); @@ -136,7 +136,7 @@ const langs = Object.keys(syntax_styler.langs).join(', '); // eslint-disable-next-line no-console console.error( - `[Code_Highlight] Language "${lang}" is not supported and no custom grammar provided. ` + + `[CodeHighlight] Language "${lang}" is not supported and no custom grammar provided. ` + `Highlighting disabled. Supported: ${langs}`, ); } diff --git a/src/lib/code_sample.ts b/src/lib/code_sample.ts index 5a17e308..07e2e218 100644 --- a/src/lib/code_sample.ts +++ b/src/lib/code_sample.ts @@ -1,4 +1,4 @@ -export interface Code_Sample { +export interface CodeSample { name: string; lang: string; content: string; @@ -7,4 +7,4 @@ export interface Code_Sample { // Languages ordered from simple to complex export const sample_langs = ['json', 'css', 'ts', 'html', 'svelte', 'md'] as const; -export type Sample_Lang = (typeof sample_langs)[number]; +export type SampleLang = (typeof sample_langs)[number]; diff --git a/src/lib/grammar_clike.ts b/src/lib/grammar_clike.ts index b93bde7e..3acbb6d6 100644 --- a/src/lib/grammar_clike.ts +++ b/src/lib/grammar_clike.ts @@ -1,4 +1,4 @@ -import type {Add_Syntax_Grammar, Syntax_Grammar_Raw} from './syntax_styler.js'; +import type {AddSyntaxGrammar, SyntaxGrammarRaw} from './syntax_styler.js'; export const class_keywords = 'class|extends|implements|instanceof|interface|new'; @@ -10,7 +10,7 @@ export const class_keywords = 'class|extends|implements|instanceof|interface|new * * @see LICENSE */ -export const add_grammar_clike: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_clike: AddSyntaxGrammar = (syntax_styler) => { const grammar_clike = { comment: [ { @@ -42,7 +42,7 @@ export const add_grammar_clike: Add_Syntax_Grammar = (syntax_styler) => { number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, punctuation: /[{}[\];(),.:]/, - } satisfies Syntax_Grammar_Raw; + } satisfies SyntaxGrammarRaw; syntax_styler.add_lang('clike', grammar_clike); }; diff --git a/src/lib/grammar_css.ts b/src/lib/grammar_css.ts index 23dbdec1..7a4b37f8 100644 --- a/src/lib/grammar_css.ts +++ b/src/lib/grammar_css.ts @@ -1,4 +1,4 @@ -import type {Add_Syntax_Grammar, Syntax_Grammar_Raw} from './syntax_styler.js'; +import type {AddSyntaxGrammar, SyntaxGrammarRaw} from './syntax_styler.js'; import {grammar_markup_add_attribute, grammar_markup_add_inlined} from './grammar_markup.js'; var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/; @@ -11,7 +11,7 @@ var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\ * * @see LICENSE */ -export const add_grammar_css: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_css: AddSyntaxGrammar = (syntax_styler) => { const grammar_css = { comment: /\/\*[\s\S]*?\*\//, atrule: { @@ -35,7 +35,7 @@ export const add_grammar_css: Add_Syntax_Grammar = (syntax_styler) => { pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/, lookbehind: true, }, - } as Syntax_Grammar_Raw, // see `rest` below + } as SyntaxGrammarRaw, // see `rest` below }, url: { // https://drafts.csswg.org/css-values-3/#urls @@ -73,7 +73,7 @@ export const add_grammar_css: Add_Syntax_Grammar = (syntax_styler) => { lookbehind: true, }, punctuation: /[(){};:,]/, - } satisfies Syntax_Grammar_Raw; + } satisfies SyntaxGrammarRaw; grammar_css.atrule.inside.rest = grammar_css; diff --git a/src/lib/grammar_js.ts b/src/lib/grammar_js.ts index c5d76ced..2fafa8c5 100644 --- a/src/lib/grammar_js.ts +++ b/src/lib/grammar_js.ts @@ -1,4 +1,4 @@ -import type {Add_Syntax_Grammar} from './syntax_styler.js'; +import type {AddSyntaxGrammar} from './syntax_styler.js'; import {grammar_markup_add_attribute, grammar_markup_add_inlined} from './grammar_markup.js'; import {class_keywords} from './grammar_clike.js'; @@ -10,7 +10,7 @@ import {class_keywords} from './grammar_clike.js'; * * @see LICENSE */ -export const add_grammar_js: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_js: AddSyntaxGrammar = (syntax_styler) => { const grammar_clike = syntax_styler.get_lang('clike'); // Main JS keywords (from keyword pattern, excluding those with special lookaheads) diff --git a/src/lib/grammar_json.ts b/src/lib/grammar_json.ts index e10bf0c7..aecb2b5a 100644 --- a/src/lib/grammar_json.ts +++ b/src/lib/grammar_json.ts @@ -1,4 +1,4 @@ -import type {Add_Syntax_Grammar, Syntax_Grammar_Raw} from './syntax_styler.js'; +import type {AddSyntaxGrammar, SyntaxGrammarRaw} from './syntax_styler.js'; /** * Based on Prism (https://github.com/PrismJS/prism) @@ -8,7 +8,7 @@ import type {Add_Syntax_Grammar, Syntax_Grammar_Raw} from './syntax_styler.js'; * * @see LICENSE */ -export const add_grammar_json: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_json: AddSyntaxGrammar = (syntax_styler) => { const grammar_json = { property: { pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/, @@ -32,7 +32,7 @@ export const add_grammar_json: Add_Syntax_Grammar = (syntax_styler) => { pattern: /\bnull\b/, alias: 'keyword', }, - } satisfies Syntax_Grammar_Raw; + } satisfies SyntaxGrammarRaw; syntax_styler.add_lang('json', grammar_json); }; diff --git a/src/lib/grammar_markdown.ts b/src/lib/grammar_markdown.ts index acf7bec8..901d28ed 100644 --- a/src/lib/grammar_markdown.ts +++ b/src/lib/grammar_markdown.ts @@ -1,16 +1,16 @@ import type { - Add_Syntax_Grammar, - Syntax_Grammar_Token_Raw, - Syntax_Grammar_Value_Raw, - Syntax_Styler, + AddSyntaxGrammar, + SyntaxGrammarTokenRaw, + SyntaxGrammarValueRaw, + SyntaxStyler, } from './syntax_styler.js'; -interface Lang_Definition { +interface LangDefinition { aliases: Array; id: string; } -interface Fence_Type { +interface FenceType { backticks: string; suffix: string; } @@ -22,8 +22,8 @@ const create_fence_pattern = ( backticks: string, aliases: Array, lang_id: string, - syntax_styler: Syntax_Styler, -): Syntax_Grammar_Token_Raw => { + syntax_styler: SyntaxStyler, +): SyntaxGrammarTokenRaw => { const aliases_pattern = aliases.join('|'); const pattern = new RegExp( `^${backticks}(?:${aliases_pattern})[^\\n\\r]*(?:\\r?\\n|\\r)[\\s\\S]*?^${backticks}$`, @@ -50,7 +50,7 @@ const create_fence_pattern = ( /** * Helper to create catch-all fence pattern (unknown languages) */ -const create_catchall_fence = (backticks: string): Syntax_Grammar_Token_Raw => { +const create_catchall_fence = (backticks: string): SyntaxGrammarTokenRaw => { const pattern = new RegExp(`^${backticks}[^\\n\\r]*(?:\\r?\\n|\\r)[\\s\\S]*?^${backticks}$`, 'm'); const code_fence_pattern = new RegExp(`^${backticks}[^\\n\\r]*|^${backticks}$`, 'm'); @@ -69,7 +69,7 @@ const create_catchall_fence = (backticks: string): Syntax_Grammar_Token_Raw => { /** * Helper to create md self-reference placeholder pattern */ -const create_md_placeholder = (backticks: string): Syntax_Grammar_Token_Raw => { +const create_md_placeholder = (backticks: string): SyntaxGrammarTokenRaw => { const pattern = new RegExp( `^${backticks}(?:md|markdown)[^\\n\\r]*(?:\\r?\\n|\\r)[\\s\\S]*?^${backticks}$`, 'm', @@ -94,9 +94,9 @@ const create_md_placeholder = (backticks: string): Syntax_Grammar_Token_Raw => { * Supports: headings, fenced code blocks (3/4/5 backticks with nesting), lists, blockquotes, * bold, italic, strikethrough, inline code, and links. */ -export const add_grammar_markdown: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_markdown: AddSyntaxGrammar = (syntax_styler) => { // Language definitions with aliases - const langs: Array = [ + const langs: Array = [ {aliases: ['ts', 'typescript'], id: 'ts'}, {aliases: ['js', 'javascript'], id: 'js'}, {aliases: ['css'], id: 'css'}, @@ -106,14 +106,14 @@ export const add_grammar_markdown: Add_Syntax_Grammar = (syntax_styler) => { ]; // Fence types: higher counts first (for proper precedence in tokenization) - const fence_types: Array = [ + const fence_types: Array = [ {backticks: '`````', suffix: '5tick'}, {backticks: '````', suffix: '4tick'}, {backticks: '```', suffix: ''}, ]; // Build grammar dynamically - const grammar: Record = {}; + const grammar: Record = {}; const md_self_refs: Array = []; // Track md patterns for later self-reference // Generate fence patterns for each type @@ -273,7 +273,7 @@ export const add_grammar_markdown: Add_Syntax_Grammar = (syntax_styler) => { inside: syntax_styler.get_lang('md'), }; for (const key of md_self_refs) { - // After normalization, grammar values are arrays of Syntax_Grammar_Token + // After normalization, grammar values are arrays of SyntaxGrammarToken // We need to add lang_md as a normalized array const patterns = grammar_md[key]!; // Manually normalize the lang_md pattern we're adding diff --git a/src/lib/grammar_markup.ts b/src/lib/grammar_markup.ts index e1bd1354..7b565000 100644 --- a/src/lib/grammar_markup.ts +++ b/src/lib/grammar_markup.ts @@ -1,9 +1,9 @@ import type { - Syntax_Styler, - Add_Syntax_Grammar, - Syntax_Grammar_Raw, - Syntax_Grammar_Token, - Syntax_Grammar, + SyntaxStyler, + AddSyntaxGrammar, + SyntaxGrammarRaw, + SyntaxGrammarToken, + SyntaxGrammar, } from './syntax_styler.js'; /** @@ -14,7 +14,7 @@ import type { * * @see LICENSE */ -export const add_grammar_markup: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_markup: AddSyntaxGrammar = (syntax_styler) => { const grammar_markup = { comment: { pattern: //, @@ -85,7 +85,7 @@ export const add_grammar_markup: Add_Syntax_Grammar = (syntax_styler) => { }, /&#x?[\da-f]{1,8};/i, ], - } satisfies Syntax_Grammar_Raw; + } satisfies SyntaxGrammarRaw; grammar_markup.tag.inside.attr_value.inside.entity = grammar_markup.entity; @@ -103,7 +103,7 @@ export const add_grammar_markup: Add_Syntax_Grammar = (syntax_styler) => { * @param lang - The language key. */ export const grammar_markup_add_inlined = ( - syntax_styler: Syntax_Styler, + syntax_styler: SyntaxStyler, tag_name: string, lang: string, inside_lang = 'markup', @@ -154,11 +154,11 @@ export const grammar_markup_add_inlined = ( * @param lang - The language key. */ export const grammar_markup_add_attribute = ( - syntax_styler: Syntax_Styler, + syntax_styler: SyntaxStyler, attr_name: string, lang: string, ): void => { - // After normalization, grammar.tag is an array of Syntax_Grammar_Token + // After normalization, grammar.tag is an array of SyntaxGrammarToken const markup_grammar = syntax_styler.get_lang('markup'); const tag_patterns = markup_grammar.tag; const tag_inside = tag_patterns![0]!.inside!; @@ -217,9 +217,9 @@ export const grammar_markup_add_attribute = ( inside: null, }, ], - } as Syntax_Grammar, + } as SyntaxGrammar, }, ], - } as Syntax_Grammar, - } satisfies Syntax_Grammar_Token); + } as SyntaxGrammar, + } satisfies SyntaxGrammarToken); }; diff --git a/src/lib/grammar_svelte.ts b/src/lib/grammar_svelte.ts index b7694d3e..a80b192a 100644 --- a/src/lib/grammar_svelte.ts +++ b/src/lib/grammar_svelte.ts @@ -1,4 +1,4 @@ -import type {Add_Syntax_Grammar, Syntax_Styler} from './syntax_styler.js'; +import type {AddSyntaxGrammar, SyntaxStyler} from './syntax_styler.js'; import {grammar_markup_add_inlined} from './grammar_markup.js'; const blocks = '(if|else if|else|await|then|catch|each|html|debug|snippet)'; @@ -11,7 +11,7 @@ const blocks = '(if|else if|else|await|then|catch|each|html|debug|snippet)'; * * @see LICENSE */ -export const add_grammar_svelte: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_svelte: AddSyntaxGrammar = (syntax_styler) => { const grammar_ts = syntax_styler.get_lang('ts'); // Define the at_directive pattern once for reuse (matches any @word) @@ -146,7 +146,7 @@ export const add_grammar_svelte: Add_Syntax_Grammar = (syntax_styler) => { }); // oof lol - // After normalization, grammar.tag is an array of Syntax_Grammar_Token + // After normalization, grammar.tag is an array of SyntaxGrammarToken const tag_patterns = grammar_svelte.tag as any; const tag_inside = tag_patterns[0].inside; tag_inside.attr_value[0].inside.entity = grammar_svelte.entity; @@ -157,7 +157,7 @@ export const add_grammar_svelte: Add_Syntax_Grammar = (syntax_styler) => { }; export const grammar_svelte_add_inlined = ( - syntax_styler: Syntax_Styler, + syntax_styler: SyntaxStyler, tag_name: string, lang: string, ): void => { diff --git a/src/lib/grammar_ts.ts b/src/lib/grammar_ts.ts index dc74a21f..acf04055 100644 --- a/src/lib/grammar_ts.ts +++ b/src/lib/grammar_ts.ts @@ -1,4 +1,4 @@ -import type {Add_Syntax_Grammar} from './syntax_styler.js'; +import type {AddSyntaxGrammar} from './syntax_styler.js'; import {class_keywords} from './grammar_clike.js'; /** @@ -9,7 +9,7 @@ import {class_keywords} from './grammar_clike.js'; * * @see LICENSE */ -export const add_grammar_ts: Add_Syntax_Grammar = (syntax_styler) => { +export const add_grammar_ts: AddSyntaxGrammar = (syntax_styler) => { const grammar_ts = syntax_styler.add_extended_lang( 'js', 'ts', diff --git a/src/lib/highlight_manager.ts b/src/lib/highlight_manager.ts index bdc906c4..816868fb 100644 --- a/src/lib/highlight_manager.ts +++ b/src/lib/highlight_manager.ts @@ -1,7 +1,7 @@ -import type {Syntax_Token_Stream} from './syntax_token.js'; +import type {SyntaxTokenStream} from './syntax_token.js'; import {highlight_priorities} from './highlight_priorities.js'; -export type Highlight_Mode = 'auto' | 'ranges' | 'html'; +export type HighlightMode = 'auto' | 'ranges' | 'html'; /** * Check for CSS Highlights API support. @@ -13,7 +13,7 @@ export const supports_css_highlight_api = (): boolean => * Manages highlights for a single element. * Tracks ranges per element and only removes its own ranges when clearing. */ -export class Highlight_Manager { +export class HighlightManager { element_ranges: Map>; constructor() { @@ -26,7 +26,7 @@ export class Highlight_Manager { /** * Highlight from syntax styler token stream. */ - highlight_from_syntax_tokens(element: Element, tokens: Syntax_Token_Stream): void { + highlight_from_syntax_tokens(element: Element, tokens: SyntaxTokenStream): void { // Find the text node (it might not be firstChild due to Svelte comment nodes) let text_node: Node | null = null; for (const node of element.childNodes) { @@ -106,7 +106,7 @@ export class Highlight_Manager { * Create ranges for all tokens in the tree. */ #create_all_ranges( - tokens: Syntax_Token_Stream, + tokens: SyntaxTokenStream, text_node: Node, ranges_by_type: Map>, offset: number, diff --git a/src/lib/highlight_priorities.gen.ts b/src/lib/highlight_priorities.gen.ts index d752f9d9..c30352f8 100644 --- a/src/lib/highlight_priorities.gen.ts +++ b/src/lib/highlight_priorities.gen.ts @@ -58,9 +58,9 @@ export const gen: Gen = { return ` ${banner} - export type Highlight_Token_Name = ${token_names}; + export type HighlightTokenName = ${token_names}; - export const highlight_priorities: Record = { + export const highlight_priorities: Record = { ${priority_entries}, } as const; diff --git a/src/lib/highlight_priorities.ts b/src/lib/highlight_priorities.ts index f74e3b62..b7338151 100644 --- a/src/lib/highlight_priorities.ts +++ b/src/lib/highlight_priorities.ts @@ -1,6 +1,6 @@ // generated by src/lib/highlight_priorities.gen.ts - DO NOT EDIT OR RISK LOST DATA -export type Highlight_Token_Name = +export type HighlightTokenName = | 'token_processing_instruction' | 'token_doctype' | 'token_cdata' @@ -53,7 +53,7 @@ export type Highlight_Token_Name = | 'token_bold' | 'token_italic'; -export const highlight_priorities: Record = { +export const highlight_priorities: Record = { token_processing_instruction: 1, token_doctype: 1, token_cdata: 1, diff --git a/src/lib/syntax_styler.ts b/src/lib/syntax_styler.ts index cf2fc447..9e9a21ff 100644 --- a/src/lib/syntax_styler.ts +++ b/src/lib/syntax_styler.ts @@ -1,7 +1,7 @@ -import {Syntax_Token, type Syntax_Token_Stream} from './syntax_token.js'; +import {SyntaxToken, type SyntaxTokenStream} from './syntax_token.js'; import {tokenize_syntax} from './tokenize_syntax.js'; -export type Add_Syntax_Grammar = (syntax_styler: Syntax_Styler) => void; +export type AddSyntaxGrammar = (syntax_styler: SyntaxStyler) => void; /** * Based on Prism (https://github.com/PrismJS/prism) @@ -11,18 +11,18 @@ export type Add_Syntax_Grammar = (syntax_styler: Syntax_Styler) => void; * * @see LICENSE */ -export class Syntax_Styler { - langs: Record = { +export class SyntaxStyler { + langs: Record = { plaintext: {}, }; // constructor() { // TODO this API? problem is the grammars rely on mutating existing grammars in the `syntax_styler`, // so for now adding grammars will remain inherently stateful - // export interface Syntax_Styler_Options { - // grammars?: Add_Grammar[]; + // export interface SyntaxStylerOptions { + // grammars?: AddGrammar[]; // } - // options: Syntax_Styler_Options = {} + // options: SyntaxStylerOptions = {} // const {grammars} = options; // if (grammars) { // for (const add_grammar of grammars) { @@ -32,12 +32,12 @@ export class Syntax_Styler { // } // } - add_lang(id: string, grammar: Syntax_Grammar_Raw, aliases?: Array): void { + add_lang(id: string, grammar: SyntaxGrammarRaw, aliases?: Array): void { // Normalize grammar once at registration for optimal runtime performance // Use a visited set to handle circular references this.normalize_grammar(grammar, new Set()); - // After normalization, grammar has the shape of Syntax_Grammar - const normalized = grammar as unknown as Syntax_Grammar; + // After normalization, grammar has the shape of SyntaxGrammar + const normalized = grammar as unknown as SyntaxGrammar; this.langs[id] = normalized; if (aliases !== undefined) { for (var alias of aliases) { @@ -49,9 +49,9 @@ export class Syntax_Styler { add_extended_lang( base_id: string, extension_id: string, - extension: Syntax_Grammar_Raw, + extension: SyntaxGrammarRaw, aliases?: Array, - ): Syntax_Grammar { + ): SyntaxGrammar { // extend_grammar returns already normalized grammar var grammar = this.extend_grammar(base_id, extension); // Store the normalized grammar directly @@ -64,7 +64,7 @@ export class Syntax_Styler { return grammar; } - get_lang(id: string): Syntax_Grammar { + get_lang(id: string): SyntaxGrammar { var lang = this.langs[id]; if (lang === undefined) { throw Error(`The language "${id}" has no grammar.`); @@ -120,16 +120,16 @@ export class Syntax_Styler { stylize( text: string, lang: string, - grammar: Syntax_Grammar | undefined = this.get_lang(lang), + grammar: SyntaxGrammar | undefined = this.get_lang(lang), ): string { - var ctx: Hook_Before_Tokenize_Callback_Context = { + var ctx: HookBeforeTokenizeCallbackContext = { code: text, grammar, lang, tokens: undefined, }; this.run_hook_before_tokenize(ctx); - const c = ctx as any as Hook_After_Tokenize_Callback_Context; + const c = ctx as any as HookAfterTokenizeCallbackContext; c.tokens = tokenize_syntax(c.code, c.grammar); this.run_hook_after_tokenize(c); return this.stringify_token(c.tokens, c.lang); @@ -213,11 +213,11 @@ export class Syntax_Styler { grammar_insert_before( inside: string, before: string, - insert: Syntax_Grammar_Raw, + insert: SyntaxGrammarRaw, root: Record = this.langs, - ): Syntax_Grammar { + ): SyntaxGrammar { var grammar = root[inside]; - var updated: Syntax_Grammar_Raw = {}; + var updated: SyntaxGrammarRaw = {}; for (var token in grammar) { if (token === before) { @@ -235,8 +235,8 @@ export class Syntax_Styler { // Normalize the updated grammar to ensure inserted patterns have consistent shape this.normalize_grammar(updated, new Set()); - // After normalization, cast to Syntax_Grammar - const normalized = updated as unknown as Syntax_Grammar; + // After normalization, cast to SyntaxGrammar + const normalized = updated as unknown as SyntaxGrammar; var old = root[inside]; root[inside] = normalized; @@ -253,13 +253,13 @@ export class Syntax_Styler { /** * Converts the given token or token stream to an HTML representation. * - * Runs the `wrap` hook on each `Syntax_Token`. + * Runs the `wrap` hook on each `SyntaxToken`. * * @param o - The token or token stream to be converted. * @param lang - The name of current language. * @returns The HTML representation of the token or token stream. */ - stringify_token(o: string | Syntax_Token | Syntax_Token_Stream, lang: string): string { + stringify_token(o: string | SyntaxToken | SyntaxTokenStream, lang: string): string { if (typeof o === 'string') { return o .replace(/&/g, '&') @@ -274,7 +274,7 @@ export class Syntax_Styler { return s; } - var ctx: Hook_Wrap_Callback_Context = { + var ctx: HookWrapCallbackContext = { type: o.type, content: this.stringify_token(o.content, lang), tag: 'span', @@ -330,13 +330,13 @@ export class Syntax_Styler { * @param extension - The new tokens to append. * @returns the new grammar */ - extend_grammar(base_id: string, extension: Syntax_Grammar_Raw): Syntax_Grammar { + extend_grammar(base_id: string, extension: SyntaxGrammarRaw): SyntaxGrammar { // Merge normalized base with un-normalized extension const extended = {...structuredClone(this.get_lang(base_id)), ...extension}; // Normalize the extension parts - this.normalize_grammar(extended as Syntax_Grammar_Raw, new Set()); - // Return as Syntax_Grammar - return extended as unknown as Syntax_Grammar; + this.normalize_grammar(extended as SyntaxGrammarRaw, new Set()); + // Return as SyntaxGrammar + return extended as unknown as SyntaxGrammar; } /** @@ -344,9 +344,9 @@ export class Syntax_Styler { * This ensures all patterns have the same object shape for V8 optimization. */ private normalize_pattern( - pattern: RegExp | Syntax_Grammar_Token_Raw, + pattern: RegExp | SyntaxGrammarTokenRaw, visited: Set, - ): Syntax_Grammar_Token { + ): SyntaxGrammarToken { const p = pattern instanceof RegExp ? {pattern} : pattern; let regex = p.pattern; @@ -364,11 +364,11 @@ export class Syntax_Styler { } // Recursively normalize the inside grammar if present - let normalized_inside: Syntax_Grammar | null = null; + let normalized_inside: SyntaxGrammar | null = null; if (p.inside) { this.normalize_grammar(p.inside, visited); - // After normalization, cast to Syntax_Grammar - normalized_inside = p.inside as unknown as Syntax_Grammar; + // After normalization, cast to SyntaxGrammar + normalized_inside = p.inside as unknown as SyntaxGrammar; } return { @@ -391,7 +391,7 @@ export class Syntax_Styler { * This is called once at registration time to avoid runtime overhead. * @param visited - Set of grammar object IDs already normalized (for circular references) */ - private normalize_grammar(grammar: Syntax_Grammar_Raw, visited: Set): void { + private normalize_grammar(grammar: SyntaxGrammarRaw, visited: Set): void { // Check if we've already normalized this grammar (circular reference) const grammar_id = id_of(grammar); if (visited.has(grammar_id)) { @@ -430,44 +430,44 @@ export class Syntax_Styler { plugins: Record = {}; // TODO maybe extend/compose an event listener? - hooks_before_tokenize: Array = []; - hooks_after_tokenize: Array = []; - hooks_wrap: Array = []; + hooks_before_tokenize: Array = []; + hooks_after_tokenize: Array = []; + hooks_wrap: Array = []; - add_hook_before_tokenize(cb: Hook_Before_Tokenize_Callback): void { + add_hook_before_tokenize(cb: HookBeforeTokenizeCallback): void { this.hooks_before_tokenize.push(cb); } - add_hook_after_tokenize(cb: Hook_After_Tokenize_Callback): void { + add_hook_after_tokenize(cb: HookAfterTokenizeCallback): void { this.hooks_after_tokenize.push(cb); } - add_hook_wrap(cb: Hook_Wrap_Callback): void { + add_hook_wrap(cb: HookWrapCallback): void { this.hooks_wrap.push(cb); } - run_hook_before_tokenize(ctx: Hook_Before_Tokenize_Callback_Context): void { + run_hook_before_tokenize(ctx: HookBeforeTokenizeCallbackContext): void { for (var cb of this.hooks_before_tokenize) { cb(ctx); } } - run_hook_after_tokenize(ctx: Hook_After_Tokenize_Callback_Context): void { + run_hook_after_tokenize(ctx: HookAfterTokenizeCallbackContext): void { for (var cb of this.hooks_after_tokenize) { cb(ctx); } } - run_hook_wrap(ctx: Hook_Wrap_Callback_Context): void { + run_hook_wrap(ctx: HookWrapCallbackContext): void { for (var cb of this.hooks_wrap) { cb(ctx); } } } -export type Syntax_Grammar_Value_Raw = +export type SyntaxGrammarValueRaw = | RegExp - | Syntax_Grammar_Token_Raw - | Array; + | SyntaxGrammarTokenRaw + | Array; -export type Syntax_Grammar_Raw = Record & { - rest?: Syntax_Grammar_Raw | undefined; +export type SyntaxGrammarRaw = Record & { + rest?: SyntaxGrammarRaw | undefined; }; /** @@ -483,7 +483,7 @@ export type Syntax_Grammar_Raw = Record; - inside: Syntax_Grammar | null; + inside: SyntaxGrammar | null; } /** * A grammar after normalization. * All values are arrays of normalized tokens with consistent shapes. */ -export type Syntax_Grammar = Record>; +export type SyntaxGrammar = Record>; const depth_first_search = ( o: any, @@ -549,23 +549,23 @@ const depth_first_search = ( } }; -export type Hook_Before_Tokenize_Callback = (ctx: Hook_Before_Tokenize_Callback_Context) => void; -export type Hook_After_Tokenize_Callback = (ctx: Hook_After_Tokenize_Callback_Context) => void; -export type Hook_Wrap_Callback = (ctx: Hook_Wrap_Callback_Context) => void; +export type HookBeforeTokenizeCallback = (ctx: HookBeforeTokenizeCallbackContext) => void; +export type HookAfterTokenizeCallback = (ctx: HookAfterTokenizeCallbackContext) => void; +export type HookWrapCallback = (ctx: HookWrapCallbackContext) => void; -export interface Hook_Before_Tokenize_Callback_Context { +export interface HookBeforeTokenizeCallbackContext { code: string; - grammar: Syntax_Grammar; + grammar: SyntaxGrammar; lang: string; tokens: undefined; } -export interface Hook_After_Tokenize_Callback_Context { +export interface HookAfterTokenizeCallbackContext { code: string; - grammar: Syntax_Grammar; + grammar: SyntaxGrammar; lang: string; - tokens: Syntax_Token_Stream; + tokens: SyntaxTokenStream; } -export interface Hook_Wrap_Callback_Context { +export interface HookWrapCallbackContext { type: string; content: string; tag: string; diff --git a/src/lib/syntax_styler_global.ts b/src/lib/syntax_styler_global.ts index 5279786c..a1e5d778 100644 --- a/src/lib/syntax_styler_global.ts +++ b/src/lib/syntax_styler_global.ts @@ -1,4 +1,4 @@ -import {Syntax_Styler} from './syntax_styler.js'; +import {SyntaxStyler} from './syntax_styler.js'; import {add_grammar_markup} from './grammar_markup.js'; import {add_grammar_css} from './grammar_css.js'; import {add_grammar_clike} from './grammar_clike.js'; @@ -8,7 +8,7 @@ import {add_grammar_svelte} from './grammar_svelte.js'; import {add_grammar_json} from './grammar_json.js'; import {add_grammar_markdown} from './grammar_markdown.js'; -export const syntax_styler_global = new Syntax_Styler(); +export const syntax_styler_global = new SyntaxStyler(); add_grammar_markup(syntax_styler_global); add_grammar_css(syntax_styler_global); diff --git a/src/lib/syntax_token.ts b/src/lib/syntax_token.ts index d83b02b3..1f2882cd 100644 --- a/src/lib/syntax_token.ts +++ b/src/lib/syntax_token.ts @@ -1,4 +1,4 @@ -export class Syntax_Token { +export class SyntaxToken { /** * The type of the token. * @@ -11,7 +11,7 @@ export class Syntax_Token { * * This will be a token stream if the pattern matched also defined an `inside` grammar. */ - content: string | Syntax_Token_Stream; + content: string | SyntaxTokenStream; /** * The alias(es) of the token. @@ -23,7 +23,7 @@ export class Syntax_Token { constructor( type: string, - content: string | Syntax_Token_Stream, + content: string | SyntaxTokenStream, alias: string | Array | undefined, matched_str: string = '', ) { @@ -36,7 +36,7 @@ export class Syntax_Token { } /** - * A token stream is an array of strings and `Syntax_Token` objects. + * A token stream is an array of strings and `SyntaxToken` objects. * * Syntax token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process * them. @@ -46,4 +46,4 @@ export class Syntax_Token { * * The only exception here is the token stream that only contains the empty string and nothing else. */ -export type Syntax_Token_Stream = Array; +export type SyntaxTokenStream = Array; diff --git a/src/lib/tokenize_syntax.ts b/src/lib/tokenize_syntax.ts index bf466def..3ffd55d0 100644 --- a/src/lib/tokenize_syntax.ts +++ b/src/lib/tokenize_syntax.ts @@ -1,5 +1,5 @@ -import type {Syntax_Grammar} from './syntax_styler.js'; -import {Syntax_Token, type Syntax_Token_Stream} from './syntax_token.js'; +import type {SyntaxGrammar} from './syntax_styler.js'; +import {SyntaxToken, type SyntaxTokenStream} from './syntax_token.js'; /** * Accepts a string of text as input and the language definitions to use, @@ -18,16 +18,16 @@ import {Syntax_Token, type Syntax_Token_Stream} from './syntax_token.js'; * * @example * var code = `var foo = 0;`; - * var tokens = tokenize_syntax(code, Syntax_Styler.langs.js); + * var tokens = tokenize_syntax(code, SyntaxStyler.langs.js); * for (var token of tokens) { - * if (token instanceof Syntax_Token && token.type === 'number') { + * if (token instanceof SyntaxToken && token.type === 'number') { * console.log(`Found numeric literal: ${token.content}`); * } * } */ -export const tokenize_syntax = (text: string, grammar: Syntax_Grammar): Syntax_Token_Stream => { +export const tokenize_syntax = (text: string, grammar: SyntaxGrammar): SyntaxTokenStream => { // Grammar is already normalized (rest merged, patterns in arrays, etc.) - var token_list = new Linked_List(); + var token_list = new LinkedList(); add_after(token_list, token_list.head, text); match_grammar(text, token_list, grammar, token_list.head, 0); @@ -35,18 +35,18 @@ export const tokenize_syntax = (text: string, grammar: Syntax_Grammar): Syntax_T return to_array(token_list); }; -interface Rematch_Options { +interface RematchOptions { cause: string; reach: number; } const match_grammar = ( text: string, - token_list: Linked_List, - grammar: Syntax_Grammar, - start_node: Linked_List_Node, + token_list: LinkedList, + grammar: SyntaxGrammar, + start_node: LinkedListNode, start_pos: number, - rematch?: Rematch_Options, + rematch?: RematchOptions, ): void => { for (var token in grammar) { // Grammar is normalized: patterns is always an array of normalized objects @@ -88,7 +88,7 @@ const match_grammar = ( return; } - if (str instanceof Syntax_Token) { + if (str instanceof SyntaxToken) { continue; } @@ -116,7 +116,7 @@ const match_grammar = ( pos = p; // the current node is a Token, then the match starts inside another Token, which is invalid - if (current_node!.value instanceof Syntax_Token) { + if (current_node!.value instanceof SyntaxToken) { continue; } @@ -160,7 +160,7 @@ const match_grammar = ( remove_range(token_list, remove_from!, remove_count); - var wrapped = new Syntax_Token( + var wrapped = new SyntaxToken( token, inside ? tokenize_syntax(match_str, inside) : match_str, alias, @@ -176,7 +176,7 @@ const match_grammar = ( // at least one Token object was removed, so we have to do some rematching // this can only happen if the current pattern is greedy - var nested_rematch: Rematch_Options = { + var nested_rematch: RematchOptions = { cause: token + ',' + j, reach, }; @@ -192,9 +192,9 @@ const match_grammar = ( } }; -class Linked_List { - head: Linked_List_Node; - tail: Linked_List_Node; +class LinkedList { + head: LinkedListNode; + tail: LinkedListNode; length: number = 0; constructor() { @@ -204,20 +204,20 @@ class Linked_List { } } -interface Linked_List_Node { +interface LinkedListNode { value: T | null; - prev: Linked_List_Node | null; - next: Linked_List_Node | null; + prev: LinkedListNode | null; + next: LinkedListNode | null; } /** * Adds a new node with the given value to the list. */ const add_after = ( - list: Linked_List, - node: Linked_List_Node, + list: LinkedList, + node: LinkedListNode, value: T, -): Linked_List_Node => { +): LinkedListNode => { // assumes that node != list.tail && values.length >= 0 var next = node.next!; @@ -232,7 +232,7 @@ const add_after = ( /** * Removes `count` nodes after the given node. The given node will not be removed. */ -const remove_range = (list: Linked_List, node: Linked_List_Node, count: number) => { +const remove_range = (list: LinkedList, node: LinkedListNode, count: number) => { var next = node.next; for (var i = 0; i < count && next !== list.tail; i++) { next = next!.next; @@ -242,7 +242,7 @@ const remove_range = (list: Linked_List, node: Linked_List_Node, count: list.length -= i; }; -const to_array = (list: Linked_List): Array => { +const to_array = (list: LinkedList): Array => { var array = []; var node = list.head.next; while (node !== list.tail) { diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index fcba0780..c9078a01 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,11 +1,11 @@ - +

Usage

The - + Svelte component supports syntax styling originally based on Prism by Lea Verou. @@ -30,7 +30,7 @@ content="// +layout.svelte import '@ryanatkn/fuz_code/theme.css'; // add this" /> -

then use :

+

then use :

\n\t// Something.svelte\n\timport Code from '@ryanatkn/fuz_code/Code.svelte';\n\n\n`} @@ -56,7 +56,7 @@ import '@ryanatkn/fuz_code/theme_variables.css'; // also this if not using Moss"

Caveats

The Code component generates HTML with CSS classes for text highlighting. It also - includes experimental support for the CSS Custom Highlight API with Code_Highlight, + includes experimental support for the CSS Custom Highlight API with CodeHighlight, see the samples for more. @@ -70,7 +70,7 @@ import '@ryanatkn/fuz_code/theme_variables.css'; // also this if not using Moss"

Svelte support

- styles + styles Svelte by default, originally based on prism-svelte @@ -97,7 +97,7 @@ import '@ryanatkn/fuz_code/theme_variables.css'; // also this if not using Moss"

TypeScript support

- supports TypeScript with lang="ts": + supports TypeScript with lang="ts":

`} /> @@ -109,7 +109,7 @@ import '@ryanatkn/fuz_code/theme_variables.css'; // also this if not using Moss"

Markdown support

- supports Markdown with lang="md", and fenced blocks for + supports Markdown with lang="md", and fenced blocks for all languages:

@@ -132,7 +132,7 @@ import '@ryanatkn/fuz_code/theme_variables.css'; // also this if not using Moss"

Layout

- is a block by default: + is a block by default:

ab
ab
'} /> diff --git a/src/routes/Tome_Link.svelte b/src/routes/TomeLink.svelte similarity index 81% rename from src/routes/Tome_Link.svelte rename to src/routes/TomeLink.svelte index 18290977..c201fdae 100644 --- a/src/routes/Tome_Link.svelte +++ b/src/routes/TomeLink.svelte @@ -6,7 +6,7 @@ name: string; extension?: string; // TODO shouldn't be a thing } = $props(); - // TODO confusing overlap with @ryanatkn/fuz/Tome_Link.svelte + // TODO confusing overlap with @ryanatkn/fuz/TomeLink.svelte - import Package_Detail from '@ryanatkn/fuz/Package_Detail.svelte'; + import PackageDetail from '@ryanatkn/fuz/PackageDetail.svelte'; import {pkg_context} from '@ryanatkn/fuz/pkg.svelte.js'; - import Docs_Footer from '@ryanatkn/fuz/Docs_Footer.svelte'; - import Ecosystem_Links_Panel from '@ryanatkn/fuz/Ecosystem_Links_Panel.svelte'; + import DocsFooter from '@ryanatkn/fuz/DocsFooter.svelte'; + import EcosystemLinksPanel from '@ryanatkn/fuz/EcosystemLinksPanel.svelte'; import Breadcrumb from '@ryanatkn/fuz/Breadcrumb.svelte'; const pkg = pkg_context.get(); @@ -17,16 +17,16 @@
- +
- +
- +
{pkg.package_json.glyph}
-
+
diff --git a/src/routes/benchmark/+page.svelte b/src/routes/benchmark/+page.svelte index 51e24155..3597d41c 100644 --- a/src/routes/benchmark/+page.svelte +++ b/src/routes/benchmark/+page.svelte @@ -1,10 +1,10 @@
- {#if Benchmarked_Component && props} - + {#if BenchmarkedComponent && props} + {/if}
diff --git a/src/routes/benchmark/Benchmark_Results.svelte b/src/routes/benchmark/BenchmarkResults.svelte similarity index 88% rename from src/routes/benchmark/Benchmark_Results.svelte rename to src/routes/benchmark/BenchmarkResults.svelte index 3facadba..6197a98e 100644 --- a/src/routes/benchmark/Benchmark_Results.svelte +++ b/src/routes/benchmark/BenchmarkResults.svelte @@ -1,17 +1,17 @@ @@ -86,9 +86,9 @@
- + copy results as markdown - +
diff --git a/src/routes/benchmark/benchmark_fixtures.ts b/src/routes/benchmark/benchmark_fixtures.ts index 7ee10922..92a0655b 100644 --- a/src/routes/benchmark/benchmark_fixtures.ts +++ b/src/routes/benchmark/benchmark_fixtures.ts @@ -1,20 +1,20 @@ import Code from '$lib/Code.svelte'; -import Code_Highlight from '$lib/Code_Highlight.svelte'; -import type {Benchmarked_Implementation} from './benchmark_types.js'; -import type {Code_Sample} from '$lib/code_sample.js'; +import CodeHighlight from '$lib/CodeHighlight.svelte'; +import type {BenchmarkedImplementation} from './benchmark_types.js'; +import type {CodeSample} from '$lib/code_sample.js'; /* eslint-disable no-console */ // Find appropriate sample for a language export const find_sample = ( - samples: Record, + samples: Record, lang: string, -): Code_Sample | undefined => +): CodeSample | undefined => Object.values(samples).find((s) => s.lang === lang && s.name.includes('complex')); // Simple pre-generation using content.repeat() export const pre_generate_large_contents = ( - samples: Record, + samples: Record, langs: ReadonlyArray, multiplier: number, ): Map => { @@ -36,11 +36,11 @@ export const pre_generate_large_contents = ( }; export const implementation_names = ['html', 'ranges'] as const; -export type Implementation_Name = (typeof implementation_names)[number]; +export type ImplementationName = (typeof implementation_names)[number]; -export const implementations: Array = [ +export const implementations: Array = [ {name: 'html', component: Code, mode: null}, - {name: 'ranges', component: Code_Highlight, mode: 'ranges'}, + {name: 'ranges', component: CodeHighlight, mode: 'ranges'}, ]; // Languages to test diff --git a/src/routes/benchmark/benchmark_results.ts b/src/routes/benchmark/benchmark_results.ts index d7fee6cc..90c95e1b 100644 --- a/src/routes/benchmark/benchmark_results.ts +++ b/src/routes/benchmark/benchmark_results.ts @@ -1,17 +1,17 @@ import {fmt} from './benchmark_stats.js'; -import type {Benchmark_Result} from './benchmark_types.js'; +import type {BenchmarkResult} from './benchmark_types.js'; /** * Column definitions for benchmark results table */ -export interface Result_Column { +export interface ResultColumn { header: string; - key: keyof Benchmark_Result; - format: (value: any, result: Benchmark_Result) => string; - class?: (value: any, result: Benchmark_Result) => string; + key: keyof BenchmarkResult; + format: (value: any, result: BenchmarkResult) => string; + class?: (value: any, result: BenchmarkResult) => string; } -export const RESULT_COLUMNS: Array = [ +export const RESULT_COLUMNS: Array = [ { header: 'Language', key: 'language', @@ -76,7 +76,7 @@ export const RESULT_COLUMNS: Array = [ /** * Convert benchmark results to a markdown table */ -export const results_to_markdown = (results: Array): string => { +export const results_to_markdown = (results: Array): string => { if (results.length === 0) return ''; // Header diff --git a/src/routes/benchmark/benchmark_runner.ts b/src/routes/benchmark/benchmark_runner.ts index 01f98af8..4030be85 100644 --- a/src/routes/benchmark/benchmark_runner.ts +++ b/src/routes/benchmark/benchmark_runner.ts @@ -1,14 +1,14 @@ import type { - Benchmarked_Implementation, - Measurement_Data, - Benchmark_Config, - Benchmark_Result, - Progress_Callbacks, - Benchmark_State, - Benchmark_Harness_Controller, - Benchmark_Component_Props, + BenchmarkedImplementation, + MeasurementData, + BenchmarkConfig, + BenchmarkResult, + ProgressCallbacks, + BenchmarkState, + BenchmarkHarnessController, + BenchmarkComponentProps, } from './benchmark_types.js'; -import type {Code_Sample} from '$lib/code_sample.js'; +import type {CodeSample} from '$lib/code_sample.js'; import {inter_test_cooldown} from './benchmark_dom.js'; import { check_system_stability, @@ -29,15 +29,15 @@ const HIGH_OUTLIER_RATIO = 0.2; // Warmup phase using harness with large content export const warmup_phase = async ( - impl: Benchmarked_Implementation, + impl: BenchmarkedImplementation, content: string, lang: string, warmup_count: number, cooldown_ms: number, - harness: Benchmark_Harness_Controller, + harness: BenchmarkHarnessController, ): Promise => { for (let i = 0; i < warmup_count; i++) { - const props: Benchmark_Component_Props = {content, lang}; + const props: BenchmarkComponentProps = {content, lang}; if (impl.mode !== null) { props.mode = impl.mode; } @@ -50,15 +50,15 @@ export const warmup_phase = async ( // Run measurements for a single implementation using harness with large content export const measurement_phase = async ( - impl: Benchmarked_Implementation, + impl: BenchmarkedImplementation, content: string, lang: string, - config: Benchmark_Config, + config: BenchmarkConfig, recent_timings: Array, - harness: Benchmark_Harness_Controller, + harness: BenchmarkHarnessController, on_progress?: () => void, should_stop?: () => boolean, -): Promise => { +): Promise => { const times: Array = []; const stability_checks = []; const timestamps = []; @@ -84,7 +84,7 @@ export const measurement_phase = async ( await extended_cooldown(reason); } - const props: Benchmark_Component_Props = {content, lang}; + const props: BenchmarkComponentProps = {content, lang}; if (impl.mode !== null) { props.mode = impl.mode; } @@ -138,16 +138,16 @@ export const measurement_phase = async ( // Run complete benchmark suite export const run_all_benchmarks = async ( - samples: Record, - config: Benchmark_Config, - harness: Benchmark_Harness_Controller, - callbacks?: Progress_Callbacks, - custom_implementations?: Array, + samples: Record, + config: BenchmarkConfig, + harness: BenchmarkHarnessController, + callbacks?: ProgressCallbacks, + custom_implementations?: Array, custom_languages?: Array, -): Promise => { +): Promise => { const impls = custom_implementations || implementations; const langs = custom_languages || languages; - const results: Array = []; + const results: Array = []; const warnings: Array = []; const recent_timings: Array = []; diff --git a/src/routes/benchmark/benchmark_stability.ts b/src/routes/benchmark/benchmark_stability.ts index 0e7a4acf..8e4c0783 100644 --- a/src/routes/benchmark/benchmark_stability.ts +++ b/src/routes/benchmark/benchmark_stability.ts @@ -1,4 +1,4 @@ -import type {Stability_Check} from './benchmark_types.js'; +import type {StabilityCheck} from './benchmark_types.js'; const MIN_SAMPLES_FOR_JITTER = 5; const RECENT_SAMPLE_COUNT = 10; const MAX_ACCEPTABLE_LAG_MS = 5; @@ -23,7 +23,7 @@ export const calculate_timing_jitter = (recent_timings: Array): number = }; export const check_system_stability = async ( recent_timings: Array, -): Promise => { +): Promise => { const lag_start = performance.now(); await new Promise((resolve) => setTimeout(resolve, 0)); const lag = performance.now() - lag_start; @@ -44,7 +44,7 @@ export const check_system_stability = async ( return {is_stable, lag, memory_pressure, jitter}; }; -export const get_instability_reason = (stability: Stability_Check): string => { +export const get_instability_reason = (stability: StabilityCheck): string => { if (stability.lag > MAX_ACCEPTABLE_LAG_MS) return 'high_lag'; if (stability.jitter > MAX_JITTER_RATIO) return 'high_jitter'; if (stability.memory_pressure && stability.memory_pressure > MAX_MEMORY_PRESSURE) diff --git a/src/routes/benchmark/benchmark_stats.ts b/src/routes/benchmark/benchmark_stats.ts index 78a783f7..b4b8af67 100644 --- a/src/routes/benchmark/benchmark_stats.ts +++ b/src/routes/benchmark/benchmark_stats.ts @@ -1,10 +1,10 @@ // Statistical analysis functions for benchmark results import type { - Benchmark_Result, - Benchmark_Stats, - Measurement_Data, - Summary_Stats, + BenchmarkResult, + BenchmarkStats, + MeasurementData, + SummaryStats, } from './benchmark_types.js'; // Statistical constants @@ -129,7 +129,7 @@ export const detect_outliers = ( }; // Statistical analysis -export const analyze_results = (data: Measurement_Data): Benchmark_Stats => { +export const analyze_results = (data: MeasurementData): BenchmarkStats => { // Filter out invalid values (failed iterations) const valid_times: Array = []; let failed_count = 0; @@ -217,19 +217,19 @@ export const analyze_results = (data: Measurement_Data): Benchmark_Stats => { // Calculate summary across all tests export const calculate_summary = ( - results: Array, -): Record => { - const by_impl: Record> = {}; + results: Array, +): Record => { + const by_impl: Record> = {}; // Group results by implementation for (const result of results) { - if (!(by_impl as Record | undefined>)[result.implementation]) { + if (!(by_impl as Record | undefined>)[result.implementation]) { by_impl[result.implementation] = []; } by_impl[result.implementation]!.push(result); } - const summary: Record = {}; + const summary: Record = {}; // Calculate averages for each implementation for (const [impl, impl_results] of Object.entries(by_impl)) { @@ -259,7 +259,7 @@ export const calculate_summary = ( // Check for high variance export const check_high_variance = ( - results: Array, + results: Array, threshold = 0.15, ): Array => { const warnings: Array = []; diff --git a/src/routes/benchmark/benchmark_types.ts b/src/routes/benchmark/benchmark_types.ts index 71b12212..2c5e6a88 100644 --- a/src/routes/benchmark/benchmark_types.ts +++ b/src/routes/benchmark/benchmark_types.ts @@ -1,14 +1,14 @@ import type {SvelteHTMLElements} from 'svelte/elements'; -import type {Implementation_Name} from './benchmark_fixtures.js'; +import type {ImplementationName} from './benchmark_fixtures.js'; -export type Benchmark_Component_Props = SvelteHTMLElements['code'] & { +export type BenchmarkComponentProps = SvelteHTMLElements['code'] & { content: string; lang: string; mode?: 'html' | 'ranges' | 'auto'; }; -export interface Benchmark_Config { +export interface BenchmarkConfig { iterations: number; warmup_count: number; cooldown_ms: number; @@ -17,26 +17,26 @@ export interface Benchmark_Config { import type {Component} from 'svelte'; -export interface Benchmarked_Implementation { +export interface BenchmarkedImplementation { name: string; - component: Component; + component: Component; mode: 'html' | 'ranges' | 'auto' | null; } -export interface Stability_Check { +export interface StabilityCheck { is_stable: boolean; lag: number; memory_pressure?: number; jitter: number; } -export interface Measurement_Data { +export interface MeasurementData { times: Array; - stability_checks: Array; + stability_checks: Array; timestamps: Array; } -export interface Benchmark_Stats { +export interface BenchmarkStats { mean: number; median: number; std_dev: number; @@ -56,12 +56,12 @@ export interface Benchmark_Stats { failed_iterations: number; } -export interface Benchmark_Result extends Benchmark_Stats { +export interface BenchmarkResult extends BenchmarkStats { implementation: string; language: string; } -export interface Summary_Stats { +export interface SummaryStats { avg_mean: number; avg_ops: number; avg_cv: number; @@ -71,16 +71,16 @@ export interface Summary_Stats { } // Benchmark harness controller interface -export interface Benchmark_Harness_Controller { +export interface BenchmarkHarnessController { run_iteration: ( - component: Component, - props: Benchmark_Component_Props, + component: Component, + props: BenchmarkComponentProps, ) => Promise; cleanup: () => Promise; } // Progress tracking callbacks -export interface Progress_Callbacks { +export interface ProgressCallbacks { on_progress?: (current: number, total: number) => void; on_test_start?: (test: string) => void; on_test_complete?: () => void; @@ -88,8 +88,8 @@ export interface Progress_Callbacks { } // Benchmark runner state -export interface Benchmark_State { - results: Array; +export interface BenchmarkState { + results: Array; warnings: Array; - summary: Record | null; + summary: Record | null; } diff --git a/src/routes/docs/+page.svelte b/src/routes/docs/+page.svelte index d22966d6..8543179b 100644 --- a/src/routes/docs/+page.svelte +++ b/src/routes/docs/+page.svelte @@ -1,5 +1,5 @@
- +
diff --git a/src/routes/docs/api/+page.svelte b/src/routes/docs/api/+page.svelte index c282bbbc..2284175d 100644 --- a/src/routes/docs/api/+page.svelte +++ b/src/routes/docs/api/+page.svelte @@ -1,9 +1,9 @@ - + diff --git a/src/routes/docs/api/[...module_path]/+page.svelte b/src/routes/docs/api/[...module_path]/+page.svelte index 839cc26b..a73992f4 100644 --- a/src/routes/docs/api/[...module_path]/+page.svelte +++ b/src/routes/docs/api/[...module_path]/+page.svelte @@ -1,9 +1,9 @@ - + diff --git a/src/routes/docs/package/+page.svelte b/src/routes/docs/package/+page.svelte index 7b859dc1..42490892 100644 --- a/src/routes/docs/package/+page.svelte +++ b/src/routes/docs/package/+page.svelte @@ -1,6 +1,6 @@ - +
- +
-
+ diff --git a/src/routes/moss.css b/src/routes/moss.css index 050327be..519d3d0c 100644 --- a/src/routes/moss.css +++ b/src/routes/moss.css @@ -7,13 +7,6 @@ justify-content: center; } -/* can be used to override the direction of a `.box` */ -.row { - display: flex; - flex-direction: row; - align-items: center; -} - .ellipsis { display: block; white-space: nowrap; @@ -50,20 +43,6 @@ background-color: var(--panel_bg, var(--fg_1)); } -/* TODO other button variants? */ -/* TODO this is slightly strange that it doesn't use --icon_size */ -/* These are used as modifiers to buttons, and so they use `:where` so they cascade. */ -.icon_button { - width: var(--input_height); - height: var(--input_height); - min-width: var(--input_height); - min-height: var(--input_height); - flex-shrink: 0; - line-height: 1; - font-weight: 900; - padding: 0; -} - /* TODO maybe this belongs with the reset, like `selected`? or does `selected` belong here? */ .plain:not(:hover) { --border_color: transparent; @@ -147,45 +126,22 @@ a.chip { .position_relative { position: relative; } -.position_absolute { - position: absolute; -} -.position_sticky { - position: sticky; -} -.display_block { - display: block; -} .display_inline_block { display: inline-block; } .display_flex { display: flex; } -.flex_1 { - flex: 1; -} .flex_wrap_wrap { flex-wrap: wrap; } .justify_content_center { justify-content: center; } -.justify_content_space_between { - justify-content: space-between; -} .font_size_sm { font-size: var(--font_size_sm); --font_size: var(--font_size_sm); } -.font_size_md { - font-size: var(--font_size_md); - --font_size: var(--font_size_md); -} -.font_size_xl { - font-size: var(--font_size_xl); - --font_size: var(--font_size_xl); -} .font_size_xl2 { font-size: var(--font_size_xl2); --font_size: var(--font_size_xl2); @@ -193,21 +149,9 @@ a.chip { .text_align_center { text-align: center; } -.word_break_break_all { - word-break: break-all; -} -.white_space_pre { - white-space: pre; -} -.white_space_pre_wrap { - white-space: pre-wrap; -} .bg { background-color: var(--bg); } -.color_c_5 { - color: var(--color_c_5); -} .border_radius_xs { border-radius: var(--border_radius_xs); } @@ -222,15 +166,6 @@ a.chip { .width_100 { width: 100%; } -.height_100 { - height: 100%; -} -.top_0 { - top: 0; -} -.right_0 { - right: 0; -} .p_md { padding: var(--space_md); } @@ -286,15 +221,9 @@ a.chip { .mt_lg { margin-top: var(--space_lg); } -.mt_xl4 { - margin-top: var(--space_xl4); -} .mt_xl5 { margin-top: var(--space_xl5); } -.mr_xs { - margin-right: var(--space_xs); -} .mb_0 { margin-bottom: 0; } @@ -313,9 +242,6 @@ a.chip { .mb_xl5 { margin-bottom: var(--space_xl5); } -.mb_xl9 { - margin-bottom: var(--space_xl9); -} .mx_auto { margin-left: auto; margin-right: auto; @@ -327,9 +253,6 @@ a.chip { .gap_sm { gap: var(--space_sm); } -.gap_md { - gap: var(--space_md); -} .gap_xl3 { gap: var(--space_xl3); } diff --git a/src/routes/package.ts b/src/routes/package.ts index 8516cc1f..de47e0e8 100644 --- a/src/routes/package.ts +++ b/src/routes/package.ts @@ -118,10 +118,50 @@ export const src_json: Src_Json = { version: '0.35.0', modules: [ { - path: 'Code_Highlight.svelte', + path: 'code_sample.ts', + identifiers: [ + { + name: 'CodeSample', + kind: 'type', + source_line: 1, + type_signature: 'CodeSample', + properties: [ + { + name: 'name', + kind: 'variable', + type_signature: 'string', + }, + { + name: 'lang', + kind: 'variable', + type_signature: 'string', + }, + { + name: 'content', + kind: 'variable', + type_signature: 'string', + }, + ], + }, + { + name: 'sample_langs', + kind: 'variable', + source_line: 8, + type_signature: 'readonly ["json", "css", "ts", "html", "svelte", "md"]', + }, + { + name: 'SampleLang', + kind: 'type', + source_line: 10, + type_signature: '"json" | "css" | "ts" | "html" | "svelte" | "md"', + }, + ], + }, + { + path: 'Code.svelte', identifiers: [ { - name: 'Code_Highlight', + name: 'Code', kind: 'component', props: [ { @@ -137,16 +177,9 @@ export const src_json: Src_Json = { description: "Language identifier (e.g., 'ts', 'css', 'html', 'json', 'svelte', 'md').\n\n**Purpose:**\n- When `grammar` is not provided, used to look up the grammar via `syntax_styler.get_lang(lang)`\n- Used for metadata: sets the `data-lang` attribute and determines `language_supported`\n\n**Special values:**\n- `null` - Explicitly disables syntax highlighting (content rendered as plain text)\n- `undefined` - Falls back to default ('svelte')\n\n**Relationship with `grammar`:**\n- If both `lang` and `grammar` are provided, `grammar` takes precedence for tokenization\n- However, `lang` is still used for the `data-lang` attribute and language detection", }, - { - name: 'mode', - type: 'Highlight_Mode', - optional: true, - description: - "Highlighting mode for this component.\n\n**Options:**\n- `'auto'` - Uses CSS Custom Highlight API if supported, falls back to HTML mode\n- `'ranges'` - Forces CSS Custom Highlight API (requires browser support)\n- `'html'` - Forces HTML generation with CSS classes\n\n**Note:** CSS Custom Highlight API has limitations and limited browser support.\nRequires importing `theme_highlight.css` instead of `theme.css`.", - }, { name: 'grammar', - type: 'Syntax_Grammar | undefined', + type: 'SyntaxGrammar | undefined', optional: true, description: 'Optional custom grammar object for syntax tokenization.\n\n**When to use:**\n- To provide a custom language definition not registered in `syntax_styler.langs`\n- To use a modified/extended version of an existing grammar\n- For one-off grammar variations without registering globally\n\n**Behavior:**\n- When provided, this grammar is used for tokenization instead of looking up via `lang`\n- Enables highlighting even if `lang` is not in the registry (useful for custom languages)\n- The `lang` parameter is still used for metadata (data-lang attribute)\n- When undefined, the grammar is automatically looked up via `syntax_styler.get_lang(lang)`', @@ -167,69 +200,29 @@ export const src_json: Src_Json = { }, { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: true, description: - 'Custom Syntax_Styler instance to use for highlighting.\nAllows using a different styler with custom grammars or configuration.', + 'Custom SyntaxStyler instance to use for highlighting.\nAllows using a different styler with custom grammars or configuration.', }, { name: 'children', type: 'Snippet<[markup: string]>', optional: true, description: - 'Optional snippet to customize how the highlighted markup is rendered.\n- In HTML mode: receives the generated HTML string\n- In range mode: receives the plain text content', + 'Optional snippet to customize how the highlighted markup is rendered.\nReceives the generated HTML string as a parameter.', }, ], source_line: 1, }, ], - dependencies: ['highlight_manager.ts', 'syntax_styler_global.ts', 'tokenize_syntax.ts'], - }, - { - path: 'code_sample.ts', - identifiers: [ - { - name: 'Code_Sample', - kind: 'type', - source_line: 1, - type_signature: 'Code_Sample', - properties: [ - { - name: 'name', - kind: 'variable', - type_signature: 'string', - }, - { - name: 'lang', - kind: 'variable', - type_signature: 'string', - }, - { - name: 'content', - kind: 'variable', - type_signature: 'string', - }, - ], - }, - { - name: 'sample_langs', - kind: 'variable', - source_line: 8, - type_signature: 'readonly ["json", "css", "ts", "html", "svelte", "md"]', - }, - { - name: 'Sample_Lang', - kind: 'type', - source_line: 10, - type_signature: '"json" | "css" | "ts" | "html" | "svelte" | "md"', - }, - ], + dependencies: ['syntax_styler_global.ts'], }, { - path: 'Code.svelte', + path: 'CodeHighlight.svelte', identifiers: [ { - name: 'Code', + name: 'CodeHighlight', kind: 'component', props: [ { @@ -245,9 +238,16 @@ export const src_json: Src_Json = { description: "Language identifier (e.g., 'ts', 'css', 'html', 'json', 'svelte', 'md').\n\n**Purpose:**\n- When `grammar` is not provided, used to look up the grammar via `syntax_styler.get_lang(lang)`\n- Used for metadata: sets the `data-lang` attribute and determines `language_supported`\n\n**Special values:**\n- `null` - Explicitly disables syntax highlighting (content rendered as plain text)\n- `undefined` - Falls back to default ('svelte')\n\n**Relationship with `grammar`:**\n- If both `lang` and `grammar` are provided, `grammar` takes precedence for tokenization\n- However, `lang` is still used for the `data-lang` attribute and language detection", }, + { + name: 'mode', + type: 'HighlightMode', + optional: true, + description: + "Highlighting mode for this component.\n\n**Options:**\n- `'auto'` - Uses CSS Custom Highlight API if supported, falls back to HTML mode\n- `'ranges'` - Forces CSS Custom Highlight API (requires browser support)\n- `'html'` - Forces HTML generation with CSS classes\n\n**Note:** CSS Custom Highlight API has limitations and limited browser support.\nRequires importing `theme_highlight.css` instead of `theme.css`.", + }, { name: 'grammar', - type: 'Syntax_Grammar | undefined', + type: 'SyntaxGrammar | undefined', optional: true, description: 'Optional custom grammar object for syntax tokenization.\n\n**When to use:**\n- To provide a custom language definition not registered in `syntax_styler.langs`\n- To use a modified/extended version of an existing grammar\n- For one-off grammar variations without registering globally\n\n**Behavior:**\n- When provided, this grammar is used for tokenization instead of looking up via `lang`\n- Enables highlighting even if `lang` is not in the registry (useful for custom languages)\n- The `lang` parameter is still used for metadata (data-lang attribute)\n- When undefined, the grammar is automatically looked up via `syntax_styler.get_lang(lang)`', @@ -268,23 +268,23 @@ export const src_json: Src_Json = { }, { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: true, description: - 'Custom Syntax_Styler instance to use for highlighting.\nAllows using a different styler with custom grammars or configuration.', + 'Custom SyntaxStyler instance to use for highlighting.\nAllows using a different styler with custom grammars or configuration.', }, { name: 'children', type: 'Snippet<[markup: string]>', optional: true, description: - 'Optional snippet to customize how the highlighted markup is rendered.\nReceives the generated HTML string as a parameter.', + 'Optional snippet to customize how the highlighted markup is rendered.\n- In HTML mode: receives the generated HTML string\n- In range mode: receives the plain text content', }, ], source_line: 1, }, ], - dependencies: ['syntax_styler_global.ts'], + dependencies: ['highlight_manager.ts', 'syntax_styler_global.ts', 'tokenize_syntax.ts'], }, { path: 'grammar_clike.ts', @@ -302,12 +302,12 @@ export const src_json: Src_Json = { 'Based on Prism (https://github.com/PrismJS/prism)\nby Lea Verou (https://lea.verou.me/)\n\nMIT license', see_also: ['`LICENSE`'], source_line: 13, - type_signature: '(syntax_styler: Syntax_Styler): void', + type_signature: '(syntax_styler: SyntaxStyler): void', return_type: 'void', parameters: [ { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: false, }, ], @@ -325,12 +325,12 @@ export const src_json: Src_Json = { 'Based on Prism (https://github.com/PrismJS/prism)\nby Lea Verou (https://lea.verou.me/)\n\nMIT license', see_also: ['`LICENSE`'], source_line: 14, - type_signature: '(syntax_styler: Syntax_Styler): void', + type_signature: '(syntax_styler: SyntaxStyler): void', return_type: 'void', parameters: [ { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: false, }, ], @@ -349,12 +349,12 @@ export const src_json: Src_Json = { 'Based on Prism (https://github.com/PrismJS/prism)\nby Lea Verou (https://lea.verou.me/)\n\nMIT license', see_also: ['`LICENSE`'], source_line: 13, - type_signature: '(syntax_styler: Syntax_Styler): void', + type_signature: '(syntax_styler: SyntaxStyler): void', return_type: 'void', parameters: [ { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: false, }, ], @@ -373,12 +373,12 @@ export const src_json: Src_Json = { 'Based on Prism (https://github.com/PrismJS/prism)\nby Lea Verou (https://lea.verou.me/)\n\nMIT license', see_also: ['`LICENSE`'], source_line: 11, - type_signature: '(syntax_styler: Syntax_Styler): void', + type_signature: '(syntax_styler: SyntaxStyler): void', return_type: 'void', parameters: [ { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: false, }, ], @@ -395,12 +395,12 @@ export const src_json: Src_Json = { doc_comment: 'Markdown grammar extending markup.\nSupports: headings, fenced code blocks (3/4/5 backticks with nesting), lists, blockquotes,\nbold, italic, strikethrough, inline code, and links.', source_line: 97, - type_signature: '(syntax_styler: Syntax_Styler): void', + type_signature: '(syntax_styler: SyntaxStyler): void', return_type: 'void', parameters: [ { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: false, }, ], @@ -418,12 +418,12 @@ export const src_json: Src_Json = { 'Based on Prism (https://github.com/PrismJS/prism)\nby Lea Verou (https://lea.verou.me/)\n\nMIT license', see_also: ['`LICENSE`'], source_line: 17, - type_signature: '(syntax_styler: Syntax_Styler): void', + type_signature: '(syntax_styler: SyntaxStyler): void', return_type: 'void', parameters: [ { name: 'syntax_styler', - type: 'Syntax_Styler', + type: 'SyntaxStyler', optional: false, }, ], @@ -435,12 +435,12 @@ export const src_json: Src_Json = { 'Adds an inlined language to markup.\n\nAn example of an inlined language is CSS with `