@fuzdev/fuz_code 0.37.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 (76) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +185 -0
  3. package/dist/Code.svelte +146 -0
  4. package/dist/Code.svelte.d.ts +79 -0
  5. package/dist/Code.svelte.d.ts.map +1 -0
  6. package/dist/CodeHighlight.svelte +205 -0
  7. package/dist/CodeHighlight.svelte.d.ts +101 -0
  8. package/dist/CodeHighlight.svelte.d.ts.map +1 -0
  9. package/dist/code_sample.d.ts +8 -0
  10. package/dist/code_sample.d.ts.map +1 -0
  11. package/dist/code_sample.js +2 -0
  12. package/dist/grammar_clike.d.ts +12 -0
  13. package/dist/grammar_clike.d.ts.map +1 -0
  14. package/dist/grammar_clike.js +43 -0
  15. package/dist/grammar_css.d.ts +11 -0
  16. package/dist/grammar_css.d.ts.map +1 -0
  17. package/dist/grammar_css.js +70 -0
  18. package/dist/grammar_js.d.ts +11 -0
  19. package/dist/grammar_js.d.ts.map +1 -0
  20. package/dist/grammar_js.js +180 -0
  21. package/dist/grammar_json.d.ts +11 -0
  22. package/dist/grammar_json.d.ts.map +1 -0
  23. package/dist/grammar_json.js +35 -0
  24. package/dist/grammar_markdown.d.ts +8 -0
  25. package/dist/grammar_markdown.d.ts.map +1 -0
  26. package/dist/grammar_markdown.js +228 -0
  27. package/dist/grammar_markup.d.ts +31 -0
  28. package/dist/grammar_markup.d.ts.map +1 -0
  29. package/dist/grammar_markup.js +192 -0
  30. package/dist/grammar_svelte.d.ts +12 -0
  31. package/dist/grammar_svelte.d.ts.map +1 -0
  32. package/dist/grammar_svelte.js +150 -0
  33. package/dist/grammar_ts.d.ts +11 -0
  34. package/dist/grammar_ts.d.ts.map +1 -0
  35. package/dist/grammar_ts.js +95 -0
  36. package/dist/highlight_manager.d.ts +25 -0
  37. package/dist/highlight_manager.d.ts.map +1 -0
  38. package/dist/highlight_manager.js +139 -0
  39. package/dist/highlight_priorities.d.ts +3 -0
  40. package/dist/highlight_priorities.d.ts.map +1 -0
  41. package/dist/highlight_priorities.gen.d.ts +4 -0
  42. package/dist/highlight_priorities.gen.d.ts.map +1 -0
  43. package/dist/highlight_priorities.gen.js +58 -0
  44. package/dist/highlight_priorities.js +55 -0
  45. package/dist/syntax_styler.d.ts +277 -0
  46. package/dist/syntax_styler.d.ts.map +1 -0
  47. package/dist/syntax_styler.js +426 -0
  48. package/dist/syntax_styler_global.d.ts +3 -0
  49. package/dist/syntax_styler_global.d.ts.map +1 -0
  50. package/dist/syntax_styler_global.js +18 -0
  51. package/dist/syntax_token.d.ts +34 -0
  52. package/dist/syntax_token.d.ts.map +1 -0
  53. package/dist/syntax_token.js +27 -0
  54. package/dist/theme.css +98 -0
  55. package/dist/theme_highlight.css +160 -0
  56. package/dist/theme_variables.css +20 -0
  57. package/dist/tokenize_syntax.d.ts +28 -0
  58. package/dist/tokenize_syntax.d.ts.map +1 -0
  59. package/dist/tokenize_syntax.js +194 -0
  60. package/package.json +117 -0
  61. package/src/lib/code_sample.ts +10 -0
  62. package/src/lib/grammar_clike.ts +48 -0
  63. package/src/lib/grammar_css.ts +84 -0
  64. package/src/lib/grammar_js.ts +215 -0
  65. package/src/lib/grammar_json.ts +38 -0
  66. package/src/lib/grammar_markdown.ts +289 -0
  67. package/src/lib/grammar_markup.ts +225 -0
  68. package/src/lib/grammar_svelte.ts +165 -0
  69. package/src/lib/grammar_ts.ts +114 -0
  70. package/src/lib/highlight_manager.ts +182 -0
  71. package/src/lib/highlight_priorities.gen.ts +71 -0
  72. package/src/lib/highlight_priorities.ts +110 -0
  73. package/src/lib/syntax_styler.ts +583 -0
  74. package/src/lib/syntax_styler_global.ts +20 -0
  75. package/src/lib/syntax_token.ts +49 -0
  76. package/src/lib/tokenize_syntax.ts +270 -0
@@ -0,0 +1,215 @@
1
+ import type {AddSyntaxGrammar} from './syntax_styler.js';
2
+ import {grammar_markup_add_attribute, grammar_markup_add_inlined} from './grammar_markup.js';
3
+ import {class_keywords} from './grammar_clike.js';
4
+
5
+ /**
6
+ * Based on Prism (https://github.com/PrismJS/prism)
7
+ * by Lea Verou (https://lea.verou.me/)
8
+ *
9
+ * MIT license
10
+ *
11
+ * @see LICENSE
12
+ */
13
+ export const add_grammar_js: AddSyntaxGrammar = (syntax_styler) => {
14
+ const grammar_clike = syntax_styler.get_lang('clike');
15
+
16
+ // Main JS keywords (from keyword pattern, excluding those with special lookaheads)
17
+ const main_keywords =
18
+ 'class|const|debugger|delete|enum|extends|function|implements|in|instanceof|interface|let|new|null|of|package|private|protected|public|static|super|this|typeof|undefined|var|void|with';
19
+
20
+ // Keywords that are treated specially (inserted before 'function')
21
+ const special_keywords =
22
+ 'as|await|break|case|catch|continue|default|do|else|export|finally|for|from|if|import|return|switch|throw|try|while|yield';
23
+
24
+ // All JS keywords (for negative lookahead in parameter pattern)
25
+ // Note: 'assert', 'async', 'get', 'set' have special lookahead requirements in the main keyword pattern
26
+ const all_js_keywords = `assert|async|${main_keywords}|get|set|${special_keywords}`;
27
+
28
+ const grammar_js = syntax_styler.add_extended_lang(
29
+ 'clike',
30
+ 'js',
31
+ {
32
+ class_name: [
33
+ ...grammar_clike.class_name!,
34
+ {
35
+ pattern:
36
+ /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
37
+ lookbehind: true,
38
+ },
39
+ ],
40
+ keyword: [
41
+ {
42
+ pattern: new RegExp(
43
+ `(^|[^.]|\\.\\.\\.\\s*)\\b(?:assert(?=\\s*\\{)|async(?=\\s*(?:function\\b|\\*|\\(|[$\\w\\xA0-\\uFFFF]|$))|${main_keywords}|(?:get|set)(?=\\s*(?:[#[$\\w\\xA0-\\uFFFF]|$)))\\b`,
44
+ ),
45
+ lookbehind: true,
46
+ },
47
+ ],
48
+ // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
49
+ function:
50
+ /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
51
+ number: {
52
+ pattern: RegExp(
53
+ /(^|[^\w$])/.source +
54
+ '(?:' +
55
+ // constant
56
+ (/NaN|Infinity/.source +
57
+ '|' +
58
+ // binary integer
59
+ /0[bB][01]+(?:_[01]+)*n?/.source +
60
+ '|' +
61
+ // octal integer
62
+ /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
63
+ '|' +
64
+ // hexadecimal integer
65
+ /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
66
+ '|' +
67
+ // decimal bigint
68
+ /\d+(?:_\d+)*n/.source +
69
+ '|' +
70
+ // decimal number (integer or float) but no bigint
71
+ /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/
72
+ .source) +
73
+ ')' +
74
+ /(?![\w$])/.source,
75
+ ),
76
+ lookbehind: true,
77
+ },
78
+ operator:
79
+ /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/,
80
+ },
81
+ ['javascript'],
82
+ );
83
+
84
+ (grammar_js as any).class_name[0].pattern = new RegExp(
85
+ `(\\b(?:${class_keywords})\\s+)[\\w.\\\\]+`,
86
+ );
87
+
88
+ syntax_styler.grammar_insert_before('js', 'function', {
89
+ special_keyword: new RegExp(`\\b(?:${special_keywords})\\b`),
90
+ });
91
+
92
+ syntax_styler.grammar_insert_before('js', 'keyword', {
93
+ regex: {
94
+ pattern: RegExp(
95
+ // lookbehind
96
+ /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
97
+ // Regex pattern:
98
+ // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
99
+ // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
100
+ // with the only syntax, so we have to define 2 different regex patterns.
101
+ /\//.source +
102
+ '(?:' +
103
+ /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\[\r\n])+\/[dgimyus]{0,7}/.source +
104
+ '|' +
105
+ // `v` flag syntax. This supports 3 levels of nested character classes.
106
+ /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/
107
+ .source +
108
+ ')' +
109
+ // lookahead
110
+ /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source,
111
+ ),
112
+ lookbehind: true,
113
+ greedy: true,
114
+ inside: {
115
+ regex_source: {
116
+ pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
117
+ lookbehind: true,
118
+ alias: 'lang_regex',
119
+ inside: syntax_styler.langs.regex, // TODO use `get_lang` after adding `regex` support
120
+ },
121
+ regex_delimiter: /^\/|\/$/,
122
+ regex_flags: /^[a-z]+$/,
123
+ },
124
+ },
125
+ // Arrow function and function expression variable names
126
+ // This must be declared before keyword because we use "function" inside the look-forward
127
+ function_variable: {
128
+ pattern:
129
+ /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
130
+ alias: 'function',
131
+ },
132
+ parameter: [
133
+ {
134
+ pattern:
135
+ /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
136
+ lookbehind: true,
137
+ inside: grammar_js,
138
+ },
139
+ {
140
+ pattern:
141
+ /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
142
+ lookbehind: true,
143
+ inside: grammar_js,
144
+ },
145
+ {
146
+ pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
147
+ lookbehind: true,
148
+ inside: grammar_js,
149
+ },
150
+ {
151
+ pattern: new RegExp(
152
+ `((?:\\b|\\s|^)(?!(?:${all_js_keywords})(?![$\\w\\xA0-\\uFFFF]))(?:(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*\\s*)\\(\\s*|\\]\\s*\\(\\s*)(?!\\s)(?:[^()\\s]|\\s+(?![\\s)])|\\([^()]*\\))+(?=\\s*\\)\\s*\\{)`,
153
+ ),
154
+ lookbehind: true,
155
+ inside: grammar_js,
156
+ },
157
+ ],
158
+ constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/,
159
+ // Heuristic: treat capitalized identifiers as class names when not already matched
160
+ capitalized_identifier: {
161
+ pattern: /\b[A-Z][\w]*\b/,
162
+ alias: 'class_name',
163
+ },
164
+ });
165
+
166
+ syntax_styler.grammar_insert_before('js', 'string', {
167
+ hashbang: {
168
+ pattern: /^#!.*/,
169
+ greedy: true,
170
+ alias: 'comment',
171
+ },
172
+ template_string: {
173
+ pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
174
+ greedy: true,
175
+ inside: {
176
+ template_punctuation: {
177
+ pattern: /^`|`$/,
178
+ alias: 'string',
179
+ },
180
+ interpolation: {
181
+ pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
182
+ lookbehind: true,
183
+ inside: {
184
+ interpolation_punctuation: {
185
+ pattern: /^\$\{|\}$/,
186
+ alias: 'punctuation',
187
+ },
188
+ rest: grammar_js as any, // TODO try to fix this type
189
+ },
190
+ },
191
+ string: /[\s\S]+/,
192
+ },
193
+ },
194
+ string_property: {
195
+ pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
196
+ lookbehind: true,
197
+ greedy: true,
198
+ alias: 'property',
199
+ },
200
+ });
201
+
202
+ syntax_styler.grammar_insert_before('js', 'operator', {
203
+ literal_property: {
204
+ pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
205
+ lookbehind: true,
206
+ alias: 'property',
207
+ },
208
+ });
209
+
210
+ grammar_markup_add_inlined(syntax_styler, 'script', 'js');
211
+
212
+ // add attribute support for all DOM events (on* attributes)
213
+ // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
214
+ grammar_markup_add_attribute(syntax_styler, 'on\\w+', 'js');
215
+ };
@@ -0,0 +1,38 @@
1
+ import type {AddSyntaxGrammar, SyntaxGrammarRaw} from './syntax_styler.js';
2
+
3
+ /**
4
+ * Based on Prism (https://github.com/PrismJS/prism)
5
+ * by Lea Verou (https://lea.verou.me/)
6
+ *
7
+ * MIT license
8
+ *
9
+ * @see LICENSE
10
+ */
11
+ export const add_grammar_json: AddSyntaxGrammar = (syntax_styler) => {
12
+ const grammar_json = {
13
+ property: {
14
+ pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,
15
+ lookbehind: true,
16
+ greedy: true,
17
+ },
18
+ string: {
19
+ pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
20
+ lookbehind: true,
21
+ greedy: true,
22
+ },
23
+ comment: {
24
+ pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
25
+ greedy: true,
26
+ },
27
+ number: /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,
28
+ punctuation: /[{}[\],]/,
29
+ operator: /:/,
30
+ boolean: /\b(?:false|true)\b/,
31
+ null: {
32
+ pattern: /\bnull\b/,
33
+ alias: 'keyword',
34
+ },
35
+ } satisfies SyntaxGrammarRaw;
36
+
37
+ syntax_styler.add_lang('json', grammar_json);
38
+ };
@@ -0,0 +1,289 @@
1
+ import type {
2
+ AddSyntaxGrammar,
3
+ SyntaxGrammarTokenRaw,
4
+ SyntaxGrammarValueRaw,
5
+ SyntaxStyler,
6
+ } from './syntax_styler.js';
7
+
8
+ interface LangDefinition {
9
+ aliases: Array<string>;
10
+ id: string;
11
+ }
12
+
13
+ interface FenceType {
14
+ backticks: string;
15
+ suffix: string;
16
+ }
17
+
18
+ /**
19
+ * Helper to create fenced code block pattern for a language
20
+ */
21
+ const create_fence_pattern = (
22
+ backticks: string,
23
+ aliases: Array<string>,
24
+ lang_id: string,
25
+ syntax_styler: SyntaxStyler,
26
+ ): SyntaxGrammarTokenRaw => {
27
+ const aliases_pattern = aliases.join('|');
28
+ const pattern = new RegExp(
29
+ `^${backticks}(?:${aliases_pattern})[^\\n\\r]*(?:\\r?\\n|\\r)[\\s\\S]*?^${backticks}$`,
30
+ 'm',
31
+ );
32
+ const code_fence_pattern = new RegExp(`^${backticks}[^\\n\\r]*|^${backticks}$`, 'm');
33
+
34
+ return {
35
+ pattern,
36
+ greedy: true,
37
+ inside: {
38
+ code_fence: {
39
+ pattern: code_fence_pattern,
40
+ alias: 'punctuation',
41
+ },
42
+ [`lang_${lang_id}`]: {
43
+ pattern: /[\s\S]+/,
44
+ inside: syntax_styler.get_lang(lang_id),
45
+ },
46
+ },
47
+ };
48
+ };
49
+
50
+ /**
51
+ * Helper to create catch-all fence pattern (unknown languages)
52
+ */
53
+ const create_catchall_fence = (backticks: string): SyntaxGrammarTokenRaw => {
54
+ const pattern = new RegExp(`^${backticks}[^\\n\\r]*(?:\\r?\\n|\\r)[\\s\\S]*?^${backticks}$`, 'm');
55
+ const code_fence_pattern = new RegExp(`^${backticks}[^\\n\\r]*|^${backticks}$`, 'm');
56
+
57
+ return {
58
+ pattern,
59
+ greedy: true,
60
+ inside: {
61
+ code_fence: {
62
+ pattern: code_fence_pattern,
63
+ alias: 'punctuation',
64
+ },
65
+ },
66
+ };
67
+ };
68
+
69
+ /**
70
+ * Helper to create md self-reference placeholder pattern
71
+ */
72
+ const create_md_placeholder = (backticks: string): SyntaxGrammarTokenRaw => {
73
+ const pattern = new RegExp(
74
+ `^${backticks}(?:md|markdown)[^\\n\\r]*(?:\\r?\\n|\\r)[\\s\\S]*?^${backticks}$`,
75
+ 'm',
76
+ );
77
+ const code_fence_pattern = new RegExp(`^${backticks}[^\\n\\r]*|^${backticks}$`, 'm');
78
+
79
+ return {
80
+ pattern,
81
+ greedy: true,
82
+ inside: {
83
+ code_fence: {
84
+ pattern: code_fence_pattern,
85
+ alias: 'punctuation',
86
+ },
87
+ // lang_md will be added after registration
88
+ },
89
+ };
90
+ };
91
+
92
+ /**
93
+ * Markdown grammar extending markup.
94
+ * Supports: headings, fenced code blocks (3/4/5 backticks with nesting), lists, blockquotes,
95
+ * bold, italic, strikethrough, inline code, and links.
96
+ */
97
+ export const add_grammar_markdown: AddSyntaxGrammar = (syntax_styler) => {
98
+ // Language definitions with aliases
99
+ const langs: Array<LangDefinition> = [
100
+ {aliases: ['ts', 'typescript'], id: 'ts'},
101
+ {aliases: ['js', 'javascript'], id: 'js'},
102
+ {aliases: ['css'], id: 'css'},
103
+ {aliases: ['html', 'markup'], id: 'markup'},
104
+ {aliases: ['json'], id: 'json'},
105
+ {aliases: ['svelte'], id: 'svelte'},
106
+ ];
107
+
108
+ // Fence types: higher counts first (for proper precedence in tokenization)
109
+ const fence_types: Array<FenceType> = [
110
+ {backticks: '`````', suffix: '5tick'},
111
+ {backticks: '````', suffix: '4tick'},
112
+ {backticks: '```', suffix: ''},
113
+ ];
114
+
115
+ // Build grammar dynamically
116
+ const grammar: Record<string, SyntaxGrammarValueRaw> = {};
117
+ const md_self_refs: Array<string> = []; // Track md patterns for later self-reference
118
+
119
+ // Generate fence patterns for each type
120
+ for (const {backticks, suffix} of fence_types) {
121
+ const token_suffix = suffix ? `_${suffix}` : '';
122
+
123
+ // md pattern (self-reference added after registration)
124
+ const md_key = `fenced_code${token_suffix}_md`;
125
+ grammar[md_key] = create_md_placeholder(backticks);
126
+ md_self_refs.push(md_key);
127
+
128
+ // Other language patterns (use first alias as token name for backward compatibility)
129
+ for (const {aliases, id} of langs) {
130
+ const token_name = aliases[0]; // Use first alias for token name
131
+ grammar[`fenced_code${token_suffix}_${token_name}`] = create_fence_pattern(
132
+ backticks,
133
+ aliases,
134
+ id,
135
+ syntax_styler,
136
+ );
137
+ }
138
+
139
+ // Catch-all fence
140
+ grammar[`fenced_code${token_suffix}`] = create_catchall_fence(backticks);
141
+ }
142
+
143
+ // Register markdown grammar first, then add self-references for md fences
144
+ const grammar_md = syntax_styler.add_extended_lang(
145
+ 'markup',
146
+ 'md',
147
+ {
148
+ ...grammar,
149
+
150
+ // Headings (# through ######)
151
+ heading: {
152
+ pattern: /^#{1,6}\s+.+$/m,
153
+ inside: {
154
+ punctuation: {
155
+ pattern: /^#{1,6}/,
156
+ alias: 'heading_punctuation',
157
+ },
158
+ },
159
+ },
160
+
161
+ // Blockquotes (> at line start)
162
+ blockquote: {
163
+ pattern: /^>\s*.+$/m,
164
+ inside: {
165
+ punctuation: {
166
+ pattern: /^>/,
167
+ alias: 'blockquote_punctuation',
168
+ },
169
+ },
170
+ },
171
+
172
+ // Lists (* or - with any preceding whitespace)
173
+ list: {
174
+ pattern: /^\s*[-*]\s+.+$/m,
175
+ inside: {
176
+ punctuation: /^\s*[-*]/,
177
+ },
178
+ },
179
+
180
+ // Inline elements
181
+
182
+ // Links [text](url)
183
+ link: {
184
+ pattern: /\[[^[\]\n\r]+\]\([^)\n\r]+\)/,
185
+ inside: {
186
+ link_text_wrapper: {
187
+ pattern: /^\[[^\]]+\]/,
188
+ inside: {
189
+ punctuation: {
190
+ pattern: /^\[|\]$/,
191
+ alias: 'link_punctuation',
192
+ },
193
+ link_text: /[^[\]]+/,
194
+ },
195
+ },
196
+ url_wrapper: {
197
+ pattern: /\([^)]+\)$/,
198
+ inside: {
199
+ punctuation: {
200
+ pattern: /^\(|\)$/,
201
+ alias: 'link_punctuation',
202
+ },
203
+ url: /[^()]+/,
204
+ },
205
+ },
206
+ },
207
+ },
208
+
209
+ // Inline code `text`
210
+ inline_code: {
211
+ pattern: /`[^`\n\r]+`/,
212
+ alias: 'code',
213
+ inside: {
214
+ punctuation: {
215
+ pattern: /^`|`$/,
216
+ alias: 'code_punctuation',
217
+ },
218
+ content: /[^`]+/,
219
+ },
220
+ },
221
+
222
+ // Bold **text** or __text__
223
+ bold: [
224
+ {
225
+ // **text** - no asterisks inside
226
+ pattern: /\*\*[^\s*][^*]*[^\s*]\*\*|\*\*[^\s*]\*\*/,
227
+ inside: {
228
+ punctuation: /^\*\*|\*\*$/,
229
+ },
230
+ },
231
+ {
232
+ // __text__ - at word boundaries, no underscores inside
233
+ pattern: /\b__[^\s_][^_]*[^\s_]__\b|\b__[^\s_]__\b/,
234
+ inside: {
235
+ punctuation: /^__|__$/,
236
+ },
237
+ },
238
+ ],
239
+
240
+ // Italic *text* or _text_
241
+ italic: [
242
+ {
243
+ // *text* - no asterisks inside
244
+ pattern: /\*[^\s*][^*]*[^\s*]\*|\*[^\s*]\*/,
245
+ inside: {
246
+ punctuation: /^\*|\*$/,
247
+ },
248
+ },
249
+ {
250
+ // _text_ - at word boundaries, no underscores inside
251
+ pattern: /\b_[^\s_][^_]*[^\s_]_\b|\b_[^\s_]_\b/,
252
+ inside: {
253
+ punctuation: /^_|_$/,
254
+ },
255
+ },
256
+ ],
257
+
258
+ // Strikethrough ~~text~~
259
+ strikethrough: {
260
+ pattern: /~~[^\s~][^~]*[^\s~]~~|~~[^\s~]~~/,
261
+ inside: {
262
+ punctuation: /^~~|~~$/,
263
+ },
264
+ },
265
+ },
266
+ ['markdown'],
267
+ );
268
+
269
+ // Add self-reference for markdown-in-markdown (all fence types)
270
+ // This must be done after registration to avoid circular dependency
271
+ const lang_md_inside = {
272
+ pattern: /[\s\S]+/,
273
+ inside: syntax_styler.get_lang('md'),
274
+ };
275
+ for (const key of md_self_refs) {
276
+ // After normalization, grammar values are arrays of SyntaxGrammarToken
277
+ // We need to add lang_md as a normalized array
278
+ const patterns = grammar_md[key]!;
279
+ // Manually normalize the lang_md pattern we're adding
280
+ const lang_md_token = {
281
+ pattern: lang_md_inside.pattern,
282
+ lookbehind: false,
283
+ greedy: false,
284
+ alias: [],
285
+ inside: lang_md_inside.inside,
286
+ };
287
+ patterns[0]!.inside!.lang_md = [lang_md_token];
288
+ }
289
+ };