@scalar/code-highlight 0.3.4 → 0.3.5

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 (38) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/chunks/code.js +124 -0
  3. package/dist/chunks/code.js.map +1 -0
  4. package/dist/chunks/languages.js +12720 -0
  5. package/dist/chunks/languages.js.map +1 -0
  6. package/dist/chunks/lib.js +13688 -0
  7. package/dist/chunks/lib.js.map +1 -0
  8. package/dist/chunks/lib2.js +731 -0
  9. package/dist/chunks/lib2.js.map +1 -0
  10. package/dist/chunks/markdown.js +20921 -0
  11. package/dist/chunks/markdown.js.map +1 -0
  12. package/dist/chunks/rehype-alert.js +74 -0
  13. package/dist/chunks/rehype-alert.js.map +1 -0
  14. package/dist/chunks/rehype-highlight.js +2987 -0
  15. package/dist/chunks/rehype-highlight.js.map +1 -0
  16. package/dist/code/index.d.ts +1 -1
  17. package/dist/code/index.js +3 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +6 -5
  20. package/dist/languages/index.d.ts +3 -3
  21. package/dist/languages/index.js +2 -3
  22. package/dist/markdown/index.d.ts +1 -1
  23. package/dist/markdown/index.js +3 -1
  24. package/dist/rehype-alert/index.d.ts +1 -1
  25. package/dist/rehype-alert/index.js +2 -1
  26. package/dist/rehype-highlight/index.d.ts +1 -1
  27. package/dist/rehype-highlight/index.js +2 -1
  28. package/package.json +4 -4
  29. package/dist/code/highlight.js +0 -62
  30. package/dist/code/line-numbers.js +0 -94
  31. package/dist/constants.js +0 -11
  32. package/dist/languages/basic.js +0 -30
  33. package/dist/languages/curl.js +0 -86
  34. package/dist/languages/json-yaml.js +0 -9
  35. package/dist/languages/standard.js +0 -115
  36. package/dist/markdown/markdown.js +0 -228
  37. package/dist/rehype-alert/rehype-alert.js +0 -102
  38. package/dist/rehype-highlight/rehype-highlight.js +0 -98
@@ -0,0 +1,2987 @@
1
+ import { i as convert, t as visit } from "./lib2.js";
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
10
+ var __exportAll = (all, no_symbols) => {
11
+ let target = {};
12
+ for (var name in all) __defProp(target, name, {
13
+ get: all[name],
14
+ enumerable: true
15
+ });
16
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17
+ return target;
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
21
+ key = keys[i];
22
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
23
+ get: ((k) => from[k]).bind(null, key),
24
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
25
+ });
26
+ }
27
+ return to;
28
+ };
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
30
+ value: mod,
31
+ enumerable: true
32
+ }) : target, mod));
33
+ //#endregion
34
+ //#region ../../node_modules/.pnpm/devlop@1.1.0/node_modules/devlop/lib/default.js
35
+ function ok() {}
36
+ //#endregion
37
+ //#region src/constants.ts
38
+ /** Map common markdown language shortcuts to lowlight languages */
39
+ var lowlightLanguageMappings = {
40
+ "ts": "typescript",
41
+ "js": "javascript",
42
+ "py": "python",
43
+ "py3": "python",
44
+ "c#": "csharp",
45
+ "c++": "cpp",
46
+ "node": "javascript"
47
+ };
48
+ //#endregion
49
+ //#region ../../node_modules/.pnpm/unist-util-find-after@5.0.0/node_modules/unist-util-find-after/lib/index.js
50
+ /**
51
+ * @typedef {import('unist').Node} UnistNode
52
+ * @typedef {import('unist').Parent} UnistParent
53
+ */
54
+ /**
55
+ * @typedef {Exclude<import('unist-util-is').Test, undefined> | undefined} Test
56
+ * Test from `unist-util-is`.
57
+ *
58
+ * Note: we have remove and add `undefined`, because otherwise when generating
59
+ * automatic `.d.ts` files, TS tries to flatten paths from a local perspective,
60
+ * which doesn’t work when publishing on npm.
61
+ */
62
+ /**
63
+ * @typedef {(
64
+ * Fn extends (value: any) => value is infer Thing
65
+ * ? Thing
66
+ * : Fallback
67
+ * )} Predicate
68
+ * Get the value of a type guard `Fn`.
69
+ * @template Fn
70
+ * Value; typically function that is a type guard (such as `(x): x is Y`).
71
+ * @template Fallback
72
+ * Value to yield if `Fn` is not a type guard.
73
+ */
74
+ /**
75
+ * @typedef {(
76
+ * Check extends null | undefined // No test.
77
+ * ? Value
78
+ * : Value extends {type: Check} // String (type) test.
79
+ * ? Value
80
+ * : Value extends Check // Partial test.
81
+ * ? Value
82
+ * : Check extends Function // Function test.
83
+ * ? Predicate<Check, Value> extends Value
84
+ * ? Predicate<Check, Value>
85
+ * : never
86
+ * : never // Some other test?
87
+ * )} MatchesOne
88
+ * Check whether a node matches a primitive check in the type system.
89
+ * @template Value
90
+ * Value; typically unist `Node`.
91
+ * @template Check
92
+ * Value; typically `unist-util-is`-compatible test, but not arrays.
93
+ */
94
+ /**
95
+ * @typedef {(
96
+ * Check extends Array<any>
97
+ * ? MatchesOne<Value, Check[keyof Check]>
98
+ * : MatchesOne<Value, Check>
99
+ * )} Matches
100
+ * Check whether a node matches a check in the type system.
101
+ * @template Value
102
+ * Value; typically unist `Node`.
103
+ * @template Check
104
+ * Value; typically `unist-util-is`-compatible test.
105
+ */
106
+ /**
107
+ * @typedef {(
108
+ * Kind extends {children: Array<infer Child>}
109
+ * ? Child
110
+ * : never
111
+ * )} Child
112
+ * Collect nodes that can be parents of `Child`.
113
+ * @template {UnistNode} Kind
114
+ * All node types.
115
+ */
116
+ /**
117
+ * Find the first node in `parent` after another `node` or after an index,
118
+ * that passes `test`.
119
+ *
120
+ * @param parent
121
+ * Parent node.
122
+ * @param index
123
+ * Child node or index.
124
+ * @param [test=undefined]
125
+ * Test for child to look for (optional).
126
+ * @returns
127
+ * A child (matching `test`, if given) or `undefined`.
128
+ */
129
+ var findAfter = (function(parent, index, test) {
130
+ const is = convert(test);
131
+ if (!parent || !parent.type || !parent.children) throw new Error("Expected parent node");
132
+ if (typeof index === "number") {
133
+ if (index < 0 || index === Number.POSITIVE_INFINITY) throw new Error("Expected positive finite number as index");
134
+ } else {
135
+ index = parent.children.indexOf(index);
136
+ if (index < 0) throw new Error("Expected child node or index");
137
+ }
138
+ while (++index < parent.children.length) if (is(parent.children[index], index, parent)) return parent.children[index];
139
+ });
140
+ //#endregion
141
+ //#region ../../node_modules/.pnpm/hast-util-is-element@3.0.0/node_modules/hast-util-is-element/lib/index.js
142
+ /**
143
+ * @typedef {import('hast').Element} Element
144
+ * @typedef {import('hast').Parents} Parents
145
+ */
146
+ /**
147
+ * @template Fn
148
+ * @template Fallback
149
+ * @typedef {Fn extends (value: any) => value is infer Thing ? Thing : Fallback} Predicate
150
+ */
151
+ /**
152
+ * @callback Check
153
+ * Check that an arbitrary value is an element.
154
+ * @param {unknown} this
155
+ * Context object (`this`) to call `test` with
156
+ * @param {unknown} [element]
157
+ * Anything (typically a node).
158
+ * @param {number | null | undefined} [index]
159
+ * Position of `element` in its parent.
160
+ * @param {Parents | null | undefined} [parent]
161
+ * Parent of `element`.
162
+ * @returns {boolean}
163
+ * Whether this is an element and passes a test.
164
+ *
165
+ * @typedef {Array<TestFunction | string> | TestFunction | string | null | undefined} Test
166
+ * Check for an arbitrary element.
167
+ *
168
+ * * when `string`, checks that the element has that tag name
169
+ * * when `function`, see `TestFunction`
170
+ * * when `Array`, checks if one of the subtests pass
171
+ *
172
+ * @callback TestFunction
173
+ * Check if an element passes a test.
174
+ * @param {unknown} this
175
+ * The given context.
176
+ * @param {Element} element
177
+ * An element.
178
+ * @param {number | undefined} [index]
179
+ * Position of `element` in its parent.
180
+ * @param {Parents | undefined} [parent]
181
+ * Parent of `element`.
182
+ * @returns {boolean | undefined | void}
183
+ * Whether this element passes the test.
184
+ *
185
+ * Note: `void` is included until TS sees no return as `undefined`.
186
+ */
187
+ /**
188
+ * Check if `element` is an `Element` and whether it passes the given test.
189
+ *
190
+ * @param element
191
+ * Thing to check, typically `element`.
192
+ * @param test
193
+ * Check for a specific element.
194
+ * @param index
195
+ * Position of `element` in its parent.
196
+ * @param parent
197
+ * Parent of `element`.
198
+ * @param context
199
+ * Context object (`this`) to call `test` with.
200
+ * @returns
201
+ * Whether `element` is an `Element` and passes a test.
202
+ * @throws
203
+ * When an incorrect `test`, `index`, or `parent` is given; there is no error
204
+ * thrown when `element` is not a node or not an element.
205
+ */
206
+ var isElement = (function(element, test, index, parent, context) {
207
+ const check = convertElement(test);
208
+ if (index !== null && index !== void 0 && (typeof index !== "number" || index < 0 || index === Number.POSITIVE_INFINITY)) throw new Error("Expected positive finite `index`");
209
+ if (parent !== null && parent !== void 0 && (!parent.type || !parent.children)) throw new Error("Expected valid `parent`");
210
+ if ((index === null || index === void 0) !== (parent === null || parent === void 0)) throw new Error("Expected both `index` and `parent`");
211
+ return looksLikeAnElement(element) ? check.call(context, element, index, parent) : false;
212
+ });
213
+ /**
214
+ * Generate a check from a test.
215
+ *
216
+ * Useful if you’re going to test many nodes, for example when creating a
217
+ * utility where something else passes a compatible test.
218
+ *
219
+ * The created function is a bit faster because it expects valid input only:
220
+ * an `element`, `index`, and `parent`.
221
+ *
222
+ * @param test
223
+ * A test for a specific element.
224
+ * @returns
225
+ * A check.
226
+ */
227
+ var convertElement = (function(test) {
228
+ if (test === null || test === void 0) return element;
229
+ if (typeof test === "string") return tagNameFactory(test);
230
+ if (typeof test === "object") return anyFactory(test);
231
+ if (typeof test === "function") return castFactory(test);
232
+ throw new Error("Expected function, string, or array as `test`");
233
+ });
234
+ /**
235
+ * Handle multiple tests.
236
+ *
237
+ * @param {Array<TestFunction | string>} tests
238
+ * @returns {Check}
239
+ */
240
+ function anyFactory(tests) {
241
+ /** @type {Array<Check>} */
242
+ const checks = [];
243
+ let index = -1;
244
+ while (++index < tests.length) checks[index] = convertElement(tests[index]);
245
+ return castFactory(any);
246
+ /**
247
+ * @this {unknown}
248
+ * @type {TestFunction}
249
+ */
250
+ function any(...parameters) {
251
+ let index = -1;
252
+ while (++index < checks.length) if (checks[index].apply(this, parameters)) return true;
253
+ return false;
254
+ }
255
+ }
256
+ /**
257
+ * Turn a string into a test for an element with a certain type.
258
+ *
259
+ * @param {string} check
260
+ * @returns {Check}
261
+ */
262
+ function tagNameFactory(check) {
263
+ return castFactory(tagName);
264
+ /**
265
+ * @param {Element} element
266
+ * @returns {boolean}
267
+ */
268
+ function tagName(element) {
269
+ return element.tagName === check;
270
+ }
271
+ }
272
+ /**
273
+ * Turn a custom test into a test for an element that passes that test.
274
+ *
275
+ * @param {TestFunction} testFunction
276
+ * @returns {Check}
277
+ */
278
+ function castFactory(testFunction) {
279
+ return check;
280
+ /**
281
+ * @this {unknown}
282
+ * @type {Check}
283
+ */
284
+ function check(value, index, parent) {
285
+ return Boolean(looksLikeAnElement(value) && testFunction.call(this, value, typeof index === "number" ? index : void 0, parent || void 0));
286
+ }
287
+ }
288
+ /**
289
+ * Make sure something is an element.
290
+ *
291
+ * @param {unknown} element
292
+ * @returns {element is Element}
293
+ */
294
+ function element(element) {
295
+ return Boolean(element && typeof element === "object" && "type" in element && element.type === "element" && "tagName" in element && typeof element.tagName === "string");
296
+ }
297
+ /**
298
+ * @param {unknown} value
299
+ * @returns {value is Element}
300
+ */
301
+ function looksLikeAnElement(value) {
302
+ return value !== null && typeof value === "object" && "type" in value && "tagName" in value;
303
+ }
304
+ //#endregion
305
+ //#region ../../node_modules/.pnpm/hast-util-to-text@4.0.2/node_modules/hast-util-to-text/lib/index.js
306
+ /**
307
+ * @typedef {import('hast').Comment} Comment
308
+ * @typedef {import('hast').Element} Element
309
+ * @typedef {import('hast').Nodes} Nodes
310
+ * @typedef {import('hast').Parents} Parents
311
+ * @typedef {import('hast').Text} Text
312
+ * @typedef {import('hast-util-is-element').TestFunction} TestFunction
313
+ */
314
+ /**
315
+ * @typedef {'normal' | 'nowrap' | 'pre' | 'pre-wrap'} Whitespace
316
+ * Valid and useful whitespace values (from CSS).
317
+ *
318
+ * @typedef {0 | 1 | 2} BreakNumber
319
+ * Specific break:
320
+ *
321
+ * * `0` — space
322
+ * * `1` — line ending
323
+ * * `2` — blank line
324
+ *
325
+ * @typedef {'\n'} BreakForce
326
+ * Forced break.
327
+ *
328
+ * @typedef {boolean} BreakValue
329
+ * Whether there was a break.
330
+ *
331
+ * @typedef {BreakNumber | BreakValue | undefined} BreakBefore
332
+ * Any value for a break before.
333
+ *
334
+ * @typedef {BreakForce | BreakNumber | BreakValue | undefined} BreakAfter
335
+ * Any value for a break after.
336
+ *
337
+ * @typedef CollectionInfo
338
+ * Info on current collection.
339
+ * @property {BreakAfter} breakAfter
340
+ * Whether there was a break after.
341
+ * @property {BreakBefore} breakBefore
342
+ * Whether there was a break before.
343
+ * @property {Whitespace} whitespace
344
+ * Current whitespace setting.
345
+ *
346
+ * @typedef Options
347
+ * Configuration.
348
+ * @property {Whitespace | null | undefined} [whitespace='normal']
349
+ * Initial CSS whitespace setting to use (default: `'normal'`).
350
+ */
351
+ var searchLineFeeds = /\n/g;
352
+ var searchTabOrSpaces = /[\t ]+/g;
353
+ var br = convertElement("br");
354
+ var cell = convertElement(isCell);
355
+ var p = convertElement("p");
356
+ var row = convertElement("tr");
357
+ var notRendered = convertElement([
358
+ "datalist",
359
+ "head",
360
+ "noembed",
361
+ "noframes",
362
+ "noscript",
363
+ "rp",
364
+ "script",
365
+ "style",
366
+ "template",
367
+ "title",
368
+ hidden,
369
+ closedDialog
370
+ ]);
371
+ var blockOrCaption = convertElement([
372
+ "address",
373
+ "article",
374
+ "aside",
375
+ "blockquote",
376
+ "body",
377
+ "caption",
378
+ "center",
379
+ "dd",
380
+ "dialog",
381
+ "dir",
382
+ "dl",
383
+ "dt",
384
+ "div",
385
+ "figure",
386
+ "figcaption",
387
+ "footer",
388
+ "form,",
389
+ "h1",
390
+ "h2",
391
+ "h3",
392
+ "h4",
393
+ "h5",
394
+ "h6",
395
+ "header",
396
+ "hgroup",
397
+ "hr",
398
+ "html",
399
+ "legend",
400
+ "li",
401
+ "listing",
402
+ "main",
403
+ "menu",
404
+ "nav",
405
+ "ol",
406
+ "p",
407
+ "plaintext",
408
+ "pre",
409
+ "section",
410
+ "ul",
411
+ "xmp"
412
+ ]);
413
+ /**
414
+ * Get the plain-text value of a node.
415
+ *
416
+ * ###### Algorithm
417
+ *
418
+ * * if `tree` is a comment, returns its `value`
419
+ * * if `tree` is a text, applies normal whitespace collapsing to its
420
+ * `value`, as defined by the CSS Text spec
421
+ * * if `tree` is a root or element, applies an algorithm similar to the
422
+ * `innerText` getter as defined by HTML
423
+ *
424
+ * ###### Notes
425
+ *
426
+ * > 👉 **Note**: the algorithm acts as if `tree` is being rendered, and as if
427
+ * > we’re a CSS-supporting user agent, with scripting enabled.
428
+ *
429
+ * * if `tree` is an element that is not displayed (such as a `head`), we’ll
430
+ * still use the `innerText` algorithm instead of switching to `textContent`
431
+ * * if descendants of `tree` are elements that are not displayed, they are
432
+ * ignored
433
+ * * CSS is not considered, except for the default user agent style sheet
434
+ * * a line feed is collapsed instead of ignored in cases where Fullwidth, Wide,
435
+ * or Halfwidth East Asian Width characters are used, the same goes for a case
436
+ * with Chinese, Japanese, or Yi writing systems
437
+ * * replaced elements (such as `audio`) are treated like non-replaced elements
438
+ *
439
+ * @param {Nodes} tree
440
+ * Tree to turn into text.
441
+ * @param {Readonly<Options> | null | undefined} [options]
442
+ * Configuration (optional).
443
+ * @returns {string}
444
+ * Serialized `tree`.
445
+ */
446
+ function toText(tree, options) {
447
+ const options_ = options || {};
448
+ const children = "children" in tree ? tree.children : [];
449
+ const block = blockOrCaption(tree);
450
+ const whitespace = inferWhitespace(tree, {
451
+ whitespace: options_.whitespace || "normal",
452
+ breakBefore: false,
453
+ breakAfter: false
454
+ });
455
+ /** @type {Array<BreakNumber | string>} */
456
+ const results = [];
457
+ if (tree.type === "text" || tree.type === "comment") results.push(...collectText(tree, {
458
+ whitespace,
459
+ breakBefore: true,
460
+ breakAfter: true
461
+ }));
462
+ let index = -1;
463
+ while (++index < children.length) results.push(...renderedTextCollection(children[index], tree, {
464
+ whitespace,
465
+ breakBefore: index ? void 0 : block,
466
+ breakAfter: index < children.length - 1 ? br(children[index + 1]) : block
467
+ }));
468
+ /** @type {Array<string>} */
469
+ const result = [];
470
+ /** @type {number | undefined} */
471
+ let count;
472
+ index = -1;
473
+ while (++index < results.length) {
474
+ const value = results[index];
475
+ if (typeof value === "number") {
476
+ if (count !== void 0 && value > count) count = value;
477
+ } else if (value) {
478
+ if (count !== void 0 && count > -1) result.push("\n".repeat(count) || " ");
479
+ count = -1;
480
+ result.push(value);
481
+ }
482
+ }
483
+ return result.join("");
484
+ }
485
+ /**
486
+ * <https://html.spec.whatwg.org/multipage/dom.html#rendered-text-collection-steps>
487
+ *
488
+ * @param {Nodes} node
489
+ * @param {Parents} parent
490
+ * @param {CollectionInfo} info
491
+ * @returns {Array<BreakNumber | string>}
492
+ */
493
+ function renderedTextCollection(node, parent, info) {
494
+ if (node.type === "element") return collectElement(node, parent, info);
495
+ if (node.type === "text") return info.whitespace === "normal" ? collectText(node, info) : collectPreText(node);
496
+ return [];
497
+ }
498
+ /**
499
+ * Collect an element.
500
+ *
501
+ * @param {Element} node
502
+ * Element node.
503
+ * @param {Parents} parent
504
+ * @param {CollectionInfo} info
505
+ * Info on current collection.
506
+ * @returns {Array<BreakNumber | string>}
507
+ */
508
+ function collectElement(node, parent, info) {
509
+ const whitespace = inferWhitespace(node, info);
510
+ const children = node.children || [];
511
+ let index = -1;
512
+ /** @type {Array<BreakNumber | string>} */
513
+ let items = [];
514
+ if (notRendered(node)) return items;
515
+ /** @type {BreakNumber | undefined} */
516
+ let prefix;
517
+ /** @type {BreakForce | BreakNumber | undefined} */
518
+ let suffix;
519
+ if (br(node)) suffix = "\n";
520
+ else if (row(node) && findAfter(parent, node, row)) suffix = "\n";
521
+ else if (p(node)) {
522
+ prefix = 2;
523
+ suffix = 2;
524
+ } else if (blockOrCaption(node)) {
525
+ prefix = 1;
526
+ suffix = 1;
527
+ }
528
+ while (++index < children.length) items = items.concat(renderedTextCollection(children[index], node, {
529
+ whitespace,
530
+ breakBefore: index ? void 0 : prefix,
531
+ breakAfter: index < children.length - 1 ? br(children[index + 1]) : suffix
532
+ }));
533
+ if (cell(node) && findAfter(parent, node, cell)) items.push(" ");
534
+ if (prefix) items.unshift(prefix);
535
+ if (suffix) items.push(suffix);
536
+ return items;
537
+ }
538
+ /**
539
+ * 4. If node is a Text node, then for each CSS text box produced by node,
540
+ * in content order, compute the text of the box after application of the
541
+ * CSS `white-space` processing rules and `text-transform` rules, set
542
+ * items to the list of the resulting strings, and return items.
543
+ * The CSS `white-space` processing rules are slightly modified:
544
+ * collapsible spaces at the end of lines are always collapsed, but they
545
+ * are only removed if the line is the last line of the block, or it ends
546
+ * with a br element.
547
+ * Soft hyphens should be preserved.
548
+ *
549
+ * Note: See `collectText` and `collectPreText`.
550
+ * Note: we don’t deal with `text-transform`, no element has that by
551
+ * default.
552
+ *
553
+ * See: <https://drafts.csswg.org/css-text/#white-space-phase-1>
554
+ *
555
+ * @param {Comment | Text} node
556
+ * Text node.
557
+ * @param {CollectionInfo} info
558
+ * Info on current collection.
559
+ * @returns {Array<BreakNumber | string>}
560
+ * Result.
561
+ */
562
+ function collectText(node, info) {
563
+ const value = String(node.value);
564
+ /** @type {Array<string>} */
565
+ const lines = [];
566
+ /** @type {Array<BreakNumber | string>} */
567
+ const result = [];
568
+ let start = 0;
569
+ while (start <= value.length) {
570
+ searchLineFeeds.lastIndex = start;
571
+ const match = searchLineFeeds.exec(value);
572
+ const end = match && "index" in match ? match.index : value.length;
573
+ lines.push(trimAndCollapseSpacesAndTabs(value.slice(start, end).replace(/[\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/g, ""), start === 0 ? info.breakBefore : true, end === value.length ? info.breakAfter : true));
574
+ start = end + 1;
575
+ }
576
+ let index = -1;
577
+ /** @type {BreakNumber | undefined} */
578
+ let join;
579
+ while (++index < lines.length) if (lines[index].charCodeAt(lines[index].length - 1) === 8203 || index < lines.length - 1 && lines[index + 1].charCodeAt(0) === 8203) {
580
+ result.push(lines[index]);
581
+ join = void 0;
582
+ } else if (lines[index]) {
583
+ if (typeof join === "number") result.push(join);
584
+ result.push(lines[index]);
585
+ join = 0;
586
+ } else if (index === 0 || index === lines.length - 1) result.push(0);
587
+ return result;
588
+ }
589
+ /**
590
+ * Collect a text node as “pre” whitespace.
591
+ *
592
+ * @param {Text} node
593
+ * Text node.
594
+ * @returns {Array<BreakNumber | string>}
595
+ * Result.
596
+ */
597
+ function collectPreText(node) {
598
+ return [String(node.value)];
599
+ }
600
+ /**
601
+ * 3. Every collapsible tab is converted to a collapsible space (U+0020).
602
+ * 4. Any collapsible space immediately following another collapsible
603
+ * space—even one outside the boundary of the inline containing that
604
+ * space, provided both spaces are within the same inline formatting
605
+ * context—is collapsed to have zero advance width. (It is invisible,
606
+ * but retains its soft wrap opportunity, if any.)
607
+ *
608
+ * @param {string} value
609
+ * Value to collapse.
610
+ * @param {BreakBefore} breakBefore
611
+ * Whether there was a break before.
612
+ * @param {BreakAfter} breakAfter
613
+ * Whether there was a break after.
614
+ * @returns {string}
615
+ * Result.
616
+ */
617
+ function trimAndCollapseSpacesAndTabs(value, breakBefore, breakAfter) {
618
+ /** @type {Array<string>} */
619
+ const result = [];
620
+ let start = 0;
621
+ /** @type {number | undefined} */
622
+ let end;
623
+ while (start < value.length) {
624
+ searchTabOrSpaces.lastIndex = start;
625
+ const match = searchTabOrSpaces.exec(value);
626
+ end = match ? match.index : value.length;
627
+ if (!start && !end && match && !breakBefore) result.push("");
628
+ if (start !== end) result.push(value.slice(start, end));
629
+ start = match ? end + match[0].length : end;
630
+ }
631
+ if (start !== end && !breakAfter) result.push("");
632
+ return result.join(" ");
633
+ }
634
+ /**
635
+ * Figure out the whitespace of a node.
636
+ *
637
+ * We don’t support void elements here (so `nobr wbr` -> `normal` is ignored).
638
+ *
639
+ * @param {Nodes} node
640
+ * Node (typically `Element`).
641
+ * @param {CollectionInfo} info
642
+ * Info on current collection.
643
+ * @returns {Whitespace}
644
+ * Applied whitespace.
645
+ */
646
+ function inferWhitespace(node, info) {
647
+ if (node.type === "element") {
648
+ const properties = node.properties || {};
649
+ switch (node.tagName) {
650
+ case "listing":
651
+ case "plaintext":
652
+ case "xmp": return "pre";
653
+ case "nobr": return "nowrap";
654
+ case "pre": return properties.wrap ? "pre-wrap" : "pre";
655
+ case "td":
656
+ case "th": return properties.noWrap ? "nowrap" : info.whitespace;
657
+ case "textarea": return "pre-wrap";
658
+ default:
659
+ }
660
+ }
661
+ return info.whitespace;
662
+ }
663
+ /**
664
+ * @type {TestFunction}
665
+ * @param {Element} node
666
+ * @returns {node is {properties: {hidden: true}}}
667
+ */
668
+ function hidden(node) {
669
+ return Boolean((node.properties || {}).hidden);
670
+ }
671
+ /**
672
+ * @type {TestFunction}
673
+ * @param {Element} node
674
+ * @returns {node is {tagName: 'td' | 'th'}}
675
+ */
676
+ function isCell(node) {
677
+ return node.tagName === "td" || node.tagName === "th";
678
+ }
679
+ /**
680
+ * @type {TestFunction}
681
+ */
682
+ function closedDialog(node) {
683
+ return node.tagName === "dialog" && !(node.properties || {}).open;
684
+ }
685
+ var core_default = (/* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
686
+ function deepFreeze(obj) {
687
+ if (obj instanceof Map) obj.clear = obj.delete = obj.set = function() {
688
+ throw new Error("map is read-only");
689
+ };
690
+ else if (obj instanceof Set) obj.add = obj.clear = obj.delete = function() {
691
+ throw new Error("set is read-only");
692
+ };
693
+ Object.freeze(obj);
694
+ Object.getOwnPropertyNames(obj).forEach((name) => {
695
+ const prop = obj[name];
696
+ const type = typeof prop;
697
+ if ((type === "object" || type === "function") && !Object.isFrozen(prop)) deepFreeze(prop);
698
+ });
699
+ return obj;
700
+ }
701
+ /** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */
702
+ /** @typedef {import('highlight.js').CompiledMode} CompiledMode */
703
+ /** @implements CallbackResponse */
704
+ var Response = class {
705
+ /**
706
+ * @param {CompiledMode} mode
707
+ */
708
+ constructor(mode) {
709
+ if (mode.data === void 0) mode.data = {};
710
+ this.data = mode.data;
711
+ this.isMatchIgnored = false;
712
+ }
713
+ ignoreMatch() {
714
+ this.isMatchIgnored = true;
715
+ }
716
+ };
717
+ /**
718
+ * @param {string} value
719
+ * @returns {string}
720
+ */
721
+ function escapeHTML(value) {
722
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
723
+ }
724
+ /**
725
+ * performs a shallow merge of multiple objects into one
726
+ *
727
+ * @template T
728
+ * @param {T} original
729
+ * @param {Record<string,any>[]} objects
730
+ * @returns {T} a single new object
731
+ */
732
+ function inherit$1(original, ...objects) {
733
+ /** @type Record<string,any> */
734
+ const result = Object.create(null);
735
+ for (const key in original) result[key] = original[key];
736
+ objects.forEach(function(obj) {
737
+ for (const key in obj) result[key] = obj[key];
738
+ });
739
+ return result;
740
+ }
741
+ /**
742
+ * @typedef {object} Renderer
743
+ * @property {(text: string) => void} addText
744
+ * @property {(node: Node) => void} openNode
745
+ * @property {(node: Node) => void} closeNode
746
+ * @property {() => string} value
747
+ */
748
+ /** @typedef {{scope?: string, language?: string, sublanguage?: boolean}} Node */
749
+ /** @typedef {{walk: (r: Renderer) => void}} Tree */
750
+ /** */
751
+ var SPAN_CLOSE = "</span>";
752
+ /**
753
+ * Determines if a node needs to be wrapped in <span>
754
+ *
755
+ * @param {Node} node */
756
+ var emitsWrappingTags = (node) => {
757
+ return !!node.scope;
758
+ };
759
+ /**
760
+ *
761
+ * @param {string} name
762
+ * @param {{prefix:string}} options
763
+ */
764
+ var scopeToCSSClass = (name, { prefix }) => {
765
+ if (name.startsWith("language:")) return name.replace("language:", "language-");
766
+ if (name.includes(".")) {
767
+ const pieces = name.split(".");
768
+ return [`${prefix}${pieces.shift()}`, ...pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`)].join(" ");
769
+ }
770
+ return `${prefix}${name}`;
771
+ };
772
+ /** @type {Renderer} */
773
+ var HTMLRenderer = class {
774
+ /**
775
+ * Creates a new HTMLRenderer
776
+ *
777
+ * @param {Tree} parseTree - the parse tree (must support `walk` API)
778
+ * @param {{classPrefix: string}} options
779
+ */
780
+ constructor(parseTree, options) {
781
+ this.buffer = "";
782
+ this.classPrefix = options.classPrefix;
783
+ parseTree.walk(this);
784
+ }
785
+ /**
786
+ * Adds texts to the output stream
787
+ *
788
+ * @param {string} text */
789
+ addText(text) {
790
+ this.buffer += escapeHTML(text);
791
+ }
792
+ /**
793
+ * Adds a node open to the output stream (if needed)
794
+ *
795
+ * @param {Node} node */
796
+ openNode(node) {
797
+ if (!emitsWrappingTags(node)) return;
798
+ const className = scopeToCSSClass(node.scope, { prefix: this.classPrefix });
799
+ this.span(className);
800
+ }
801
+ /**
802
+ * Adds a node close to the output stream (if needed)
803
+ *
804
+ * @param {Node} node */
805
+ closeNode(node) {
806
+ if (!emitsWrappingTags(node)) return;
807
+ this.buffer += SPAN_CLOSE;
808
+ }
809
+ /**
810
+ * returns the accumulated buffer
811
+ */
812
+ value() {
813
+ return this.buffer;
814
+ }
815
+ /**
816
+ * Builds a span element
817
+ *
818
+ * @param {string} className */
819
+ span(className) {
820
+ this.buffer += `<span class="${className}">`;
821
+ }
822
+ };
823
+ /** @typedef {{scope?: string, language?: string, children: Node[]} | string} Node */
824
+ /** @typedef {{scope?: string, language?: string, children: Node[]} } DataNode */
825
+ /** @typedef {import('highlight.js').Emitter} Emitter */
826
+ /** */
827
+ /** @returns {DataNode} */
828
+ var newNode = (opts = {}) => {
829
+ /** @type DataNode */
830
+ const result = { children: [] };
831
+ Object.assign(result, opts);
832
+ return result;
833
+ };
834
+ var TokenTree = class TokenTree {
835
+ constructor() {
836
+ /** @type DataNode */
837
+ this.rootNode = newNode();
838
+ this.stack = [this.rootNode];
839
+ }
840
+ get top() {
841
+ return this.stack[this.stack.length - 1];
842
+ }
843
+ get root() {
844
+ return this.rootNode;
845
+ }
846
+ /** @param {Node} node */
847
+ add(node) {
848
+ this.top.children.push(node);
849
+ }
850
+ /** @param {string} scope */
851
+ openNode(scope) {
852
+ /** @type Node */
853
+ const node = newNode({ scope });
854
+ this.add(node);
855
+ this.stack.push(node);
856
+ }
857
+ closeNode() {
858
+ if (this.stack.length > 1) return this.stack.pop();
859
+ }
860
+ closeAllNodes() {
861
+ while (this.closeNode());
862
+ }
863
+ toJSON() {
864
+ return JSON.stringify(this.rootNode, null, 4);
865
+ }
866
+ /**
867
+ * @typedef { import("./html_renderer").Renderer } Renderer
868
+ * @param {Renderer} builder
869
+ */
870
+ walk(builder) {
871
+ return this.constructor._walk(builder, this.rootNode);
872
+ }
873
+ /**
874
+ * @param {Renderer} builder
875
+ * @param {Node} node
876
+ */
877
+ static _walk(builder, node) {
878
+ if (typeof node === "string") builder.addText(node);
879
+ else if (node.children) {
880
+ builder.openNode(node);
881
+ node.children.forEach((child) => this._walk(builder, child));
882
+ builder.closeNode(node);
883
+ }
884
+ return builder;
885
+ }
886
+ /**
887
+ * @param {Node} node
888
+ */
889
+ static _collapse(node) {
890
+ if (typeof node === "string") return;
891
+ if (!node.children) return;
892
+ if (node.children.every((el) => typeof el === "string")) node.children = [node.children.join("")];
893
+ else node.children.forEach((child) => {
894
+ TokenTree._collapse(child);
895
+ });
896
+ }
897
+ };
898
+ /**
899
+ Currently this is all private API, but this is the minimal API necessary
900
+ that an Emitter must implement to fully support the parser.
901
+
902
+ Minimal interface:
903
+
904
+ - addText(text)
905
+ - __addSublanguage(emitter, subLanguageName)
906
+ - startScope(scope)
907
+ - endScope()
908
+ - finalize()
909
+ - toHTML()
910
+
911
+ */
912
+ /**
913
+ * @implements {Emitter}
914
+ */
915
+ var TokenTreeEmitter = class extends TokenTree {
916
+ /**
917
+ * @param {*} options
918
+ */
919
+ constructor(options) {
920
+ super();
921
+ this.options = options;
922
+ }
923
+ /**
924
+ * @param {string} text
925
+ */
926
+ addText(text) {
927
+ if (text === "") return;
928
+ this.add(text);
929
+ }
930
+ /** @param {string} scope */
931
+ startScope(scope) {
932
+ this.openNode(scope);
933
+ }
934
+ endScope() {
935
+ this.closeNode();
936
+ }
937
+ /**
938
+ * @param {Emitter & {root: DataNode}} emitter
939
+ * @param {string} name
940
+ */
941
+ __addSublanguage(emitter, name) {
942
+ /** @type DataNode */
943
+ const node = emitter.root;
944
+ if (name) node.scope = `language:${name}`;
945
+ this.add(node);
946
+ }
947
+ toHTML() {
948
+ return new HTMLRenderer(this, this.options).value();
949
+ }
950
+ finalize() {
951
+ this.closeAllNodes();
952
+ return true;
953
+ }
954
+ };
955
+ /**
956
+ * @param {string} value
957
+ * @returns {RegExp}
958
+ * */
959
+ /**
960
+ * @param {RegExp | string } re
961
+ * @returns {string}
962
+ */
963
+ function source(re) {
964
+ if (!re) return null;
965
+ if (typeof re === "string") return re;
966
+ return re.source;
967
+ }
968
+ /**
969
+ * @param {RegExp | string } re
970
+ * @returns {string}
971
+ */
972
+ function lookahead(re) {
973
+ return concat("(?=", re, ")");
974
+ }
975
+ /**
976
+ * @param {RegExp | string } re
977
+ * @returns {string}
978
+ */
979
+ function anyNumberOfTimes(re) {
980
+ return concat("(?:", re, ")*");
981
+ }
982
+ /**
983
+ * @param {RegExp | string } re
984
+ * @returns {string}
985
+ */
986
+ function optional(re) {
987
+ return concat("(?:", re, ")?");
988
+ }
989
+ /**
990
+ * @param {...(RegExp | string) } args
991
+ * @returns {string}
992
+ */
993
+ function concat(...args) {
994
+ return args.map((x) => source(x)).join("");
995
+ }
996
+ /**
997
+ * @param { Array<string | RegExp | Object> } args
998
+ * @returns {object}
999
+ */
1000
+ function stripOptionsFromArgs(args) {
1001
+ const opts = args[args.length - 1];
1002
+ if (typeof opts === "object" && opts.constructor === Object) {
1003
+ args.splice(args.length - 1, 1);
1004
+ return opts;
1005
+ } else return {};
1006
+ }
1007
+ /** @typedef { {capture?: boolean} } RegexEitherOptions */
1008
+ /**
1009
+ * Any of the passed expresssions may match
1010
+ *
1011
+ * Creates a huge this | this | that | that match
1012
+ * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args
1013
+ * @returns {string}
1014
+ */
1015
+ function either(...args) {
1016
+ return "(" + (stripOptionsFromArgs(args).capture ? "" : "?:") + args.map((x) => source(x)).join("|") + ")";
1017
+ }
1018
+ /**
1019
+ * @param {RegExp | string} re
1020
+ * @returns {number}
1021
+ */
1022
+ function countMatchGroups(re) {
1023
+ return new RegExp(re.toString() + "|").exec("").length - 1;
1024
+ }
1025
+ /**
1026
+ * Does lexeme start with a regular expression match at the beginning
1027
+ * @param {RegExp} re
1028
+ * @param {string} lexeme
1029
+ */
1030
+ function startsWith(re, lexeme) {
1031
+ const match = re && re.exec(lexeme);
1032
+ return match && match.index === 0;
1033
+ }
1034
+ var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
1035
+ /**
1036
+ * @param {(string | RegExp)[]} regexps
1037
+ * @param {{joinWith: string}} opts
1038
+ * @returns {string}
1039
+ */
1040
+ function _rewriteBackreferences(regexps, { joinWith }) {
1041
+ let numCaptures = 0;
1042
+ return regexps.map((regex) => {
1043
+ numCaptures += 1;
1044
+ const offset = numCaptures;
1045
+ let re = source(regex);
1046
+ let out = "";
1047
+ while (re.length > 0) {
1048
+ const match = BACKREF_RE.exec(re);
1049
+ if (!match) {
1050
+ out += re;
1051
+ break;
1052
+ }
1053
+ out += re.substring(0, match.index);
1054
+ re = re.substring(match.index + match[0].length);
1055
+ if (match[0][0] === "\\" && match[1]) out += "\\" + String(Number(match[1]) + offset);
1056
+ else {
1057
+ out += match[0];
1058
+ if (match[0] === "(") numCaptures++;
1059
+ }
1060
+ }
1061
+ return out;
1062
+ }).map((re) => `(${re})`).join(joinWith);
1063
+ }
1064
+ /** @typedef {import('highlight.js').Mode} Mode */
1065
+ /** @typedef {import('highlight.js').ModeCallback} ModeCallback */
1066
+ var MATCH_NOTHING_RE = /\b\B/;
1067
+ var IDENT_RE = "[a-zA-Z]\\w*";
1068
+ var UNDERSCORE_IDENT_RE = "[a-zA-Z_]\\w*";
1069
+ var NUMBER_RE = "\\b\\d+(\\.\\d+)?";
1070
+ var C_NUMBER_RE = "(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";
1071
+ var BINARY_NUMBER_RE = "\\b(0b[01]+)";
1072
+ var RE_STARTERS_RE = "!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";
1073
+ /**
1074
+ * @param { Partial<Mode> & {binary?: string | RegExp} } opts
1075
+ */
1076
+ var SHEBANG = (opts = {}) => {
1077
+ const beginShebang = /^#![ ]*\//;
1078
+ if (opts.binary) opts.begin = concat(beginShebang, /.*\b/, opts.binary, /\b.*/);
1079
+ return inherit$1({
1080
+ scope: "meta",
1081
+ begin: beginShebang,
1082
+ end: /$/,
1083
+ relevance: 0,
1084
+ "on:begin": (m, resp) => {
1085
+ if (m.index !== 0) resp.ignoreMatch();
1086
+ }
1087
+ }, opts);
1088
+ };
1089
+ var BACKSLASH_ESCAPE = {
1090
+ begin: "\\\\[\\s\\S]",
1091
+ relevance: 0
1092
+ };
1093
+ var APOS_STRING_MODE = {
1094
+ scope: "string",
1095
+ begin: "'",
1096
+ end: "'",
1097
+ illegal: "\\n",
1098
+ contains: [BACKSLASH_ESCAPE]
1099
+ };
1100
+ var QUOTE_STRING_MODE = {
1101
+ scope: "string",
1102
+ begin: "\"",
1103
+ end: "\"",
1104
+ illegal: "\\n",
1105
+ contains: [BACKSLASH_ESCAPE]
1106
+ };
1107
+ var PHRASAL_WORDS_MODE = { begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ };
1108
+ /**
1109
+ * Creates a comment mode
1110
+ *
1111
+ * @param {string | RegExp} begin
1112
+ * @param {string | RegExp} end
1113
+ * @param {Mode | {}} [modeOptions]
1114
+ * @returns {Partial<Mode>}
1115
+ */
1116
+ var COMMENT = function(begin, end, modeOptions = {}) {
1117
+ const mode = inherit$1({
1118
+ scope: "comment",
1119
+ begin,
1120
+ end,
1121
+ contains: []
1122
+ }, modeOptions);
1123
+ mode.contains.push({
1124
+ scope: "doctag",
1125
+ begin: "[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",
1126
+ end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,
1127
+ excludeBegin: true,
1128
+ relevance: 0
1129
+ });
1130
+ const ENGLISH_WORD = either("I", "a", "is", "so", "us", "to", "at", "if", "in", "it", "on", /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, /[A-Za-z]+[-][a-z]+/, /[A-Za-z][a-z]{2,}/);
1131
+ mode.contains.push({ begin: concat(/[ ]+/, "(", ENGLISH_WORD, /[.]?[:]?([.][ ]|[ ])/, "){3}") });
1132
+ return mode;
1133
+ };
1134
+ var C_LINE_COMMENT_MODE = COMMENT("//", "$");
1135
+ var C_BLOCK_COMMENT_MODE = COMMENT("/\\*", "\\*/");
1136
+ var HASH_COMMENT_MODE = COMMENT("#", "$");
1137
+ var NUMBER_MODE = {
1138
+ scope: "number",
1139
+ begin: NUMBER_RE,
1140
+ relevance: 0
1141
+ };
1142
+ var C_NUMBER_MODE = {
1143
+ scope: "number",
1144
+ begin: C_NUMBER_RE,
1145
+ relevance: 0
1146
+ };
1147
+ var BINARY_NUMBER_MODE = {
1148
+ scope: "number",
1149
+ begin: BINARY_NUMBER_RE,
1150
+ relevance: 0
1151
+ };
1152
+ var REGEXP_MODE = {
1153
+ scope: "regexp",
1154
+ begin: /\/(?=[^/\n]*\/)/,
1155
+ end: /\/[gimuy]*/,
1156
+ contains: [BACKSLASH_ESCAPE, {
1157
+ begin: /\[/,
1158
+ end: /\]/,
1159
+ relevance: 0,
1160
+ contains: [BACKSLASH_ESCAPE]
1161
+ }]
1162
+ };
1163
+ var TITLE_MODE = {
1164
+ scope: "title",
1165
+ begin: IDENT_RE,
1166
+ relevance: 0
1167
+ };
1168
+ var UNDERSCORE_TITLE_MODE = {
1169
+ scope: "title",
1170
+ begin: UNDERSCORE_IDENT_RE,
1171
+ relevance: 0
1172
+ };
1173
+ var METHOD_GUARD = {
1174
+ begin: "\\.\\s*" + UNDERSCORE_IDENT_RE,
1175
+ relevance: 0
1176
+ };
1177
+ /**
1178
+ * Adds end same as begin mechanics to a mode
1179
+ *
1180
+ * Your mode must include at least a single () match group as that first match
1181
+ * group is what is used for comparison
1182
+ * @param {Partial<Mode>} mode
1183
+ */
1184
+ var END_SAME_AS_BEGIN = function(mode) {
1185
+ return Object.assign(mode, {
1186
+ "on:begin": (m, resp) => {
1187
+ resp.data._beginMatch = m[1];
1188
+ },
1189
+ "on:end": (m, resp) => {
1190
+ if (resp.data._beginMatch !== m[1]) resp.ignoreMatch();
1191
+ }
1192
+ });
1193
+ };
1194
+ var MODES = /* @__PURE__ */ Object.freeze({
1195
+ __proto__: null,
1196
+ APOS_STRING_MODE,
1197
+ BACKSLASH_ESCAPE,
1198
+ BINARY_NUMBER_MODE,
1199
+ BINARY_NUMBER_RE,
1200
+ COMMENT,
1201
+ C_BLOCK_COMMENT_MODE,
1202
+ C_LINE_COMMENT_MODE,
1203
+ C_NUMBER_MODE,
1204
+ C_NUMBER_RE,
1205
+ END_SAME_AS_BEGIN,
1206
+ HASH_COMMENT_MODE,
1207
+ IDENT_RE,
1208
+ MATCH_NOTHING_RE,
1209
+ METHOD_GUARD,
1210
+ NUMBER_MODE,
1211
+ NUMBER_RE,
1212
+ PHRASAL_WORDS_MODE,
1213
+ QUOTE_STRING_MODE,
1214
+ REGEXP_MODE,
1215
+ RE_STARTERS_RE,
1216
+ SHEBANG,
1217
+ TITLE_MODE,
1218
+ UNDERSCORE_IDENT_RE,
1219
+ UNDERSCORE_TITLE_MODE
1220
+ });
1221
+ /**
1222
+ @typedef {import('highlight.js').CallbackResponse} CallbackResponse
1223
+ @typedef {import('highlight.js').CompilerExt} CompilerExt
1224
+ */
1225
+ /**
1226
+ * Skip a match if it has a preceding dot
1227
+ *
1228
+ * This is used for `beginKeywords` to prevent matching expressions such as
1229
+ * `bob.keyword.do()`. The mode compiler automatically wires this up as a
1230
+ * special _internal_ 'on:begin' callback for modes with `beginKeywords`
1231
+ * @param {RegExpMatchArray} match
1232
+ * @param {CallbackResponse} response
1233
+ */
1234
+ function skipIfHasPrecedingDot(match, response) {
1235
+ if (match.input[match.index - 1] === ".") response.ignoreMatch();
1236
+ }
1237
+ /**
1238
+ *
1239
+ * @type {CompilerExt}
1240
+ */
1241
+ function scopeClassName(mode, _parent) {
1242
+ if (mode.className !== void 0) {
1243
+ mode.scope = mode.className;
1244
+ delete mode.className;
1245
+ }
1246
+ }
1247
+ /**
1248
+ * `beginKeywords` syntactic sugar
1249
+ * @type {CompilerExt}
1250
+ */
1251
+ function beginKeywords(mode, parent) {
1252
+ if (!parent) return;
1253
+ if (!mode.beginKeywords) return;
1254
+ mode.begin = "\\b(" + mode.beginKeywords.split(" ").join("|") + ")(?!\\.)(?=\\b|\\s)";
1255
+ mode.__beforeBegin = skipIfHasPrecedingDot;
1256
+ mode.keywords = mode.keywords || mode.beginKeywords;
1257
+ delete mode.beginKeywords;
1258
+ if (mode.relevance === void 0) mode.relevance = 0;
1259
+ }
1260
+ /**
1261
+ * Allow `illegal` to contain an array of illegal values
1262
+ * @type {CompilerExt}
1263
+ */
1264
+ function compileIllegal(mode, _parent) {
1265
+ if (!Array.isArray(mode.illegal)) return;
1266
+ mode.illegal = either(...mode.illegal);
1267
+ }
1268
+ /**
1269
+ * `match` to match a single expression for readability
1270
+ * @type {CompilerExt}
1271
+ */
1272
+ function compileMatch(mode, _parent) {
1273
+ if (!mode.match) return;
1274
+ if (mode.begin || mode.end) throw new Error("begin & end are not supported with match");
1275
+ mode.begin = mode.match;
1276
+ delete mode.match;
1277
+ }
1278
+ /**
1279
+ * provides the default 1 relevance to all modes
1280
+ * @type {CompilerExt}
1281
+ */
1282
+ function compileRelevance(mode, _parent) {
1283
+ if (mode.relevance === void 0) mode.relevance = 1;
1284
+ }
1285
+ var beforeMatchExt = (mode, parent) => {
1286
+ if (!mode.beforeMatch) return;
1287
+ if (mode.starts) throw new Error("beforeMatch cannot be used with starts");
1288
+ const originalMode = Object.assign({}, mode);
1289
+ Object.keys(mode).forEach((key) => {
1290
+ delete mode[key];
1291
+ });
1292
+ mode.keywords = originalMode.keywords;
1293
+ mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));
1294
+ mode.starts = {
1295
+ relevance: 0,
1296
+ contains: [Object.assign(originalMode, { endsParent: true })]
1297
+ };
1298
+ mode.relevance = 0;
1299
+ delete originalMode.beforeMatch;
1300
+ };
1301
+ var COMMON_KEYWORDS = [
1302
+ "of",
1303
+ "and",
1304
+ "for",
1305
+ "in",
1306
+ "not",
1307
+ "or",
1308
+ "if",
1309
+ "then",
1310
+ "parent",
1311
+ "list",
1312
+ "value"
1313
+ ];
1314
+ var DEFAULT_KEYWORD_SCOPE = "keyword";
1315
+ /**
1316
+ * Given raw keywords from a language definition, compile them.
1317
+ *
1318
+ * @param {string | Record<string,string|string[]> | Array<string>} rawKeywords
1319
+ * @param {boolean} caseInsensitive
1320
+ */
1321
+ function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {
1322
+ /** @type {import("highlight.js/private").KeywordDict} */
1323
+ const compiledKeywords = Object.create(null);
1324
+ if (typeof rawKeywords === "string") compileList(scopeName, rawKeywords.split(" "));
1325
+ else if (Array.isArray(rawKeywords)) compileList(scopeName, rawKeywords);
1326
+ else Object.keys(rawKeywords).forEach(function(scopeName) {
1327
+ Object.assign(compiledKeywords, compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName));
1328
+ });
1329
+ return compiledKeywords;
1330
+ /**
1331
+ * Compiles an individual list of keywords
1332
+ *
1333
+ * Ex: "for if when while|5"
1334
+ *
1335
+ * @param {string} scopeName
1336
+ * @param {Array<string>} keywordList
1337
+ */
1338
+ function compileList(scopeName, keywordList) {
1339
+ if (caseInsensitive) keywordList = keywordList.map((x) => x.toLowerCase());
1340
+ keywordList.forEach(function(keyword) {
1341
+ const pair = keyword.split("|");
1342
+ compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];
1343
+ });
1344
+ }
1345
+ }
1346
+ /**
1347
+ * Returns the proper score for a given keyword
1348
+ *
1349
+ * Also takes into account comment keywords, which will be scored 0 UNLESS
1350
+ * another score has been manually assigned.
1351
+ * @param {string} keyword
1352
+ * @param {string} [providedScore]
1353
+ */
1354
+ function scoreForKeyword(keyword, providedScore) {
1355
+ if (providedScore) return Number(providedScore);
1356
+ return commonKeyword(keyword) ? 0 : 1;
1357
+ }
1358
+ /**
1359
+ * Determines if a given keyword is common or not
1360
+ *
1361
+ * @param {string} keyword */
1362
+ function commonKeyword(keyword) {
1363
+ return COMMON_KEYWORDS.includes(keyword.toLowerCase());
1364
+ }
1365
+ /**
1366
+ * @type {Record<string, boolean>}
1367
+ */
1368
+ var seenDeprecations = {};
1369
+ /**
1370
+ * @param {string} message
1371
+ */
1372
+ var error = (message) => {
1373
+ console.error(message);
1374
+ };
1375
+ /**
1376
+ * @param {string} message
1377
+ * @param {any} args
1378
+ */
1379
+ var warn = (message, ...args) => {
1380
+ console.log(`WARN: ${message}`, ...args);
1381
+ };
1382
+ /**
1383
+ * @param {string} version
1384
+ * @param {string} message
1385
+ */
1386
+ var deprecated = (version, message) => {
1387
+ if (seenDeprecations[`${version}/${message}`]) return;
1388
+ console.log(`Deprecated as of ${version}. ${message}`);
1389
+ seenDeprecations[`${version}/${message}`] = true;
1390
+ };
1391
+ /**
1392
+ @typedef {import('highlight.js').CompiledMode} CompiledMode
1393
+ */
1394
+ var MultiClassError = /* @__PURE__ */ new Error();
1395
+ /**
1396
+ * Renumbers labeled scope names to account for additional inner match
1397
+ * groups that otherwise would break everything.
1398
+ *
1399
+ * Lets say we 3 match scopes:
1400
+ *
1401
+ * { 1 => ..., 2 => ..., 3 => ... }
1402
+ *
1403
+ * So what we need is a clean match like this:
1404
+ *
1405
+ * (a)(b)(c) => [ "a", "b", "c" ]
1406
+ *
1407
+ * But this falls apart with inner match groups:
1408
+ *
1409
+ * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ]
1410
+ *
1411
+ * Our scopes are now "out of alignment" and we're repeating `b` 3 times.
1412
+ * What needs to happen is the numbers are remapped:
1413
+ *
1414
+ * { 1 => ..., 2 => ..., 5 => ... }
1415
+ *
1416
+ * We also need to know that the ONLY groups that should be output
1417
+ * are 1, 2, and 5. This function handles this behavior.
1418
+ *
1419
+ * @param {CompiledMode} mode
1420
+ * @param {Array<RegExp | string>} regexes
1421
+ * @param {{key: "beginScope"|"endScope"}} opts
1422
+ */
1423
+ function remapScopeNames(mode, regexes, { key }) {
1424
+ let offset = 0;
1425
+ const scopeNames = mode[key];
1426
+ /** @type Record<number,boolean> */
1427
+ const emit = {};
1428
+ /** @type Record<number,string> */
1429
+ const positions = {};
1430
+ for (let i = 1; i <= regexes.length; i++) {
1431
+ positions[i + offset] = scopeNames[i];
1432
+ emit[i + offset] = true;
1433
+ offset += countMatchGroups(regexes[i - 1]);
1434
+ }
1435
+ mode[key] = positions;
1436
+ mode[key]._emit = emit;
1437
+ mode[key]._multi = true;
1438
+ }
1439
+ /**
1440
+ * @param {CompiledMode} mode
1441
+ */
1442
+ function beginMultiClass(mode) {
1443
+ if (!Array.isArray(mode.begin)) return;
1444
+ if (mode.skip || mode.excludeBegin || mode.returnBegin) {
1445
+ error("skip, excludeBegin, returnBegin not compatible with beginScope: {}");
1446
+ throw MultiClassError;
1447
+ }
1448
+ if (typeof mode.beginScope !== "object" || mode.beginScope === null) {
1449
+ error("beginScope must be object");
1450
+ throw MultiClassError;
1451
+ }
1452
+ remapScopeNames(mode, mode.begin, { key: "beginScope" });
1453
+ mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" });
1454
+ }
1455
+ /**
1456
+ * @param {CompiledMode} mode
1457
+ */
1458
+ function endMultiClass(mode) {
1459
+ if (!Array.isArray(mode.end)) return;
1460
+ if (mode.skip || mode.excludeEnd || mode.returnEnd) {
1461
+ error("skip, excludeEnd, returnEnd not compatible with endScope: {}");
1462
+ throw MultiClassError;
1463
+ }
1464
+ if (typeof mode.endScope !== "object" || mode.endScope === null) {
1465
+ error("endScope must be object");
1466
+ throw MultiClassError;
1467
+ }
1468
+ remapScopeNames(mode, mode.end, { key: "endScope" });
1469
+ mode.end = _rewriteBackreferences(mode.end, { joinWith: "" });
1470
+ }
1471
+ /**
1472
+ * this exists only to allow `scope: {}` to be used beside `match:`
1473
+ * Otherwise `beginScope` would necessary and that would look weird
1474
+
1475
+ {
1476
+ match: [ /def/, /\w+/ ]
1477
+ scope: { 1: "keyword" , 2: "title" }
1478
+ }
1479
+
1480
+ * @param {CompiledMode} mode
1481
+ */
1482
+ function scopeSugar(mode) {
1483
+ if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) {
1484
+ mode.beginScope = mode.scope;
1485
+ delete mode.scope;
1486
+ }
1487
+ }
1488
+ /**
1489
+ * @param {CompiledMode} mode
1490
+ */
1491
+ function MultiClass(mode) {
1492
+ scopeSugar(mode);
1493
+ if (typeof mode.beginScope === "string") mode.beginScope = { _wrap: mode.beginScope };
1494
+ if (typeof mode.endScope === "string") mode.endScope = { _wrap: mode.endScope };
1495
+ beginMultiClass(mode);
1496
+ endMultiClass(mode);
1497
+ }
1498
+ /**
1499
+ @typedef {import('highlight.js').Mode} Mode
1500
+ @typedef {import('highlight.js').CompiledMode} CompiledMode
1501
+ @typedef {import('highlight.js').Language} Language
1502
+ @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin
1503
+ @typedef {import('highlight.js').CompiledLanguage} CompiledLanguage
1504
+ */
1505
+ /**
1506
+ * Compiles a language definition result
1507
+ *
1508
+ * Given the raw result of a language definition (Language), compiles this so
1509
+ * that it is ready for highlighting code.
1510
+ * @param {Language} language
1511
+ * @returns {CompiledLanguage}
1512
+ */
1513
+ function compileLanguage(language) {
1514
+ /**
1515
+ * Builds a regex with the case sensitivity of the current language
1516
+ *
1517
+ * @param {RegExp | string} value
1518
+ * @param {boolean} [global]
1519
+ */
1520
+ function langRe(value, global) {
1521
+ return new RegExp(source(value), "m" + (language.case_insensitive ? "i" : "") + (language.unicodeRegex ? "u" : "") + (global ? "g" : ""));
1522
+ }
1523
+ /**
1524
+ Stores multiple regular expressions and allows you to quickly search for
1525
+ them all in a string simultaneously - returning the first match. It does
1526
+ this by creating a huge (a|b|c) regex - each individual item wrapped with ()
1527
+ and joined by `|` - using match groups to track position. When a match is
1528
+ found checking which position in the array has content allows us to figure
1529
+ out which of the original regexes / match groups triggered the match.
1530
+
1531
+ The match object itself (the result of `Regex.exec`) is returned but also
1532
+ enhanced by merging in any meta-data that was registered with the regex.
1533
+ This is how we keep track of which mode matched, and what type of rule
1534
+ (`illegal`, `begin`, end, etc).
1535
+ */
1536
+ class MultiRegex {
1537
+ constructor() {
1538
+ this.matchIndexes = {};
1539
+ this.regexes = [];
1540
+ this.matchAt = 1;
1541
+ this.position = 0;
1542
+ }
1543
+ addRule(re, opts) {
1544
+ opts.position = this.position++;
1545
+ this.matchIndexes[this.matchAt] = opts;
1546
+ this.regexes.push([opts, re]);
1547
+ this.matchAt += countMatchGroups(re) + 1;
1548
+ }
1549
+ compile() {
1550
+ if (this.regexes.length === 0) this.exec = () => null;
1551
+ this.matcherRe = langRe(_rewriteBackreferences(this.regexes.map((el) => el[1]), { joinWith: "|" }), true);
1552
+ this.lastIndex = 0;
1553
+ }
1554
+ /** @param {string} s */
1555
+ exec(s) {
1556
+ this.matcherRe.lastIndex = this.lastIndex;
1557
+ const match = this.matcherRe.exec(s);
1558
+ if (!match) return null;
1559
+ const i = match.findIndex((el, i) => i > 0 && el !== void 0);
1560
+ const matchData = this.matchIndexes[i];
1561
+ match.splice(0, i);
1562
+ return Object.assign(match, matchData);
1563
+ }
1564
+ }
1565
+ class ResumableMultiRegex {
1566
+ constructor() {
1567
+ this.rules = [];
1568
+ this.multiRegexes = [];
1569
+ this.count = 0;
1570
+ this.lastIndex = 0;
1571
+ this.regexIndex = 0;
1572
+ }
1573
+ getMatcher(index) {
1574
+ if (this.multiRegexes[index]) return this.multiRegexes[index];
1575
+ const matcher = new MultiRegex();
1576
+ this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));
1577
+ matcher.compile();
1578
+ this.multiRegexes[index] = matcher;
1579
+ return matcher;
1580
+ }
1581
+ resumingScanAtSamePosition() {
1582
+ return this.regexIndex !== 0;
1583
+ }
1584
+ considerAll() {
1585
+ this.regexIndex = 0;
1586
+ }
1587
+ addRule(re, opts) {
1588
+ this.rules.push([re, opts]);
1589
+ if (opts.type === "begin") this.count++;
1590
+ }
1591
+ /** @param {string} s */
1592
+ exec(s) {
1593
+ const m = this.getMatcher(this.regexIndex);
1594
+ m.lastIndex = this.lastIndex;
1595
+ let result = m.exec(s);
1596
+ if (this.resumingScanAtSamePosition()) if (result && result.index === this.lastIndex);
1597
+ else {
1598
+ const m2 = this.getMatcher(0);
1599
+ m2.lastIndex = this.lastIndex + 1;
1600
+ result = m2.exec(s);
1601
+ }
1602
+ if (result) {
1603
+ this.regexIndex += result.position + 1;
1604
+ if (this.regexIndex === this.count) this.considerAll();
1605
+ }
1606
+ return result;
1607
+ }
1608
+ }
1609
+ /**
1610
+ * Given a mode, builds a huge ResumableMultiRegex that can be used to walk
1611
+ * the content and find matches.
1612
+ *
1613
+ * @param {CompiledMode} mode
1614
+ * @returns {ResumableMultiRegex}
1615
+ */
1616
+ function buildModeRegex(mode) {
1617
+ const mm = new ResumableMultiRegex();
1618
+ mode.contains.forEach((term) => mm.addRule(term.begin, {
1619
+ rule: term,
1620
+ type: "begin"
1621
+ }));
1622
+ if (mode.terminatorEnd) mm.addRule(mode.terminatorEnd, { type: "end" });
1623
+ if (mode.illegal) mm.addRule(mode.illegal, { type: "illegal" });
1624
+ return mm;
1625
+ }
1626
+ /** skip vs abort vs ignore
1627
+ *
1628
+ * @skip - The mode is still entered and exited normally (and contains rules apply),
1629
+ * but all content is held and added to the parent buffer rather than being
1630
+ * output when the mode ends. Mostly used with `sublanguage` to build up
1631
+ * a single large buffer than can be parsed by sublanguage.
1632
+ *
1633
+ * - The mode begin ands ends normally.
1634
+ * - Content matched is added to the parent mode buffer.
1635
+ * - The parser cursor is moved forward normally.
1636
+ *
1637
+ * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it
1638
+ * never matched) but DOES NOT continue to match subsequent `contains`
1639
+ * modes. Abort is bad/suboptimal because it can result in modes
1640
+ * farther down not getting applied because an earlier rule eats the
1641
+ * content but then aborts.
1642
+ *
1643
+ * - The mode does not begin.
1644
+ * - Content matched by `begin` is added to the mode buffer.
1645
+ * - The parser cursor is moved forward accordingly.
1646
+ *
1647
+ * @ignore - Ignores the mode (as if it never matched) and continues to match any
1648
+ * subsequent `contains` modes. Ignore isn't technically possible with
1649
+ * the current parser implementation.
1650
+ *
1651
+ * - The mode does not begin.
1652
+ * - Content matched by `begin` is ignored.
1653
+ * - The parser cursor is not moved forward.
1654
+ */
1655
+ /**
1656
+ * Compiles an individual mode
1657
+ *
1658
+ * This can raise an error if the mode contains certain detectable known logic
1659
+ * issues.
1660
+ * @param {Mode} mode
1661
+ * @param {CompiledMode | null} [parent]
1662
+ * @returns {CompiledMode | never}
1663
+ */
1664
+ function compileMode(mode, parent) {
1665
+ const cmode = mode;
1666
+ if (mode.isCompiled) return cmode;
1667
+ [
1668
+ scopeClassName,
1669
+ compileMatch,
1670
+ MultiClass,
1671
+ beforeMatchExt
1672
+ ].forEach((ext) => ext(mode, parent));
1673
+ language.compilerExtensions.forEach((ext) => ext(mode, parent));
1674
+ mode.__beforeBegin = null;
1675
+ [
1676
+ beginKeywords,
1677
+ compileIllegal,
1678
+ compileRelevance
1679
+ ].forEach((ext) => ext(mode, parent));
1680
+ mode.isCompiled = true;
1681
+ let keywordPattern = null;
1682
+ if (typeof mode.keywords === "object" && mode.keywords.$pattern) {
1683
+ mode.keywords = Object.assign({}, mode.keywords);
1684
+ keywordPattern = mode.keywords.$pattern;
1685
+ delete mode.keywords.$pattern;
1686
+ }
1687
+ keywordPattern = keywordPattern || /\w+/;
1688
+ if (mode.keywords) mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);
1689
+ cmode.keywordPatternRe = langRe(keywordPattern, true);
1690
+ if (parent) {
1691
+ if (!mode.begin) mode.begin = /\B|\b/;
1692
+ cmode.beginRe = langRe(cmode.begin);
1693
+ if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/;
1694
+ if (mode.end) cmode.endRe = langRe(cmode.end);
1695
+ cmode.terminatorEnd = source(cmode.end) || "";
1696
+ if (mode.endsWithParent && parent.terminatorEnd) cmode.terminatorEnd += (mode.end ? "|" : "") + parent.terminatorEnd;
1697
+ }
1698
+ if (mode.illegal) cmode.illegalRe = langRe(mode.illegal);
1699
+ if (!mode.contains) mode.contains = [];
1700
+ mode.contains = [].concat(...mode.contains.map(function(c) {
1701
+ return expandOrCloneMode(c === "self" ? mode : c);
1702
+ }));
1703
+ mode.contains.forEach(function(c) {
1704
+ compileMode(c, cmode);
1705
+ });
1706
+ if (mode.starts) compileMode(mode.starts, parent);
1707
+ cmode.matcher = buildModeRegex(cmode);
1708
+ return cmode;
1709
+ }
1710
+ if (!language.compilerExtensions) language.compilerExtensions = [];
1711
+ if (language.contains && language.contains.includes("self")) throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");
1712
+ language.classNameAliases = inherit$1(language.classNameAliases || {});
1713
+ return compileMode(language);
1714
+ }
1715
+ /**
1716
+ * Determines if a mode has a dependency on it's parent or not
1717
+ *
1718
+ * If a mode does have a parent dependency then often we need to clone it if
1719
+ * it's used in multiple places so that each copy points to the correct parent,
1720
+ * where-as modes without a parent can often safely be re-used at the bottom of
1721
+ * a mode chain.
1722
+ *
1723
+ * @param {Mode | null} mode
1724
+ * @returns {boolean} - is there a dependency on the parent?
1725
+ * */
1726
+ function dependencyOnParent(mode) {
1727
+ if (!mode) return false;
1728
+ return mode.endsWithParent || dependencyOnParent(mode.starts);
1729
+ }
1730
+ /**
1731
+ * Expands a mode or clones it if necessary
1732
+ *
1733
+ * This is necessary for modes with parental dependenceis (see notes on
1734
+ * `dependencyOnParent`) and for nodes that have `variants` - which must then be
1735
+ * exploded into their own individual modes at compile time.
1736
+ *
1737
+ * @param {Mode} mode
1738
+ * @returns {Mode | Mode[]}
1739
+ * */
1740
+ function expandOrCloneMode(mode) {
1741
+ if (mode.variants && !mode.cachedVariants) mode.cachedVariants = mode.variants.map(function(variant) {
1742
+ return inherit$1(mode, { variants: null }, variant);
1743
+ });
1744
+ if (mode.cachedVariants) return mode.cachedVariants;
1745
+ if (dependencyOnParent(mode)) return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null });
1746
+ if (Object.isFrozen(mode)) return inherit$1(mode);
1747
+ return mode;
1748
+ }
1749
+ var version = "11.11.1";
1750
+ var HTMLInjectionError = class extends Error {
1751
+ constructor(reason, html) {
1752
+ super(reason);
1753
+ this.name = "HTMLInjectionError";
1754
+ this.html = html;
1755
+ }
1756
+ };
1757
+ /**
1758
+ @typedef {import('highlight.js').Mode} Mode
1759
+ @typedef {import('highlight.js').CompiledMode} CompiledMode
1760
+ @typedef {import('highlight.js').CompiledScope} CompiledScope
1761
+ @typedef {import('highlight.js').Language} Language
1762
+ @typedef {import('highlight.js').HLJSApi} HLJSApi
1763
+ @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin
1764
+ @typedef {import('highlight.js').PluginEvent} PluginEvent
1765
+ @typedef {import('highlight.js').HLJSOptions} HLJSOptions
1766
+ @typedef {import('highlight.js').LanguageFn} LanguageFn
1767
+ @typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement
1768
+ @typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext
1769
+ @typedef {import('highlight.js/private').MatchType} MatchType
1770
+ @typedef {import('highlight.js/private').KeywordData} KeywordData
1771
+ @typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch
1772
+ @typedef {import('highlight.js/private').AnnotatedError} AnnotatedError
1773
+ @typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult
1774
+ @typedef {import('highlight.js').HighlightOptions} HighlightOptions
1775
+ @typedef {import('highlight.js').HighlightResult} HighlightResult
1776
+ */
1777
+ var escape = escapeHTML;
1778
+ var inherit = inherit$1;
1779
+ var NO_MATCH = Symbol("nomatch");
1780
+ var MAX_KEYWORD_HITS = 7;
1781
+ /**
1782
+ * @param {any} hljs - object that is extended (legacy)
1783
+ * @returns {HLJSApi}
1784
+ */
1785
+ var HLJS = function(hljs) {
1786
+ /** @type {Record<string, Language>} */
1787
+ const languages = Object.create(null);
1788
+ /** @type {Record<string, string>} */
1789
+ const aliases = Object.create(null);
1790
+ /** @type {HLJSPlugin[]} */
1791
+ const plugins = [];
1792
+ let SAFE_MODE = true;
1793
+ const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?";
1794
+ /** @type {Language} */
1795
+ const PLAINTEXT_LANGUAGE = {
1796
+ disableAutodetect: true,
1797
+ name: "Plain text",
1798
+ contains: []
1799
+ };
1800
+ /** @type HLJSOptions */
1801
+ let options = {
1802
+ ignoreUnescapedHTML: false,
1803
+ throwUnescapedHTML: false,
1804
+ noHighlightRe: /^(no-?highlight)$/i,
1805
+ languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i,
1806
+ classPrefix: "hljs-",
1807
+ cssSelector: "pre code",
1808
+ languages: null,
1809
+ __emitter: TokenTreeEmitter
1810
+ };
1811
+ /**
1812
+ * Tests a language name to see if highlighting should be skipped
1813
+ * @param {string} languageName
1814
+ */
1815
+ function shouldNotHighlight(languageName) {
1816
+ return options.noHighlightRe.test(languageName);
1817
+ }
1818
+ /**
1819
+ * @param {HighlightedHTMLElement} block - the HTML element to determine language for
1820
+ */
1821
+ function blockLanguage(block) {
1822
+ let classes = block.className + " ";
1823
+ classes += block.parentNode ? block.parentNode.className : "";
1824
+ const match = options.languageDetectRe.exec(classes);
1825
+ if (match) {
1826
+ const language = getLanguage(match[1]);
1827
+ if (!language) {
1828
+ warn(LANGUAGE_NOT_FOUND.replace("{}", match[1]));
1829
+ warn("Falling back to no-highlight mode for this block.", block);
1830
+ }
1831
+ return language ? match[1] : "no-highlight";
1832
+ }
1833
+ return classes.split(/\s+/).find((_class) => shouldNotHighlight(_class) || getLanguage(_class));
1834
+ }
1835
+ /**
1836
+ * Core highlighting function.
1837
+ *
1838
+ * OLD API
1839
+ * highlight(lang, code, ignoreIllegals, continuation)
1840
+ *
1841
+ * NEW API
1842
+ * highlight(code, {lang, ignoreIllegals})
1843
+ *
1844
+ * @param {string} codeOrLanguageName - the language to use for highlighting
1845
+ * @param {string | HighlightOptions} optionsOrCode - the code to highlight
1846
+ * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail
1847
+ *
1848
+ * @returns {HighlightResult} Result - an object that represents the result
1849
+ * @property {string} language - the language name
1850
+ * @property {number} relevance - the relevance score
1851
+ * @property {string} value - the highlighted HTML code
1852
+ * @property {string} code - the original raw code
1853
+ * @property {CompiledMode} top - top of the current mode stack
1854
+ * @property {boolean} illegal - indicates whether any illegal matches were found
1855
+ */
1856
+ function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) {
1857
+ let code = "";
1858
+ let languageName = "";
1859
+ if (typeof optionsOrCode === "object") {
1860
+ code = codeOrLanguageName;
1861
+ ignoreIllegals = optionsOrCode.ignoreIllegals;
1862
+ languageName = optionsOrCode.language;
1863
+ } else {
1864
+ deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated.");
1865
+ deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277");
1866
+ languageName = codeOrLanguageName;
1867
+ code = optionsOrCode;
1868
+ }
1869
+ if (ignoreIllegals === void 0) ignoreIllegals = true;
1870
+ /** @type {BeforeHighlightContext} */
1871
+ const context = {
1872
+ code,
1873
+ language: languageName
1874
+ };
1875
+ fire("before:highlight", context);
1876
+ const result = context.result ? context.result : _highlight(context.language, context.code, ignoreIllegals);
1877
+ result.code = context.code;
1878
+ fire("after:highlight", result);
1879
+ return result;
1880
+ }
1881
+ /**
1882
+ * private highlight that's used internally and does not fire callbacks
1883
+ *
1884
+ * @param {string} languageName - the language to use for highlighting
1885
+ * @param {string} codeToHighlight - the code to highlight
1886
+ * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail
1887
+ * @param {CompiledMode?} [continuation] - current continuation mode, if any
1888
+ * @returns {HighlightResult} - result of the highlight operation
1889
+ */
1890
+ function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {
1891
+ const keywordHits = Object.create(null);
1892
+ /**
1893
+ * Return keyword data if a match is a keyword
1894
+ * @param {CompiledMode} mode - current mode
1895
+ * @param {string} matchText - the textual match
1896
+ * @returns {KeywordData | false}
1897
+ */
1898
+ function keywordData(mode, matchText) {
1899
+ return mode.keywords[matchText];
1900
+ }
1901
+ function processKeywords() {
1902
+ if (!top.keywords) {
1903
+ emitter.addText(modeBuffer);
1904
+ return;
1905
+ }
1906
+ let lastIndex = 0;
1907
+ top.keywordPatternRe.lastIndex = 0;
1908
+ let match = top.keywordPatternRe.exec(modeBuffer);
1909
+ let buf = "";
1910
+ while (match) {
1911
+ buf += modeBuffer.substring(lastIndex, match.index);
1912
+ const word = language.case_insensitive ? match[0].toLowerCase() : match[0];
1913
+ const data = keywordData(top, word);
1914
+ if (data) {
1915
+ const [kind, keywordRelevance] = data;
1916
+ emitter.addText(buf);
1917
+ buf = "";
1918
+ keywordHits[word] = (keywordHits[word] || 0) + 1;
1919
+ if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance;
1920
+ if (kind.startsWith("_")) buf += match[0];
1921
+ else {
1922
+ const cssClass = language.classNameAliases[kind] || kind;
1923
+ emitKeyword(match[0], cssClass);
1924
+ }
1925
+ } else buf += match[0];
1926
+ lastIndex = top.keywordPatternRe.lastIndex;
1927
+ match = top.keywordPatternRe.exec(modeBuffer);
1928
+ }
1929
+ buf += modeBuffer.substring(lastIndex);
1930
+ emitter.addText(buf);
1931
+ }
1932
+ function processSubLanguage() {
1933
+ if (modeBuffer === "") return;
1934
+ /** @type HighlightResult */
1935
+ let result = null;
1936
+ if (typeof top.subLanguage === "string") {
1937
+ if (!languages[top.subLanguage]) {
1938
+ emitter.addText(modeBuffer);
1939
+ return;
1940
+ }
1941
+ result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);
1942
+ continuations[top.subLanguage] = result._top;
1943
+ } else result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);
1944
+ if (top.relevance > 0) relevance += result.relevance;
1945
+ emitter.__addSublanguage(result._emitter, result.language);
1946
+ }
1947
+ function processBuffer() {
1948
+ if (top.subLanguage != null) processSubLanguage();
1949
+ else processKeywords();
1950
+ modeBuffer = "";
1951
+ }
1952
+ /**
1953
+ * @param {string} text
1954
+ * @param {string} scope
1955
+ */
1956
+ function emitKeyword(keyword, scope) {
1957
+ if (keyword === "") return;
1958
+ emitter.startScope(scope);
1959
+ emitter.addText(keyword);
1960
+ emitter.endScope();
1961
+ }
1962
+ /**
1963
+ * @param {CompiledScope} scope
1964
+ * @param {RegExpMatchArray} match
1965
+ */
1966
+ function emitMultiClass(scope, match) {
1967
+ let i = 1;
1968
+ const max = match.length - 1;
1969
+ while (i <= max) {
1970
+ if (!scope._emit[i]) {
1971
+ i++;
1972
+ continue;
1973
+ }
1974
+ const klass = language.classNameAliases[scope[i]] || scope[i];
1975
+ const text = match[i];
1976
+ if (klass) emitKeyword(text, klass);
1977
+ else {
1978
+ modeBuffer = text;
1979
+ processKeywords();
1980
+ modeBuffer = "";
1981
+ }
1982
+ i++;
1983
+ }
1984
+ }
1985
+ /**
1986
+ * @param {CompiledMode} mode - new mode to start
1987
+ * @param {RegExpMatchArray} match
1988
+ */
1989
+ function startNewMode(mode, match) {
1990
+ if (mode.scope && typeof mode.scope === "string") emitter.openNode(language.classNameAliases[mode.scope] || mode.scope);
1991
+ if (mode.beginScope) {
1992
+ if (mode.beginScope._wrap) {
1993
+ emitKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);
1994
+ modeBuffer = "";
1995
+ } else if (mode.beginScope._multi) {
1996
+ emitMultiClass(mode.beginScope, match);
1997
+ modeBuffer = "";
1998
+ }
1999
+ }
2000
+ top = Object.create(mode, { parent: { value: top } });
2001
+ return top;
2002
+ }
2003
+ /**
2004
+ * @param {CompiledMode } mode - the mode to potentially end
2005
+ * @param {RegExpMatchArray} match - the latest match
2006
+ * @param {string} matchPlusRemainder - match plus remainder of content
2007
+ * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode
2008
+ */
2009
+ function endOfMode(mode, match, matchPlusRemainder) {
2010
+ let matched = startsWith(mode.endRe, matchPlusRemainder);
2011
+ if (matched) {
2012
+ if (mode["on:end"]) {
2013
+ const resp = new Response(mode);
2014
+ mode["on:end"](match, resp);
2015
+ if (resp.isMatchIgnored) matched = false;
2016
+ }
2017
+ if (matched) {
2018
+ while (mode.endsParent && mode.parent) mode = mode.parent;
2019
+ return mode;
2020
+ }
2021
+ }
2022
+ if (mode.endsWithParent) return endOfMode(mode.parent, match, matchPlusRemainder);
2023
+ }
2024
+ /**
2025
+ * Handle matching but then ignoring a sequence of text
2026
+ *
2027
+ * @param {string} lexeme - string containing full match text
2028
+ */
2029
+ function doIgnore(lexeme) {
2030
+ if (top.matcher.regexIndex === 0) {
2031
+ modeBuffer += lexeme[0];
2032
+ return 1;
2033
+ } else {
2034
+ resumeScanAtSamePosition = true;
2035
+ return 0;
2036
+ }
2037
+ }
2038
+ /**
2039
+ * Handle the start of a new potential mode match
2040
+ *
2041
+ * @param {EnhancedMatch} match - the current match
2042
+ * @returns {number} how far to advance the parse cursor
2043
+ */
2044
+ function doBeginMatch(match) {
2045
+ const lexeme = match[0];
2046
+ const newMode = match.rule;
2047
+ const resp = new Response(newMode);
2048
+ const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]];
2049
+ for (const cb of beforeCallbacks) {
2050
+ if (!cb) continue;
2051
+ cb(match, resp);
2052
+ if (resp.isMatchIgnored) return doIgnore(lexeme);
2053
+ }
2054
+ if (newMode.skip) modeBuffer += lexeme;
2055
+ else {
2056
+ if (newMode.excludeBegin) modeBuffer += lexeme;
2057
+ processBuffer();
2058
+ if (!newMode.returnBegin && !newMode.excludeBegin) modeBuffer = lexeme;
2059
+ }
2060
+ startNewMode(newMode, match);
2061
+ return newMode.returnBegin ? 0 : lexeme.length;
2062
+ }
2063
+ /**
2064
+ * Handle the potential end of mode
2065
+ *
2066
+ * @param {RegExpMatchArray} match - the current match
2067
+ */
2068
+ function doEndMatch(match) {
2069
+ const lexeme = match[0];
2070
+ const matchPlusRemainder = codeToHighlight.substring(match.index);
2071
+ const endMode = endOfMode(top, match, matchPlusRemainder);
2072
+ if (!endMode) return NO_MATCH;
2073
+ const origin = top;
2074
+ if (top.endScope && top.endScope._wrap) {
2075
+ processBuffer();
2076
+ emitKeyword(lexeme, top.endScope._wrap);
2077
+ } else if (top.endScope && top.endScope._multi) {
2078
+ processBuffer();
2079
+ emitMultiClass(top.endScope, match);
2080
+ } else if (origin.skip) modeBuffer += lexeme;
2081
+ else {
2082
+ if (!(origin.returnEnd || origin.excludeEnd)) modeBuffer += lexeme;
2083
+ processBuffer();
2084
+ if (origin.excludeEnd) modeBuffer = lexeme;
2085
+ }
2086
+ do {
2087
+ if (top.scope) emitter.closeNode();
2088
+ if (!top.skip && !top.subLanguage) relevance += top.relevance;
2089
+ top = top.parent;
2090
+ } while (top !== endMode.parent);
2091
+ if (endMode.starts) startNewMode(endMode.starts, match);
2092
+ return origin.returnEnd ? 0 : lexeme.length;
2093
+ }
2094
+ function processContinuations() {
2095
+ const list = [];
2096
+ for (let current = top; current !== language; current = current.parent) if (current.scope) list.unshift(current.scope);
2097
+ list.forEach((item) => emitter.openNode(item));
2098
+ }
2099
+ /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */
2100
+ let lastMatch = {};
2101
+ /**
2102
+ * Process an individual match
2103
+ *
2104
+ * @param {string} textBeforeMatch - text preceding the match (since the last match)
2105
+ * @param {EnhancedMatch} [match] - the match itself
2106
+ */
2107
+ function processLexeme(textBeforeMatch, match) {
2108
+ const lexeme = match && match[0];
2109
+ modeBuffer += textBeforeMatch;
2110
+ if (lexeme == null) {
2111
+ processBuffer();
2112
+ return 0;
2113
+ }
2114
+ if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") {
2115
+ modeBuffer += codeToHighlight.slice(match.index, match.index + 1);
2116
+ if (!SAFE_MODE) {
2117
+ /** @type {AnnotatedError} */
2118
+ const err = /* @__PURE__ */ new Error(`0 width match regex (${languageName})`);
2119
+ err.languageName = languageName;
2120
+ err.badRule = lastMatch.rule;
2121
+ throw err;
2122
+ }
2123
+ return 1;
2124
+ }
2125
+ lastMatch = match;
2126
+ if (match.type === "begin") return doBeginMatch(match);
2127
+ else if (match.type === "illegal" && !ignoreIllegals) {
2128
+ /** @type {AnnotatedError} */
2129
+ const err = /* @__PURE__ */ new Error("Illegal lexeme \"" + lexeme + "\" for mode \"" + (top.scope || "<unnamed>") + "\"");
2130
+ err.mode = top;
2131
+ throw err;
2132
+ } else if (match.type === "end") {
2133
+ const processed = doEndMatch(match);
2134
+ if (processed !== NO_MATCH) return processed;
2135
+ }
2136
+ if (match.type === "illegal" && lexeme === "") {
2137
+ modeBuffer += "\n";
2138
+ return 1;
2139
+ }
2140
+ if (iterations > 1e5 && iterations > match.index * 3) throw /* @__PURE__ */ new Error("potential infinite loop, way more iterations than matches");
2141
+ modeBuffer += lexeme;
2142
+ return lexeme.length;
2143
+ }
2144
+ const language = getLanguage(languageName);
2145
+ if (!language) {
2146
+ error(LANGUAGE_NOT_FOUND.replace("{}", languageName));
2147
+ throw new Error("Unknown language: \"" + languageName + "\"");
2148
+ }
2149
+ const md = compileLanguage(language);
2150
+ let result = "";
2151
+ /** @type {CompiledMode} */
2152
+ let top = continuation || md;
2153
+ /** @type Record<string,CompiledMode> */
2154
+ const continuations = {};
2155
+ const emitter = new options.__emitter(options);
2156
+ processContinuations();
2157
+ let modeBuffer = "";
2158
+ let relevance = 0;
2159
+ let index = 0;
2160
+ let iterations = 0;
2161
+ let resumeScanAtSamePosition = false;
2162
+ try {
2163
+ if (!language.__emitTokens) {
2164
+ top.matcher.considerAll();
2165
+ for (;;) {
2166
+ iterations++;
2167
+ if (resumeScanAtSamePosition) resumeScanAtSamePosition = false;
2168
+ else top.matcher.considerAll();
2169
+ top.matcher.lastIndex = index;
2170
+ const match = top.matcher.exec(codeToHighlight);
2171
+ if (!match) break;
2172
+ const processedCount = processLexeme(codeToHighlight.substring(index, match.index), match);
2173
+ index = match.index + processedCount;
2174
+ }
2175
+ processLexeme(codeToHighlight.substring(index));
2176
+ } else language.__emitTokens(codeToHighlight, emitter);
2177
+ emitter.finalize();
2178
+ result = emitter.toHTML();
2179
+ return {
2180
+ language: languageName,
2181
+ value: result,
2182
+ relevance,
2183
+ illegal: false,
2184
+ _emitter: emitter,
2185
+ _top: top
2186
+ };
2187
+ } catch (err) {
2188
+ if (err.message && err.message.includes("Illegal")) return {
2189
+ language: languageName,
2190
+ value: escape(codeToHighlight),
2191
+ illegal: true,
2192
+ relevance: 0,
2193
+ _illegalBy: {
2194
+ message: err.message,
2195
+ index,
2196
+ context: codeToHighlight.slice(index - 100, index + 100),
2197
+ mode: err.mode,
2198
+ resultSoFar: result
2199
+ },
2200
+ _emitter: emitter
2201
+ };
2202
+ else if (SAFE_MODE) return {
2203
+ language: languageName,
2204
+ value: escape(codeToHighlight),
2205
+ illegal: false,
2206
+ relevance: 0,
2207
+ errorRaised: err,
2208
+ _emitter: emitter,
2209
+ _top: top
2210
+ };
2211
+ else throw err;
2212
+ }
2213
+ }
2214
+ /**
2215
+ * returns a valid highlight result, without actually doing any actual work,
2216
+ * auto highlight starts with this and it's possible for small snippets that
2217
+ * auto-detection may not find a better match
2218
+ * @param {string} code
2219
+ * @returns {HighlightResult}
2220
+ */
2221
+ function justTextHighlightResult(code) {
2222
+ const result = {
2223
+ value: escape(code),
2224
+ illegal: false,
2225
+ relevance: 0,
2226
+ _top: PLAINTEXT_LANGUAGE,
2227
+ _emitter: new options.__emitter(options)
2228
+ };
2229
+ result._emitter.addText(code);
2230
+ return result;
2231
+ }
2232
+ /**
2233
+ Highlighting with language detection. Accepts a string with the code to
2234
+ highlight. Returns an object with the following properties:
2235
+
2236
+ - language (detected language)
2237
+ - relevance (int)
2238
+ - value (an HTML string with highlighting markup)
2239
+ - secondBest (object with the same structure for second-best heuristically
2240
+ detected language, may be absent)
2241
+
2242
+ @param {string} code
2243
+ @param {Array<string>} [languageSubset]
2244
+ @returns {AutoHighlightResult}
2245
+ */
2246
+ function highlightAuto(code, languageSubset) {
2247
+ languageSubset = languageSubset || options.languages || Object.keys(languages);
2248
+ const plaintext = justTextHighlightResult(code);
2249
+ const results = languageSubset.filter(getLanguage).filter(autoDetection).map((name) => _highlight(name, code, false));
2250
+ results.unshift(plaintext);
2251
+ const [best, secondBest] = results.sort((a, b) => {
2252
+ if (a.relevance !== b.relevance) return b.relevance - a.relevance;
2253
+ if (a.language && b.language) {
2254
+ if (getLanguage(a.language).supersetOf === b.language) return 1;
2255
+ else if (getLanguage(b.language).supersetOf === a.language) return -1;
2256
+ }
2257
+ return 0;
2258
+ });
2259
+ /** @type {AutoHighlightResult} */
2260
+ const result = best;
2261
+ result.secondBest = secondBest;
2262
+ return result;
2263
+ }
2264
+ /**
2265
+ * Builds new class name for block given the language name
2266
+ *
2267
+ * @param {HTMLElement} element
2268
+ * @param {string} [currentLang]
2269
+ * @param {string} [resultLang]
2270
+ */
2271
+ function updateClassName(element, currentLang, resultLang) {
2272
+ const language = currentLang && aliases[currentLang] || resultLang;
2273
+ element.classList.add("hljs");
2274
+ element.classList.add(`language-${language}`);
2275
+ }
2276
+ /**
2277
+ * Applies highlighting to a DOM node containing code.
2278
+ *
2279
+ * @param {HighlightedHTMLElement} element - the HTML element to highlight
2280
+ */
2281
+ function highlightElement(element) {
2282
+ /** @type HTMLElement */
2283
+ let node = null;
2284
+ const language = blockLanguage(element);
2285
+ if (shouldNotHighlight(language)) return;
2286
+ fire("before:highlightElement", {
2287
+ el: element,
2288
+ language
2289
+ });
2290
+ if (element.dataset.highlighted) {
2291
+ console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.", element);
2292
+ return;
2293
+ }
2294
+ if (element.children.length > 0) {
2295
+ if (!options.ignoreUnescapedHTML) {
2296
+ console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk.");
2297
+ console.warn("https://github.com/highlightjs/highlight.js/wiki/security");
2298
+ console.warn("The element with unescaped HTML:");
2299
+ console.warn(element);
2300
+ }
2301
+ if (options.throwUnescapedHTML) throw new HTMLInjectionError("One of your code blocks includes unescaped HTML.", element.innerHTML);
2302
+ }
2303
+ node = element;
2304
+ const text = node.textContent;
2305
+ const result = language ? highlight(text, {
2306
+ language,
2307
+ ignoreIllegals: true
2308
+ }) : highlightAuto(text);
2309
+ element.innerHTML = result.value;
2310
+ element.dataset.highlighted = "yes";
2311
+ updateClassName(element, language, result.language);
2312
+ element.result = {
2313
+ language: result.language,
2314
+ re: result.relevance,
2315
+ relevance: result.relevance
2316
+ };
2317
+ if (result.secondBest) element.secondBest = {
2318
+ language: result.secondBest.language,
2319
+ relevance: result.secondBest.relevance
2320
+ };
2321
+ fire("after:highlightElement", {
2322
+ el: element,
2323
+ result,
2324
+ text
2325
+ });
2326
+ }
2327
+ /**
2328
+ * Updates highlight.js global options with the passed options
2329
+ *
2330
+ * @param {Partial<HLJSOptions>} userOptions
2331
+ */
2332
+ function configure(userOptions) {
2333
+ options = inherit(options, userOptions);
2334
+ }
2335
+ const initHighlighting = () => {
2336
+ highlightAll();
2337
+ deprecated("10.6.0", "initHighlighting() deprecated. Use highlightAll() now.");
2338
+ };
2339
+ function initHighlightingOnLoad() {
2340
+ highlightAll();
2341
+ deprecated("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now.");
2342
+ }
2343
+ let wantsHighlight = false;
2344
+ /**
2345
+ * auto-highlights all pre>code elements on the page
2346
+ */
2347
+ function highlightAll() {
2348
+ function boot() {
2349
+ highlightAll();
2350
+ }
2351
+ if (document.readyState === "loading") {
2352
+ if (!wantsHighlight) window.addEventListener("DOMContentLoaded", boot, false);
2353
+ wantsHighlight = true;
2354
+ return;
2355
+ }
2356
+ document.querySelectorAll(options.cssSelector).forEach(highlightElement);
2357
+ }
2358
+ /**
2359
+ * Register a language grammar module
2360
+ *
2361
+ * @param {string} languageName
2362
+ * @param {LanguageFn} languageDefinition
2363
+ */
2364
+ function registerLanguage(languageName, languageDefinition) {
2365
+ let lang = null;
2366
+ try {
2367
+ lang = languageDefinition(hljs);
2368
+ } catch (error$1) {
2369
+ error("Language definition for '{}' could not be registered.".replace("{}", languageName));
2370
+ if (!SAFE_MODE) throw error$1;
2371
+ else error(error$1);
2372
+ lang = PLAINTEXT_LANGUAGE;
2373
+ }
2374
+ if (!lang.name) lang.name = languageName;
2375
+ languages[languageName] = lang;
2376
+ lang.rawDefinition = languageDefinition.bind(null, hljs);
2377
+ if (lang.aliases) registerAliases(lang.aliases, { languageName });
2378
+ }
2379
+ /**
2380
+ * Remove a language grammar module
2381
+ *
2382
+ * @param {string} languageName
2383
+ */
2384
+ function unregisterLanguage(languageName) {
2385
+ delete languages[languageName];
2386
+ for (const alias of Object.keys(aliases)) if (aliases[alias] === languageName) delete aliases[alias];
2387
+ }
2388
+ /**
2389
+ * @returns {string[]} List of language internal names
2390
+ */
2391
+ function listLanguages() {
2392
+ return Object.keys(languages);
2393
+ }
2394
+ /**
2395
+ * @param {string} name - name of the language to retrieve
2396
+ * @returns {Language | undefined}
2397
+ */
2398
+ function getLanguage(name) {
2399
+ name = (name || "").toLowerCase();
2400
+ return languages[name] || languages[aliases[name]];
2401
+ }
2402
+ /**
2403
+ *
2404
+ * @param {string|string[]} aliasList - single alias or list of aliases
2405
+ * @param {{languageName: string}} opts
2406
+ */
2407
+ function registerAliases(aliasList, { languageName }) {
2408
+ if (typeof aliasList === "string") aliasList = [aliasList];
2409
+ aliasList.forEach((alias) => {
2410
+ aliases[alias.toLowerCase()] = languageName;
2411
+ });
2412
+ }
2413
+ /**
2414
+ * Determines if a given language has auto-detection enabled
2415
+ * @param {string} name - name of the language
2416
+ */
2417
+ function autoDetection(name) {
2418
+ const lang = getLanguage(name);
2419
+ return lang && !lang.disableAutodetect;
2420
+ }
2421
+ /**
2422
+ * Upgrades the old highlightBlock plugins to the new
2423
+ * highlightElement API
2424
+ * @param {HLJSPlugin} plugin
2425
+ */
2426
+ function upgradePluginAPI(plugin) {
2427
+ if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) plugin["before:highlightElement"] = (data) => {
2428
+ plugin["before:highlightBlock"](Object.assign({ block: data.el }, data));
2429
+ };
2430
+ if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) plugin["after:highlightElement"] = (data) => {
2431
+ plugin["after:highlightBlock"](Object.assign({ block: data.el }, data));
2432
+ };
2433
+ }
2434
+ /**
2435
+ * @param {HLJSPlugin} plugin
2436
+ */
2437
+ function addPlugin(plugin) {
2438
+ upgradePluginAPI(plugin);
2439
+ plugins.push(plugin);
2440
+ }
2441
+ /**
2442
+ * @param {HLJSPlugin} plugin
2443
+ */
2444
+ function removePlugin(plugin) {
2445
+ const index = plugins.indexOf(plugin);
2446
+ if (index !== -1) plugins.splice(index, 1);
2447
+ }
2448
+ /**
2449
+ *
2450
+ * @param {PluginEvent} event
2451
+ * @param {any} args
2452
+ */
2453
+ function fire(event, args) {
2454
+ const cb = event;
2455
+ plugins.forEach(function(plugin) {
2456
+ if (plugin[cb]) plugin[cb](args);
2457
+ });
2458
+ }
2459
+ /**
2460
+ * DEPRECATED
2461
+ * @param {HighlightedHTMLElement} el
2462
+ */
2463
+ function deprecateHighlightBlock(el) {
2464
+ deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0");
2465
+ deprecated("10.7.0", "Please use highlightElement now.");
2466
+ return highlightElement(el);
2467
+ }
2468
+ Object.assign(hljs, {
2469
+ highlight,
2470
+ highlightAuto,
2471
+ highlightAll,
2472
+ highlightElement,
2473
+ highlightBlock: deprecateHighlightBlock,
2474
+ configure,
2475
+ initHighlighting,
2476
+ initHighlightingOnLoad,
2477
+ registerLanguage,
2478
+ unregisterLanguage,
2479
+ listLanguages,
2480
+ getLanguage,
2481
+ registerAliases,
2482
+ autoDetection,
2483
+ inherit,
2484
+ addPlugin,
2485
+ removePlugin
2486
+ });
2487
+ hljs.debugMode = function() {
2488
+ SAFE_MODE = false;
2489
+ };
2490
+ hljs.safeMode = function() {
2491
+ SAFE_MODE = true;
2492
+ };
2493
+ hljs.versionString = version;
2494
+ hljs.regex = {
2495
+ concat,
2496
+ lookahead,
2497
+ either,
2498
+ optional,
2499
+ anyNumberOfTimes
2500
+ };
2501
+ for (const key in MODES) if (typeof MODES[key] === "object") deepFreeze(MODES[key]);
2502
+ Object.assign(hljs, MODES);
2503
+ return hljs;
2504
+ };
2505
+ var highlight = HLJS({});
2506
+ highlight.newInstance = () => HLJS({});
2507
+ module.exports = highlight;
2508
+ highlight.HighlightJS = highlight;
2509
+ highlight.default = highlight;
2510
+ })))())).default;
2511
+ //#endregion
2512
+ //#region ../../node_modules/.pnpm/lowlight@3.3.0/node_modules/lowlight/lib/index.js
2513
+ /**
2514
+ * @import {ElementContent, Element, RootData, Root} from 'hast'
2515
+ * @import {Emitter, HLJSOptions as HljsOptions, HighlightResult, LanguageFn} from 'highlight.js'
2516
+ */
2517
+ /**
2518
+ * @typedef {Object} ExtraOptions
2519
+ * Extra fields.
2520
+ * @property {ReadonlyArray<string> | null | undefined} [subset]
2521
+ * List of allowed languages (default: all registered languages).
2522
+ *
2523
+ * @typedef Options
2524
+ * Configuration for `highlight`.
2525
+ * @property {string | null | undefined} [prefix='hljs-']
2526
+ * Class prefix (default: `'hljs-'`).
2527
+ *
2528
+ * @typedef {Options & ExtraOptions} AutoOptions
2529
+ * Configuration for `highlightAuto`.
2530
+ */
2531
+ /** @type {AutoOptions} */
2532
+ var emptyOptions$1 = {};
2533
+ var defaultPrefix = "hljs-";
2534
+ /**
2535
+ * Create a `lowlight` instance.
2536
+ *
2537
+ * @param {Readonly<Record<string, LanguageFn>> | null | undefined} [grammars]
2538
+ * Grammars to add (optional).
2539
+ * @returns
2540
+ * Lowlight.
2541
+ */
2542
+ function createLowlight(grammars) {
2543
+ const high = core_default.newInstance();
2544
+ if (grammars) register(grammars);
2545
+ return {
2546
+ highlight,
2547
+ highlightAuto,
2548
+ listLanguages,
2549
+ register,
2550
+ registerAlias,
2551
+ registered
2552
+ };
2553
+ /**
2554
+ * Highlight `value` (code) as `language` (name).
2555
+ *
2556
+ * @example
2557
+ * ```js
2558
+ * import {common, createLowlight} from 'lowlight'
2559
+ *
2560
+ * const lowlight = createLowlight(common)
2561
+ *
2562
+ * console.log(lowlight.highlight('css', 'em { color: red }'))
2563
+ * ```
2564
+ *
2565
+ * Yields:
2566
+ *
2567
+ * ```js
2568
+ * {type: 'root', children: [Array], data: {language: 'css', relevance: 3}}
2569
+ * ```
2570
+ *
2571
+ * @param {string} language
2572
+ * Programming language name.
2573
+ * @param {string} value
2574
+ * Code to highlight.
2575
+ * @param {Readonly<Options> | null | undefined} [options={}]
2576
+ * Configuration (optional).
2577
+ * @returns {Root}
2578
+ * Tree; with the following `data` fields: `language` (`string`), detected
2579
+ * programming language name; `relevance` (`number`), how sure lowlight is
2580
+ * that the given code is in the language.
2581
+ */
2582
+ function highlight(language, value, options) {
2583
+ const settings = options || emptyOptions$1;
2584
+ const prefix = typeof settings.prefix === "string" ? settings.prefix : defaultPrefix;
2585
+ if (!high.getLanguage(language)) throw new Error("Unknown language: `" + language + "` is not registered");
2586
+ high.configure({
2587
+ __emitter: HastEmitter,
2588
+ classPrefix: prefix
2589
+ });
2590
+ const result = high.highlight(value, {
2591
+ ignoreIllegals: true,
2592
+ language
2593
+ });
2594
+ /* c8 ignore next 5 */
2595
+ if (result.errorRaised) throw new Error("Could not highlight with `Highlight.js`", { cause: result.errorRaised });
2596
+ const root = result._emitter.root;
2597
+ const data = root.data;
2598
+ data.language = result.language;
2599
+ data.relevance = result.relevance;
2600
+ return root;
2601
+ }
2602
+ /**
2603
+ * Highlight `value` (code) and guess its programming language.
2604
+ *
2605
+ * @example
2606
+ * ```js
2607
+ * import {common, createLowlight} from 'lowlight'
2608
+ *
2609
+ * const lowlight = createLowlight(common)
2610
+ *
2611
+ * console.log(lowlight.highlightAuto('"hello, " + name + "!"'))
2612
+ * ```
2613
+ *
2614
+ * Yields:
2615
+ *
2616
+ * ```js
2617
+ * {type: 'root', children: [Array], data: {language: 'arduino', relevance: 2}}
2618
+ * ```
2619
+ *
2620
+ * @param {string} value
2621
+ * Code to highlight.
2622
+ * @param {Readonly<AutoOptions> | null | undefined} [options={}]
2623
+ * Configuration (optional).
2624
+ * @returns {Root}
2625
+ * Tree; with the following `data` fields: `language` (`string`), detected
2626
+ * programming language name; `relevance` (`number`), how sure lowlight is
2627
+ * that the given code is in the language.
2628
+ */
2629
+ function highlightAuto(value, options) {
2630
+ const subset = (options || emptyOptions$1).subset || listLanguages();
2631
+ let index = -1;
2632
+ let relevance = 0;
2633
+ /** @type {Root | undefined} */
2634
+ let result;
2635
+ while (++index < subset.length) {
2636
+ const name = subset[index];
2637
+ if (!high.getLanguage(name)) continue;
2638
+ const current = highlight(name, value, options);
2639
+ if (current.data && current.data.relevance !== void 0 && current.data.relevance > relevance) {
2640
+ relevance = current.data.relevance;
2641
+ result = current;
2642
+ }
2643
+ }
2644
+ return result || {
2645
+ type: "root",
2646
+ children: [],
2647
+ data: {
2648
+ language: void 0,
2649
+ relevance
2650
+ }
2651
+ };
2652
+ }
2653
+ /**
2654
+ * List registered languages.
2655
+ *
2656
+ * @example
2657
+ * ```js
2658
+ * import {createLowlight} from 'lowlight'
2659
+ * import markdown from 'highlight.js/lib/languages/markdown'
2660
+ *
2661
+ * const lowlight = createLowlight()
2662
+ *
2663
+ * console.log(lowlight.listLanguages()) // => []
2664
+ *
2665
+ * lowlight.register({markdown})
2666
+ *
2667
+ * console.log(lowlight.listLanguages()) // => ['markdown']
2668
+ * ```
2669
+ *
2670
+ * @returns {Array<string>}
2671
+ * Names of registered language.
2672
+ */
2673
+ function listLanguages() {
2674
+ return high.listLanguages();
2675
+ }
2676
+ /**
2677
+ * Register languages.
2678
+ *
2679
+ * @example
2680
+ * ```js
2681
+ * import {createLowlight} from 'lowlight'
2682
+ * import xml from 'highlight.js/lib/languages/xml'
2683
+ *
2684
+ * const lowlight = createLowlight()
2685
+ *
2686
+ * lowlight.register({xml})
2687
+ *
2688
+ * // Note: `html` is an alias for `xml`.
2689
+ * console.log(lowlight.highlight('html', '<em>Emphasis</em>'))
2690
+ * ```
2691
+ *
2692
+ * Yields:
2693
+ *
2694
+ * ```js
2695
+ * {type: 'root', children: [Array], data: {language: 'html', relevance: 2}}
2696
+ * ```
2697
+ *
2698
+ * @overload
2699
+ * @param {Readonly<Record<string, LanguageFn>>} grammars
2700
+ * @returns {undefined}
2701
+ *
2702
+ * @overload
2703
+ * @param {string} name
2704
+ * @param {LanguageFn} grammar
2705
+ * @returns {undefined}
2706
+ *
2707
+ * @param {Readonly<Record<string, LanguageFn>> | string} grammarsOrName
2708
+ * Grammars or programming language name.
2709
+ * @param {LanguageFn | undefined} [grammar]
2710
+ * Grammar, if with name.
2711
+ * @returns {undefined}
2712
+ * Nothing.
2713
+ */
2714
+ function register(grammarsOrName, grammar) {
2715
+ if (typeof grammarsOrName === "string") high.registerLanguage(grammarsOrName, grammar);
2716
+ else {
2717
+ /** @type {string} */
2718
+ let name;
2719
+ for (name in grammarsOrName) if (Object.hasOwn(grammarsOrName, name)) high.registerLanguage(name, grammarsOrName[name]);
2720
+ }
2721
+ }
2722
+ /**
2723
+ * Register aliases.
2724
+ *
2725
+ * @example
2726
+ * ```js
2727
+ * import {createLowlight} from 'lowlight'
2728
+ * import markdown from 'highlight.js/lib/languages/markdown'
2729
+ *
2730
+ * const lowlight = createLowlight()
2731
+ *
2732
+ * lowlight.register({markdown})
2733
+ *
2734
+ * // lowlight.highlight('mdown', '<em>Emphasis</em>')
2735
+ * // ^ would throw: Error: Unknown language: `mdown` is not registered
2736
+ *
2737
+ * lowlight.registerAlias({markdown: ['mdown', 'mkdn', 'mdwn', 'ron']})
2738
+ * lowlight.highlight('mdown', '<em>Emphasis</em>')
2739
+ * // ^ Works!
2740
+ * ```
2741
+ *
2742
+ * @overload
2743
+ * @param {Readonly<Record<string, ReadonlyArray<string> | string>>} aliases
2744
+ * @returns {undefined}
2745
+ *
2746
+ * @overload
2747
+ * @param {string} language
2748
+ * @param {ReadonlyArray<string> | string} alias
2749
+ * @returns {undefined}
2750
+ *
2751
+ * @param {Readonly<Record<string, ReadonlyArray<string> | string>> | string} aliasesOrName
2752
+ * Map of programming language names to one or more aliases, or programming
2753
+ * language name.
2754
+ * @param {ReadonlyArray<string> | string | undefined} [alias]
2755
+ * One or more aliases for the programming language, if with `name`.
2756
+ * @returns {undefined}
2757
+ * Nothing.
2758
+ */
2759
+ function registerAlias(aliasesOrName, alias) {
2760
+ if (typeof aliasesOrName === "string") high.registerAliases(typeof alias === "string" ? alias : [...alias], { languageName: aliasesOrName });
2761
+ else {
2762
+ /** @type {string} */
2763
+ let key;
2764
+ for (key in aliasesOrName) if (Object.hasOwn(aliasesOrName, key)) {
2765
+ const aliases = aliasesOrName[key];
2766
+ high.registerAliases(typeof aliases === "string" ? aliases : [...aliases], { languageName: key });
2767
+ }
2768
+ }
2769
+ }
2770
+ /**
2771
+ * Check whether an alias or name is registered.
2772
+ *
2773
+ * @example
2774
+ * ```js
2775
+ * import {createLowlight} from 'lowlight'
2776
+ * import javascript from 'highlight.js/lib/languages/javascript'
2777
+ *
2778
+ * const lowlight = createLowlight({javascript})
2779
+ *
2780
+ * console.log(lowlight.registered('funkyscript')) // => `false`
2781
+ *
2782
+ * lowlight.registerAlias({javascript: 'funkyscript'})
2783
+ * console.log(lowlight.registered('funkyscript')) // => `true`
2784
+ * ```
2785
+ *
2786
+ * @param {string} aliasOrName
2787
+ * Name of a language or alias for one.
2788
+ * @returns {boolean}
2789
+ * Whether `aliasOrName` is registered.
2790
+ */
2791
+ function registered(aliasOrName) {
2792
+ return Boolean(high.getLanguage(aliasOrName));
2793
+ }
2794
+ }
2795
+ /** @type {Emitter} */
2796
+ var HastEmitter = class {
2797
+ /**
2798
+ * @param {Readonly<HljsOptions>} options
2799
+ * Configuration.
2800
+ * @returns
2801
+ * Instance.
2802
+ */
2803
+ constructor(options) {
2804
+ /** @type {HljsOptions} */
2805
+ this.options = options;
2806
+ /** @type {Root} */
2807
+ this.root = {
2808
+ type: "root",
2809
+ children: [],
2810
+ data: {
2811
+ language: void 0,
2812
+ relevance: 0
2813
+ }
2814
+ };
2815
+ /** @type {[Root, ...Array<Element>]} */
2816
+ this.stack = [this.root];
2817
+ }
2818
+ /**
2819
+ * @param {string} value
2820
+ * Text to add.
2821
+ * @returns {undefined}
2822
+ * Nothing.
2823
+ *
2824
+ */
2825
+ addText(value) {
2826
+ if (value === "") return;
2827
+ const current = this.stack[this.stack.length - 1];
2828
+ const tail = current.children[current.children.length - 1];
2829
+ if (tail && tail.type === "text") tail.value += value;
2830
+ else current.children.push({
2831
+ type: "text",
2832
+ value
2833
+ });
2834
+ }
2835
+ /**
2836
+ *
2837
+ * @param {unknown} rawName
2838
+ * Name to add.
2839
+ * @returns {undefined}
2840
+ * Nothing.
2841
+ */
2842
+ startScope(rawName) {
2843
+ this.openNode(String(rawName));
2844
+ }
2845
+ /**
2846
+ * @returns {undefined}
2847
+ * Nothing.
2848
+ */
2849
+ endScope() {
2850
+ this.closeNode();
2851
+ }
2852
+ /**
2853
+ * @param {HastEmitter} other
2854
+ * Other emitter.
2855
+ * @param {string} name
2856
+ * Name of the sublanguage.
2857
+ * @returns {undefined}
2858
+ * Nothing.
2859
+ */
2860
+ __addSublanguage(other, name) {
2861
+ const current = this.stack[this.stack.length - 1];
2862
+ const results = other.root.children;
2863
+ if (name) current.children.push({
2864
+ type: "element",
2865
+ tagName: "span",
2866
+ properties: { className: [name] },
2867
+ children: results
2868
+ });
2869
+ else current.children.push(...results);
2870
+ }
2871
+ /**
2872
+ * @param {string} name
2873
+ * Name to add.
2874
+ * @returns {undefined}
2875
+ * Nothing.
2876
+ */
2877
+ openNode(name) {
2878
+ const self = this;
2879
+ const className = name.split(".").map(function(d, i) {
2880
+ return i ? d + "_".repeat(i) : self.options.classPrefix + d;
2881
+ });
2882
+ const current = this.stack[this.stack.length - 1];
2883
+ /** @type {Element} */
2884
+ const child = {
2885
+ type: "element",
2886
+ tagName: "span",
2887
+ properties: { className },
2888
+ children: []
2889
+ };
2890
+ current.children.push(child);
2891
+ this.stack.push(child);
2892
+ }
2893
+ /**
2894
+ * @returns {undefined}
2895
+ * Nothing.
2896
+ */
2897
+ closeNode() {
2898
+ this.stack.pop();
2899
+ }
2900
+ /**
2901
+ * @returns {undefined}
2902
+ * Nothing.
2903
+ */
2904
+ finalize() {}
2905
+ /**
2906
+ * @returns {string}
2907
+ * Nothing.
2908
+ */
2909
+ toHTML() {
2910
+ return "";
2911
+ }
2912
+ };
2913
+ //#endregion
2914
+ //#region src/rehype-highlight/rehype-highlight.ts
2915
+ var emptyOptions = {};
2916
+ /**
2917
+ * Lowlight syntax highlighting plugin for rehype pipelines
2918
+ *
2919
+ * Derived from: @url https://github.com/rehypejs/rehype-highlight/blob/main/lib/index.js
2920
+ */
2921
+ function rehypeHighlight(options) {
2922
+ const settings = options || emptyOptions;
2923
+ const aliases = settings.aliases;
2924
+ const detect = options?.detect ?? false;
2925
+ const languages = settings.languages;
2926
+ const plainText = settings.plainText;
2927
+ const prefix = settings.prefix;
2928
+ const subset = settings.subset;
2929
+ let name = "hljs";
2930
+ const lowlight = options?.lowlight ?? createLowlight(languages);
2931
+ if (aliases) lowlight.registerAlias(aliases);
2932
+ if (prefix) {
2933
+ const pos = prefix.indexOf("-");
2934
+ name = pos > -1 ? prefix.slice(0, pos) : prefix;
2935
+ }
2936
+ /** Transform.*/
2937
+ return (tree, file) => {
2938
+ visit(tree, "element", (node, _, parent) => {
2939
+ if (node.tagName !== "code" || !parent || parent.type !== "element" || parent.tagName !== "pre") return;
2940
+ const lang = language(node);
2941
+ if (lang === "no-highlight" || !lang && !detect || lang && plainText?.includes(lang)) return;
2942
+ if (!Array.isArray(node.properties.className)) node.properties.className = [];
2943
+ if (!node.properties.className.includes(name)) node.properties.className.unshift(name);
2944
+ let result;
2945
+ try {
2946
+ result = lang ? lowlight.highlight(lang, toText(parent), { prefix }) : lowlight.highlightAuto(toText(parent), {
2947
+ prefix,
2948
+ subset
2949
+ });
2950
+ } catch (error) {
2951
+ const cause = error;
2952
+ if (lang && /Unknown language/.test(cause.message)) {
2953
+ file.message(`Cannot highlight as \`${lang}\`, it's not registered`, {
2954
+ ancestors: [parent, node],
2955
+ cause,
2956
+ place: node.position,
2957
+ ruleId: "missing-language",
2958
+ source: "rehype-highlight"
2959
+ });
2960
+ /* c8 ignore next 5 -- throw arbitrary hljs errors */
2961
+ return;
2962
+ }
2963
+ throw cause;
2964
+ }
2965
+ if (!lang && result.data?.language) node.properties.className.push("language-" + result.data.language);
2966
+ if (result.children.length > 0) node.children = result.children;
2967
+ });
2968
+ };
2969
+ }
2970
+ /** Get the programming language of `node` or an empty string */
2971
+ function language(node) {
2972
+ const list = node.properties.className;
2973
+ if (!Array.isArray(list)) return "";
2974
+ const name = list.reduce((result, _item) => {
2975
+ if (result) return result;
2976
+ const item = String(_item);
2977
+ if (item === "no-highlight" || item === "nohighlight") return "no-highlight";
2978
+ if (item.slice(0, 5) === "lang-") return item.slice(5);
2979
+ if (item.slice(0, 9) === "language-") return item.slice(9);
2980
+ return result;
2981
+ }, "");
2982
+ return lowlightLanguageMappings[name || ""] || name;
2983
+ }
2984
+ //#endregion
2985
+ export { ok as a, __toESM as c, lowlightLanguageMappings as i, convertElement as n, __commonJSMin as o, isElement as r, __exportAll as s, rehypeHighlight as t };
2986
+
2987
+ //# sourceMappingURL=rehype-highlight.js.map