fractalpop 0.1.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.
- package/LICENSE +21 -0
- package/README.md +232 -0
- package/dist/core.d.ts +110 -0
- package/dist/core.js +313 -0
- package/dist/full.d.ts +1 -0
- package/dist/full.js +356 -0
- package/dist/gpu.d.ts +59 -0
- package/dist/gpu.js +215 -0
- package/dist/index.d.ts +108 -0
- package/dist/index.js +523 -0
- package/dist/lang/c.d.ts +5 -0
- package/dist/lang/c.js +90 -0
- package/dist/lang/cpp.d.ts +5 -0
- package/dist/lang/cpp.js +138 -0
- package/dist/lang/csharp.d.ts +5 -0
- package/dist/lang/csharp.js +148 -0
- package/dist/lang/css.d.ts +21 -0
- package/dist/lang/css.js +164 -0
- package/dist/lang/diff.d.ts +30 -0
- package/dist/lang/diff.js +18 -0
- package/dist/lang/dockerfile.d.ts +5 -0
- package/dist/lang/dockerfile.js +60 -0
- package/dist/lang/go.d.ts +5 -0
- package/dist/lang/go.js +91 -0
- package/dist/lang/graphql.d.ts +5 -0
- package/dist/lang/graphql.js +66 -0
- package/dist/lang/hcl.d.ts +5 -0
- package/dist/lang/hcl.js +51 -0
- package/dist/lang/html.d.ts +12 -0
- package/dist/lang/html.js +168 -0
- package/dist/lang/java.d.ts +5 -0
- package/dist/lang/java.js +96 -0
- package/dist/lang/javascript.d.ts +5 -0
- package/dist/lang/javascript.js +0 -0
- package/dist/lang/json.d.ts +5 -0
- package/dist/lang/json.js +47 -0
- package/dist/lang/kotlin.d.ts +5 -0
- package/dist/lang/kotlin.js +113 -0
- package/dist/lang/lua.d.ts +5 -0
- package/dist/lang/lua.js +65 -0
- package/dist/lang/markdown.d.ts +12 -0
- package/dist/lang/markdown.js +172 -0
- package/dist/lang/php.d.ts +5 -0
- package/dist/lang/php.js +129 -0
- package/dist/lang/plaintext.d.ts +7 -0
- package/dist/lang/plaintext.js +3 -0
- package/dist/lang/powershell.d.ts +5 -0
- package/dist/lang/powershell.js +74 -0
- package/dist/lang/python.d.ts +5 -0
- package/dist/lang/python.js +75 -0
- package/dist/lang/ruby.d.ts +5 -0
- package/dist/lang/ruby.js +84 -0
- package/dist/lang/rust.d.ts +5 -0
- package/dist/lang/rust.js +95 -0
- package/dist/lang/sass.d.ts +15 -0
- package/dist/lang/sass.js +201 -0
- package/dist/lang/scss.d.ts +14 -0
- package/dist/lang/scss.js +105 -0
- package/dist/lang/shell.d.ts +5 -0
- package/dist/lang/shell.js +64 -0
- package/dist/lang/sql.d.ts +5 -0
- package/dist/lang/sql.js +129 -0
- package/dist/lang/svelte.d.ts +15 -0
- package/dist/lang/svelte.js +0 -0
- package/dist/lang/swift.d.ts +5 -0
- package/dist/lang/swift.js +125 -0
- package/dist/lang/toml.d.ts +5 -0
- package/dist/lang/toml.js +45 -0
- package/dist/lang/typescript.d.ts +5 -0
- package/dist/lang/typescript.js +0 -0
- package/dist/lang/yaml.d.ts +5 -0
- package/dist/lang/yaml.js +64 -0
- package/dist/lang/zig.d.ts +5 -0
- package/dist/lang/zig.js +133 -0
- package/dist/lang.d.ts +30 -0
- package/dist/lang.js +345 -0
- package/package.json +68 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as __core_js from './core.js';
|
|
2
|
+
import { ParseOptions } from './core.js';
|
|
3
|
+
|
|
4
|
+
/** Mutable registry that maps a canonical language id to its parse config. */
|
|
5
|
+
|
|
6
|
+
declare function getLanguageConfig(id: string): ParseOptions | undefined;
|
|
7
|
+
declare function resetLanguageConfigRegistry(): void;
|
|
8
|
+
|
|
9
|
+
/** Mutable language metadata registry with alias/extension normalization. */
|
|
10
|
+
|
|
11
|
+
interface Language {
|
|
12
|
+
id: string;
|
|
13
|
+
extension: string;
|
|
14
|
+
aliases: readonly string[];
|
|
15
|
+
}
|
|
16
|
+
declare function registerLanguage(language: Language, config?: ParseOptions): void;
|
|
17
|
+
declare function setDefaults(languages: readonly Language[]): void;
|
|
18
|
+
declare function setDefaults(configs: Record<string, ParseOptions>): void;
|
|
19
|
+
declare function importDefaults(ids: string[]): Promise<void>;
|
|
20
|
+
/** Find canonical language metadata by name, alias, or extension. */
|
|
21
|
+
declare function findLanguage(name: string): Language | undefined;
|
|
22
|
+
/** Resolve a name/alias/extension to its canonical language id. */
|
|
23
|
+
declare function lang(name: string): string | undefined;
|
|
24
|
+
/** Alias for {@link lang}. */
|
|
25
|
+
declare const canonicalizeLang: typeof lang;
|
|
26
|
+
declare function getRegisteredLanguages(): readonly Language[];
|
|
27
|
+
declare function resetLanguageRegistry(): void;
|
|
28
|
+
|
|
29
|
+
declare const allLanguages: readonly Language[];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* fractalpop core — token model, line assembly, and rendering.
|
|
33
|
+
*
|
|
34
|
+
* Design: tokens are numeric `[type, value]` pairs during lexing (fast Set/array
|
|
35
|
+
* work); the string type names are resolved only at render. Output is an HTML
|
|
36
|
+
* string with no DOM required — so SSR and client produce identical markup.
|
|
37
|
+
*/
|
|
38
|
+
/** The stable, ordered token-type list. This list is the theming contract:
|
|
39
|
+
* each type maps to one CSS variable `--fp-<type>` and one class `fp__token--<type>`. */
|
|
40
|
+
declare const TokenTypes: readonly ["identifier", "keyword", "string", "class", "property", "entity", "jsxliterals", "sign", "comment", "break", "space"];
|
|
41
|
+
type TokenType = (typeof TokenTypes)[number];
|
|
42
|
+
interface ParsedToken {
|
|
43
|
+
type: TokenType;
|
|
44
|
+
value: string;
|
|
45
|
+
}
|
|
46
|
+
/** Mutable token handed to `mark`. Hooks may change className/style/properties. */
|
|
47
|
+
interface MarkToken {
|
|
48
|
+
type: TokenType;
|
|
49
|
+
value: string;
|
|
50
|
+
className: string;
|
|
51
|
+
style: Record<string, string | number>;
|
|
52
|
+
properties: Record<string, string | number | boolean>;
|
|
53
|
+
}
|
|
54
|
+
/** Mutable line handed to `markLine`. Hooks may change className/style/properties. */
|
|
55
|
+
interface MarkLine {
|
|
56
|
+
index: number;
|
|
57
|
+
value: string;
|
|
58
|
+
tokens: ParsedToken[];
|
|
59
|
+
annotations: string[];
|
|
60
|
+
className: string;
|
|
61
|
+
style: Record<string, string | number>;
|
|
62
|
+
properties: Record<string, string | number | boolean>;
|
|
63
|
+
}
|
|
64
|
+
interface DisplayOptions {
|
|
65
|
+
/** Extra class name appended per token type, e.g. `{ keyword: 'font-bold' }`. */
|
|
66
|
+
cx?: Partial<Record<TokenType, string>>;
|
|
67
|
+
/** Mutate a single token before it renders. */
|
|
68
|
+
mark?: (token: MarkToken) => void;
|
|
69
|
+
/** Mutate a whole line before it renders (used for line highlighting). */
|
|
70
|
+
markLine?: (line: MarkLine) => void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Highlight range: either a single 1-based line or an inclusive [start, end] pair. */
|
|
74
|
+
type HighlightRange = number | [number, number];
|
|
75
|
+
/**
|
|
76
|
+
* Parse `{1,3-5,7}` fence metadata into a Set of 1-based line numbers.
|
|
77
|
+
*
|
|
78
|
+
* Tolerates whitespace (`{ 1 , 3 - 5 }`) and silently ignores invalid or
|
|
79
|
+
* negative numbers.
|
|
80
|
+
*/
|
|
81
|
+
declare function parseHighlightMeta(meta?: string | null): Set<number>;
|
|
82
|
+
/**
|
|
83
|
+
* Convert `{1,3-5,7}` fence metadata into remark-compatible highlight ranges.
|
|
84
|
+
*
|
|
85
|
+
* Returns single numbers for individual lines and `[start, end]` tuples for
|
|
86
|
+
* explicit ranges. Invalid/negative numbers are ignored.
|
|
87
|
+
*/
|
|
88
|
+
declare function toHighlightRanges(meta?: string | null): HighlightRange[];
|
|
89
|
+
/** Escape characters Svelte's compiler would otherwise interpret in markup. */
|
|
90
|
+
declare function escapeSvelte(html: string): string;
|
|
91
|
+
|
|
92
|
+
interface HighlightOptions extends DisplayOptions {
|
|
93
|
+
/** Language id, extension, or alias. Defaults to 'typescript'. */
|
|
94
|
+
lang?: string;
|
|
95
|
+
/** Explicit parse config that overrides the registry. */
|
|
96
|
+
config?: __core_js.ParseOptions;
|
|
97
|
+
}
|
|
98
|
+
interface LanguagePair {
|
|
99
|
+
language: Language;
|
|
100
|
+
config: __core_js.ParseOptions;
|
|
101
|
+
}
|
|
102
|
+
/** Register multiple languages with their parse configs. */
|
|
103
|
+
declare function registerLanguages(languages: readonly LanguagePair[]): void;
|
|
104
|
+
/** Highlight `code` to an HTML string. No DOM required. */
|
|
105
|
+
declare function highlight(code: string, options?: HighlightOptions): string;
|
|
106
|
+
|
|
107
|
+
export { allLanguages, canonicalizeLang, escapeSvelte, findLanguage, getLanguageConfig, getRegisteredLanguages, highlight, importDefaults, lang, parseHighlightMeta, registerLanguage, registerLanguages, resetLanguageConfigRegistry, resetLanguageRegistry, setDefaults, toHighlightRanges };
|
|
108
|
+
export type { DisplayOptions, HighlightOptions, HighlightRange, LanguagePair, MarkLine, MarkToken, HighlightOptions as Options, TokenType };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
import { parse } from './core.js';
|
|
2
|
+
import { config as config$1 } from './lang/typescript.js';
|
|
3
|
+
import { config } from './lang/plaintext.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* fractalpop core — token model, line assembly, and rendering.
|
|
7
|
+
*
|
|
8
|
+
* Design: tokens are numeric `[type, value]` pairs during lexing (fast Set/array
|
|
9
|
+
* work); the string type names are resolved only at render. Output is an HTML
|
|
10
|
+
* string with no DOM required — so SSR and client produce identical markup.
|
|
11
|
+
*/ /** The stable, ordered token-type list. This list is the theming contract:
|
|
12
|
+
* each type maps to one CSS variable `--fp-<type>` and one class `fp__token--<type>`. */ const TokenTypes = [
|
|
13
|
+
'identifier',
|
|
14
|
+
'keyword',
|
|
15
|
+
'string',
|
|
16
|
+
'class',
|
|
17
|
+
'property',
|
|
18
|
+
'entity',
|
|
19
|
+
'jsxliterals',
|
|
20
|
+
'sign',
|
|
21
|
+
'comment',
|
|
22
|
+
'break',
|
|
23
|
+
'space'
|
|
24
|
+
];
|
|
25
|
+
({
|
|
26
|
+
TokenMap: new Map(TokenTypes.map((type, index)=>[
|
|
27
|
+
type,
|
|
28
|
+
index
|
|
29
|
+
]))
|
|
30
|
+
});
|
|
31
|
+
function lineClassName(annotations) {
|
|
32
|
+
return `fp__line${annotations.map((annotation)=>` fp__line--${annotation}`).join('')}`;
|
|
33
|
+
}
|
|
34
|
+
function createLine(parsedLine, markLine) {
|
|
35
|
+
const line = {
|
|
36
|
+
index: parsedLine.index,
|
|
37
|
+
value: parsedLine.value,
|
|
38
|
+
tokens: parsedLine.tokens,
|
|
39
|
+
annotations: parsedLine.annotations,
|
|
40
|
+
className: lineClassName(parsedLine.annotations),
|
|
41
|
+
style: {},
|
|
42
|
+
properties: {}
|
|
43
|
+
};
|
|
44
|
+
markLine?.(line);
|
|
45
|
+
return line;
|
|
46
|
+
}
|
|
47
|
+
function createToken({ type, value }, cx, mark) {
|
|
48
|
+
const extraClassName = cx?.[type];
|
|
49
|
+
const token = {
|
|
50
|
+
type,
|
|
51
|
+
value,
|
|
52
|
+
className: `fp__token--${type}${extraClassName ? ` ${extraClassName}` : ''}`,
|
|
53
|
+
style: {
|
|
54
|
+
color: `var(--fp-${type})`
|
|
55
|
+
},
|
|
56
|
+
properties: {}
|
|
57
|
+
};
|
|
58
|
+
mark?.(token);
|
|
59
|
+
return token;
|
|
60
|
+
}
|
|
61
|
+
/** Render parsed lines to an HTML string. Fast path when no display hooks are set. */ function render(parsed, options) {
|
|
62
|
+
const cx = options?.cx;
|
|
63
|
+
const mark = options?.mark;
|
|
64
|
+
const markLine = options?.markLine;
|
|
65
|
+
// Fast path: no per-token object allocation, straight string concat.
|
|
66
|
+
if (!cx && !mark && !markLine) {
|
|
67
|
+
return parsed.lines.map((line)=>{
|
|
68
|
+
const className = lineClassName(line.annotations);
|
|
69
|
+
const children = line.tokens.map(({ type, value })=>`<span class="fp__token--${type}" style="color:var(--fp-${type})">${encode(value)}</span>`).join('');
|
|
70
|
+
return `<span class="${encode(className)}">${children}</span>`;
|
|
71
|
+
}).join('\n');
|
|
72
|
+
}
|
|
73
|
+
// Hook path: build mutable objects and run cx/mark/markLine.
|
|
74
|
+
return parsed.lines.map((parsedLine)=>{
|
|
75
|
+
const line = createLine(parsedLine, markLine);
|
|
76
|
+
const children = parsedLine.tokens.map((parsedToken)=>{
|
|
77
|
+
const token = createToken(parsedToken, cx, mark);
|
|
78
|
+
return `<span ${attributes({
|
|
79
|
+
...token.properties,
|
|
80
|
+
className: token.className,
|
|
81
|
+
style: token.style
|
|
82
|
+
})}>${encode(token.value)}</span>`;
|
|
83
|
+
}).join('');
|
|
84
|
+
return `<span ${attributes({
|
|
85
|
+
...line.properties,
|
|
86
|
+
className: line.className,
|
|
87
|
+
style: line.style
|
|
88
|
+
})}>${children}</span>`;
|
|
89
|
+
}).join('\n');
|
|
90
|
+
}
|
|
91
|
+
const entities = {
|
|
92
|
+
'&': '&',
|
|
93
|
+
'<': '<',
|
|
94
|
+
'>': '>',
|
|
95
|
+
'"': '"',
|
|
96
|
+
"'": '''
|
|
97
|
+
};
|
|
98
|
+
const encode = (value)=>value.replace(/[&<>"']/g, (character)=>entities[character]);
|
|
99
|
+
function attributes(values) {
|
|
100
|
+
const styleValue = values.style ?? {};
|
|
101
|
+
const style = Object.entries(styleValue).map(([key, value])=>`${key.replace(/[A-Z]/g, (match)=>`-${match.toLowerCase()}`)}:${value}`).join(';');
|
|
102
|
+
const properties = Object.entries(values).filter(([key, value])=>/^[\w:-]+$/.test(key) && key !== 'className' && key !== 'style' && value !== false && value != null).map(([key, value])=>value === true ? key : `${key}="${encode(String(value))}"`).join(' ');
|
|
103
|
+
const className = values.className || '';
|
|
104
|
+
return `class="${encode(className)}"${style ? ` style="${encode(style)}"` : ''}${properties ? ` ${properties}` : ''}`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Mutable registry that maps a canonical language id to its parse config. */ const configRegistry = new Map();
|
|
108
|
+
function registerLanguageConfig(id, config) {
|
|
109
|
+
configRegistry.set(id, config);
|
|
110
|
+
}
|
|
111
|
+
function getLanguageConfig(id) {
|
|
112
|
+
return configRegistry.get(id);
|
|
113
|
+
}
|
|
114
|
+
function resetLanguageConfigRegistry() {
|
|
115
|
+
configRegistry.clear();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const languageRegistry = new Map();
|
|
119
|
+
function normalizeLanguageName(value) {
|
|
120
|
+
return value.trim().toLowerCase().replace(/^\./, '');
|
|
121
|
+
}
|
|
122
|
+
function registerName(name, language) {
|
|
123
|
+
const normalized = normalizeLanguageName(name);
|
|
124
|
+
if (!normalized) return;
|
|
125
|
+
const existing = languageRegistry.get(normalized);
|
|
126
|
+
if (existing && existing.id !== language.id) {
|
|
127
|
+
throw new Error(`Language name "${normalized}" is shared by "${existing.id}" and "${language.id}"`);
|
|
128
|
+
}
|
|
129
|
+
languageRegistry.set(normalized, language);
|
|
130
|
+
}
|
|
131
|
+
function registerLanguage(language, config) {
|
|
132
|
+
const names = new Set([
|
|
133
|
+
language.id,
|
|
134
|
+
language.extension,
|
|
135
|
+
...language.aliases
|
|
136
|
+
]);
|
|
137
|
+
for (const name of names){
|
|
138
|
+
registerName(name, language);
|
|
139
|
+
}
|
|
140
|
+
if (config) {
|
|
141
|
+
registerLanguageConfig(language.id, config);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function setDefaults(input) {
|
|
145
|
+
resetLanguageRegistry();
|
|
146
|
+
resetLanguageConfigRegistry();
|
|
147
|
+
if (Array.isArray(input)) {
|
|
148
|
+
for (const language of input){
|
|
149
|
+
registerLanguage(language);
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
for (const [id, config] of Object.entries(input)){
|
|
153
|
+
const language = allLanguages.find((l)=>l.id === id);
|
|
154
|
+
if (language) {
|
|
155
|
+
registerLanguage(language, config);
|
|
156
|
+
} else {
|
|
157
|
+
registerLanguage({
|
|
158
|
+
id,
|
|
159
|
+
extension: id,
|
|
160
|
+
aliases: []
|
|
161
|
+
}, config);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const configImporters = {
|
|
167
|
+
javascript: ()=>import('./lang/javascript.js'),
|
|
168
|
+
typescript: ()=>import('./lang/typescript.js'),
|
|
169
|
+
css: ()=>import('./lang/css.js'),
|
|
170
|
+
scss: ()=>import('./lang/scss.js'),
|
|
171
|
+
sass: ()=>import('./lang/sass.js'),
|
|
172
|
+
html: ()=>import('./lang/html.js'),
|
|
173
|
+
svelte: ()=>import('./lang/svelte.js'),
|
|
174
|
+
markdown: ()=>import('./lang/markdown.js'),
|
|
175
|
+
diff: ()=>import('./lang/diff.js'),
|
|
176
|
+
plaintext: ()=>import('./lang/plaintext.js'),
|
|
177
|
+
c: ()=>import('./lang/c.js'),
|
|
178
|
+
cpp: ()=>import('./lang/cpp.js'),
|
|
179
|
+
csharp: ()=>import('./lang/csharp.js'),
|
|
180
|
+
dockerfile: ()=>import('./lang/dockerfile.js'),
|
|
181
|
+
go: ()=>import('./lang/go.js'),
|
|
182
|
+
graphql: ()=>import('./lang/graphql.js'),
|
|
183
|
+
hcl: ()=>import('./lang/hcl.js'),
|
|
184
|
+
java: ()=>import('./lang/java.js'),
|
|
185
|
+
json: ()=>import('./lang/json.js'),
|
|
186
|
+
kotlin: ()=>import('./lang/kotlin.js'),
|
|
187
|
+
lua: ()=>import('./lang/lua.js'),
|
|
188
|
+
php: ()=>import('./lang/php.js'),
|
|
189
|
+
powershell: ()=>import('./lang/powershell.js'),
|
|
190
|
+
python: ()=>import('./lang/python.js'),
|
|
191
|
+
ruby: ()=>import('./lang/ruby.js'),
|
|
192
|
+
rust: ()=>import('./lang/rust.js'),
|
|
193
|
+
shell: ()=>import('./lang/shell.js'),
|
|
194
|
+
sql: ()=>import('./lang/sql.js'),
|
|
195
|
+
swift: ()=>import('./lang/swift.js'),
|
|
196
|
+
toml: ()=>import('./lang/toml.js'),
|
|
197
|
+
yaml: ()=>import('./lang/yaml.js'),
|
|
198
|
+
zig: ()=>import('./lang/zig.js')
|
|
199
|
+
};
|
|
200
|
+
async function importDefaults(ids) {
|
|
201
|
+
await Promise.all(ids.map(async (id)=>{
|
|
202
|
+
const importer = configImporters[id];
|
|
203
|
+
if (!importer) return;
|
|
204
|
+
const { config } = await importer();
|
|
205
|
+
const language = allLanguages.find((l)=>l.id === id);
|
|
206
|
+
if (language) {
|
|
207
|
+
registerLanguage(language, config);
|
|
208
|
+
} else {
|
|
209
|
+
registerLanguage({
|
|
210
|
+
id,
|
|
211
|
+
extension: id,
|
|
212
|
+
aliases: []
|
|
213
|
+
}, config);
|
|
214
|
+
}
|
|
215
|
+
}));
|
|
216
|
+
}
|
|
217
|
+
/** Find canonical language metadata by name, alias, or extension. */ function findLanguage(name) {
|
|
218
|
+
if (typeof name !== 'string') return undefined;
|
|
219
|
+
return languageRegistry.get(normalizeLanguageName(name));
|
|
220
|
+
}
|
|
221
|
+
/** Resolve a name/alias/extension to its canonical language id. */ function lang(name) {
|
|
222
|
+
return findLanguage(name)?.id;
|
|
223
|
+
}
|
|
224
|
+
/** Alias for {@link lang}. */ const canonicalizeLang = lang;
|
|
225
|
+
function getRegisteredLanguages() {
|
|
226
|
+
return [
|
|
227
|
+
...new Set(languageRegistry.values())
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
function resetLanguageRegistry() {
|
|
231
|
+
languageRegistry.clear();
|
|
232
|
+
}
|
|
233
|
+
const allLanguages = [
|
|
234
|
+
{
|
|
235
|
+
id: 'javascript',
|
|
236
|
+
extension: 'js',
|
|
237
|
+
aliases: [
|
|
238
|
+
'jsx',
|
|
239
|
+
'node'
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
id: 'typescript',
|
|
244
|
+
extension: 'ts',
|
|
245
|
+
aliases: [
|
|
246
|
+
'tsx'
|
|
247
|
+
]
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
id: 'css',
|
|
251
|
+
extension: 'css',
|
|
252
|
+
aliases: []
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
id: 'scss',
|
|
256
|
+
extension: 'scss',
|
|
257
|
+
aliases: []
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
id: 'sass',
|
|
261
|
+
extension: 'sass',
|
|
262
|
+
aliases: [
|
|
263
|
+
'indented-sass'
|
|
264
|
+
]
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: 'html',
|
|
268
|
+
extension: 'html',
|
|
269
|
+
aliases: [
|
|
270
|
+
'htm',
|
|
271
|
+
'xml'
|
|
272
|
+
]
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
id: 'svelte',
|
|
276
|
+
extension: 'svelte',
|
|
277
|
+
aliases: []
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
id: 'markdown',
|
|
281
|
+
extension: 'md',
|
|
282
|
+
aliases: [
|
|
283
|
+
'md',
|
|
284
|
+
'mdx',
|
|
285
|
+
'svx'
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
id: 'diff',
|
|
290
|
+
extension: 'diff',
|
|
291
|
+
aliases: [
|
|
292
|
+
'patch'
|
|
293
|
+
]
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
id: 'plaintext',
|
|
297
|
+
extension: 'txt',
|
|
298
|
+
aliases: [
|
|
299
|
+
'text',
|
|
300
|
+
'plain'
|
|
301
|
+
]
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
id: 'c',
|
|
305
|
+
extension: 'c',
|
|
306
|
+
aliases: []
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: 'cpp',
|
|
310
|
+
extension: 'cpp',
|
|
311
|
+
aliases: [
|
|
312
|
+
'c++',
|
|
313
|
+
'cc',
|
|
314
|
+
'cxx'
|
|
315
|
+
]
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
id: 'csharp',
|
|
319
|
+
extension: 'cs',
|
|
320
|
+
aliases: [
|
|
321
|
+
'c#',
|
|
322
|
+
'dotnet'
|
|
323
|
+
]
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
id: 'dockerfile',
|
|
327
|
+
extension: 'dockerfile',
|
|
328
|
+
aliases: [
|
|
329
|
+
'docker'
|
|
330
|
+
]
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
id: 'go',
|
|
334
|
+
extension: 'go',
|
|
335
|
+
aliases: [
|
|
336
|
+
'golang'
|
|
337
|
+
]
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
id: 'graphql',
|
|
341
|
+
extension: 'graphql',
|
|
342
|
+
aliases: [
|
|
343
|
+
'gql'
|
|
344
|
+
]
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
id: 'hcl',
|
|
348
|
+
extension: 'hcl',
|
|
349
|
+
aliases: [
|
|
350
|
+
'terraform',
|
|
351
|
+
'tf'
|
|
352
|
+
]
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
id: 'java',
|
|
356
|
+
extension: 'java',
|
|
357
|
+
aliases: []
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
id: 'json',
|
|
361
|
+
extension: 'json',
|
|
362
|
+
aliases: [
|
|
363
|
+
'jsonc'
|
|
364
|
+
]
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
id: 'kotlin',
|
|
368
|
+
extension: 'kt',
|
|
369
|
+
aliases: [
|
|
370
|
+
'kts'
|
|
371
|
+
]
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
id: 'lua',
|
|
375
|
+
extension: 'lua',
|
|
376
|
+
aliases: []
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
id: 'php',
|
|
380
|
+
extension: 'php',
|
|
381
|
+
aliases: []
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
id: 'powershell',
|
|
385
|
+
extension: 'ps1',
|
|
386
|
+
aliases: [
|
|
387
|
+
'pwsh'
|
|
388
|
+
]
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
id: 'python',
|
|
392
|
+
extension: 'py',
|
|
393
|
+
aliases: [
|
|
394
|
+
'python3'
|
|
395
|
+
]
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
id: 'ruby',
|
|
399
|
+
extension: 'rb',
|
|
400
|
+
aliases: []
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
id: 'rust',
|
|
404
|
+
extension: 'rs',
|
|
405
|
+
aliases: []
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
id: 'shell',
|
|
409
|
+
extension: 'sh',
|
|
410
|
+
aliases: [
|
|
411
|
+
'bash',
|
|
412
|
+
'zsh'
|
|
413
|
+
]
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
id: 'sql',
|
|
417
|
+
extension: 'sql',
|
|
418
|
+
aliases: []
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
id: 'swift',
|
|
422
|
+
extension: 'swift',
|
|
423
|
+
aliases: []
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
id: 'toml',
|
|
427
|
+
extension: 'toml',
|
|
428
|
+
aliases: []
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
id: 'yaml',
|
|
432
|
+
extension: 'yaml',
|
|
433
|
+
aliases: [
|
|
434
|
+
'yml'
|
|
435
|
+
]
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
id: 'zig',
|
|
439
|
+
extension: 'zig',
|
|
440
|
+
aliases: []
|
|
441
|
+
}
|
|
442
|
+
];
|
|
443
|
+
setDefaults({
|
|
444
|
+
typescript: config$1,
|
|
445
|
+
plaintext: config
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
/** Highlight range: either a single 1-based line or an inclusive [start, end] pair. */ function parseMetaParts(meta) {
|
|
449
|
+
const match = meta?.match(/\{([^}]*)\}/);
|
|
450
|
+
return match ? match[1].split(',') : undefined;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Parse `{1,3-5,7}` fence metadata into a Set of 1-based line numbers.
|
|
454
|
+
*
|
|
455
|
+
* Tolerates whitespace (`{ 1 , 3 - 5 }`) and silently ignores invalid or
|
|
456
|
+
* negative numbers.
|
|
457
|
+
*/ function parseHighlightMeta(meta) {
|
|
458
|
+
const lines = new Set();
|
|
459
|
+
const parts = parseMetaParts(meta);
|
|
460
|
+
if (!parts) return lines;
|
|
461
|
+
for (const part of parts){
|
|
462
|
+
const range = part.trim();
|
|
463
|
+
if (!range) continue;
|
|
464
|
+
if (range.includes('-')) {
|
|
465
|
+
const [start, end] = range.split('-').map((n)=>Number(n.trim()));
|
|
466
|
+
if (Number.isFinite(start) && Number.isFinite(end) && start > 0 && end >= start) {
|
|
467
|
+
for(let i = start; i <= end; i++)lines.add(i);
|
|
468
|
+
}
|
|
469
|
+
} else {
|
|
470
|
+
const n = Number(range);
|
|
471
|
+
if (Number.isFinite(n) && n > 0) lines.add(n);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return lines;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Convert `{1,3-5,7}` fence metadata into remark-compatible highlight ranges.
|
|
478
|
+
*
|
|
479
|
+
* Returns single numbers for individual lines and `[start, end]` tuples for
|
|
480
|
+
* explicit ranges. Invalid/negative numbers are ignored.
|
|
481
|
+
*/ function toHighlightRanges(meta) {
|
|
482
|
+
const out = [];
|
|
483
|
+
const parts = parseMetaParts(meta);
|
|
484
|
+
if (!parts) return out;
|
|
485
|
+
for (const part of parts){
|
|
486
|
+
const range = part.trim();
|
|
487
|
+
if (!range) continue;
|
|
488
|
+
if (range.includes('-')) {
|
|
489
|
+
const [start, end] = range.split('-').map((n)=>Number(n.trim()));
|
|
490
|
+
if (Number.isFinite(start) && Number.isFinite(end) && start > 0 && end >= start) {
|
|
491
|
+
out.push([
|
|
492
|
+
start,
|
|
493
|
+
end
|
|
494
|
+
]);
|
|
495
|
+
}
|
|
496
|
+
} else {
|
|
497
|
+
const n = Number(range);
|
|
498
|
+
if (Number.isFinite(n) && n > 0) out.push(n);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return out;
|
|
502
|
+
}
|
|
503
|
+
/** Escape characters Svelte's compiler would otherwise interpret in markup. */ function escapeSvelte(html) {
|
|
504
|
+
return html.replace(/\{/g, '{').replace(/\}/g, '}').replace(/`/g, '`');
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** Register multiple languages with their parse configs. */ function registerLanguages(languages) {
|
|
508
|
+
for (const { language, config } of languages){
|
|
509
|
+
registerLanguage(language, config);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
/** Highlight `code` to an HTML string. No DOM required. */ function highlight(code, options) {
|
|
513
|
+
const { lang, config, cx, mark, markLine } = options || {};
|
|
514
|
+
const resolvedConfig = config ?? (lang ? getLanguageConfig(canonicalizeLang(lang) ?? lang) : undefined) ?? getLanguageConfig('typescript') ?? {};
|
|
515
|
+
const parsed = parse(code, resolvedConfig);
|
|
516
|
+
return render(parsed, {
|
|
517
|
+
cx,
|
|
518
|
+
mark,
|
|
519
|
+
markLine
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export { allLanguages, canonicalizeLang, escapeSvelte, findLanguage, getLanguageConfig, getRegisteredLanguages, highlight, importDefaults, lang, parseHighlightMeta, registerLanguage, registerLanguages, resetLanguageConfigRegistry, resetLanguageRegistry, setDefaults, toHighlightRanges };
|