quikdown 1.2.10 → 1.2.11

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 (60) hide show
  1. package/README.md +2 -2
  2. package/dist/quikdown.cjs +96 -3
  3. package/dist/quikdown.d.ts +12 -0
  4. package/dist/quikdown.dark.css +1 -1
  5. package/dist/quikdown.esm.js +96 -3
  6. package/dist/quikdown.esm.min.js +2 -2
  7. package/dist/quikdown.esm.min.js.gz +0 -0
  8. package/dist/quikdown.esm.min.js.map +1 -1
  9. package/dist/quikdown.light.css +1 -1
  10. package/dist/quikdown.umd.js +96 -3
  11. package/dist/quikdown.umd.min.js +2 -2
  12. package/dist/quikdown.umd.min.js.gz +0 -0
  13. package/dist/quikdown.umd.min.js.map +1 -1
  14. package/dist/quikdown_ast.cjs +2 -2
  15. package/dist/quikdown_ast.esm.js +2 -2
  16. package/dist/quikdown_ast.esm.min.js +2 -2
  17. package/dist/quikdown_ast.esm.min.js.gz +0 -0
  18. package/dist/quikdown_ast.umd.js +2 -2
  19. package/dist/quikdown_ast.umd.min.js +2 -2
  20. package/dist/quikdown_ast.umd.min.js.gz +0 -0
  21. package/dist/quikdown_ast_html.cjs +3 -3
  22. package/dist/quikdown_ast_html.esm.js +3 -3
  23. package/dist/quikdown_ast_html.esm.min.js +2 -2
  24. package/dist/quikdown_ast_html.esm.min.js.gz +0 -0
  25. package/dist/quikdown_ast_html.umd.js +3 -3
  26. package/dist/quikdown_ast_html.umd.min.js +2 -2
  27. package/dist/quikdown_ast_html.umd.min.js.gz +0 -0
  28. package/dist/quikdown_bd.cjs +96 -3
  29. package/dist/quikdown_bd.esm.js +96 -3
  30. package/dist/quikdown_bd.esm.min.js +2 -2
  31. package/dist/quikdown_bd.esm.min.js.gz +0 -0
  32. package/dist/quikdown_bd.esm.min.js.map +1 -1
  33. package/dist/quikdown_bd.umd.js +96 -3
  34. package/dist/quikdown_bd.umd.min.js +2 -2
  35. package/dist/quikdown_bd.umd.min.js.gz +0 -0
  36. package/dist/quikdown_bd.umd.min.js.map +1 -1
  37. package/dist/quikdown_edit.cjs +232 -6
  38. package/dist/quikdown_edit.esm.js +232 -6
  39. package/dist/quikdown_edit.esm.min.js +3 -3
  40. package/dist/quikdown_edit.esm.min.js.gz +0 -0
  41. package/dist/quikdown_edit.esm.min.js.map +1 -1
  42. package/dist/quikdown_edit.umd.js +232 -6
  43. package/dist/quikdown_edit.umd.min.js +3 -3
  44. package/dist/quikdown_edit.umd.min.js.gz +0 -0
  45. package/dist/quikdown_edit.umd.min.js.map +1 -1
  46. package/dist/quikdown_json.cjs +3 -3
  47. package/dist/quikdown_json.esm.js +3 -3
  48. package/dist/quikdown_json.esm.min.js +2 -2
  49. package/dist/quikdown_json.esm.min.js.gz +0 -0
  50. package/dist/quikdown_json.umd.js +3 -3
  51. package/dist/quikdown_json.umd.min.js +2 -2
  52. package/dist/quikdown_json.umd.min.js.gz +0 -0
  53. package/dist/quikdown_yaml.cjs +3 -3
  54. package/dist/quikdown_yaml.esm.js +3 -3
  55. package/dist/quikdown_yaml.esm.min.js +2 -2
  56. package/dist/quikdown_yaml.esm.min.js.gz +0 -0
  57. package/dist/quikdown_yaml.umd.js +3 -3
  58. package/dist/quikdown_yaml.umd.min.js +2 -2
  59. package/dist/quikdown_yaml.umd.min.js.gz +0 -0
  60. package/package.json +2 -2
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  [![CI](https://github.com/deftio/quikdown/actions/workflows/ci.yml/badge.svg)](https://github.com/deftio/quikdown/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/quikdown.svg)](https://www.npmjs.com/package/quikdown)
5
- [![Coverage](https://img.shields.io/badge/coverage-95.8%25-brightgreen)](https://github.com/deftio/quikdown)
5
+ [![Coverage](https://img.shields.io/badge/coverage-96%25-brightgreen)](https://github.com/deftio/quikdown)
6
6
  [![License: BSD-2-Clause](https://img.shields.io/badge/License-BSD%202--Clause-blue.svg)](https://opensource.org/licenses/BSD-2-Clause)
7
- [![Bundle Size](https://img.shields.io/badge/minified-9.8KB-green.svg)](https://bundlephobia.com/package/quikdown)
7
+ [![Bundle Size](https://img.shields.io/badge/minified-10.8KB-green.svg)](https://bundlephobia.com/package/quikdown)
8
8
 
9
9
  A small, secure markdown parser and editor for browsers and Node.js. Three modules — use only what you need.
10
10
 
package/dist/quikdown.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.2.10
3
+ * @version 1.2.11
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
@@ -114,7 +114,7 @@ function isDashHRLine(trimmed) {
114
114
  // ────────────────────────────────────────────────────────────────────
115
115
 
116
116
  /** Build-time version stamp (injected by tools/updateVersion) */
117
- const quikdownVersion = '1.2.10';
117
+ const quikdownVersion = '1.2.11';
118
118
 
119
119
  /** CSS class prefix used for all generated elements */
120
120
  const CLASS_PREFIX = 'quikdown-';
@@ -122,6 +122,10 @@ const CLASS_PREFIX = 'quikdown-';
122
122
  /** Placeholder sigils — chosen to be extremely unlikely in real text */
123
123
  const PLACEHOLDER_CB = '§CB'; // fenced code blocks
124
124
  const PLACEHOLDER_IC = '§IC'; // inline code spans
125
+ const PLACEHOLDER_HT = '§HT'; // safe HTML tags (limited mode)
126
+
127
+ /** Attributes whose values need URL sanitization */
128
+ const URL_ATTRIBUTES = { href:1, src:1, action:1, formaction:1 };
125
129
 
126
130
  /** HTML entity escape map */
127
131
  const ESC_MAP = {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'};
@@ -256,6 +260,46 @@ function quikdown(markdown, options = {}) {
256
260
  return trimmedUrl;
257
261
  }
258
262
 
263
+ /**
264
+ * Sanitize attributes on an HTML tag string for limited mode.
265
+ * Strips on* event handlers (case-insensitive) and runs sanitizeUrl()
266
+ * on href/src/action/formaction values.
267
+ */
268
+ function sanitizeHtmlTagAttrs(tagStr) {
269
+ // Self-closing or void tag without attributes — pass through
270
+ if (!/\s/.test(tagStr.replace(/<\/?[a-zA-Z][a-zA-Z0-9]*/, '').replace(/\/?>$/, ''))) {
271
+ return tagStr;
272
+ }
273
+ // Parse: <tagname ...attrs... > or <tagname ...attrs... />
274
+ const m = tagStr.match(/^(<\/?[a-zA-Z][a-zA-Z0-9]*)([\s\S]*?)(\/?>)$/);
275
+ /* istanbul ignore next - defensive: Phase 1.5 regex guarantees valid tag shape */
276
+ if (!m) return tagStr;
277
+
278
+ const [, open, attrStr, close] = m;
279
+ // Match individual attributes: name="value", name='value', name=value, or bare name
280
+ // eslint-disable-next-line security/detect-unsafe-regex -- linear: no nested quantifiers
281
+ const attrRe = /([a-zA-Z_][\w\-.:]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+)))?/g;
282
+ const attrs = [];
283
+ let am;
284
+ while ((am = attrRe.exec(attrStr)) !== null) {
285
+ const name = am[1];
286
+ const value = am[2] !== undefined ? am[2] : am[3] !== undefined ? am[3] : am[4];
287
+ // Strip event handlers (on*)
288
+ if (/^on/i.test(name)) continue;
289
+ if (value === undefined) {
290
+ // Boolean attribute (e.g. disabled, checked)
291
+ attrs.push(name);
292
+ } else {
293
+ let sanitized = value;
294
+ if (name.toLowerCase() in URL_ATTRIBUTES) {
295
+ sanitized = sanitizeUrl(value);
296
+ }
297
+ attrs.push(`${name}="${sanitized}"`);
298
+ }
299
+ }
300
+ return open + (attrs.length ? ' ' + attrs.join(' ') : '') + close;
301
+ }
302
+
259
303
  // ────────────────────────────────────────────────────────────────
260
304
  // Phase 1 — Code Extraction
261
305
  // ────────────────────────────────────────────────────────────────
@@ -307,17 +351,57 @@ function quikdown(markdown, options = {}) {
307
351
  return placeholder;
308
352
  });
309
353
 
354
+ // ────────────────────────────────────────────────────────────────
355
+ // Phase 1.5 — Safe HTML Extraction (whitelist mode)
356
+ // ────────────────────────────────────────────────────────────────
357
+ // When allow_unsafe_html is an object or array, extract whitelisted
358
+ // HTML tags, sanitize their attributes, and replace with placeholders.
359
+ // Non-whitelisted tags stay in text so Phase 2 will escape them.
360
+
361
+ const safeTags = [];
362
+ // Normalize: array → object for O(1) lookup; object used as-is
363
+ const htmlAllow = Array.isArray(allow_unsafe_html)
364
+ ? Object.fromEntries(allow_unsafe_html.map(t => [t, 1]))
365
+ : (allow_unsafe_html && typeof allow_unsafe_html === 'object') ? allow_unsafe_html : null;
366
+
367
+ if (htmlAllow) {
368
+ // Pass through HTML comments — browsers render them as nothing
369
+ html = html.replace(/<!--[\s\S]*?-->/g, (match) => {
370
+ const idx = safeTags.length;
371
+ safeTags.push(match);
372
+ return `${PLACEHOLDER_HT}${idx}§`;
373
+ });
374
+ html = html.replace(/<\/?([a-zA-Z][a-zA-Z0-9]*)\b[^>]*\/?>/g, (match, tagName) => {
375
+ if (tagName.toLowerCase() in htmlAllow) {
376
+ const sanitized = sanitizeHtmlTagAttrs(match);
377
+ const idx = safeTags.length;
378
+ safeTags.push(sanitized);
379
+ return `${PLACEHOLDER_HT}${idx}§`;
380
+ }
381
+ // Not whitelisted — leave in text for Phase 2 to escape
382
+ return match;
383
+ });
384
+ }
385
+
310
386
  // ────────────────────────────────────────────────────────────────
311
387
  // Phase 2 — HTML Escaping
312
388
  // ────────────────────────────────────────────────────────────────
313
389
  // All remaining text (everything except code placeholders) is escaped
314
390
  // to prevent XSS. The `allow_unsafe_html` option skips this for
315
391
  // trusted pipelines that intentionally embed raw HTML.
392
+ // For whitelist mode, escaping still runs (only `true` bypasses it).
316
393
 
317
- if (!allow_unsafe_html) {
394
+ if (allow_unsafe_html !== true) {
318
395
  html = escapeHtml(html);
319
396
  }
320
397
 
398
+ // Restore safe HTML tag placeholders after escaping
399
+ if (htmlAllow) {
400
+ safeTags.forEach((tag, i) => {
401
+ html = html.replace(`${PLACEHOLDER_HT}${i}§`, tag);
402
+ });
403
+ }
404
+
321
405
  // ────────────────────────────────────────────────────────────────
322
406
  // Phase 3 — Block Scanning + Inline Formatting + Paragraphs
323
407
  // ────────────────────────────────────────────────────────────────
@@ -559,6 +643,14 @@ function scanLineBlocks(text, getAttr, dataQd) {
559
643
  while (i < lines.length) {
560
644
  const line = lines[i];
561
645
 
646
+ // ── Markdown comment (reference-link hack) ──
647
+ // [//]: # (comment) or [//]: # "comment" or [//]: #
648
+ // These produce no output — standard markdown comment convention.
649
+ if (/^\[\/\/\]: #/.test(line)) {
650
+ i++;
651
+ continue;
652
+ }
653
+
562
654
  // ── Heading ──
563
655
  // Count leading '#' characters. Valid heading: 1-6 hashes then a space.
564
656
  // Example: "## Hello World ##" → <h2>Hello World</h2>
@@ -923,6 +1015,7 @@ quikdown.configure = function(options) {
923
1015
  /** Semantic version (injected at build time) */
924
1016
  quikdown.version = quikdownVersion;
925
1017
 
1018
+
926
1019
  // ════════════════════════════════════════════════════════════════════
927
1020
  // Exports
928
1021
  // ════════════════════════════════════════════════════════════════════
@@ -52,6 +52,17 @@ declare module 'quikdown' {
52
52
  */
53
53
  allow_unsafe_urls?: boolean;
54
54
 
55
+ /**
56
+ * Controls HTML passthrough in parsed output.
57
+ * - false (default): all HTML tags are escaped (secure)
58
+ * - true: all HTML passes through unchanged (unsafe, use with trusted content only)
59
+ * - Record<string, any>: object whose keys are lowercase tag names to allow
60
+ * (e.g. { img: 1, a: 1, div: 1 }). Use quikdown.SAFE_HTML_TAGS for a curated default.
61
+ * - string[]: array of tag names (converted to object internally)
62
+ * @default false
63
+ */
64
+ allow_unsafe_html?: boolean | Record<string, any> | string[];
65
+
55
66
  /**
56
67
  * If true, adds data-qd attributes for bidirectional conversion.
57
68
  * Enables HTML to Markdown conversion.
@@ -95,6 +106,7 @@ declare module 'quikdown' {
95
106
  * The version of quikdown
96
107
  */
97
108
  export const version: string;
109
+
98
110
  }
99
111
 
100
112
  export = quikdown;
@@ -5,7 +5,7 @@
5
5
  * Theme with container-based scoping.
6
6
  * Usage: <div class="quikdown-dark">...content...</div>
7
7
  *
8
- * @version 1.2.10
8
+ * @version 1.2.11
9
9
  * @source tools/generateThemeCSS.js
10
10
  */
11
11
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.2.10
3
+ * @version 1.2.11
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
@@ -112,7 +112,7 @@ function isDashHRLine(trimmed) {
112
112
  // ────────────────────────────────────────────────────────────────────
113
113
 
114
114
  /** Build-time version stamp (injected by tools/updateVersion) */
115
- const quikdownVersion = '1.2.10';
115
+ const quikdownVersion = '1.2.11';
116
116
 
117
117
  /** CSS class prefix used for all generated elements */
118
118
  const CLASS_PREFIX = 'quikdown-';
@@ -120,6 +120,10 @@ const CLASS_PREFIX = 'quikdown-';
120
120
  /** Placeholder sigils — chosen to be extremely unlikely in real text */
121
121
  const PLACEHOLDER_CB = '§CB'; // fenced code blocks
122
122
  const PLACEHOLDER_IC = '§IC'; // inline code spans
123
+ const PLACEHOLDER_HT = '§HT'; // safe HTML tags (limited mode)
124
+
125
+ /** Attributes whose values need URL sanitization */
126
+ const URL_ATTRIBUTES = { href:1, src:1, action:1, formaction:1 };
123
127
 
124
128
  /** HTML entity escape map */
125
129
  const ESC_MAP = {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'};
@@ -254,6 +258,46 @@ function quikdown(markdown, options = {}) {
254
258
  return trimmedUrl;
255
259
  }
256
260
 
261
+ /**
262
+ * Sanitize attributes on an HTML tag string for limited mode.
263
+ * Strips on* event handlers (case-insensitive) and runs sanitizeUrl()
264
+ * on href/src/action/formaction values.
265
+ */
266
+ function sanitizeHtmlTagAttrs(tagStr) {
267
+ // Self-closing or void tag without attributes — pass through
268
+ if (!/\s/.test(tagStr.replace(/<\/?[a-zA-Z][a-zA-Z0-9]*/, '').replace(/\/?>$/, ''))) {
269
+ return tagStr;
270
+ }
271
+ // Parse: <tagname ...attrs... > or <tagname ...attrs... />
272
+ const m = tagStr.match(/^(<\/?[a-zA-Z][a-zA-Z0-9]*)([\s\S]*?)(\/?>)$/);
273
+ /* istanbul ignore next - defensive: Phase 1.5 regex guarantees valid tag shape */
274
+ if (!m) return tagStr;
275
+
276
+ const [, open, attrStr, close] = m;
277
+ // Match individual attributes: name="value", name='value', name=value, or bare name
278
+ // eslint-disable-next-line security/detect-unsafe-regex -- linear: no nested quantifiers
279
+ const attrRe = /([a-zA-Z_][\w\-.:]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+)))?/g;
280
+ const attrs = [];
281
+ let am;
282
+ while ((am = attrRe.exec(attrStr)) !== null) {
283
+ const name = am[1];
284
+ const value = am[2] !== undefined ? am[2] : am[3] !== undefined ? am[3] : am[4];
285
+ // Strip event handlers (on*)
286
+ if (/^on/i.test(name)) continue;
287
+ if (value === undefined) {
288
+ // Boolean attribute (e.g. disabled, checked)
289
+ attrs.push(name);
290
+ } else {
291
+ let sanitized = value;
292
+ if (name.toLowerCase() in URL_ATTRIBUTES) {
293
+ sanitized = sanitizeUrl(value);
294
+ }
295
+ attrs.push(`${name}="${sanitized}"`);
296
+ }
297
+ }
298
+ return open + (attrs.length ? ' ' + attrs.join(' ') : '') + close;
299
+ }
300
+
257
301
  // ────────────────────────────────────────────────────────────────
258
302
  // Phase 1 — Code Extraction
259
303
  // ────────────────────────────────────────────────────────────────
@@ -305,17 +349,57 @@ function quikdown(markdown, options = {}) {
305
349
  return placeholder;
306
350
  });
307
351
 
352
+ // ────────────────────────────────────────────────────────────────
353
+ // Phase 1.5 — Safe HTML Extraction (whitelist mode)
354
+ // ────────────────────────────────────────────────────────────────
355
+ // When allow_unsafe_html is an object or array, extract whitelisted
356
+ // HTML tags, sanitize their attributes, and replace with placeholders.
357
+ // Non-whitelisted tags stay in text so Phase 2 will escape them.
358
+
359
+ const safeTags = [];
360
+ // Normalize: array → object for O(1) lookup; object used as-is
361
+ const htmlAllow = Array.isArray(allow_unsafe_html)
362
+ ? Object.fromEntries(allow_unsafe_html.map(t => [t, 1]))
363
+ : (allow_unsafe_html && typeof allow_unsafe_html === 'object') ? allow_unsafe_html : null;
364
+
365
+ if (htmlAllow) {
366
+ // Pass through HTML comments — browsers render them as nothing
367
+ html = html.replace(/<!--[\s\S]*?-->/g, (match) => {
368
+ const idx = safeTags.length;
369
+ safeTags.push(match);
370
+ return `${PLACEHOLDER_HT}${idx}§`;
371
+ });
372
+ html = html.replace(/<\/?([a-zA-Z][a-zA-Z0-9]*)\b[^>]*\/?>/g, (match, tagName) => {
373
+ if (tagName.toLowerCase() in htmlAllow) {
374
+ const sanitized = sanitizeHtmlTagAttrs(match);
375
+ const idx = safeTags.length;
376
+ safeTags.push(sanitized);
377
+ return `${PLACEHOLDER_HT}${idx}§`;
378
+ }
379
+ // Not whitelisted — leave in text for Phase 2 to escape
380
+ return match;
381
+ });
382
+ }
383
+
308
384
  // ────────────────────────────────────────────────────────────────
309
385
  // Phase 2 — HTML Escaping
310
386
  // ────────────────────────────────────────────────────────────────
311
387
  // All remaining text (everything except code placeholders) is escaped
312
388
  // to prevent XSS. The `allow_unsafe_html` option skips this for
313
389
  // trusted pipelines that intentionally embed raw HTML.
390
+ // For whitelist mode, escaping still runs (only `true` bypasses it).
314
391
 
315
- if (!allow_unsafe_html) {
392
+ if (allow_unsafe_html !== true) {
316
393
  html = escapeHtml(html);
317
394
  }
318
395
 
396
+ // Restore safe HTML tag placeholders after escaping
397
+ if (htmlAllow) {
398
+ safeTags.forEach((tag, i) => {
399
+ html = html.replace(`${PLACEHOLDER_HT}${i}§`, tag);
400
+ });
401
+ }
402
+
319
403
  // ────────────────────────────────────────────────────────────────
320
404
  // Phase 3 — Block Scanning + Inline Formatting + Paragraphs
321
405
  // ────────────────────────────────────────────────────────────────
@@ -557,6 +641,14 @@ function scanLineBlocks(text, getAttr, dataQd) {
557
641
  while (i < lines.length) {
558
642
  const line = lines[i];
559
643
 
644
+ // ── Markdown comment (reference-link hack) ──
645
+ // [//]: # (comment) or [//]: # "comment" or [//]: #
646
+ // These produce no output — standard markdown comment convention.
647
+ if (/^\[\/\/\]: #/.test(line)) {
648
+ i++;
649
+ continue;
650
+ }
651
+
560
652
  // ── Heading ──
561
653
  // Count leading '#' characters. Valid heading: 1-6 hashes then a space.
562
654
  // Example: "## Hello World ##" → <h2>Hello World</h2>
@@ -921,6 +1013,7 @@ quikdown.configure = function(options) {
921
1013
  /** Semantic version (injected at build time) */
922
1014
  quikdown.version = quikdownVersion;
923
1015
 
1016
+
924
1017
  // ════════════════════════════════════════════════════════════════════
925
1018
  // Exports
926
1019
  // ════════════════════════════════════════════════════════════════════
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.2.10
3
+ * @version 1.2.11
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
7
- function e(e){if(e.length<3)return!1;for(let t=0;t<e.length;t++){const n=e[t];if("-"!==n){if(" "===n||"\t"===n){for(let n=t+1;n<e.length;n++)if(" "!==e[n]&&"\t"!==e[n])return!1;return t>=3}return!1}}return!0}const t="quikdown-",n="§CB",r={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},o={h1:"font-size:2em;font-weight:600;margin:.67em 0;text-align:left",h2:"font-size:1.5em;font-weight:600;margin:.83em 0",h3:"font-size:1.25em;font-weight:600;margin:1em 0",h4:"font-size:1em;font-weight:600;margin:1.33em 0",h5:"font-size:.875em;font-weight:600;margin:1.67em 0",h6:"font-size:.85em;font-weight:600;margin:2em 0",pre:"background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0",code:"background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace",blockquote:"border-left:4px solid #ddd;margin-left:0;padding-left:1em",table:"border-collapse:collapse;width:100%;margin:1em 0",th:"border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left",td:"border:1px solid #ddd;padding:8px;text-align:left",hr:"border:none;border-top:1px solid #ddd;margin:1em 0",img:"max-width:100%;height:auto",a:"color:#06c;text-decoration:underline",strong:"font-weight:bold",em:"font-style:italic",del:"text-decoration:line-through",ul:"margin:.5em 0;padding-left:2em",ol:"margin:.5em 0;padding-left:2em",li:"margin:.25em 0","task-item":"list-style:none","task-checkbox":"margin-right:.5em"};function l(l,a={}){if(!l||"string"!=typeof l)return"";const{fence_plugin:s,inline_styles:i=!1,bidirectional:p=!1,lazy_linefeeds:d=!1,allow_unsafe_html:g=!1}=a,f=function(e,n){return function(r,o=""){if(e){let e=n[r];return e||o?(o&&o.includes("text-align")&&e&&e.includes("text-align")&&(e=e.replace(/text-align:[^;]+;?/,"").trim(),e&&!e.endsWith(";")&&(e+=";")),` style="${o?e?`${e}${o}`:o:e}"`):""}{const e=` class="${t}${r}"`;return o?`${e} style="${o}"`:e}}}(i,o);function $(e){return e.replace(/[&<>"']/g,e=>r[e])}const u=p?e=>` data-qd="${$(e)}"`:()=>"";function h(e,t=!1){if(!e)return"";if(t)return e;const n=e.trim(),r=n.toLowerCase(),o=["javascript:","vbscript:","data:"];for(const e of o)if(r.startsWith(e))return"data:"===e&&r.startsWith("data:image/")?n:"#";return n}let m=l;const b=[],_=[];m=m.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,t,r,o)=>{const l=`${n}${b.length}§`,a=r?r.trim():"";return s&&s.render&&"function"==typeof s.render?b.push({lang:a,code:o.trimEnd(),custom:!0,fence:t,hasReverse:!!s.reverse}):b.push({lang:a,code:$(o.trimEnd()),custom:!1,fence:t}),l}),m=m.replace(/`([^`]+)`/g,(e,t)=>{const n=`§IC${_.length}§`;return _.push($(t)),n}),g||(m=$(m)),m=function(e,t){const n=e.split("\n"),r=[];let o=!1,l=[];for(let e=0;e<n.length;e++){const a=n[e].trim();if(a.includes("|")&&(a.startsWith("|")||/[^\\|]/.test(a)))o||(o=!0,l=[]),l.push(a);else{if(o){const e=c(l,t);e?r.push(e):r.push(...l),o=!1,l=[]}r.push(n[e])}}if(o&&l.length>0){const e=c(l,t);e?r.push(e):r.push(...l)}return r.join("\n")}(m,f),m=function(t,n,r){const o=t.split("\n"),l=[];let a=0;for(;a<o.length;){const t=o[a];let c=0;for(;c<t.length&&c<7&&"#"===t[c];)c++;if(c>=1&&c<=6&&" "===t[c]){const e=t.slice(c+1).replace(/\s*#+\s*$/,""),o="h"+c;l.push(`<${o}${n(o)}${r("#".repeat(c))}>${e}</${o}>`),a++;continue}e(t)?(l.push(`<hr${n("hr")}>`),a++):/^&gt;\s+/.test(t)?(l.push(`<blockquote${n("blockquote")}>${t.replace(/^&gt;\s+/,"")}</blockquote>`),a++):(l.push(t),a++)}let c=l.join("\n");return c=c.replace(/<\/blockquote>\n<blockquote>/g,"\n"),c}(m,f,u),m=function(e,n,r,o){const l=e.split("\n"),a=[],c=[],s=e=>e.replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[e])),i=o?e=>` data-qd="${s(e)}"`:()=>"";for(let e=0;e<l.length;e++){const o=l[e],s=o.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(s){const[,e,o,l]=s,p=Math.floor(e.length/2),d=/^\d+\./.test(o),g=d?"ol":"ul";let f=l,$="";const u=l.match(/^\[([x ])\]\s+(.*)$/i);if(u&&!d){const[,e,n]=u,o="x"===e.toLowerCase();f=`<input type="checkbox"${r?' style="margin-right:.5em"':` class="${t}task-checkbox"`}${o?" checked":""} disabled> ${n}`,$=r?' style="list-style:none"':` class="${t}task-item"`}for(;c.length>p+1;){const e=c.pop();a.push(`</${e.type}>`)}if(c.length===p)c.push({type:g,level:p}),a.push(`<${g}${n(g)}>`);else if(c.length===p+1){const e=c[c.length-1];e.type!==g&&(a.push(`</${e.type}>`),c.pop(),c.push({type:g,level:p}),a.push(`<${g}${n(g)}>`))}const h=$||n("li");a.push(`<li${h}${i(o)}>${f}</li>`)}else{for(;c.length>0;){const e=c.pop();a.push(`</${e.type}>`)}a.push(o)}}for(;c.length>0;){const e=c.pop();a.push(`</${e.type}>`)}return a.join("\n")}(m,f,i,p),m=m.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,t,n)=>{const r=h(n,a.allow_unsafe_urls),o=p&&t?` data-qd-alt="${$(t)}"`:"",l=p?` data-qd-src="${$(n)}"`:"";return`<img${f("img")} src="${r}" alt="${t}"${o}${l}${u("!")}>`}),m=m.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,t,n)=>{const r=h(n,a.allow_unsafe_urls),o=/^https?:\/\//i.test(r)?' rel="noopener noreferrer"':"",l=p?` data-qd-text="${$(t)}"`:"";return`<a${f("a")} href="${r}"${o}${l}${u("[")}>${t}</a>`}),m=m.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,t,n)=>{const r=h(n,a.allow_unsafe_urls);return`${t}<a${f("a")} href="${r}" rel="noopener noreferrer">${n}</a>`});const x=[];m=m.replace(/<[^>]+>/g,e=>(x.push(e),`%%T${x.length-1}%%`));if([[/\*\*(.+?)\*\*/g,"strong","**"],[/__(.+?)__/g,"strong","__"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em","*"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em","_"],[/~~(.+?)~~/g,"del","~~"]].forEach(([e,t,n])=>{m=m.replace(e,`<${t}${f(t)}${u(n)}>$1</${t}>`)}),m=m.replace(/%%T(\d+)%%/g,(e,t)=>x[t]),d){const e=[];let t=0;m=m.replace(/<(table|[uo]l)[^>]*>[\s\S]*?<\/\1>/g,n=>(e[t]=n,`§B${t++}§`)),m=m.replace(/\n\n+/g,"§P§").replace(/(<\/(?:h[1-6]|blockquote|pre)>)\n/g,"$1§N§").replace(/(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)\n/g,"$1§N§").replace(/\n(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)/g,"§N§$1").replace(/\n(§B\d+§)/g,"§N§$1").replace(/(§B\d+§)\n/g,"$1§N§").replace(/\n/g,`<br${f("br")}>`).replace(/§N§/g,"\n").replace(/§P§/g,"</p><p>"),e.forEach((e,t)=>m=m.replace(`§B${t}§`,e)),m="<p>"+m+"</p>"}else m=m.replace(/ {2}$/gm,`<br${f("br")}>`),m=m.replace(/\n\n+/g,(e,t)=>m.substring(0,t).match(/<\/(h[1-6]|blockquote|ul|ol|table|pre|hr)>$/)?"<p>":"</p><p>"),m="<p>"+m+"</p>";return[[/<p><\/p>/g,""],[/<p>(<h[1-6][^>]*>)/g,"$1"],[/(<\/h[1-6]>)<\/p>/g,"$1"],[/<p>(<blockquote[^>]*>)/g,"$1"],[/(<\/blockquote>)<\/p>/g,"$1"],[/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"],[/(<\/ul>|<\/ol>)<\/p>/g,"$1"],[/<p>(<hr[^>]*>)<\/p>/g,"$1"],[/<p>(<table[^>]*>)/g,"$1"],[/(<\/table>)<\/p>/g,"$1"],[/<p>(<pre[^>]*>)/g,"$1"],[/(<\/pre>)<\/p>/g,"$1"],[new RegExp(`<p>(${n}\\d+§)</p>`,"g"),"$1"]].forEach(([e,t])=>{m=m.replace(e,t)}),m=m.replace(/(<\/(?:h[1-6]|blockquote|ul|ol|table|pre|hr)>)\n([^<])/g,"$1\n<p>$2"),b.forEach((e,t)=>{let r;if(e.custom&&s&&s.render)if(r=s.render(e.code,e.lang),void 0===r){const t=!i&&e.lang?` class="language-${e.lang}"`:"",n=i?f("code"):t,o=p&&e.lang?` data-qd-lang="${$(e.lang)}"`:"",l=p?` data-qd-fence="${$(e.fence)}"`:"";r=`<pre${f("pre")}${l}${o}><code${n}>${$(e.code)}</code></pre>`}else p&&(r=r.replace(/^<(\w+)/,`<$1 data-qd-fence="${$(e.fence)}" data-qd-lang="${$(e.lang)}" data-qd-source="${$(e.code)}"`));else{const t=!i&&e.lang?` class="language-${e.lang}"`:"",n=i?f("code"):t,o=p&&e.lang?` data-qd-lang="${$(e.lang)}"`:"",l=p?` data-qd-fence="${$(e.fence)}"`:"";r=`<pre${f("pre")}${l}${o}><code${n}>${e.code}</code></pre>`}const o=`${n}${t}§`;m=m.replace(o,r)}),_.forEach((e,t)=>{const n=`§IC${t}§`;m=m.replace(n,`<code${f("code")}${u("`")}>${e}</code>`)}),m.trim()}function a(e,t){return[[/\*\*(.+?)\*\*/g,"strong"],[/__(.+?)__/g,"strong"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em"],[/~~(.+?)~~/g,"del"],[/`([^`]+)`/g,"code"]].forEach(([n,r])=>{e=e.replace(n,`<${r}${t(r)}>$1</${r}>`)}),e}function c(e,t){if(e.length<2)return null;let n=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){n=t;break}if(-1===n)return null;const r=e.slice(0,n),o=e.slice(n+1),l=e[n].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let c=`<table${t("table")}>\n`;return c+=`<thead${t("thead")}>\n`,r.forEach(e=>{c+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const r=l[n]&&"left"!==l[n]?`text-align:${l[n]}`:"",o=a(e.trim(),t);c+=`<th${t("th",r)}>${o}</th>\n`}),c+="</tr>\n"}),c+="</thead>\n",o.length>0&&(c+=`<tbody${t("tbody")}>\n`,o.forEach(e=>{c+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const r=l[n]&&"left"!==l[n]?`text-align:${l[n]}`:"",o=a(e.trim(),t);c+=`<td${t("td",r)}>${o}</td>\n`}),c+="</tr>\n"}),c+="</tbody>\n"),c+="</table>",c}l.emitStyles=function(e="quikdown-",t="light"){const n=o,r={"#f4f4f4":"#2a2a2a","#f0f0f0":"#2a2a2a","#f2f2f2":"#2a2a2a","#ddd":"#3a3a3a","#06c":"#6db3f2",_textColor:"#e0e0e0"},l={_textColor:"#333"};let a="";for(const[o,c]of Object.entries(n)){let n=c;if("dark"===t&&r){for(const[e,t]of Object.entries(r))e.startsWith("_")||(n=n.replaceAll(e,t));["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(o)&&(n+=`;color:${r._textColor}`)}else if("light"===t&&l){["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(o)&&(n+=`;color:${l._textColor}`)}a+=`.${e}${o} { ${n} }\n`}return a},l.configure=function(e){return function(t){return l(t,e)}},l.version="1.2.10","undefined"!=typeof module&&module.exports&&(module.exports=l),"undefined"!=typeof window&&(window.quikdown=l);export{l as default};
7
+ function e(e){if(e.length<3)return!1;for(let t=0;t<e.length;t++){const n=e[t];if("-"!==n){if(" "===n||"\t"===n){for(let n=t+1;n<e.length;n++)if(" "!==e[n]&&"\t"!==e[n])return!1;return t>=3}return!1}}return!0}const t="quikdown-",n="§CB",r="§HT",o={href:1,src:1,action:1,formaction:1},l={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},a={h1:"font-size:2em;font-weight:600;margin:.67em 0;text-align:left",h2:"font-size:1.5em;font-weight:600;margin:.83em 0",h3:"font-size:1.25em;font-weight:600;margin:1em 0",h4:"font-size:1em;font-weight:600;margin:1.33em 0",h5:"font-size:.875em;font-weight:600;margin:1.67em 0",h6:"font-size:.85em;font-weight:600;margin:2em 0",pre:"background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0",code:"background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace",blockquote:"border-left:4px solid #ddd;margin-left:0;padding-left:1em",table:"border-collapse:collapse;width:100%;margin:1em 0",th:"border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left",td:"border:1px solid #ddd;padding:8px;text-align:left",hr:"border:none;border-top:1px solid #ddd;margin:1em 0",img:"max-width:100%;height:auto",a:"color:#06c;text-decoration:underline",strong:"font-weight:bold",em:"font-style:italic",del:"text-decoration:line-through",ul:"margin:.5em 0;padding-left:2em",ol:"margin:.5em 0;padding-left:2em",li:"margin:.25em 0","task-item":"list-style:none","task-checkbox":"margin-right:.5em"};function c(c,s={}){if(!c||"string"!=typeof c)return"";const{fence_plugin:p,inline_styles:g=!1,bidirectional:d=!1,lazy_linefeeds:f=!1,allow_unsafe_html:u=!1}=s,$=function(e,n){return function(r,o=""){if(e){let e=n[r];return e||o?(o&&o.includes("text-align")&&e&&e.includes("text-align")&&(e=e.replace(/text-align:[^;]+;?/,"").trim(),e&&!e.endsWith(";")&&(e+=";")),` style="${o?e?`${e}${o}`:o:e}"`):""}{const e=` class="${t}${r}"`;return o?`${e} style="${o}"`:e}}}(g,a);function h(e){return e.replace(/[&<>"']/g,e=>l[e])}const m=d?e=>` data-qd="${h(e)}"`:()=>"";function b(e,t=!1){if(!e)return"";if(t)return e;const n=e.trim(),r=n.toLowerCase(),o=["javascript:","vbscript:","data:"];for(const e of o)if(r.startsWith(e))return"data:"===e&&r.startsWith("data:image/")?n:"#";return n}let _=c;const x=[],q=[];_=_.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,t,r,o)=>{const l=`${n}${x.length}§`,a=r?r.trim():"";return p&&p.render&&"function"==typeof p.render?x.push({lang:a,code:o.trimEnd(),custom:!0,fence:t,hasReverse:!!p.reverse}):x.push({lang:a,code:h(o.trimEnd()),custom:!1,fence:t}),l}),_=_.replace(/`([^`]+)`/g,(e,t)=>{const n=`§IC${q.length}§`;return q.push(h(t)),n});const k=[],w=Array.isArray(u)?Object.fromEntries(u.map(e=>[e,1])):u&&"object"==typeof u?u:null;w&&(_=_.replace(/<!--[\s\S]*?-->/g,e=>{const t=k.length;return k.push(e),`${r}${t}§`}),_=_.replace(/<\/?([a-zA-Z][a-zA-Z0-9]*)\b[^>]*\/?>/g,(e,t)=>{if(t.toLowerCase()in w){const t=function(e){if(!/\s/.test(e.replace(/<\/?[a-zA-Z][a-zA-Z0-9]*/,"").replace(/\/?>$/,"")))return e;const t=e.match(/^(<\/?[a-zA-Z][a-zA-Z0-9]*)([\s\S]*?)(\/?>)$/);if(!t)return e;const[,n,r,l]=t,a=/([a-zA-Z_][\w\-.:]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+)))?/g,c=[];let s;for(;null!==(s=a.exec(r));){const e=s[1],t=void 0!==s[2]?s[2]:void 0!==s[3]?s[3]:s[4];if(!/^on/i.test(e))if(void 0===t)c.push(e);else{let n=t;e.toLowerCase()in o&&(n=b(t)),c.push(`${e}="${n}"`)}}return n+(c.length?" "+c.join(" "):"")+l}(e),n=k.length;return k.push(t),`${r}${n}§`}return e})),!0!==u&&(_=h(_)),w&&k.forEach((e,t)=>{_=_.replace(`${r}${t}§`,e)}),_=function(e,t){const n=e.split("\n"),r=[];let o=!1,l=[];for(let e=0;e<n.length;e++){const a=n[e].trim();if(a.includes("|")&&(a.startsWith("|")||/[^\\|]/.test(a)))o||(o=!0,l=[]),l.push(a);else{if(o){const e=i(l,t);e?r.push(e):r.push(...l),o=!1,l=[]}r.push(n[e])}}if(o&&l.length>0){const e=i(l,t);e?r.push(e):r.push(...l)}return r.join("\n")}(_,$),_=function(t,n,r){const o=t.split("\n"),l=[];let a=0;for(;a<o.length;){const t=o[a];if(/^\[\/\/\]: #/.test(t)){a++;continue}let c=0;for(;c<t.length&&c<7&&"#"===t[c];)c++;if(c>=1&&c<=6&&" "===t[c]){const e=t.slice(c+1).replace(/\s*#+\s*$/,""),o="h"+c;l.push(`<${o}${n(o)}${r("#".repeat(c))}>${e}</${o}>`),a++;continue}e(t)?(l.push(`<hr${n("hr")}>`),a++):/^&gt;\s+/.test(t)?(l.push(`<blockquote${n("blockquote")}>${t.replace(/^&gt;\s+/,"")}</blockquote>`),a++):(l.push(t),a++)}let c=l.join("\n");return c=c.replace(/<\/blockquote>\n<blockquote>/g,"\n"),c}(_,$,m),_=function(e,n,r,o){const l=e.split("\n"),a=[],c=[],s=e=>e.replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[e])),i=o?e=>` data-qd="${s(e)}"`:()=>"";for(let e=0;e<l.length;e++){const o=l[e],s=o.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(s){const[,e,o,l]=s,p=Math.floor(e.length/2),g=/^\d+\./.test(o),d=g?"ol":"ul";let f=l,u="";const $=l.match(/^\[([x ])\]\s+(.*)$/i);if($&&!g){const[,e,n]=$,o="x"===e.toLowerCase();f=`<input type="checkbox"${r?' style="margin-right:.5em"':` class="${t}task-checkbox"`}${o?" checked":""} disabled> ${n}`,u=r?' style="list-style:none"':` class="${t}task-item"`}for(;c.length>p+1;){const e=c.pop();a.push(`</${e.type}>`)}if(c.length===p)c.push({type:d,level:p}),a.push(`<${d}${n(d)}>`);else if(c.length===p+1){const e=c[c.length-1];e.type!==d&&(a.push(`</${e.type}>`),c.pop(),c.push({type:d,level:p}),a.push(`<${d}${n(d)}>`))}const h=u||n("li");a.push(`<li${h}${i(o)}>${f}</li>`)}else{for(;c.length>0;){const e=c.pop();a.push(`</${e.type}>`)}a.push(o)}}for(;c.length>0;){const e=c.pop();a.push(`</${e.type}>`)}return a.join("\n")}(_,$,g,d),_=_.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,t,n)=>{const r=b(n,s.allow_unsafe_urls),o=d&&t?` data-qd-alt="${h(t)}"`:"",l=d?` data-qd-src="${h(n)}"`:"";return`<img${$("img")} src="${r}" alt="${t}"${o}${l}${m("!")}>`}),_=_.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,t,n)=>{const r=b(n,s.allow_unsafe_urls),o=/^https?:\/\//i.test(r)?' rel="noopener noreferrer"':"",l=d?` data-qd-text="${h(t)}"`:"";return`<a${$("a")} href="${r}"${o}${l}${m("[")}>${t}</a>`}),_=_.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,t,n)=>{const r=b(n,s.allow_unsafe_urls);return`${t}<a${$("a")} href="${r}" rel="noopener noreferrer">${n}</a>`});const y=[];_=_.replace(/<[^>]+>/g,e=>(y.push(e),`%%T${y.length-1}%%`));if([[/\*\*(.+?)\*\*/g,"strong","**"],[/__(.+?)__/g,"strong","__"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em","*"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em","_"],[/~~(.+?)~~/g,"del","~~"]].forEach(([e,t,n])=>{_=_.replace(e,`<${t}${$(t)}${m(n)}>$1</${t}>`)}),_=_.replace(/%%T(\d+)%%/g,(e,t)=>y[t]),f){const e=[];let t=0;_=_.replace(/<(table|[uo]l)[^>]*>[\s\S]*?<\/\1>/g,n=>(e[t]=n,`§B${t++}§`)),_=_.replace(/\n\n+/g,"§P§").replace(/(<\/(?:h[1-6]|blockquote|pre)>)\n/g,"$1§N§").replace(/(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)\n/g,"$1§N§").replace(/\n(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)/g,"§N§$1").replace(/\n(§B\d+§)/g,"§N§$1").replace(/(§B\d+§)\n/g,"$1§N§").replace(/\n/g,`<br${$("br")}>`).replace(/§N§/g,"\n").replace(/§P§/g,"</p><p>"),e.forEach((e,t)=>_=_.replace(`§B${t}§`,e)),_="<p>"+_+"</p>"}else _=_.replace(/ {2}$/gm,`<br${$("br")}>`),_=_.replace(/\n\n+/g,(e,t)=>_.substring(0,t).match(/<\/(h[1-6]|blockquote|ul|ol|table|pre|hr)>$/)?"<p>":"</p><p>"),_="<p>"+_+"</p>";return[[/<p><\/p>/g,""],[/<p>(<h[1-6][^>]*>)/g,"$1"],[/(<\/h[1-6]>)<\/p>/g,"$1"],[/<p>(<blockquote[^>]*>)/g,"$1"],[/(<\/blockquote>)<\/p>/g,"$1"],[/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"],[/(<\/ul>|<\/ol>)<\/p>/g,"$1"],[/<p>(<hr[^>]*>)<\/p>/g,"$1"],[/<p>(<table[^>]*>)/g,"$1"],[/(<\/table>)<\/p>/g,"$1"],[/<p>(<pre[^>]*>)/g,"$1"],[/(<\/pre>)<\/p>/g,"$1"],[new RegExp(`<p>(${n}\\d+§)</p>`,"g"),"$1"]].forEach(([e,t])=>{_=_.replace(e,t)}),_=_.replace(/(<\/(?:h[1-6]|blockquote|ul|ol|table|pre|hr)>)\n([^<])/g,"$1\n<p>$2"),x.forEach((e,t)=>{let r;if(e.custom&&p&&p.render)if(r=p.render(e.code,e.lang),void 0===r){const t=!g&&e.lang?` class="language-${e.lang}"`:"",n=g?$("code"):t,o=d&&e.lang?` data-qd-lang="${h(e.lang)}"`:"",l=d?` data-qd-fence="${h(e.fence)}"`:"";r=`<pre${$("pre")}${l}${o}><code${n}>${h(e.code)}</code></pre>`}else d&&(r=r.replace(/^<(\w+)/,`<$1 data-qd-fence="${h(e.fence)}" data-qd-lang="${h(e.lang)}" data-qd-source="${h(e.code)}"`));else{const t=!g&&e.lang?` class="language-${e.lang}"`:"",n=g?$("code"):t,o=d&&e.lang?` data-qd-lang="${h(e.lang)}"`:"",l=d?` data-qd-fence="${h(e.fence)}"`:"";r=`<pre${$("pre")}${l}${o}><code${n}>${e.code}</code></pre>`}const o=`${n}${t}§`;_=_.replace(o,r)}),q.forEach((e,t)=>{const n=`§IC${t}§`;_=_.replace(n,`<code${$("code")}${m("`")}>${e}</code>`)}),_.trim()}function s(e,t){return[[/\*\*(.+?)\*\*/g,"strong"],[/__(.+?)__/g,"strong"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em"],[/~~(.+?)~~/g,"del"],[/`([^`]+)`/g,"code"]].forEach(([n,r])=>{e=e.replace(n,`<${r}${t(r)}>$1</${r}>`)}),e}function i(e,t){if(e.length<2)return null;let n=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){n=t;break}if(-1===n)return null;const r=e.slice(0,n),o=e.slice(n+1),l=e[n].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let a=`<table${t("table")}>\n`;return a+=`<thead${t("thead")}>\n`,r.forEach(e=>{a+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const r=l[n]&&"left"!==l[n]?`text-align:${l[n]}`:"",o=s(e.trim(),t);a+=`<th${t("th",r)}>${o}</th>\n`}),a+="</tr>\n"}),a+="</thead>\n",o.length>0&&(a+=`<tbody${t("tbody")}>\n`,o.forEach(e=>{a+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const r=l[n]&&"left"!==l[n]?`text-align:${l[n]}`:"",o=s(e.trim(),t);a+=`<td${t("td",r)}>${o}</td>\n`}),a+="</tr>\n"}),a+="</tbody>\n"),a+="</table>",a}c.emitStyles=function(e="quikdown-",t="light"){const n=a,r={"#f4f4f4":"#2a2a2a","#f0f0f0":"#2a2a2a","#f2f2f2":"#2a2a2a","#ddd":"#3a3a3a","#06c":"#6db3f2",_textColor:"#e0e0e0"},o={_textColor:"#333"};let l="";for(const[a,c]of Object.entries(n)){let n=c;if("dark"===t&&r){for(const[e,t]of Object.entries(r))e.startsWith("_")||(n=n.replaceAll(e,t));["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(a)&&(n+=`;color:${r._textColor}`)}else if("light"===t&&o){["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(a)&&(n+=`;color:${o._textColor}`)}l+=`.${e}${a} { ${n} }\n`}return l},c.configure=function(e){return function(t){return c(t,e)}},c.version="1.2.11","undefined"!=typeof module&&module.exports&&(module.exports=c),"undefined"!=typeof window&&(window.quikdown=c);export{c as default};
8
8
  //# sourceMappingURL=quikdown.esm.min.js.map
Binary file