@fuzdev/fuz_code 0.45.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +2 -1
  2. package/dist/Code.svelte +2 -2
  3. package/dist/Code.svelte.d.ts +2 -2
  4. package/dist/CodeHighlight.svelte +4 -4
  5. package/dist/CodeHighlight.svelte.d.ts +3 -3
  6. package/dist/code_sample.d.ts +1 -1
  7. package/dist/code_sample.d.ts.map +1 -1
  8. package/dist/code_sample.js +1 -1
  9. package/dist/grammar_bash.d.ts +17 -0
  10. package/dist/grammar_bash.d.ts.map +1 -0
  11. package/dist/grammar_bash.js +153 -0
  12. package/dist/grammar_markdown.d.ts.map +1 -1
  13. package/dist/grammar_markdown.js +4 -3
  14. package/dist/grammar_markup.d.ts +8 -7
  15. package/dist/grammar_markup.d.ts.map +1 -1
  16. package/dist/grammar_markup.js +8 -7
  17. package/dist/highlight_manager.d.ts +4 -4
  18. package/dist/highlight_manager.js +6 -6
  19. package/dist/svelte_preprocess_fuz_code.d.ts +4 -4
  20. package/dist/svelte_preprocess_fuz_code.d.ts.map +1 -1
  21. package/dist/svelte_preprocess_fuz_code.js +3 -3
  22. package/dist/syntax_styler.d.ts +28 -32
  23. package/dist/syntax_styler.d.ts.map +1 -1
  24. package/dist/syntax_styler.js +32 -36
  25. package/dist/syntax_styler_global.d.ts.map +1 -1
  26. package/dist/syntax_styler_global.js +2 -0
  27. package/dist/syntax_token.d.ts +4 -4
  28. package/dist/syntax_token.js +2 -2
  29. package/dist/tokenize_syntax.d.ts +2 -4
  30. package/dist/tokenize_syntax.d.ts.map +1 -1
  31. package/dist/tokenize_syntax.js +2 -4
  32. package/package.json +27 -31
  33. package/src/lib/code_sample.ts +1 -1
  34. package/src/lib/grammar_bash.ts +175 -0
  35. package/src/lib/grammar_markdown.ts +4 -3
  36. package/src/lib/grammar_markup.ts +8 -7
  37. package/src/lib/highlight_manager.ts +6 -6
  38. package/src/lib/svelte_preprocess_fuz_code.ts +6 -6
  39. package/src/lib/syntax_styler.ts +35 -39
  40. package/src/lib/syntax_styler_global.ts +2 -0
  41. package/src/lib/syntax_token.ts +4 -4
  42. package/src/lib/tokenize_syntax.ts +2 -4
@@ -16,7 +16,7 @@ interface FenceType {
16
16
  }
17
17
 
18
18
  /**
19
- * Helper to create fenced code block pattern for a language
19
+ * Helper to create fenced code block pattern for a language.
20
20
  */
21
21
  const create_fence_pattern = (
22
22
  backticks: string,
@@ -48,7 +48,7 @@ const create_fence_pattern = (
48
48
  };
49
49
 
50
50
  /**
51
- * Helper to create catch-all fence pattern (unknown languages)
51
+ * Helper to create catch-all fence pattern (unknown languages).
52
52
  */
53
53
  const create_catchall_fence = (backticks: string): SyntaxGrammarTokenRaw => {
54
54
  const pattern = new RegExp(`^${backticks}[^\\n\\r]*(?:\\r?\\n|\\r)[\\s\\S]*?^${backticks}$`, 'm');
@@ -67,7 +67,7 @@ const create_catchall_fence = (backticks: string): SyntaxGrammarTokenRaw => {
67
67
  };
68
68
 
69
69
  /**
70
- * Helper to create md self-reference placeholder pattern
70
+ * Helper to create md self-reference placeholder pattern.
71
71
  */
72
72
  const create_md_placeholder = (backticks: string): SyntaxGrammarTokenRaw => {
73
73
  const pattern = new RegExp(
@@ -103,6 +103,7 @@ export const add_grammar_markdown: AddSyntaxGrammar = (syntax_styler) => {
103
103
  {aliases: ['html', 'markup'], id: 'markup'},
104
104
  {aliases: ['json'], id: 'json'},
105
105
  {aliases: ['svelte'], id: 'svelte'},
106
+ {aliases: ['bash', 'sh', 'shell'], id: 'bash'},
106
107
  ];
107
108
 
108
109
  // Fence types: higher counts first (for proper precedence in tokenization)
@@ -98,9 +98,10 @@ export const add_grammar_markup: AddSyntaxGrammar = (syntax_styler) => {
98
98
  *
99
99
  * An example of an inlined language is CSS with `<style>` tags.
100
100
  *
101
- * @param tag_name - The name of the tag that contains the inlined language. This name will be treated as
102
- * case insensitive.
103
- * @param lang - The language key.
101
+ * @param syntax_styler - the `SyntaxStyler` instance to modify
102
+ * @param tag_name - the name of the tag that contains the inlined language, treated as case insensitive
103
+ * @param lang - the language key
104
+ * @param inside_lang - the language to insert into, defaults to `'markup'`
104
105
  */
105
106
  export const grammar_markup_add_inlined = (
106
107
  syntax_styler: SyntaxStyler,
@@ -145,13 +146,13 @@ export const grammar_markup_add_inlined = (
145
146
  };
146
147
 
147
148
  /**
148
- * Adds an pattern to style languages embedded in HTML attributes.
149
+ * Adds a pattern to style languages embedded in HTML attributes.
149
150
  *
150
151
  * An example of an inlined language is CSS with `style` attributes.
151
152
  *
152
- * @param attr_name - The name of the tag that contains the inlined language. This name will be treated as
153
- * case insensitive.
154
- * @param lang - The language key.
153
+ * @param syntax_styler - the `SyntaxStyler` instance to modify
154
+ * @param attr_name - the name of the attribute that contains the inlined language, treated as case insensitive
155
+ * @param lang - the language key
155
156
  */
156
157
  export const grammar_markup_add_attribute = (
157
158
  syntax_styler: SyntaxStyler,
@@ -4,16 +4,16 @@ import {highlight_priorities} from './highlight_priorities.js';
4
4
  export type HighlightMode = 'auto' | 'ranges' | 'html';
5
5
 
6
6
  /**
7
- * Check for CSS Highlights API support.
7
+ * Checks for CSS Highlights API support.
8
8
  */
9
9
  export const supports_css_highlight_api = (): boolean =>
10
- !!(globalThis.CSS?.highlights && globalThis.Highlight); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
10
+ !!(globalThis.CSS?.highlights && globalThis.Highlight);
11
11
 
12
12
  /**
13
13
  * Manages CSS Custom Highlight API ranges for a single element.
14
14
  * Tracks ranges per element and only removes its own ranges when clearing.
15
15
  *
16
- * **Experimental** — limited browser support. Use `Code` for production.
16
+ * **Experimental** — limited browser support. Use `Code.svelte` for production.
17
17
  *
18
18
  * @example
19
19
  * ```ts
@@ -32,7 +32,7 @@ export class HighlightManager {
32
32
  }
33
33
 
34
34
  /**
35
- * Highlight from syntax styler token stream.
35
+ * Highlights from a `SyntaxTokenStream` produced by `tokenize_syntax`.
36
36
  */
37
37
  highlight_from_syntax_tokens(element: Element, tokens: SyntaxTokenStream): void {
38
38
  // Find the text node (it might not be firstChild due to Svelte comment nodes)
@@ -85,7 +85,7 @@ export class HighlightManager {
85
85
  }
86
86
 
87
87
  /**
88
- * Clear only this element's ranges from highlights.
88
+ * Clears only this element's ranges from highlights.
89
89
  */
90
90
  clear_element_ranges(): void {
91
91
  for (const [name, ranges] of this.element_ranges) {
@@ -111,7 +111,7 @@ export class HighlightManager {
111
111
  }
112
112
 
113
113
  /**
114
- * Create ranges for all tokens in the tree.
114
+ * Creates ranges for all tokens in the tree.
115
115
  */
116
116
  #create_all_ranges(
117
117
  tokens: SyntaxTokenStream,
@@ -23,15 +23,15 @@ export interface PreprocessFuzCodeOptions {
23
23
  /** File patterns to exclude. */
24
24
  exclude?: Array<string | RegExp>;
25
25
 
26
- /** Custom syntax styler. @default syntax_styler_global */
26
+ /** Custom `SyntaxStyler` instance. @default syntax_styler_global */
27
27
  syntax_styler?: SyntaxStyler;
28
28
 
29
29
  /** Enable in-memory caching. @default true */
30
30
  cache?: boolean;
31
31
 
32
32
  /**
33
- * Import sources that resolve to the Code component.
34
- * Used to verify that `<Code>` in templates actually refers to fuz_code's Code.svelte.
33
+ * Import sources that resolve to the `Code` component.
34
+ * Used to verify that `<Code>` in templates actually refers to `Code.svelte`.
35
35
  *
36
36
  * @default ['@fuzdev/fuz_code/Code.svelte']
37
37
  */
@@ -48,7 +48,7 @@ export interface PreprocessFuzCodeOptions {
48
48
  * Svelte preprocessor that compiles static `Code` component content at build time,
49
49
  * replacing runtime syntax highlighting with pre-rendered HTML.
50
50
  *
51
- * @param options preprocessor configuration
51
+ * @param options - `PreprocessFuzCodeOptions` configuration
52
52
  * @returns a Svelte preprocessor group
53
53
  *
54
54
  * @example
@@ -141,7 +141,7 @@ interface FindCodeUsagesOptions {
141
141
  }
142
142
 
143
143
  /**
144
- * Attempt to highlight content, using cache if available.
144
+ * Attempts to highlight content, using cache if available.
145
145
  * Returns the highlighted HTML, or `null` on error.
146
146
  */
147
147
  const try_highlight = (
@@ -165,7 +165,7 @@ const try_highlight = (
165
165
  };
166
166
 
167
167
  /**
168
- * Walks the AST to find Code component usages with static `content` props
168
+ * Walks the AST to find `Code` component usages with static `content` props
169
169
  * and generates transformations to replace them with `dangerous_raw_html`.
170
170
  */
171
171
  const find_code_usages = (
@@ -92,15 +92,14 @@ export class SyntaxStyler {
92
92
  * - Custom grammar: `stylize(code, 'ts', customGrammar)` - uses custom grammar but keeps 'ts' label
93
93
  * - Extended grammar: `stylize(code, 'custom', this.extend_grammar('ts', extension))` - new language variant
94
94
  *
95
- * @param text - The source code to syntax highlight.
96
- * @param lang - Language identifier (e.g., 'ts', 'css', 'html'). Used for:
97
- * - Grammar lookup when `grammar` is undefined
98
- * - Hook context (`lang` field passed to hooks)
99
- * - Language identification in output
100
- * @param grammar - Optional custom grammar object. When undefined, automatically
101
- * looks up the grammar via `this.get_lang(lang)`. Provide this to use a custom
102
- * or modified grammar instead of the registered one.
103
- *
95
+ * @param text - the source code to syntax highlight
96
+ * @param lang - language identifier (e.g., 'ts', 'css', 'html'), used for:
97
+ * - grammar lookup when `grammar` is undefined
98
+ * - hook context (`lang` field passed to hooks)
99
+ * - language identification in output
100
+ * @param grammar - optional custom `SyntaxGrammar` object; when undefined, automatically
101
+ * looks up the grammar via `this.get_lang(lang)`; provide this to use a custom
102
+ * or modified grammar instead of the registered one
104
103
  * @returns HTML string with syntax highlighting using CSS classes (`.token_*`)
105
104
  *
106
105
  * @example
@@ -158,7 +157,7 @@ export class SyntaxStyler {
158
157
  * };
159
158
  * ```
160
159
  *
161
- * then the `style` token will be added (and processed) at the end. `insert_before` allows you to insert tokens
160
+ * then the `style` token will be added (and processed) at the end. `grammar_insert_before` allows you to insert tokens
162
161
  * before existing tokens. For the CSS example above, you would use it like this:
163
162
  *
164
163
  * ```js
@@ -185,12 +184,12 @@ export class SyntaxStyler {
185
184
  *
186
185
  * ## Limitations
187
186
  *
188
- * The main problem `insert_before` has to solve is iteration order. Since ES2015, the iteration order for object
187
+ * The main problem `grammar_insert_before` has to solve is iteration order. Since ES2015, the iteration order for object
189
188
  * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
190
- * differently when keys are deleted and re-inserted. So `insert_before` can't be implemented by temporarily
189
+ * differently when keys are deleted and re-inserted. So `grammar_insert_before` can't be implemented by temporarily
191
190
  * deleting properties which is necessary to insert at arbitrary positions.
192
191
  *
193
- * To solve this problem, `insert_before` doesn't actually insert the given tokens into the target object.
192
+ * To solve this problem, `grammar_insert_before` doesn't actually insert the given tokens into the target object.
194
193
  * Instead, it will create a new object and replace all references to the target object with the new one. This
195
194
  * can be done without temporarily deleting properties, so the iteration order is well-defined.
196
195
  *
@@ -205,16 +204,13 @@ export class SyntaxStyler {
205
204
  * assert(newMarkup === syntax_styler.get_lang('markup'));
206
205
  * ```
207
206
  *
208
- * @param inside - The property of `root` (e.g. a language id in `syntax_styler.langs`) that contains the
209
- * object to be modified.
210
- * @param before - The key to insert before.
211
- * @param insert - An object containing the key-value pairs to be inserted.
212
- * @param root - The object containing `inside`, i.e. the object that contains the
213
- * object to be modified.
214
- *
215
- * Defaults to `syntax_styler.langs`.
216
- *
217
- * @returns the new grammar object
207
+ * @param inside - the property of `root` (e.g. a language id in `syntax_styler.langs`) that contains the
208
+ * object to be modified
209
+ * @param before - the key to insert before
210
+ * @param insert - an object containing the key-value pairs to be inserted
211
+ * @param root - the object containing `inside`, i.e. the object that contains the
212
+ * object to be modified; defaults to `syntax_styler.langs`
213
+ * @returns the new `SyntaxGrammar` object
218
214
  */
219
215
  grammar_insert_before(
220
216
  inside: string,
@@ -261,9 +257,9 @@ export class SyntaxStyler {
261
257
  *
262
258
  * Runs the `wrap` hook on each `SyntaxToken`.
263
259
  *
264
- * @param o - The token or token stream to be converted.
265
- * @param lang - The name of current language.
266
- * @returns The HTML representation of the token or token stream.
260
+ * @param o - the token or `SyntaxTokenStream` to be converted
261
+ * @param lang - the name of current language
262
+ * @returns HTML representation of the token or token stream
267
263
  */
268
264
  stringify_token(o: string | SyntaxToken | SyntaxTokenStream, lang: string): string {
269
265
  if (typeof o === 'string') {
@@ -332,9 +328,9 @@ export class SyntaxStyler {
332
328
  * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
333
329
  * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
334
330
  *
335
- * @param base_id - The id of the language to extend. This has to be a key in `syntax_styler.langs`.
336
- * @param extension - The new tokens to append.
337
- * @returns the new grammar
331
+ * @param base_id - the id of the language to extend, must be a key in `syntax_styler.langs`
332
+ * @param extension - the new tokens to append
333
+ * @returns the new `SyntaxGrammar`
338
334
  */
339
335
  extend_grammar(base_id: string, extension: SyntaxGrammarRaw): SyntaxGrammar {
340
336
  // Merge normalized base with un-normalized extension
@@ -346,7 +342,7 @@ export class SyntaxStyler {
346
342
  }
347
343
 
348
344
  /**
349
- * Normalize a single pattern to have consistent shape.
345
+ * Normalizes a single pattern to have consistent shape.
350
346
  * This ensures all patterns have the same object shape for V8 optimization.
351
347
  */
352
348
  #normalize_pattern(
@@ -387,15 +383,15 @@ export class SyntaxStyler {
387
383
  }
388
384
 
389
385
  /**
390
- * Normalize a grammar to have consistent object shapes.
386
+ * Normalizes a grammar to have consistent object shapes.
391
387
  * This performs several optimizations:
392
- * 1. Merges `rest` property into main grammar
393
- * 2. Ensures all pattern values are arrays
394
- * 3. Normalizes all pattern objects to have consistent shapes
395
- * 4. Adds global flag to greedy patterns
388
+ * 1. Merges `rest` property into main grammar.
389
+ * 2. Ensures all pattern values are arrays.
390
+ * 3. Normalizes all pattern objects to have consistent shapes.
391
+ * 4. Adds global flag to greedy patterns.
396
392
  *
397
393
  * This is called once at registration time to avoid runtime overhead.
398
- * @param visited - Set of grammar object IDs already normalized (for circular references)
394
+ * @param visited - set of grammar object IDs already normalized (for circular references)
399
395
  */
400
396
  #normalize_grammar(grammar: SyntaxGrammarRaw, visited: Set<number>): void {
401
397
  // Check if we've already normalized this grammar (circular reference)
@@ -510,14 +506,14 @@ export interface SyntaxGrammarTokenRaw {
510
506
  */
511
507
  alias?: string | Array<string>;
512
508
  /**
513
- * The nested grammar of this token.
509
+ * The nested `SyntaxGrammarRaw` of this token.
514
510
  */
515
511
  inside?: SyntaxGrammarRaw | null;
516
512
  }
517
513
 
518
514
  /**
519
515
  * Grammar token with all properties required.
520
- * This is the normalized representation used at runtime.
516
+ * This is the normalized representation of `SyntaxGrammarTokenRaw` used at runtime.
521
517
  */
522
518
  export interface SyntaxGrammarToken {
523
519
  pattern: RegExp;
@@ -529,7 +525,7 @@ export interface SyntaxGrammarToken {
529
525
 
530
526
  /**
531
527
  * A grammar after normalization.
532
- * All values are arrays of normalized tokens with consistent shapes.
528
+ * All values are arrays of normalized `SyntaxGrammarToken` with consistent shapes.
533
529
  */
534
530
  export type SyntaxGrammar = Record<string, Array<SyntaxGrammarToken>>;
535
531
 
@@ -6,6 +6,7 @@ import {add_grammar_js} from './grammar_js.js';
6
6
  import {add_grammar_ts} from './grammar_ts.js';
7
7
  import {add_grammar_svelte} from './grammar_svelte.js';
8
8
  import {add_grammar_json} from './grammar_json.js';
9
+ import {add_grammar_bash} from './grammar_bash.js';
9
10
  import {add_grammar_markdown} from './grammar_markdown.js';
10
11
 
11
12
  /**
@@ -27,4 +28,5 @@ add_grammar_js(syntax_styler_global);
27
28
  add_grammar_ts(syntax_styler_global);
28
29
  add_grammar_svelte(syntax_styler_global);
29
30
  add_grammar_json(syntax_styler_global);
31
+ add_grammar_bash(syntax_styler_global); // before markdown — markdown references bash for fenced code blocks
30
32
  add_grammar_markdown(syntax_styler_global);
@@ -2,14 +2,14 @@ export class SyntaxToken {
2
2
  /**
3
3
  * The type of the token.
4
4
  *
5
- * This is usually the key of a pattern in a `Grammar`.
5
+ * This is usually the key of a pattern in a `SyntaxGrammar`.
6
6
  */
7
7
  type: string;
8
8
 
9
9
  /**
10
10
  * The strings or tokens contained by this token.
11
11
  *
12
- * This will be a token stream if the pattern matched also defined an `inside` grammar.
12
+ * This will be a `SyntaxTokenStream` if the pattern matched also defined an `inside` grammar.
13
13
  */
14
14
  content: string | SyntaxTokenStream;
15
15
 
@@ -38,8 +38,8 @@ export class SyntaxToken {
38
38
  /**
39
39
  * A token stream is an array of strings and `SyntaxToken` objects.
40
40
  *
41
- * Syntax token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
42
- * them.
41
+ * `SyntaxTokenStream` values have to fulfill a few properties that are assumed by most functions
42
+ * (mostly internal ones) that process them.
43
43
  *
44
44
  * 1. No adjacent strings.
45
45
  * 2. No empty strings.
@@ -10,11 +10,9 @@ import {SyntaxToken, type SyntaxTokenStream} from './syntax_token.js';
10
10
  * This method could be useful in other contexts as well, as a very crude parser.
11
11
  *
12
12
  * @param text - a string with the code to be styled
13
- * @param grammar - an object containing the tokens to use
14
- *
13
+ * @param grammar - a `SyntaxGrammar` object containing the tokens to use.
15
14
  * Usually a language definition like `syntax_styler.get_lang('markup')`.
16
- *
17
- * @returns an array of strings and tokens, a token stream
15
+ * @returns a `SyntaxTokenStream` array of strings and tokens
18
16
  *
19
17
  * @example
20
18
  * ```ts