@fuzdev/fuz_code 0.45.0 → 0.45.1

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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [<img src="static/logo.svg" alt="a friendly pink spider facing you" align="right" width="192" height="192">](https://code.fuz.dev/)
4
4
 
5
- > syntax styling utilities and components for TypeScript, Svelte, and Markdown 🎨
5
+ > syntax styling utilities and components for TypeScript, Svelte, Markdown, and more 🎨
6
6
 
7
7
  **[code.fuz.dev](https://code.fuz.dev/)**
8
8
 
@@ -3,6 +3,6 @@ export interface CodeSample {
3
3
  lang: string;
4
4
  content: string;
5
5
  }
6
- export declare const sample_langs: readonly ["json", "css", "ts", "html", "svelte", "md"];
6
+ export declare const sample_langs: readonly ["json", "css", "ts", "html", "svelte", "md", "bash"];
7
7
  export type SampleLang = (typeof sample_langs)[number];
8
8
  //# sourceMappingURL=code_sample.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"code_sample.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/code_sample.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAGD,eAAO,MAAM,YAAY,wDAAyD,CAAC;AAEnF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"code_sample.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/code_sample.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAGD,eAAO,MAAM,YAAY,gEAAiE,CAAC;AAE3F,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -1,2 +1,2 @@
1
1
  // Languages ordered from simple to complex
2
- export const sample_langs = ['json', 'css', 'ts', 'html', 'svelte', 'md'];
2
+ export const sample_langs = ['json', 'css', 'ts', 'html', 'svelte', 'md', 'bash'];
@@ -0,0 +1,17 @@
1
+ import type { AddSyntaxGrammar } from './syntax_styler.js';
2
+ /**
3
+ * Bash/shell grammar for syntax highlighting.
4
+ *
5
+ * Standalone grammar (no base extension). Covers core bash syntax:
6
+ * comments, strings, variables, functions, keywords, builtins,
7
+ * operators, and redirections.
8
+ *
9
+ * Based on Prism (https://github.com/PrismJS/prism)
10
+ * by Lea Verou (https://lea.verou.me/)
11
+ *
12
+ * MIT license
13
+ *
14
+ * @see LICENSE
15
+ */
16
+ export declare const add_grammar_bash: AddSyntaxGrammar;
17
+ //# sourceMappingURL=grammar_bash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar_bash.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/grammar_bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAmB,MAAM,oBAAoB,CAAC;AAE3E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBA8J9B,CAAC"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Bash/shell grammar for syntax highlighting.
3
+ *
4
+ * Standalone grammar (no base extension). Covers core bash syntax:
5
+ * comments, strings, variables, functions, keywords, builtins,
6
+ * operators, and redirections.
7
+ *
8
+ * Based on Prism (https://github.com/PrismJS/prism)
9
+ * by Lea Verou (https://lea.verou.me/)
10
+ *
11
+ * MIT license
12
+ *
13
+ * @see LICENSE
14
+ */
15
+ export const add_grammar_bash = (syntax_styler) => {
16
+ // Shared inside grammar for command substitution — `rest` wired after construction
17
+ const command_sub_inside = {
18
+ punctuation: /^\$\(|\)$/,
19
+ };
20
+ // Reusable balanced-paren pattern for $(...) — handles 2 levels of inner () nesting,
21
+ // which supports up to 3 levels of $() command substitution (4+ is vanishingly rare)
22
+ const command_sub_pattern = /\$\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\)/;
23
+ const grammar_bash = {
24
+ // Shebang at file start — matched before general comments
25
+ shebang: {
26
+ pattern: /^#!.*/,
27
+ alias: 'comment',
28
+ },
29
+ // Line comments — require whitespace or start-of-string before #
30
+ comment: {
31
+ pattern: /(^|\s)#.*/,
32
+ lookbehind: true,
33
+ greedy: true,
34
+ },
35
+ // Here-documents — must precede string to avoid delimiter consumption
36
+ heredoc: [
37
+ // Quoted delimiter (<<'DELIM' or <<"DELIM") — no expansion
38
+ {
39
+ pattern: /(^|[^<])<<-?\s*(?:['"])(\w+)(?:['"])[\t ]*\n[\s\S]*?\n[\t ]*\2(?=\s*$)/m,
40
+ lookbehind: true,
41
+ greedy: true,
42
+ alias: 'string',
43
+ inside: {
44
+ // No `m` flag — `^` matches start-of-string (opening) and `$` matches
45
+ // end-of-string (closing), so single-word content lines can't false-positive
46
+ heredoc_delimiter: [
47
+ {
48
+ pattern: /^<<-?\s*(?:['"])\w+(?:['"])/,
49
+ alias: 'punctuation',
50
+ },
51
+ {
52
+ pattern: /\w+$/,
53
+ alias: 'punctuation',
54
+ },
55
+ ],
56
+ },
57
+ },
58
+ // Unquoted delimiter (<<DELIM) — with variable/command expansion
59
+ {
60
+ pattern: /(^|[^<])<<-?\s*(\w+)[\t ]*\n[\s\S]*?\n[\t ]*\2(?=\s*$)/m,
61
+ lookbehind: true,
62
+ greedy: true,
63
+ alias: 'string',
64
+ inside: {
65
+ heredoc_delimiter: [
66
+ {
67
+ pattern: /^<<-?\s*\w+/,
68
+ alias: 'punctuation',
69
+ },
70
+ {
71
+ pattern: /\w+$/,
72
+ alias: 'punctuation',
73
+ },
74
+ ],
75
+ command_substitution: {
76
+ pattern: command_sub_pattern,
77
+ greedy: true,
78
+ inside: command_sub_inside,
79
+ },
80
+ variable: /\$\{[^}]+\}|\$(?:\w+|[!@#$*?\-0-9])/,
81
+ },
82
+ },
83
+ ],
84
+ // Strings — three variants
85
+ string: [
86
+ // Double-quoted: supports escape sequences, variable interpolation, command substitution
87
+ {
88
+ pattern: /(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\)|\$(?!\()|[^"\\$])*"/,
89
+ lookbehind: true,
90
+ greedy: true,
91
+ inside: {
92
+ command_substitution: {
93
+ pattern: command_sub_pattern,
94
+ greedy: true,
95
+ inside: command_sub_inside,
96
+ },
97
+ variable: /\$\{[^}]+\}|\$(?:\w+|[!@#$*?\-0-9])/,
98
+ },
99
+ },
100
+ // Single-quoted: completely literal
101
+ {
102
+ pattern: /(^|[^\\](?:\\\\)*)'[^']*'/,
103
+ lookbehind: true,
104
+ greedy: true,
105
+ },
106
+ // ANSI-C quoting: $'...' with C-style escapes
107
+ {
108
+ pattern: /\$'(?:[^'\\]|\\[\s\S])*'/,
109
+ greedy: true,
110
+ },
111
+ ],
112
+ // Command substitution $(...) — before variable since both start with $
113
+ command_substitution: {
114
+ pattern: command_sub_pattern,
115
+ greedy: true,
116
+ inside: command_sub_inside,
117
+ },
118
+ // Variables and parameter expansion
119
+ variable: /\$\{[^}]+\}|\$(?:\w+|[!@#$*?\-0-9])/,
120
+ // Function definitions — both styles
121
+ function: [
122
+ // function fname style
123
+ {
124
+ pattern: /(\bfunction\s+)\w+/,
125
+ lookbehind: true,
126
+ },
127
+ // fname() style
128
+ {
129
+ pattern: /\b\w+(?=\s*\(\s*\))/,
130
+ },
131
+ ],
132
+ // Shell keywords
133
+ keyword: /\b(?:if|then|else|elif|fi|for|while|until|do|done|case|esac|in|select|function|return|local|export|declare|typeset|readonly|unset|set|shift|trap|break|continue|coproc|time)\b/,
134
+ // Builtin commands
135
+ builtin: /\b(?:echo|printf|cd|pwd|read|test|source|eval|exec|exit|getopts|hash|type|ulimit|umask|wait|kill|jobs|bg|fg|disown|alias|unalias|command|shopt)\b/,
136
+ // Boolean commands
137
+ boolean: /\b(?:true|false)\b/,
138
+ // File descriptors before redirections — must precede number
139
+ file_descriptor: {
140
+ pattern: /\B&\d\b|\b\d(?=>>?|<)/,
141
+ alias: 'important',
142
+ },
143
+ // Numbers: hex, octal, base-N, decimal
144
+ number: /\b(?:0x[\da-fA-F]+|0[0-7]+|\d+#[\da-zA-Z]+|\d+)\b/,
145
+ // Operators — longest first
146
+ operator: /\|\||&&|;;|&>>?|<<<?|>>?|=~|[!=]=|[<>]|[|&!]/,
147
+ // Punctuation
148
+ punctuation: /[{}[\]();,]/,
149
+ };
150
+ // Wire circular reference so command substitutions get full bash highlighting
151
+ command_sub_inside.rest = grammar_bash;
152
+ syntax_styler.add_lang('bash', grammar_bash, ['sh', 'shell']);
153
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"grammar_markdown.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/grammar_markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAIhB,MAAM,oBAAoB,CAAC;AAsF5B;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,gBAgMlC,CAAC"}
1
+ {"version":3,"file":"grammar_markdown.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/grammar_markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAIhB,MAAM,oBAAoB,CAAC;AAsF5B;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,gBAiMlC,CAAC"}
@@ -69,6 +69,7 @@ export const add_grammar_markdown = (syntax_styler) => {
69
69
  { aliases: ['html', 'markup'], id: 'markup' },
70
70
  { aliases: ['json'], id: 'json' },
71
71
  { aliases: ['svelte'], id: 'svelte' },
72
+ { aliases: ['bash', 'sh', 'shell'], id: 'bash' },
72
73
  ];
73
74
  // Fence types: higher counts first (for proper precedence in tokenization)
74
75
  const fence_types = [
@@ -1 +1 @@
1
- {"version":3,"file":"syntax_styler_global.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/syntax_styler_global.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAUhD;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,cAAqB,CAAC"}
1
+ {"version":3,"file":"syntax_styler_global.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/syntax_styler_global.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAWhD;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,cAAqB,CAAC"}
@@ -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
  * Pre-configured `SyntaxStyler` instance with all built-in grammars registered.
@@ -25,4 +26,5 @@ add_grammar_js(syntax_styler_global);
25
26
  add_grammar_ts(syntax_styler_global);
26
27
  add_grammar_svelte(syntax_styler_global);
27
28
  add_grammar_json(syntax_styler_global);
29
+ add_grammar_bash(syntax_styler_global); // before markdown — markdown references bash for fenced code blocks
28
30
  add_grammar_markdown(syntax_styler_global);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_code",
3
- "version": "0.45.0",
4
- "description": "syntax styling utilities and components for TypeScript, Svelte, and Markdown",
3
+ "version": "0.45.1",
4
+ "description": "syntax styling utilities and components for TypeScript, Svelte, Markdown, and more",
5
5
  "glyph": "🎨",
6
6
  "logo": "logo.svg",
7
7
  "logo_alt": "a friendly pink spider facing you",
@@ -58,13 +58,12 @@
58
58
  },
59
59
  "devDependencies": {
60
60
  "@changesets/changelog-git": "^0.2.1",
61
- "@fuzdev/fuz_css": "^0.48.0",
62
- "@fuzdev/fuz_ui": "^0.182.1",
63
- "@fuzdev/fuz_util": "^0.50.1",
64
- "@fuzdev/gro": "^0.192.1",
61
+ "@fuzdev/fuz_css": "^0.50.0",
62
+ "@fuzdev/fuz_ui": "^0.183.1",
63
+ "@fuzdev/fuz_util": "^0.51.0",
64
+ "@fuzdev/gro": "^0.194.0",
65
65
  "@jridgewell/trace-mapping": "^0.3.31",
66
66
  "@ryanatkn/eslint-config": "^0.9.0",
67
- "@ryanatkn/gro": "^0.191.0",
68
67
  "@sveltejs/adapter-static": "^3.0.10",
69
68
  "@sveltejs/kit": "^2.50.1",
70
69
  "@sveltejs/package": "^2.5.7",
@@ -5,6 +5,6 @@ export interface CodeSample {
5
5
  }
6
6
 
7
7
  // Languages ordered from simple to complex
8
- export const sample_langs = ['json', 'css', 'ts', 'html', 'svelte', 'md'] as const;
8
+ export const sample_langs = ['json', 'css', 'ts', 'html', 'svelte', 'md', 'bash'] as const;
9
9
 
10
10
  export type SampleLang = (typeof sample_langs)[number];
@@ -0,0 +1,175 @@
1
+ import type {AddSyntaxGrammar, SyntaxGrammarRaw} from './syntax_styler.js';
2
+
3
+ /**
4
+ * Bash/shell grammar for syntax highlighting.
5
+ *
6
+ * Standalone grammar (no base extension). Covers core bash syntax:
7
+ * comments, strings, variables, functions, keywords, builtins,
8
+ * operators, and redirections.
9
+ *
10
+ * Based on Prism (https://github.com/PrismJS/prism)
11
+ * by Lea Verou (https://lea.verou.me/)
12
+ *
13
+ * MIT license
14
+ *
15
+ * @see LICENSE
16
+ */
17
+ export const add_grammar_bash: AddSyntaxGrammar = (syntax_styler) => {
18
+ // Shared inside grammar for command substitution — `rest` wired after construction
19
+ const command_sub_inside: SyntaxGrammarRaw = {
20
+ punctuation: /^\$\(|\)$/,
21
+ };
22
+
23
+ // Reusable balanced-paren pattern for $(...) — handles 2 levels of inner () nesting,
24
+ // which supports up to 3 levels of $() command substitution (4+ is vanishingly rare)
25
+ const command_sub_pattern = /\$\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\)/;
26
+
27
+ const grammar_bash = {
28
+ // Shebang at file start — matched before general comments
29
+ shebang: {
30
+ pattern: /^#!.*/,
31
+ alias: 'comment',
32
+ },
33
+
34
+ // Line comments — require whitespace or start-of-string before #
35
+ comment: {
36
+ pattern: /(^|\s)#.*/,
37
+ lookbehind: true,
38
+ greedy: true,
39
+ },
40
+
41
+ // Here-documents — must precede string to avoid delimiter consumption
42
+ heredoc: [
43
+ // Quoted delimiter (<<'DELIM' or <<"DELIM") — no expansion
44
+ {
45
+ pattern: /(^|[^<])<<-?\s*(?:['"])(\w+)(?:['"])[\t ]*\n[\s\S]*?\n[\t ]*\2(?=\s*$)/m,
46
+ lookbehind: true,
47
+ greedy: true,
48
+ alias: 'string',
49
+ inside: {
50
+ // No `m` flag — `^` matches start-of-string (opening) and `$` matches
51
+ // end-of-string (closing), so single-word content lines can't false-positive
52
+ heredoc_delimiter: [
53
+ {
54
+ pattern: /^<<-?\s*(?:['"])\w+(?:['"])/,
55
+ alias: 'punctuation',
56
+ },
57
+ {
58
+ pattern: /\w+$/,
59
+ alias: 'punctuation',
60
+ },
61
+ ],
62
+ } as SyntaxGrammarRaw,
63
+ },
64
+ // Unquoted delimiter (<<DELIM) — with variable/command expansion
65
+ {
66
+ pattern: /(^|[^<])<<-?\s*(\w+)[\t ]*\n[\s\S]*?\n[\t ]*\2(?=\s*$)/m,
67
+ lookbehind: true,
68
+ greedy: true,
69
+ alias: 'string',
70
+ inside: {
71
+ heredoc_delimiter: [
72
+ {
73
+ pattern: /^<<-?\s*\w+/,
74
+ alias: 'punctuation',
75
+ },
76
+ {
77
+ pattern: /\w+$/,
78
+ alias: 'punctuation',
79
+ },
80
+ ],
81
+ command_substitution: {
82
+ pattern: command_sub_pattern,
83
+ greedy: true,
84
+ inside: command_sub_inside,
85
+ },
86
+ variable: /\$\{[^}]+\}|\$(?:\w+|[!@#$*?\-0-9])/,
87
+ } as SyntaxGrammarRaw,
88
+ },
89
+ ],
90
+
91
+ // Strings — three variants
92
+ string: [
93
+ // Double-quoted: supports escape sequences, variable interpolation, command substitution
94
+ {
95
+ pattern:
96
+ /(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\)|\$(?!\()|[^"\\$])*"/,
97
+ lookbehind: true,
98
+ greedy: true,
99
+ inside: {
100
+ command_substitution: {
101
+ pattern: command_sub_pattern,
102
+ greedy: true,
103
+ inside: command_sub_inside,
104
+ },
105
+ variable: /\$\{[^}]+\}|\$(?:\w+|[!@#$*?\-0-9])/,
106
+ } as SyntaxGrammarRaw,
107
+ },
108
+ // Single-quoted: completely literal
109
+ {
110
+ pattern: /(^|[^\\](?:\\\\)*)'[^']*'/,
111
+ lookbehind: true,
112
+ greedy: true,
113
+ },
114
+ // ANSI-C quoting: $'...' with C-style escapes
115
+ {
116
+ pattern: /\$'(?:[^'\\]|\\[\s\S])*'/,
117
+ greedy: true,
118
+ },
119
+ ],
120
+
121
+ // Command substitution $(...) — before variable since both start with $
122
+ command_substitution: {
123
+ pattern: command_sub_pattern,
124
+ greedy: true,
125
+ inside: command_sub_inside,
126
+ },
127
+
128
+ // Variables and parameter expansion
129
+ variable: /\$\{[^}]+\}|\$(?:\w+|[!@#$*?\-0-9])/,
130
+
131
+ // Function definitions — both styles
132
+ function: [
133
+ // function fname style
134
+ {
135
+ pattern: /(\bfunction\s+)\w+/,
136
+ lookbehind: true,
137
+ },
138
+ // fname() style
139
+ {
140
+ pattern: /\b\w+(?=\s*\(\s*\))/,
141
+ },
142
+ ],
143
+
144
+ // Shell keywords
145
+ keyword:
146
+ /\b(?:if|then|else|elif|fi|for|while|until|do|done|case|esac|in|select|function|return|local|export|declare|typeset|readonly|unset|set|shift|trap|break|continue|coproc|time)\b/,
147
+
148
+ // Builtin commands
149
+ builtin:
150
+ /\b(?:echo|printf|cd|pwd|read|test|source|eval|exec|exit|getopts|hash|type|ulimit|umask|wait|kill|jobs|bg|fg|disown|alias|unalias|command|shopt)\b/,
151
+
152
+ // Boolean commands
153
+ boolean: /\b(?:true|false)\b/,
154
+
155
+ // File descriptors before redirections — must precede number
156
+ file_descriptor: {
157
+ pattern: /\B&\d\b|\b\d(?=>>?|<)/,
158
+ alias: 'important',
159
+ },
160
+
161
+ // Numbers: hex, octal, base-N, decimal
162
+ number: /\b(?:0x[\da-fA-F]+|0[0-7]+|\d+#[\da-zA-Z]+|\d+)\b/,
163
+
164
+ // Operators — longest first
165
+ operator: /\|\||&&|;;|&>>?|<<<?|>>?|=~|[!=]=|[<>]|[|&!]/,
166
+
167
+ // Punctuation
168
+ punctuation: /[{}[\]();,]/,
169
+ } satisfies SyntaxGrammarRaw;
170
+
171
+ // Wire circular reference so command substitutions get full bash highlighting
172
+ command_sub_inside.rest = grammar_bash;
173
+
174
+ syntax_styler.add_lang('bash', grammar_bash, ['sh', 'shell']);
175
+ };
@@ -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)
@@ -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);