quikdown 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,19 +4,19 @@
4
4
  [![npm version](https://badge.fury.io/js/quikdown.svg)](https://www.npmjs.com/package/quikdown)
5
5
  [![Coverage Status](https://img.shields.io/badge/coverage-99%25-brightgreen.svg)](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-8.7KB-green.svg)](https://github.com/deftio/quikdown/tree/main/dist)
7
+ [![Bundle Size](https://img.shields.io/badge/minified-<10KB-green.svg)](https://github.com/deftio/quikdown/tree/main/dist)
8
8
 
9
9
  A lightweight, fast markdown parser with built-in XSS protection. Quikdown works in both browser and Node.js environments. Via its fenced plug-in support it can support highlighted code blocks, diagrams, and other custom fenced content.
10
10
 
11
- 📚 **[View Live Examples](https://deftio.github.io/quikdown/)** - Interactive examples on giithub of quikdown's features
12
- 📚 **[View Local Examples](examples/)** - Interactive demos of quikdown's features
11
+ 🚀 **[Try Live Demo](https://deftio.github.io/quikdown/examples/quikdown-live.html)** - Interactive markdown editor with real-time preview
12
+ 📚 **[View Examples](examples/)** - Additional demos and test pages
13
13
  📖 **[Read Documentation](docs/)** - Architecture, security, API reference, and plugin guide
14
14
 
15
15
  ## Features
16
16
 
17
- - 🚀 **Lightweight** - Under 10KB minified (currently 8.7KB)
17
+ - 🚀 **Lightweight** - Under 10KB minified
18
18
  - 🔒 **Secure by default** - Built-in XSS protection with URL sanitization
19
- - 🎨 **Flexible styling** - Inline styles or CSS classes
19
+ - 🎨 **Flexible styling** - Inline styles or CSS classes including examples for light and dark mode generation
20
20
  - 🔌 **Plugin system** - Extensible fence block handlers
21
21
  - 📦 **Zero dependencies** - No external libraries required
22
22
  - 🌐 **Universal** - Works in browsers and Node.js
package/dist/quikdown.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.0.1
3
+ * @version 1.0.2
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
@@ -9,7 +9,7 @@
9
9
  // Auto-generated version file - DO NOT EDIT MANUALLY
10
10
  // This file is automatically updated by tools/updateVersion.js
11
11
 
12
- const quikdownVersion = "1.0.1";
12
+ const quikdownVersion = "1.0.2";
13
13
 
14
14
  /**
15
15
  * quikdown - A minimal markdown parser optimized for chat/LLM output
@@ -30,35 +30,31 @@ function quikdown(markdown, options = {}) {
30
30
 
31
31
  const { fence_plugin, inline_styles = false } = options;
32
32
 
33
- // Style definitions - deduplicated to save space
34
- const headingStyle = 'margin-top: 0.5em; margin-bottom: 0.3em';
35
- const listStyle = 'margin: 0.5em 0; padding-left: 2em';
36
- const cellBorder = 'border: 1px solid #ddd; padding: 8px';
37
-
33
+ // Style definitions - minimal, matching emitStyles
38
34
  const styles = {
39
- h1: headingStyle,
40
- h2: headingStyle,
41
- h3: headingStyle,
42
- h4: headingStyle,
43
- h5: headingStyle,
44
- h6: headingStyle,
45
- pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',
46
- code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',
47
- blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',
35
+ h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',
36
+ h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',
37
+ h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',
38
+ h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',
39
+ h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',
40
+ h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',
41
+ pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',
42
+ code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',
43
+ blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',
48
44
  table: 'border-collapse: collapse; width: 100%; margin: 1em 0',
49
45
  thead: '',
50
46
  tbody: '',
51
47
  tr: '',
52
- th: cellBorder + '; background-color: #f2f2f2; font-weight: bold',
53
- td: cellBorder + '; text-align: left',
48
+ th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',
49
+ td: 'border: 1px solid #ddd; padding: 8px; text-align: left',
54
50
  hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',
55
51
  img: 'max-width: 100%; height: auto',
56
52
  a: 'color: #0066cc; text-decoration: underline',
57
53
  strong: 'font-weight: bold',
58
54
  em: 'font-style: italic',
59
55
  del: 'text-decoration: line-through',
60
- ul: listStyle,
61
- ol: listStyle,
56
+ ul: 'margin: 0.5em 0; padding-left: 2em',
57
+ ol: 'margin: 0.5em 0; padding-left: 2em',
62
58
  li: 'margin: 0.25em 0',
63
59
  br: ''
64
60
  };
@@ -122,19 +118,24 @@ function quikdown(markdown, options = {}) {
122
118
  const inlineCodes = [];
123
119
 
124
120
  // Extract fenced code blocks first (supports both ``` and ~~~)
125
- html = html.replace(/(?:```|~~~)([^\n]*)\n([\s\S]*?)(?:```|~~~)/g, (match, lang, code) => {
121
+ // Match paired fences - ``` with ``` and ~~~ with ~~~
122
+ // Fence must be at start of line
123
+ html = html.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm, (match, fence, lang, code) => {
126
124
  const placeholder = `%%%CODEBLOCK${codeBlocks.length}%%%`;
127
125
 
126
+ // Trim the language specification
127
+ const langTrimmed = lang ? lang.trim() : '';
128
+
128
129
  // If custom fence plugin is provided, use it
129
130
  if (fence_plugin && typeof fence_plugin === 'function') {
130
131
  codeBlocks.push({
131
- lang: lang || '',
132
+ lang: langTrimmed,
132
133
  code: code.trimEnd(),
133
134
  custom: true
134
135
  });
135
136
  } else {
136
137
  codeBlocks.push({
137
- lang: lang || '',
138
+ lang: langTrimmed,
138
139
  code: escapeHtml(code.trimEnd()),
139
140
  custom: false
140
141
  });
@@ -523,17 +524,17 @@ function processLists(text, inline_styles, styles) {
523
524
  */
524
525
  quikdown.emitStyles = function() {
525
526
  const styles = {
526
- h1: 'margin-top: 0.5em; margin-bottom: 0.3em',
527
- h2: 'margin-top: 0.5em; margin-bottom: 0.3em',
528
- h3: 'margin-top: 0.5em; margin-bottom: 0.3em',
529
- h4: 'margin-top: 0.5em; margin-bottom: 0.3em',
530
- h5: 'margin-top: 0.5em; margin-bottom: 0.3em',
531
- h6: 'margin-top: 0.5em; margin-bottom: 0.3em',
532
- pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',
533
- code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',
534
- blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',
527
+ h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',
528
+ h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',
529
+ h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',
530
+ h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',
531
+ h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',
532
+ h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',
533
+ pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',
534
+ code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',
535
+ blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',
535
536
  table: 'border-collapse: collapse; width: 100%; margin: 1em 0',
536
- th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold',
537
+ th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',
537
538
  td: 'border: 1px solid #ddd; padding: 8px; text-align: left',
538
539
  hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',
539
540
  img: 'max-width: 100%; height: auto',
@@ -0,0 +1,138 @@
1
+ /**
2
+ * quikdown Dark Theme CSS
3
+ * Minimal dark theme - just inverted colors, no fancy styling
4
+ */
5
+
6
+ /* Headings - just size differences */
7
+ .quikdown-h1 {
8
+ font-size: 2em;
9
+ font-weight: 600;
10
+ margin: 0.67em 0;
11
+ text-align: left;
12
+ }
13
+
14
+ .quikdown-h2 {
15
+ font-size: 1.5em;
16
+ font-weight: 600;
17
+ margin: 0.83em 0;
18
+ }
19
+
20
+ .quikdown-h3 {
21
+ font-size: 1.25em;
22
+ font-weight: 600;
23
+ margin: 1em 0;
24
+ }
25
+
26
+ .quikdown-h4 {
27
+ font-size: 1em;
28
+ font-weight: 600;
29
+ margin: 1.33em 0;
30
+ }
31
+
32
+ .quikdown-h5 {
33
+ font-size: 0.875em;
34
+ font-weight: 600;
35
+ margin: 1.67em 0;
36
+ }
37
+
38
+ .quikdown-h6 {
39
+ font-size: 0.85em;
40
+ font-weight: 600;
41
+ margin: 2em 0;
42
+ }
43
+
44
+ /* Code blocks */
45
+ .quikdown-pre {
46
+ background: #2a2a2a;
47
+ padding: 10px;
48
+ border-radius: 4px;
49
+ overflow-x: auto;
50
+ margin: 1em 0;
51
+ }
52
+
53
+ .quikdown-code {
54
+ background: #333;
55
+ padding: 2px 4px;
56
+ border-radius: 3px;
57
+ font-family: monospace;
58
+ }
59
+
60
+ /* Blockquotes */
61
+ .quikdown-blockquote {
62
+ border-left: 4px solid #444;
63
+ margin-left: 0;
64
+ padding-left: 1em;
65
+ }
66
+
67
+ /* Tables */
68
+ .quikdown-table {
69
+ border-collapse: collapse;
70
+ width: 100%;
71
+ margin: 1em 0;
72
+ }
73
+
74
+ .quikdown-th {
75
+ border: 1px solid #444;
76
+ padding: 8px;
77
+ background-color: #2a2a2a;
78
+ font-weight: bold;
79
+ text-align: left;
80
+ }
81
+
82
+ .quikdown-td {
83
+ border: 1px solid #444;
84
+ padding: 8px;
85
+ text-align: left;
86
+ }
87
+
88
+ /* Lists */
89
+ .quikdown-ul,
90
+ .quikdown-ol {
91
+ margin: 0.5em 0;
92
+ padding-left: 2em;
93
+ }
94
+
95
+ .quikdown-li {
96
+ margin: 0.25em 0;
97
+ }
98
+
99
+ /* Task lists */
100
+ .quikdown-task-item {
101
+ list-style: none;
102
+ }
103
+
104
+ .quikdown-task-checkbox {
105
+ margin-right: 0.5em;
106
+ }
107
+
108
+ /* Links */
109
+ .quikdown-a {
110
+ color: #66b3ff;
111
+ text-decoration: underline;
112
+ }
113
+
114
+ /* Images */
115
+ .quikdown-img {
116
+ max-width: 100%;
117
+ height: auto;
118
+ }
119
+
120
+ /* Horizontal rule */
121
+ .quikdown-hr {
122
+ border: none;
123
+ border-top: 1px solid #444;
124
+ margin: 1em 0;
125
+ }
126
+
127
+ /* Text formatting */
128
+ .quikdown-strong {
129
+ font-weight: bold;
130
+ }
131
+
132
+ .quikdown-em {
133
+ font-style: italic;
134
+ }
135
+
136
+ .quikdown-del {
137
+ text-decoration: line-through;
138
+ }
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.0.1
3
+ * @version 1.0.2
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
7
7
  // Auto-generated version file - DO NOT EDIT MANUALLY
8
8
  // This file is automatically updated by tools/updateVersion.js
9
9
 
10
- const quikdownVersion = "1.0.1";
10
+ const quikdownVersion = "1.0.2";
11
11
 
12
12
  /**
13
13
  * quikdown - A minimal markdown parser optimized for chat/LLM output
@@ -28,35 +28,31 @@ function quikdown(markdown, options = {}) {
28
28
 
29
29
  const { fence_plugin, inline_styles = false } = options;
30
30
 
31
- // Style definitions - deduplicated to save space
32
- const headingStyle = 'margin-top: 0.5em; margin-bottom: 0.3em';
33
- const listStyle = 'margin: 0.5em 0; padding-left: 2em';
34
- const cellBorder = 'border: 1px solid #ddd; padding: 8px';
35
-
31
+ // Style definitions - minimal, matching emitStyles
36
32
  const styles = {
37
- h1: headingStyle,
38
- h2: headingStyle,
39
- h3: headingStyle,
40
- h4: headingStyle,
41
- h5: headingStyle,
42
- h6: headingStyle,
43
- pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',
44
- code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',
45
- blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',
33
+ h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',
34
+ h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',
35
+ h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',
36
+ h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',
37
+ h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',
38
+ h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',
39
+ pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',
40
+ code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',
41
+ blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',
46
42
  table: 'border-collapse: collapse; width: 100%; margin: 1em 0',
47
43
  thead: '',
48
44
  tbody: '',
49
45
  tr: '',
50
- th: cellBorder + '; background-color: #f2f2f2; font-weight: bold',
51
- td: cellBorder + '; text-align: left',
46
+ th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',
47
+ td: 'border: 1px solid #ddd; padding: 8px; text-align: left',
52
48
  hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',
53
49
  img: 'max-width: 100%; height: auto',
54
50
  a: 'color: #0066cc; text-decoration: underline',
55
51
  strong: 'font-weight: bold',
56
52
  em: 'font-style: italic',
57
53
  del: 'text-decoration: line-through',
58
- ul: listStyle,
59
- ol: listStyle,
54
+ ul: 'margin: 0.5em 0; padding-left: 2em',
55
+ ol: 'margin: 0.5em 0; padding-left: 2em',
60
56
  li: 'margin: 0.25em 0',
61
57
  br: ''
62
58
  };
@@ -120,19 +116,24 @@ function quikdown(markdown, options = {}) {
120
116
  const inlineCodes = [];
121
117
 
122
118
  // Extract fenced code blocks first (supports both ``` and ~~~)
123
- html = html.replace(/(?:```|~~~)([^\n]*)\n([\s\S]*?)(?:```|~~~)/g, (match, lang, code) => {
119
+ // Match paired fences - ``` with ``` and ~~~ with ~~~
120
+ // Fence must be at start of line
121
+ html = html.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm, (match, fence, lang, code) => {
124
122
  const placeholder = `%%%CODEBLOCK${codeBlocks.length}%%%`;
125
123
 
124
+ // Trim the language specification
125
+ const langTrimmed = lang ? lang.trim() : '';
126
+
126
127
  // If custom fence plugin is provided, use it
127
128
  if (fence_plugin && typeof fence_plugin === 'function') {
128
129
  codeBlocks.push({
129
- lang: lang || '',
130
+ lang: langTrimmed,
130
131
  code: code.trimEnd(),
131
132
  custom: true
132
133
  });
133
134
  } else {
134
135
  codeBlocks.push({
135
- lang: lang || '',
136
+ lang: langTrimmed,
136
137
  code: escapeHtml(code.trimEnd()),
137
138
  custom: false
138
139
  });
@@ -521,17 +522,17 @@ function processLists(text, inline_styles, styles) {
521
522
  */
522
523
  quikdown.emitStyles = function() {
523
524
  const styles = {
524
- h1: 'margin-top: 0.5em; margin-bottom: 0.3em',
525
- h2: 'margin-top: 0.5em; margin-bottom: 0.3em',
526
- h3: 'margin-top: 0.5em; margin-bottom: 0.3em',
527
- h4: 'margin-top: 0.5em; margin-bottom: 0.3em',
528
- h5: 'margin-top: 0.5em; margin-bottom: 0.3em',
529
- h6: 'margin-top: 0.5em; margin-bottom: 0.3em',
530
- pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',
531
- code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',
532
- blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',
525
+ h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',
526
+ h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',
527
+ h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',
528
+ h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',
529
+ h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',
530
+ h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',
531
+ pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',
532
+ code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',
533
+ blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',
533
534
  table: 'border-collapse: collapse; width: 100%; margin: 1em 0',
534
- th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold',
535
+ th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',
535
536
  td: 'border: 1px solid #ddd; padding: 8px; text-align: left',
536
537
  hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',
537
538
  img: 'max-width: 100%; height: auto',
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.0.1
3
+ * @version 1.0.2
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
7
- function e(e,t={}){if(!e||"string"!=typeof e)return"";const{fence_plugin:o,inline_styles:n=!1}=t,l="margin-top: 0.5em; margin-bottom: 0.3em",a="margin: 0.5em 0; padding-left: 2em",c="border: 1px solid #ddd; padding: 8px",i={h1:l,h2:l,h3:l,h4:l,h5:l,h6:l,pre:"background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto",code:"background: #f0f0f0; padding: 2px 4px; border-radius: 3px",blockquote:"border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666",table:"border-collapse: collapse; width: 100%; margin: 1em 0",thead:"",tbody:"",tr:"",th:c+"; background-color: #f2f2f2; font-weight: bold",td:c+"; text-align: left",hr:"border: none; border-top: 1px solid #ddd; margin: 1em 0",img:"max-width: 100%; height: auto",a:"color: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:a,ol:a,li:"margin: 0.25em 0",br:""};function s(e,t=""){if(n){const r=i[e]||"",o=t?`${r}; ${t}`:r;return o?` style="${o}"`:""}return` class="quikdown-${e}"`}function p(e){const t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return e.replace(/[&<>"']/g,e=>t[e])}function d(e,t=!1){if(!e)return"";if(t)return e;const r=e.trim(),o=r.toLowerCase(),n=["javascript:","vbscript:","data:"];for(const e of n)if(o.startsWith(e))return"data:"===e&&o.startsWith("data:image/")?r:"#";return r}let g=e;const u=[],$=[];return g=g.replace(/(?:```|~~~)([^\n]*)\n([\s\S]*?)(?:```|~~~)/g,(e,t,r)=>{const n=`%%%CODEBLOCK${u.length}%%%`;return o&&"function"==typeof o?u.push({lang:t||"",code:r.trimEnd(),custom:!0}):u.push({lang:t||"",code:p(r.trimEnd()),custom:!1}),n}),g=g.replace(/`([^`]+)`/g,(e,t)=>{const r=`%%%INLINECODE${$.length}%%%`;return $.push(p(t)),r}),g=p(g),g=function(e,t,o){const n=e.split("\n"),l=[];let a=!1,c=[];for(let e=0;e<n.length;e++){const i=n[e].trim();if(i.includes("|")&&(i.startsWith("|")||/[^\\|]/.test(i)))a||(a=!0,c=[]),c.push(i);else{if(a){const e=r(c,t,o);e?l.push(e):l.push(...c),a=!1,c=[]}l.push(n[e])}}if(a&&c.length>0){const e=r(c,t,o);e?l.push(e):l.push(...c)}return l.join("\n")}(g,n,i),g=g.replace(/^(#{1,6})\s+(.+?)\s*#*$/gm,(e,t,r)=>{const o=t.length;return`<h${o}${s("h"+o)}>${r}</h${o}>`}),g=g.replace(/^&gt;\s+(.+)$/gm,`<blockquote${s("blockquote")}>$1</blockquote>`),g=g.replace(/<\/blockquote>\n<blockquote>/g,"\n"),g=g.replace(/^---+$/gm,`<hr${s("hr")}>`),g=function(e,t,r){function o(e,o=""){if(t){const t=r[e]||"",n=o?`${t}; ${o}`:t;return n?` style="${n}"`:""}return` class="quikdown-${e}"`}const n=e.split("\n"),l=[];let a=[];for(let e=0;e<n.length;e++){const r=n[e],c=r.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(c){const[,e,r,n]=c,i=Math.floor(e.length/2),s=/^\d+\./.test(r),p=s?"ol":"ul";let d=n,g="";const u=n.match(/^\[([x ])\]\s+(.*)$/i);if(u&&!s){const[,e,r]=u,o="x"===e.toLowerCase();d=`<input type="checkbox"${t?' style="margin-right: 0.5em"':' class="quikdown-task-checkbox"'}${o?" checked":""} disabled> ${r}`,g=t?' style="list-style: none"':' class="quikdown-task-item"'}for(;a.length>i+1;){const e=a.pop();l.push(`</${e.type}>`)}if(a.length===i)a.push({type:p,level:i}),l.push(`<${p}${o(p)}>`);else if(a.length===i+1){const e=a[a.length-1];e.type!==p&&(l.push(`</${e.type}>`),a.pop(),a.push({type:p,level:i}),l.push(`<${p}${o(p)}>`))}const $=g||o("li");l.push(`<li${$}>${d}</li>`)}else{for(;a.length>0;){const e=a.pop();l.push(`</${e.type}>`)}l.push(r)}}for(;a.length>0;){const e=a.pop();l.push(`</${e.type}>`)}return l.join("\n")}(g,n,i),g=g.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,r,o)=>{const n=d(o,t.allow_unsafe_urls);return`<img${s("img")} src="${n}" alt="${r}">`}),g=g.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,r,o)=>{const n=d(o,t.allow_unsafe_urls),l=/^https?:\/\//i.test(n)?' rel="noopener noreferrer"':"";return`<a${s("a")} href="${n}"${l}>${r}</a>`}),g=g.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,r,o)=>{const n=d(o,t.allow_unsafe_urls);return`${r}<a${s("a")} href="${n}" rel="noopener noreferrer">${o}</a>`}),g=g.replace(/\*\*(.+?)\*\*/g,`<strong${s("strong")}>$1</strong>`),g=g.replace(/__(.+?)__/g,`<strong${s("strong")}>$1</strong>`),g=g.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${s("em")}>$1</em>`),g=g.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${s("em")}>$1</em>`),g=g.replace(/~~(.+?)~~/g,`<del${s("del")}>$1</del>`),g=g.replace(/ $/gm,`<br${s("br")}>`),g=g.replace(/\n\n+/g,"</p><p>"),g="<p>"+g+"</p>",g=g.replace(/<p><\/p>/g,""),g=g.replace(/<p>(<h[1-6][^>]*>)/g,"$1"),g=g.replace(/(<\/h[1-6]>)<\/p>/g,"$1"),g=g.replace(/<p>(<blockquote[^>]*>)/g,"$1"),g=g.replace(/(<\/blockquote>)<\/p>/g,"$1"),g=g.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"),g=g.replace(/(<\/ul>|<\/ol>)<\/p>/g,"$1"),g=g.replace(/<p>(<hr[^>]*>)<\/p>/g,"$1"),g=g.replace(/<p>(<table[^>]*>)/g,"$1"),g=g.replace(/(<\/table>)<\/p>/g,"$1"),g=g.replace(/<p>(<pre[^>]*>)/g,"$1"),g=g.replace(/(<\/pre>)<\/p>/g,"$1"),g=g.replace(/<p>(%%%CODEBLOCK\d+%%%)<\/p>/g,"$1"),u.forEach((e,t)=>{let r;if(e.custom&&o){if(r=o(e.code,e.lang),void 0===r){const t=!n&&e.lang?` class="language-${e.lang}"`:"",o=n?s("code"):t;r=`<pre${s("pre")}><code${o}>${p(e.code)}</code></pre>`}}else{const t=!n&&e.lang?` class="language-${e.lang}"`:"",o=n?s("code"):t;r=`<pre${s("pre")}><code${o}>${e.code}</code></pre>`}const l=`%%%CODEBLOCK${t}%%%`;g=g.replace(l,r)}),$.forEach((e,t)=>{const r=`%%%INLINECODE${t}%%%`;g=g.replace(r,`<code${s("code")}>${e}</code>`)}),g.trim()}function t(e,t,r){function o(e,o=""){if(t){const t=r[e]||"",n=o?`${t}; ${o}`:t;return n?` style="${n}"`:""}return` class="quikdown-${e}"`}return e=(e=(e=(e=(e=(e=e.replace(/\*\*(.+?)\*\*/g,`<strong${o("strong")}>$1</strong>`)).replace(/__(.+?)__/g,`<strong${o("strong")}>$1</strong>`)).replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${o("em")}>$1</em>`)).replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${o("em")}>$1</em>`)).replace(/~~(.+?)~~/g,`<del${o("del")}>$1</del>`)).replace(/`([^`]+)`/g,`<code${o("code")}>$1</code>`)}function r(e,r,o){function n(e,t=""){if(r){const r=o[e]||"",n=t?`${r}; ${t}`:r;return n?` style="${n}"`:""}return` class="quikdown-${e}"`}if(e.length<2)return null;let l=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){l=t;break}if(-1===l)return null;const a=e.slice(0,l),c=e.slice(l+1),i=e[l].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let s=`<table${n("table")}>\n`;return a.length>0&&(s+=`<thead${n("thead")}>\n`,a.forEach(e=>{s+=`<tr${n("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const a=i[l]&&"left"!==i[l]?`text-align: ${i[l]}`:"",c=t(e.trim(),r,o);s+=`<th${n("th",a)}>${c}</th>\n`}),s+="</tr>\n"}),s+="</thead>\n"),c.length>0&&(s+=`<tbody${n("tbody")}>\n`,c.forEach(e=>{s+=`<tr${n("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const a=i[l]&&"left"!==i[l]?`text-align: ${i[l]}`:"",c=t(e.trim(),r,o);s+=`<td${n("td",a)}>${c}</td>\n`}),s+="</tr>\n"}),s+="</tbody>\n"),s+="</table>",s}e.emitStyles=function(){const e={h1:"margin-top: 0.5em; margin-bottom: 0.3em",h2:"margin-top: 0.5em; margin-bottom: 0.3em",h3:"margin-top: 0.5em; margin-bottom: 0.3em",h4:"margin-top: 0.5em; margin-bottom: 0.3em",h5:"margin-top: 0.5em; margin-bottom: 0.3em",h6:"margin-top: 0.5em; margin-bottom: 0.3em",pre:"background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto",code:"background: #f0f0f0; padding: 2px 4px; border-radius: 3px",blockquote:"border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666",table:"border-collapse: collapse; width: 100%; margin: 1em 0",th:"border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold",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: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:"margin: 0.5em 0; padding-left: 2em",ol:"margin: 0.5em 0; padding-left: 2em",li:"margin: 0.25em 0","task-item":"list-style: none","task-checkbox":"margin-right: 0.5em"};let t="";for(const[r,o]of Object.entries(e))o&&(t+=`.quikdown-${r} { ${o} }\n`);return t},e.configure=function(t){return function(r){return e(r,t)}},e.version="1.0.1","undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.quikdown=e);export{e as default};
7
+ function e(e,t={}){if(!e||"string"!=typeof e)return"";const{fence_plugin:r,inline_styles:o=!1}=t,l={h1:"font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left",h2:"font-size: 1.5em; font-weight: 600; margin: 0.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: 0.875em; font-weight: 600; margin: 1.67em 0",h6:"font-size: 0.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",thead:"",tbody:"",tr:"",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: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:"margin: 0.5em 0; padding-left: 2em",ol:"margin: 0.5em 0; padding-left: 2em",li:"margin: 0.25em 0",br:""};function i(e,t=""){if(o){const n=l[e]||"",r=t?`${n}; ${t}`:n;return r?` style="${r}"`:""}return` class="quikdown-${e}"`}function a(e){const t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return e.replace(/[&<>"']/g,e=>t[e])}function s(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=e;const p=[],d=[];return c=c.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,t,n,o)=>{const l=`%%%CODEBLOCK${p.length}%%%`,i=n?n.trim():"";return r&&"function"==typeof r?p.push({lang:i,code:o.trimEnd(),custom:!0}):p.push({lang:i,code:a(o.trimEnd()),custom:!1}),l}),c=c.replace(/`([^`]+)`/g,(e,t)=>{const n=`%%%INLINECODE${d.length}%%%`;return d.push(a(t)),n}),c=a(c),c=function(e,t,r){const o=e.split("\n"),l=[];let i=!1,a=[];for(let e=0;e<o.length;e++){const s=o[e].trim();if(s.includes("|")&&(s.startsWith("|")||/[^\\|]/.test(s)))i||(i=!0,a=[]),a.push(s);else{if(i){const e=n(a,t,r);e?l.push(e):l.push(...a),i=!1,a=[]}l.push(o[e])}}if(i&&a.length>0){const e=n(a,t,r);e?l.push(e):l.push(...a)}return l.join("\n")}(c,o,l),c=c.replace(/^(#{1,6})\s+(.+?)\s*#*$/gm,(e,t,n)=>{const r=t.length;return`<h${r}${i("h"+r)}>${n}</h${r}>`}),c=c.replace(/^&gt;\s+(.+)$/gm,`<blockquote${i("blockquote")}>$1</blockquote>`),c=c.replace(/<\/blockquote>\n<blockquote>/g,"\n"),c=c.replace(/^---+$/gm,`<hr${i("hr")}>`),c=function(e,t,n){function r(e,r=""){if(t){const t=n[e]||"",o=r?`${t}; ${r}`:t;return o?` style="${o}"`:""}return` class="quikdown-${e}"`}const o=e.split("\n"),l=[];let i=[];for(let e=0;e<o.length;e++){const n=o[e],a=n.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(a){const[,e,n,o]=a,s=Math.floor(e.length/2),c=/^\d+\./.test(n),p=c?"ol":"ul";let d=o,g="";const f=o.match(/^\[([x ])\]\s+(.*)$/i);if(f&&!c){const[,e,n]=f,r="x"===e.toLowerCase();d=`<input type="checkbox"${t?' style="margin-right: 0.5em"':' class="quikdown-task-checkbox"'}${r?" checked":""} disabled> ${n}`,g=t?' style="list-style: none"':' class="quikdown-task-item"'}for(;i.length>s+1;){const e=i.pop();l.push(`</${e.type}>`)}if(i.length===s)i.push({type:p,level:s}),l.push(`<${p}${r(p)}>`);else if(i.length===s+1){const e=i[i.length-1];e.type!==p&&(l.push(`</${e.type}>`),i.pop(),i.push({type:p,level:s}),l.push(`<${p}${r(p)}>`))}const u=g||r("li");l.push(`<li${u}>${d}</li>`)}else{for(;i.length>0;){const e=i.pop();l.push(`</${e.type}>`)}l.push(n)}}for(;i.length>0;){const e=i.pop();l.push(`</${e.type}>`)}return l.join("\n")}(c,o,l),c=c.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,n,r)=>{const o=s(r,t.allow_unsafe_urls);return`<img${i("img")} src="${o}" alt="${n}">`}),c=c.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,n,r)=>{const o=s(r,t.allow_unsafe_urls),l=/^https?:\/\//i.test(o)?' rel="noopener noreferrer"':"";return`<a${i("a")} href="${o}"${l}>${n}</a>`}),c=c.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,n,r)=>{const o=s(r,t.allow_unsafe_urls);return`${n}<a${i("a")} href="${o}" rel="noopener noreferrer">${r}</a>`}),c=c.replace(/\*\*(.+?)\*\*/g,`<strong${i("strong")}>$1</strong>`),c=c.replace(/__(.+?)__/g,`<strong${i("strong")}>$1</strong>`),c=c.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${i("em")}>$1</em>`),c=c.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${i("em")}>$1</em>`),c=c.replace(/~~(.+?)~~/g,`<del${i("del")}>$1</del>`),c=c.replace(/ $/gm,`<br${i("br")}>`),c=c.replace(/\n\n+/g,"</p><p>"),c="<p>"+c+"</p>",c=c.replace(/<p><\/p>/g,""),c=c.replace(/<p>(<h[1-6][^>]*>)/g,"$1"),c=c.replace(/(<\/h[1-6]>)<\/p>/g,"$1"),c=c.replace(/<p>(<blockquote[^>]*>)/g,"$1"),c=c.replace(/(<\/blockquote>)<\/p>/g,"$1"),c=c.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"),c=c.replace(/(<\/ul>|<\/ol>)<\/p>/g,"$1"),c=c.replace(/<p>(<hr[^>]*>)<\/p>/g,"$1"),c=c.replace(/<p>(<table[^>]*>)/g,"$1"),c=c.replace(/(<\/table>)<\/p>/g,"$1"),c=c.replace(/<p>(<pre[^>]*>)/g,"$1"),c=c.replace(/(<\/pre>)<\/p>/g,"$1"),c=c.replace(/<p>(%%%CODEBLOCK\d+%%%)<\/p>/g,"$1"),p.forEach((e,t)=>{let n;if(e.custom&&r){if(n=r(e.code,e.lang),void 0===n){const t=!o&&e.lang?` class="language-${e.lang}"`:"",r=o?i("code"):t;n=`<pre${i("pre")}><code${r}>${a(e.code)}</code></pre>`}}else{const t=!o&&e.lang?` class="language-${e.lang}"`:"",r=o?i("code"):t;n=`<pre${i("pre")}><code${r}>${e.code}</code></pre>`}const l=`%%%CODEBLOCK${t}%%%`;c=c.replace(l,n)}),d.forEach((e,t)=>{const n=`%%%INLINECODE${t}%%%`;c=c.replace(n,`<code${i("code")}>${e}</code>`)}),c.trim()}function t(e,t,n){function r(e,r=""){if(t){const t=n[e]||"",o=r?`${t}; ${r}`:t;return o?` style="${o}"`:""}return` class="quikdown-${e}"`}return e=(e=(e=(e=(e=(e=e.replace(/\*\*(.+?)\*\*/g,`<strong${r("strong")}>$1</strong>`)).replace(/__(.+?)__/g,`<strong${r("strong")}>$1</strong>`)).replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${r("em")}>$1</em>`)).replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${r("em")}>$1</em>`)).replace(/~~(.+?)~~/g,`<del${r("del")}>$1</del>`)).replace(/`([^`]+)`/g,`<code${r("code")}>$1</code>`)}function n(e,n,r){function o(e,t=""){if(n){const n=r[e]||"",o=t?`${n}; ${t}`:n;return o?` style="${o}"`:""}return` class="quikdown-${e}"`}if(e.length<2)return null;let l=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){l=t;break}if(-1===l)return null;const i=e.slice(0,l),a=e.slice(l+1),s=e[l].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let c=`<table${o("table")}>\n`;return i.length>0&&(c+=`<thead${o("thead")}>\n`,i.forEach(e=>{c+=`<tr${o("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const i=s[l]&&"left"!==s[l]?`text-align: ${s[l]}`:"",a=t(e.trim(),n,r);c+=`<th${o("th",i)}>${a}</th>\n`}),c+="</tr>\n"}),c+="</thead>\n"),a.length>0&&(c+=`<tbody${o("tbody")}>\n`,a.forEach(e=>{c+=`<tr${o("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const i=s[l]&&"left"!==s[l]?`text-align: ${s[l]}`:"",a=t(e.trim(),n,r);c+=`<td${o("td",i)}>${a}</td>\n`}),c+="</tr>\n"}),c+="</tbody>\n"),c+="</table>",c}e.emitStyles=function(){const e={h1:"font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left",h2:"font-size: 1.5em; font-weight: 600; margin: 0.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: 0.875em; font-weight: 600; margin: 1.67em 0",h6:"font-size: 0.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: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:"margin: 0.5em 0; padding-left: 2em",ol:"margin: 0.5em 0; padding-left: 2em",li:"margin: 0.25em 0","task-item":"list-style: none","task-checkbox":"margin-right: 0.5em"};let t="";for(const[n,r]of Object.entries(e))r&&(t+=`.quikdown-${n} { ${r} }\n`);return t},e.configure=function(t){return function(n){return e(n,t)}},e.version="1.0.2","undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.quikdown=e);export{e as default};
8
8
  //# sourceMappingURL=quikdown.esm.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"quikdown.esm.min.js","sources":["../src/quikdown.js","../src/quikdown_version.js"],"sourcesContent":["/**\n * quikdown - A minimal markdown parser optimized for chat/LLM output\n * Supports tables, code blocks, lists, and common formatting\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @param {Function} options.fence_plugin - Custom renderer for fenced code blocks\n * (content, fence_string) => html string\n * @param {boolean} options.inline_styles - If true, uses inline styles instead of classes\n * @returns {string} - The rendered HTML\n */\n\nimport quikdownVersion from './quikdown_version.js';\n\nfunction quikdown(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return '';\n }\n \n const { fence_plugin, inline_styles = false } = options;\n\n // Style definitions - deduplicated to save space\n const headingStyle = 'margin-top: 0.5em; margin-bottom: 0.3em';\n const listStyle = 'margin: 0.5em 0; padding-left: 2em';\n const cellBorder = 'border: 1px solid #ddd; padding: 8px';\n \n const styles = {\n h1: headingStyle,\n h2: headingStyle,\n h3: headingStyle,\n h4: headingStyle,\n h5: headingStyle,\n h6: headingStyle,\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n thead: '',\n tbody: '',\n tr: '',\n th: cellBorder + '; background-color: #f2f2f2; font-weight: bold',\n td: cellBorder + '; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: listStyle,\n ol: listStyle,\n li: 'margin: 0.25em 0',\n br: ''\n };\n\n // Helper to get class or style attribute\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n\n // Escape HTML entities to prevent XSS\n function escapeHtml(text) {\n const map = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;'\n };\n return text.replace(/[&<>\"']/g, m => map[m]);\n }\n \n // Sanitize URLs to prevent XSS attacks\n function sanitizeUrl(url, allowUnsafe = false) {\n if (!url) return '';\n \n // If unsafe URLs are explicitly allowed, return as-is\n if (allowUnsafe) return url;\n \n // Trim and lowercase for checking\n const trimmedUrl = url.trim();\n const lowerUrl = trimmedUrl.toLowerCase();\n \n // Block dangerous protocols\n const dangerousProtocols = ['javascript:', 'vbscript:', 'data:'];\n \n for (const protocol of dangerousProtocols) {\n if (lowerUrl.startsWith(protocol)) {\n // Exception: Allow data:image/* for images\n if (protocol === 'data:' && lowerUrl.startsWith('data:image/')) {\n return trimmedUrl;\n }\n // Return safe empty link for dangerous protocols\n return '#';\n }\n }\n \n return trimmedUrl;\n }\n\n // Process the markdown in phases\n let html = markdown;\n \n // Phase 1: Extract and protect code blocks and inline code\n const codeBlocks = [];\n const inlineCodes = [];\n \n // Extract fenced code blocks first (supports both ``` and ~~~)\n html = html.replace(/(?:```|~~~)([^\\n]*)\\n([\\s\\S]*?)(?:```|~~~)/g, (match, lang, code) => {\n const placeholder = `%%%CODEBLOCK${codeBlocks.length}%%%`;\n \n // If custom fence plugin is provided, use it\n if (fence_plugin && typeof fence_plugin === 'function') {\n codeBlocks.push({\n lang: lang || '',\n code: code.trimEnd(),\n custom: true\n });\n } else {\n codeBlocks.push({\n lang: lang || '',\n code: escapeHtml(code.trimEnd()),\n custom: false\n });\n }\n return placeholder;\n });\n \n // Extract inline code\n html = html.replace(/`([^`]+)`/g, (match, code) => {\n const placeholder = `%%%INLINECODE${inlineCodes.length}%%%`;\n inlineCodes.push(escapeHtml(code));\n return placeholder;\n });\n \n // Now escape HTML in the rest of the content\n html = escapeHtml(html);\n \n // Phase 2: Process block elements\n \n // Process tables\n html = processTable(html, inline_styles, styles);\n \n // Process headings (supports optional trailing #'s)\n html = html.replace(/^(#{1,6})\\s+(.+?)\\s*#*$/gm, (match, hashes, content) => {\n const level = hashes.length;\n return `<h${level}${getAttr('h' + level)}>${content}</h${level}>`;\n });\n \n // Process blockquotes (must handle escaped > since we already escaped HTML)\n html = html.replace(/^&gt;\\s+(.+)$/gm, `<blockquote${getAttr('blockquote')}>$1</blockquote>`);\n // Merge consecutive blockquotes\n html = html.replace(/<\\/blockquote>\\n<blockquote>/g, '\\n');\n \n // Process horizontal rules\n html = html.replace(/^---+$/gm, `<hr${getAttr('hr')}>`);\n \n // Process lists\n html = processLists(html, inline_styles, styles);\n \n // Phase 3: Process inline elements\n \n // Images (must come before links, with URL sanitization)\n html = html.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (match, alt, src) => {\n const sanitizedSrc = sanitizeUrl(src, options.allow_unsafe_urls);\n return `<img${getAttr('img')} src=\"${sanitizedSrc}\" alt=\"${alt}\">`;\n });\n \n // Links (with URL sanitization)\n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (match, text, href) => {\n // Sanitize URL to prevent XSS\n const sanitizedHref = sanitizeUrl(href, options.allow_unsafe_urls);\n const isExternal = /^https?:\\/\\//i.test(sanitizedHref);\n const rel = isExternal ? ' rel=\"noopener noreferrer\"' : '';\n return `<a${getAttr('a')} href=\"${sanitizedHref}\"${rel}>${text}</a>`;\n });\n \n // Autolinks - convert bare URLs to clickable links\n html = html.replace(/(^|\\s)(https?:\\/\\/[^\\s<]+)/g, (match, prefix, url) => {\n const sanitizedUrl = sanitizeUrl(url, options.allow_unsafe_urls);\n return `${prefix}<a${getAttr('a')} href=\"${sanitizedUrl}\" rel=\"noopener noreferrer\">${url}</a>`;\n });\n \n // Bold (must use non-greedy matching)\n html = html.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n html = html.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Italic (must not match bold markers)\n html = html.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n html = html.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Strikethrough\n html = html.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Line breaks (two spaces at end of line)\n html = html.replace(/ $/gm, `<br${getAttr('br')}>`);\n \n // Paragraphs (double newlines)\n html = html.replace(/\\n\\n+/g, '</p><p>');\n html = '<p>' + html + '</p>';\n \n // Clean up empty paragraphs and unwrap block elements (account for attributes)\n html = html.replace(/<p><\\/p>/g, '');\n html = html.replace(/<p>(<h[1-6][^>]*>)/g, '$1');\n html = html.replace(/(<\\/h[1-6]>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<blockquote[^>]*>)/g, '$1');\n html = html.replace(/(<\\/blockquote>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g, '$1');\n html = html.replace(/(<\\/ul>|<\\/ol>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<hr[^>]*>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<table[^>]*>)/g, '$1');\n html = html.replace(/(<\\/table>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<pre[^>]*>)/g, '$1');\n html = html.replace(/(<\\/pre>)<\\/p>/g, '$1');\n // Also unwrap code block placeholders\n html = html.replace(/<p>(%%%CODEBLOCK\\d+%%%)<\\/p>/g, '$1');\n \n // Phase 4: Restore code blocks and inline code\n \n // Restore code blocks\n codeBlocks.forEach((block, i) => {\n let replacement;\n \n if (block.custom && fence_plugin) {\n // Use custom fence plugin\n replacement = fence_plugin(block.code, block.lang);\n // If plugin returns undefined, fall back to default rendering\n if (replacement === undefined) {\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${escapeHtml(block.code)}</code></pre>`;\n }\n } else {\n // Default rendering\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${block.code}</code></pre>`;\n }\n \n const placeholder = `%%%CODEBLOCK${i}%%%`;\n html = html.replace(placeholder, replacement);\n });\n \n // Restore inline code\n inlineCodes.forEach((code, i) => {\n const placeholder = `%%%INLINECODE${i}%%%`;\n html = html.replace(placeholder, `<code${getAttr('code')}>${code}</code>`);\n });\n \n return html.trim();\n}\n\n/**\n * Process inline markdown formatting\n */\nfunction processInlineMarkdown(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n // Process bold\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n text = text.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Process italic (must not match bold markers)\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n text = text.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Process strikethrough\n text = text.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Process inline code\n text = text.replace(/`([^`]+)`/g, `<code${getAttr('code')}>$1</code>`);\n \n return text;\n}\n\n/**\n * Process markdown tables\n */\nfunction processTable(text, inline_styles, styles) {\n const lines = text.split('\\n');\n const result = [];\n let inTable = false;\n let tableLines = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Check if this line looks like a table row (with or without trailing |)\n if (line.includes('|') && (line.startsWith('|') || /[^\\\\|]/.test(line))) {\n if (!inTable) {\n inTable = true;\n tableLines = [];\n }\n tableLines.push(line);\n } else {\n // Not a table line\n if (inTable) {\n // Process the accumulated table\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n // Not a valid table, restore original lines\n result.push(...tableLines);\n }\n inTable = false;\n tableLines = [];\n }\n result.push(lines[i]);\n }\n }\n \n // Handle table at end of text\n if (inTable && tableLines.length > 0) {\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n result.push(...tableLines);\n }\n }\n \n return result.join('\\n');\n}\n\n/**\n * Build an HTML table from markdown table lines\n */\nfunction buildTable(lines, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n if (lines.length < 2) return null;\n \n // Check for separator line (second line should be the separator)\n let separatorIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n // Support separator with or without leading/trailing pipes\n if (/^\\|?[\\s\\-:|]+\\|?$/.test(lines[i]) && lines[i].includes('-')) {\n separatorIndex = i;\n break;\n }\n }\n \n if (separatorIndex === -1) return null;\n \n const headerLines = lines.slice(0, separatorIndex);\n const bodyLines = lines.slice(separatorIndex + 1);\n \n // Parse alignment from separator\n const separator = lines[separatorIndex];\n // Handle pipes at start/end or not\n const separatorCells = separator.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n const alignments = separatorCells.map(cell => {\n const trimmed = cell.trim();\n if (trimmed.startsWith(':') && trimmed.endsWith(':')) return 'center';\n if (trimmed.endsWith(':')) return 'right';\n return 'left';\n });\n \n let html = `<table${getAttr('table')}>\\n`;\n \n // Build header\n if (headerLines.length > 0) {\n html += `<thead${getAttr('thead')}>\\n`;\n headerLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<th${getAttr('th', alignStyle)}>${processedCell}</th>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</thead>\\n';\n }\n \n // Build body\n if (bodyLines.length > 0) {\n html += `<tbody${getAttr('tbody')}>\\n`;\n bodyLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<td${getAttr('td', alignStyle)}>${processedCell}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n \n html += '</table>';\n return html;\n}\n\n/**\n * Process markdown lists (ordered and unordered)\n */\nfunction processLists(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n const lines = text.split('\\n');\n const result = [];\n let listStack = []; // Track nested lists\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.+)$/);\n \n if (match) {\n const [, indent, marker, content] = match;\n const level = Math.floor(indent.length / 2);\n const isOrdered = /^\\d+\\./.test(marker);\n const listType = isOrdered ? 'ol' : 'ul';\n \n // Check for task list items\n let listItemContent = content;\n let taskListClass = '';\n const taskMatch = content.match(/^\\[([x ])\\]\\s+(.*)$/i);\n if (taskMatch && !isOrdered) {\n const [, checked, taskContent] = taskMatch;\n const isChecked = checked.toLowerCase() === 'x';\n const checkboxAttr = inline_styles \n ? ' style=\"margin-right: 0.5em\"' \n : ' class=\"quikdown-task-checkbox\"';\n listItemContent = `<input type=\"checkbox\"${checkboxAttr}${isChecked ? ' checked' : ''} disabled> ${taskContent}`;\n taskListClass = inline_styles ? ' style=\"list-style: none\"' : ' class=\"quikdown-task-item\"';\n }\n \n // Close deeper levels\n while (listStack.length > level + 1) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n // Open new level if needed\n if (listStack.length === level) {\n // Need to open a new list\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n } else if (listStack.length === level + 1) {\n // Check if we need to switch list type\n const currentList = listStack[listStack.length - 1];\n if (currentList.type !== listType) {\n result.push(`</${currentList.type}>`);\n listStack.pop();\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n }\n }\n \n const liAttr = taskListClass || getAttr('li');\n result.push(`<li${liAttr}>${listItemContent}</li>`);\n } else {\n // Not a list item, close all lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n result.push(line);\n }\n }\n \n // Close any remaining lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n return result.join('\\n');\n}\n\n/**\n * Emit CSS styles for quikdown elements\n * @returns {string} CSS string with quikdown styles\n */\nquikdown.emitStyles = function() {\n const styles = {\n h1: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h2: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h3: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h4: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h5: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h6: 'margin-top: 0.5em; margin-bottom: 0.3em',\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold',\n td: 'border: 1px solid #ddd; padding: 8px; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: 'margin: 0.5em 0; padding-left: 2em',\n ol: 'margin: 0.5em 0; padding-left: 2em',\n li: 'margin: 0.25em 0',\n 'task-item': 'list-style: none',\n 'task-checkbox': 'margin-right: 0.5em'\n };\n \n let css = '';\n for (const [tag, style] of Object.entries(styles)) {\n if (style) {\n css += `.quikdown-${tag} { ${style} }\\n`;\n }\n }\n \n return css;\n};\n\n/**\n * Configure quikdown with options and return a function\n * @param {Object} options - Configuration options\n * @returns {Function} Configured quikdown function\n */\nquikdown.configure = function(options) {\n return function(markdown) {\n return quikdown(markdown, options);\n };\n};\n\n/**\n * Version information\n */\nquikdown.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown;\n}\n\n// For browser global\nif (typeof window !== 'undefined') {\n window.quikdown = quikdown;\n}\n\nexport default quikdown;","// Auto-generated version file - DO NOT EDIT MANUALLY\n// This file is automatically updated by tools/updateVersion.js\n\nexport const quikdownVersion = \"1.0.1\";\n\nexport default quikdownVersion;"],"names":["quikdown","markdown","options","fence_plugin","inline_styles","headingStyle","listStyle","cellBorder","styles","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","thead","tbody","tr","th","td","hr","img","a","strong","em","del","ul","ol","li","br","getAttr","tag","additionalStyle","style","fullStyle","escapeHtml","text","map","replace","m","sanitizeUrl","url","allowUnsafe","trimmedUrl","trim","lowerUrl","toLowerCase","dangerousProtocols","protocol","startsWith","html","codeBlocks","inlineCodes","match","lang","placeholder","length","push","trimEnd","custom","lines","split","result","inTable","tableLines","i","line","includes","test","tableHtml","buildTable","join","processTable","hashes","content","level","listStack","indent","marker","Math","floor","isOrdered","listType","listItemContent","taskListClass","taskMatch","checked","taskContent","isChecked","list","pop","type","currentList","liAttr","processLists","alt","src","sanitizedSrc","allow_unsafe_urls","href","sanitizedHref","rel","prefix","sanitizedUrl","forEach","block","replacement","undefined","langClass","codeAttr","processInlineMarkdown","separatorIndex","headerLines","slice","bodyLines","alignments","cell","trimmed","endsWith","alignStyle","processedCell","emitStyles","css","Object","entries","configure","version","module","exports","window"],"mappings":"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"}
1
+ {"version":3,"file":"quikdown.esm.min.js","sources":["../src/quikdown.js","../src/quikdown_version.js"],"sourcesContent":["/**\n * quikdown - A minimal markdown parser optimized for chat/LLM output\n * Supports tables, code blocks, lists, and common formatting\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @param {Function} options.fence_plugin - Custom renderer for fenced code blocks\n * (content, fence_string) => html string\n * @param {boolean} options.inline_styles - If true, uses inline styles instead of classes\n * @returns {string} - The rendered HTML\n */\n\nimport quikdownVersion from './quikdown_version.js';\n\nfunction quikdown(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return '';\n }\n \n const { fence_plugin, inline_styles = false } = options;\n\n // Style definitions - minimal, matching emitStyles\n const styles = {\n h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',\n h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',\n h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',\n h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',\n h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',\n h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n thead: '',\n tbody: '',\n tr: '',\n th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',\n td: 'border: 1px solid #ddd; padding: 8px; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: 'margin: 0.5em 0; padding-left: 2em',\n ol: 'margin: 0.5em 0; padding-left: 2em',\n li: 'margin: 0.25em 0',\n br: ''\n };\n\n // Helper to get class or style attribute\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n\n // Escape HTML entities to prevent XSS\n function escapeHtml(text) {\n const map = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;'\n };\n return text.replace(/[&<>\"']/g, m => map[m]);\n }\n \n // Sanitize URLs to prevent XSS attacks\n function sanitizeUrl(url, allowUnsafe = false) {\n if (!url) return '';\n \n // If unsafe URLs are explicitly allowed, return as-is\n if (allowUnsafe) return url;\n \n // Trim and lowercase for checking\n const trimmedUrl = url.trim();\n const lowerUrl = trimmedUrl.toLowerCase();\n \n // Block dangerous protocols\n const dangerousProtocols = ['javascript:', 'vbscript:', 'data:'];\n \n for (const protocol of dangerousProtocols) {\n if (lowerUrl.startsWith(protocol)) {\n // Exception: Allow data:image/* for images\n if (protocol === 'data:' && lowerUrl.startsWith('data:image/')) {\n return trimmedUrl;\n }\n // Return safe empty link for dangerous protocols\n return '#';\n }\n }\n \n return trimmedUrl;\n }\n\n // Process the markdown in phases\n let html = markdown;\n \n // Phase 1: Extract and protect code blocks and inline code\n const codeBlocks = [];\n const inlineCodes = [];\n \n // Extract fenced code blocks first (supports both ``` and ~~~)\n // Match paired fences - ``` with ``` and ~~~ with ~~~\n // Fence must be at start of line\n html = html.replace(/^(```|~~~)([^\\n]*)\\n([\\s\\S]*?)^\\1$/gm, (match, fence, lang, code) => {\n const placeholder = `%%%CODEBLOCK${codeBlocks.length}%%%`;\n \n // Trim the language specification\n const langTrimmed = lang ? lang.trim() : '';\n \n // If custom fence plugin is provided, use it\n if (fence_plugin && typeof fence_plugin === 'function') {\n codeBlocks.push({\n lang: langTrimmed,\n code: code.trimEnd(),\n custom: true\n });\n } else {\n codeBlocks.push({\n lang: langTrimmed,\n code: escapeHtml(code.trimEnd()),\n custom: false\n });\n }\n return placeholder;\n });\n \n // Extract inline code\n html = html.replace(/`([^`]+)`/g, (match, code) => {\n const placeholder = `%%%INLINECODE${inlineCodes.length}%%%`;\n inlineCodes.push(escapeHtml(code));\n return placeholder;\n });\n \n // Now escape HTML in the rest of the content\n html = escapeHtml(html);\n \n // Phase 2: Process block elements\n \n // Process tables\n html = processTable(html, inline_styles, styles);\n \n // Process headings (supports optional trailing #'s)\n html = html.replace(/^(#{1,6})\\s+(.+?)\\s*#*$/gm, (match, hashes, content) => {\n const level = hashes.length;\n return `<h${level}${getAttr('h' + level)}>${content}</h${level}>`;\n });\n \n // Process blockquotes (must handle escaped > since we already escaped HTML)\n html = html.replace(/^&gt;\\s+(.+)$/gm, `<blockquote${getAttr('blockquote')}>$1</blockquote>`);\n // Merge consecutive blockquotes\n html = html.replace(/<\\/blockquote>\\n<blockquote>/g, '\\n');\n \n // Process horizontal rules\n html = html.replace(/^---+$/gm, `<hr${getAttr('hr')}>`);\n \n // Process lists\n html = processLists(html, inline_styles, styles);\n \n // Phase 3: Process inline elements\n \n // Images (must come before links, with URL sanitization)\n html = html.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (match, alt, src) => {\n const sanitizedSrc = sanitizeUrl(src, options.allow_unsafe_urls);\n return `<img${getAttr('img')} src=\"${sanitizedSrc}\" alt=\"${alt}\">`;\n });\n \n // Links (with URL sanitization)\n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (match, text, href) => {\n // Sanitize URL to prevent XSS\n const sanitizedHref = sanitizeUrl(href, options.allow_unsafe_urls);\n const isExternal = /^https?:\\/\\//i.test(sanitizedHref);\n const rel = isExternal ? ' rel=\"noopener noreferrer\"' : '';\n return `<a${getAttr('a')} href=\"${sanitizedHref}\"${rel}>${text}</a>`;\n });\n \n // Autolinks - convert bare URLs to clickable links\n html = html.replace(/(^|\\s)(https?:\\/\\/[^\\s<]+)/g, (match, prefix, url) => {\n const sanitizedUrl = sanitizeUrl(url, options.allow_unsafe_urls);\n return `${prefix}<a${getAttr('a')} href=\"${sanitizedUrl}\" rel=\"noopener noreferrer\">${url}</a>`;\n });\n \n // Bold (must use non-greedy matching)\n html = html.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n html = html.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Italic (must not match bold markers)\n html = html.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n html = html.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Strikethrough\n html = html.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Line breaks (two spaces at end of line)\n html = html.replace(/ $/gm, `<br${getAttr('br')}>`);\n \n // Paragraphs (double newlines)\n html = html.replace(/\\n\\n+/g, '</p><p>');\n html = '<p>' + html + '</p>';\n \n // Clean up empty paragraphs and unwrap block elements (account for attributes)\n html = html.replace(/<p><\\/p>/g, '');\n html = html.replace(/<p>(<h[1-6][^>]*>)/g, '$1');\n html = html.replace(/(<\\/h[1-6]>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<blockquote[^>]*>)/g, '$1');\n html = html.replace(/(<\\/blockquote>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g, '$1');\n html = html.replace(/(<\\/ul>|<\\/ol>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<hr[^>]*>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<table[^>]*>)/g, '$1');\n html = html.replace(/(<\\/table>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<pre[^>]*>)/g, '$1');\n html = html.replace(/(<\\/pre>)<\\/p>/g, '$1');\n // Also unwrap code block placeholders\n html = html.replace(/<p>(%%%CODEBLOCK\\d+%%%)<\\/p>/g, '$1');\n \n // Phase 4: Restore code blocks and inline code\n \n // Restore code blocks\n codeBlocks.forEach((block, i) => {\n let replacement;\n \n if (block.custom && fence_plugin) {\n // Use custom fence plugin\n replacement = fence_plugin(block.code, block.lang);\n // If plugin returns undefined, fall back to default rendering\n if (replacement === undefined) {\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${escapeHtml(block.code)}</code></pre>`;\n }\n } else {\n // Default rendering\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${block.code}</code></pre>`;\n }\n \n const placeholder = `%%%CODEBLOCK${i}%%%`;\n html = html.replace(placeholder, replacement);\n });\n \n // Restore inline code\n inlineCodes.forEach((code, i) => {\n const placeholder = `%%%INLINECODE${i}%%%`;\n html = html.replace(placeholder, `<code${getAttr('code')}>${code}</code>`);\n });\n \n return html.trim();\n}\n\n/**\n * Process inline markdown formatting\n */\nfunction processInlineMarkdown(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n // Process bold\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n text = text.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Process italic (must not match bold markers)\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n text = text.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Process strikethrough\n text = text.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Process inline code\n text = text.replace(/`([^`]+)`/g, `<code${getAttr('code')}>$1</code>`);\n \n return text;\n}\n\n/**\n * Process markdown tables\n */\nfunction processTable(text, inline_styles, styles) {\n const lines = text.split('\\n');\n const result = [];\n let inTable = false;\n let tableLines = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Check if this line looks like a table row (with or without trailing |)\n if (line.includes('|') && (line.startsWith('|') || /[^\\\\|]/.test(line))) {\n if (!inTable) {\n inTable = true;\n tableLines = [];\n }\n tableLines.push(line);\n } else {\n // Not a table line\n if (inTable) {\n // Process the accumulated table\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n // Not a valid table, restore original lines\n result.push(...tableLines);\n }\n inTable = false;\n tableLines = [];\n }\n result.push(lines[i]);\n }\n }\n \n // Handle table at end of text\n if (inTable && tableLines.length > 0) {\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n result.push(...tableLines);\n }\n }\n \n return result.join('\\n');\n}\n\n/**\n * Build an HTML table from markdown table lines\n */\nfunction buildTable(lines, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n if (lines.length < 2) return null;\n \n // Check for separator line (second line should be the separator)\n let separatorIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n // Support separator with or without leading/trailing pipes\n if (/^\\|?[\\s\\-:|]+\\|?$/.test(lines[i]) && lines[i].includes('-')) {\n separatorIndex = i;\n break;\n }\n }\n \n if (separatorIndex === -1) return null;\n \n const headerLines = lines.slice(0, separatorIndex);\n const bodyLines = lines.slice(separatorIndex + 1);\n \n // Parse alignment from separator\n const separator = lines[separatorIndex];\n // Handle pipes at start/end or not\n const separatorCells = separator.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n const alignments = separatorCells.map(cell => {\n const trimmed = cell.trim();\n if (trimmed.startsWith(':') && trimmed.endsWith(':')) return 'center';\n if (trimmed.endsWith(':')) return 'right';\n return 'left';\n });\n \n let html = `<table${getAttr('table')}>\\n`;\n \n // Build header\n if (headerLines.length > 0) {\n html += `<thead${getAttr('thead')}>\\n`;\n headerLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<th${getAttr('th', alignStyle)}>${processedCell}</th>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</thead>\\n';\n }\n \n // Build body\n if (bodyLines.length > 0) {\n html += `<tbody${getAttr('tbody')}>\\n`;\n bodyLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<td${getAttr('td', alignStyle)}>${processedCell}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n \n html += '</table>';\n return html;\n}\n\n/**\n * Process markdown lists (ordered and unordered)\n */\nfunction processLists(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n const lines = text.split('\\n');\n const result = [];\n let listStack = []; // Track nested lists\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.+)$/);\n \n if (match) {\n const [, indent, marker, content] = match;\n const level = Math.floor(indent.length / 2);\n const isOrdered = /^\\d+\\./.test(marker);\n const listType = isOrdered ? 'ol' : 'ul';\n \n // Check for task list items\n let listItemContent = content;\n let taskListClass = '';\n const taskMatch = content.match(/^\\[([x ])\\]\\s+(.*)$/i);\n if (taskMatch && !isOrdered) {\n const [, checked, taskContent] = taskMatch;\n const isChecked = checked.toLowerCase() === 'x';\n const checkboxAttr = inline_styles \n ? ' style=\"margin-right: 0.5em\"' \n : ' class=\"quikdown-task-checkbox\"';\n listItemContent = `<input type=\"checkbox\"${checkboxAttr}${isChecked ? ' checked' : ''} disabled> ${taskContent}`;\n taskListClass = inline_styles ? ' style=\"list-style: none\"' : ' class=\"quikdown-task-item\"';\n }\n \n // Close deeper levels\n while (listStack.length > level + 1) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n // Open new level if needed\n if (listStack.length === level) {\n // Need to open a new list\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n } else if (listStack.length === level + 1) {\n // Check if we need to switch list type\n const currentList = listStack[listStack.length - 1];\n if (currentList.type !== listType) {\n result.push(`</${currentList.type}>`);\n listStack.pop();\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n }\n }\n \n const liAttr = taskListClass || getAttr('li');\n result.push(`<li${liAttr}>${listItemContent}</li>`);\n } else {\n // Not a list item, close all lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n result.push(line);\n }\n }\n \n // Close any remaining lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n return result.join('\\n');\n}\n\n/**\n * Emit CSS styles for quikdown elements\n * @returns {string} CSS string with quikdown styles\n */\nquikdown.emitStyles = function() {\n const styles = {\n h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',\n h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',\n h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',\n h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',\n h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',\n h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',\n td: 'border: 1px solid #ddd; padding: 8px; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: 'margin: 0.5em 0; padding-left: 2em',\n ol: 'margin: 0.5em 0; padding-left: 2em',\n li: 'margin: 0.25em 0',\n 'task-item': 'list-style: none',\n 'task-checkbox': 'margin-right: 0.5em'\n };\n \n let css = '';\n for (const [tag, style] of Object.entries(styles)) {\n if (style) {\n css += `.quikdown-${tag} { ${style} }\\n`;\n }\n }\n \n return css;\n};\n\n/**\n * Configure quikdown with options and return a function\n * @param {Object} options - Configuration options\n * @returns {Function} Configured quikdown function\n */\nquikdown.configure = function(options) {\n return function(markdown) {\n return quikdown(markdown, options);\n };\n};\n\n/**\n * Version information\n */\nquikdown.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown;\n}\n\n// For browser global\nif (typeof window !== 'undefined') {\n window.quikdown = quikdown;\n}\n\nexport default quikdown;","// Auto-generated version file - DO NOT EDIT MANUALLY\n// This file is automatically updated by tools/updateVersion.js\n\nexport const quikdownVersion = \"1.0.2\";\n\nexport default quikdownVersion;"],"names":["quikdown","markdown","options","fence_plugin","inline_styles","styles","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","thead","tbody","tr","th","td","hr","img","a","strong","em","del","ul","ol","li","br","getAttr","tag","additionalStyle","style","fullStyle","escapeHtml","text","map","replace","m","sanitizeUrl","url","allowUnsafe","trimmedUrl","trim","lowerUrl","toLowerCase","dangerousProtocols","protocol","startsWith","html","codeBlocks","inlineCodes","match","fence","lang","placeholder","length","langTrimmed","push","trimEnd","custom","lines","split","result","inTable","tableLines","i","line","includes","test","tableHtml","buildTable","join","processTable","hashes","content","level","listStack","indent","marker","Math","floor","isOrdered","listType","listItemContent","taskListClass","taskMatch","checked","taskContent","isChecked","list","pop","type","currentList","liAttr","processLists","alt","src","sanitizedSrc","allow_unsafe_urls","href","sanitizedHref","rel","prefix","sanitizedUrl","forEach","block","replacement","undefined","langClass","codeAttr","processInlineMarkdown","separatorIndex","headerLines","slice","bodyLines","alignments","cell","trimmed","endsWith","alignStyle","processedCell","emitStyles","css","Object","entries","configure","version","module","exports","window"],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * quikdown Light Theme CSS
3
+ * Minimal light theme - just basic styling, no fancy colors
4
+ */
5
+
6
+ /* Headings - just size differences */
7
+ .quikdown-h1 {
8
+ font-size: 2em;
9
+ font-weight: 600;
10
+ margin: 0.67em 0;
11
+ text-align: left;
12
+ }
13
+
14
+ .quikdown-h2 {
15
+ font-size: 1.5em;
16
+ font-weight: 600;
17
+ margin: 0.83em 0;
18
+ }
19
+
20
+ .quikdown-h3 {
21
+ font-size: 1.25em;
22
+ font-weight: 600;
23
+ margin: 1em 0;
24
+ }
25
+
26
+ .quikdown-h4 {
27
+ font-size: 1em;
28
+ font-weight: 600;
29
+ margin: 1.33em 0;
30
+ }
31
+
32
+ .quikdown-h5 {
33
+ font-size: 0.875em;
34
+ font-weight: 600;
35
+ margin: 1.67em 0;
36
+ }
37
+
38
+ .quikdown-h6 {
39
+ font-size: 0.85em;
40
+ font-weight: 600;
41
+ margin: 2em 0;
42
+ }
43
+
44
+ /* Code blocks */
45
+ .quikdown-pre {
46
+ background: #f4f4f4;
47
+ padding: 10px;
48
+ border-radius: 4px;
49
+ overflow-x: auto;
50
+ margin: 1em 0;
51
+ }
52
+
53
+ .quikdown-code {
54
+ background: #f0f0f0;
55
+ padding: 2px 4px;
56
+ border-radius: 3px;
57
+ font-family: monospace;
58
+ }
59
+
60
+ /* Blockquotes */
61
+ .quikdown-blockquote {
62
+ border-left: 4px solid #ddd;
63
+ margin-left: 0;
64
+ padding-left: 1em;
65
+ }
66
+
67
+ /* Tables */
68
+ .quikdown-table {
69
+ border-collapse: collapse;
70
+ width: 100%;
71
+ margin: 1em 0;
72
+ }
73
+
74
+ .quikdown-th {
75
+ border: 1px solid #ddd;
76
+ padding: 8px;
77
+ background-color: #f2f2f2;
78
+ font-weight: bold;
79
+ text-align: left;
80
+ }
81
+
82
+ .quikdown-td {
83
+ border: 1px solid #ddd;
84
+ padding: 8px;
85
+ text-align: left;
86
+ }
87
+
88
+ /* Lists */
89
+ .quikdown-ul,
90
+ .quikdown-ol {
91
+ margin: 0.5em 0;
92
+ padding-left: 2em;
93
+ }
94
+
95
+ .quikdown-li {
96
+ margin: 0.25em 0;
97
+ }
98
+
99
+ /* Task lists */
100
+ .quikdown-task-item {
101
+ list-style: none;
102
+ }
103
+
104
+ .quikdown-task-checkbox {
105
+ margin-right: 0.5em;
106
+ }
107
+
108
+ /* Links */
109
+ .quikdown-a {
110
+ color: #0066cc;
111
+ text-decoration: underline;
112
+ }
113
+
114
+ /* Images */
115
+ .quikdown-img {
116
+ max-width: 100%;
117
+ height: auto;
118
+ }
119
+
120
+ /* Horizontal rule */
121
+ .quikdown-hr {
122
+ border: none;
123
+ border-top: 1px solid #ddd;
124
+ margin: 1em 0;
125
+ }
126
+
127
+ /* Text formatting */
128
+ .quikdown-strong {
129
+ font-weight: bold;
130
+ }
131
+
132
+ .quikdown-em {
133
+ font-style: italic;
134
+ }
135
+
136
+ .quikdown-del {
137
+ text-decoration: line-through;
138
+ }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.0.1
3
+ * @version 1.0.2
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
@@ -13,7 +13,7 @@
13
13
  // Auto-generated version file - DO NOT EDIT MANUALLY
14
14
  // This file is automatically updated by tools/updateVersion.js
15
15
 
16
- const quikdownVersion = "1.0.1";
16
+ const quikdownVersion = "1.0.2";
17
17
 
18
18
  /**
19
19
  * quikdown - A minimal markdown parser optimized for chat/LLM output
@@ -34,35 +34,31 @@
34
34
 
35
35
  const { fence_plugin, inline_styles = false } = options;
36
36
 
37
- // Style definitions - deduplicated to save space
38
- const headingStyle = 'margin-top: 0.5em; margin-bottom: 0.3em';
39
- const listStyle = 'margin: 0.5em 0; padding-left: 2em';
40
- const cellBorder = 'border: 1px solid #ddd; padding: 8px';
41
-
37
+ // Style definitions - minimal, matching emitStyles
42
38
  const styles = {
43
- h1: headingStyle,
44
- h2: headingStyle,
45
- h3: headingStyle,
46
- h4: headingStyle,
47
- h5: headingStyle,
48
- h6: headingStyle,
49
- pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',
50
- code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',
51
- blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',
39
+ h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',
40
+ h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',
41
+ h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',
42
+ h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',
43
+ h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',
44
+ h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',
45
+ pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',
46
+ code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',
47
+ blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',
52
48
  table: 'border-collapse: collapse; width: 100%; margin: 1em 0',
53
49
  thead: '',
54
50
  tbody: '',
55
51
  tr: '',
56
- th: cellBorder + '; background-color: #f2f2f2; font-weight: bold',
57
- td: cellBorder + '; text-align: left',
52
+ th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',
53
+ td: 'border: 1px solid #ddd; padding: 8px; text-align: left',
58
54
  hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',
59
55
  img: 'max-width: 100%; height: auto',
60
56
  a: 'color: #0066cc; text-decoration: underline',
61
57
  strong: 'font-weight: bold',
62
58
  em: 'font-style: italic',
63
59
  del: 'text-decoration: line-through',
64
- ul: listStyle,
65
- ol: listStyle,
60
+ ul: 'margin: 0.5em 0; padding-left: 2em',
61
+ ol: 'margin: 0.5em 0; padding-left: 2em',
66
62
  li: 'margin: 0.25em 0',
67
63
  br: ''
68
64
  };
@@ -126,19 +122,24 @@
126
122
  const inlineCodes = [];
127
123
 
128
124
  // Extract fenced code blocks first (supports both ``` and ~~~)
129
- html = html.replace(/(?:```|~~~)([^\n]*)\n([\s\S]*?)(?:```|~~~)/g, (match, lang, code) => {
125
+ // Match paired fences - ``` with ``` and ~~~ with ~~~
126
+ // Fence must be at start of line
127
+ html = html.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm, (match, fence, lang, code) => {
130
128
  const placeholder = `%%%CODEBLOCK${codeBlocks.length}%%%`;
131
129
 
130
+ // Trim the language specification
131
+ const langTrimmed = lang ? lang.trim() : '';
132
+
132
133
  // If custom fence plugin is provided, use it
133
134
  if (fence_plugin && typeof fence_plugin === 'function') {
134
135
  codeBlocks.push({
135
- lang: lang || '',
136
+ lang: langTrimmed,
136
137
  code: code.trimEnd(),
137
138
  custom: true
138
139
  });
139
140
  } else {
140
141
  codeBlocks.push({
141
- lang: lang || '',
142
+ lang: langTrimmed,
142
143
  code: escapeHtml(code.trimEnd()),
143
144
  custom: false
144
145
  });
@@ -527,17 +528,17 @@
527
528
  */
528
529
  quikdown.emitStyles = function() {
529
530
  const styles = {
530
- h1: 'margin-top: 0.5em; margin-bottom: 0.3em',
531
- h2: 'margin-top: 0.5em; margin-bottom: 0.3em',
532
- h3: 'margin-top: 0.5em; margin-bottom: 0.3em',
533
- h4: 'margin-top: 0.5em; margin-bottom: 0.3em',
534
- h5: 'margin-top: 0.5em; margin-bottom: 0.3em',
535
- h6: 'margin-top: 0.5em; margin-bottom: 0.3em',
536
- pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',
537
- code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',
538
- blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',
531
+ h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',
532
+ h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',
533
+ h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',
534
+ h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',
535
+ h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',
536
+ h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',
537
+ pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',
538
+ code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',
539
+ blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',
539
540
  table: 'border-collapse: collapse; width: 100%; margin: 1em 0',
540
- th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold',
541
+ th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',
541
542
  td: 'border: 1px solid #ddd; padding: 8px; text-align: left',
542
543
  hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',
543
544
  img: 'max-width: 100%; height: auto',
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * quikdown - Lightweight Markdown Parser
3
- * @version 1.0.1
3
+ * @version 1.0.2
4
4
  * @license BSD-2-Clause
5
5
  * @copyright DeftIO 2025
6
6
  */
7
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).quikdown=t()}(this,function(){"use strict";function e(e,t={}){if(!e||"string"!=typeof e)return"";const{fence_plugin:o,inline_styles:n=!1}=t,l="margin-top: 0.5em; margin-bottom: 0.3em",i="margin: 0.5em 0; padding-left: 2em",c="border: 1px solid #ddd; padding: 8px",a={h1:l,h2:l,h3:l,h4:l,h5:l,h6:l,pre:"background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto",code:"background: #f0f0f0; padding: 2px 4px; border-radius: 3px",blockquote:"border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666",table:"border-collapse: collapse; width: 100%; margin: 1em 0",thead:"",tbody:"",tr:"",th:c+"; background-color: #f2f2f2; font-weight: bold",td:c+"; text-align: left",hr:"border: none; border-top: 1px solid #ddd; margin: 1em 0",img:"max-width: 100%; height: auto",a:"color: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:i,ol:i,li:"margin: 0.25em 0",br:""};function s(e,t=""){if(n){const r=a[e]||"",o=t?`${r}; ${t}`:r;return o?` style="${o}"`:""}return` class="quikdown-${e}"`}function p(e){const t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return e.replace(/[&<>"']/g,e=>t[e])}function d(e,t=!1){if(!e)return"";if(t)return e;const r=e.trim(),o=r.toLowerCase(),n=["javascript:","vbscript:","data:"];for(const e of n)if(o.startsWith(e))return"data:"===e&&o.startsWith("data:image/")?r:"#";return r}let g=e;const u=[],f=[];return g=g.replace(/(?:```|~~~)([^\n]*)\n([\s\S]*?)(?:```|~~~)/g,(e,t,r)=>{const n=`%%%CODEBLOCK${u.length}%%%`;return o&&"function"==typeof o?u.push({lang:t||"",code:r.trimEnd(),custom:!0}):u.push({lang:t||"",code:p(r.trimEnd()),custom:!1}),n}),g=g.replace(/`([^`]+)`/g,(e,t)=>{const r=`%%%INLINECODE${f.length}%%%`;return f.push(p(t)),r}),g=p(g),g=function(e,t,o){const n=e.split("\n"),l=[];let i=!1,c=[];for(let e=0;e<n.length;e++){const a=n[e].trim();if(a.includes("|")&&(a.startsWith("|")||/[^\\|]/.test(a)))i||(i=!0,c=[]),c.push(a);else{if(i){const e=r(c,t,o);e?l.push(e):l.push(...c),i=!1,c=[]}l.push(n[e])}}if(i&&c.length>0){const e=r(c,t,o);e?l.push(e):l.push(...c)}return l.join("\n")}(g,n,a),g=g.replace(/^(#{1,6})\s+(.+?)\s*#*$/gm,(e,t,r)=>{const o=t.length;return`<h${o}${s("h"+o)}>${r}</h${o}>`}),g=g.replace(/^&gt;\s+(.+)$/gm,`<blockquote${s("blockquote")}>$1</blockquote>`),g=g.replace(/<\/blockquote>\n<blockquote>/g,"\n"),g=g.replace(/^---+$/gm,`<hr${s("hr")}>`),g=function(e,t,r){function o(e,o=""){if(t){const t=r[e]||"",n=o?`${t}; ${o}`:t;return n?` style="${n}"`:""}return` class="quikdown-${e}"`}const n=e.split("\n"),l=[];let i=[];for(let e=0;e<n.length;e++){const r=n[e],c=r.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(c){const[,e,r,n]=c,a=Math.floor(e.length/2),s=/^\d+\./.test(r),p=s?"ol":"ul";let d=n,g="";const u=n.match(/^\[([x ])\]\s+(.*)$/i);if(u&&!s){const[,e,r]=u,o="x"===e.toLowerCase();d=`<input type="checkbox"${t?' style="margin-right: 0.5em"':' class="quikdown-task-checkbox"'}${o?" checked":""} disabled> ${r}`,g=t?' style="list-style: none"':' class="quikdown-task-item"'}for(;i.length>a+1;){const e=i.pop();l.push(`</${e.type}>`)}if(i.length===a)i.push({type:p,level:a}),l.push(`<${p}${o(p)}>`);else if(i.length===a+1){const e=i[i.length-1];e.type!==p&&(l.push(`</${e.type}>`),i.pop(),i.push({type:p,level:a}),l.push(`<${p}${o(p)}>`))}const f=g||o("li");l.push(`<li${f}>${d}</li>`)}else{for(;i.length>0;){const e=i.pop();l.push(`</${e.type}>`)}l.push(r)}}for(;i.length>0;){const e=i.pop();l.push(`</${e.type}>`)}return l.join("\n")}(g,n,a),g=g.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,r,o)=>{const n=d(o,t.allow_unsafe_urls);return`<img${s("img")} src="${n}" alt="${r}">`}),g=g.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,r,o)=>{const n=d(o,t.allow_unsafe_urls),l=/^https?:\/\//i.test(n)?' rel="noopener noreferrer"':"";return`<a${s("a")} href="${n}"${l}>${r}</a>`}),g=g.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,r,o)=>{const n=d(o,t.allow_unsafe_urls);return`${r}<a${s("a")} href="${n}" rel="noopener noreferrer">${o}</a>`}),g=g.replace(/\*\*(.+?)\*\*/g,`<strong${s("strong")}>$1</strong>`),g=g.replace(/__(.+?)__/g,`<strong${s("strong")}>$1</strong>`),g=g.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${s("em")}>$1</em>`),g=g.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${s("em")}>$1</em>`),g=g.replace(/~~(.+?)~~/g,`<del${s("del")}>$1</del>`),g=g.replace(/ $/gm,`<br${s("br")}>`),g=g.replace(/\n\n+/g,"</p><p>"),g="<p>"+g+"</p>",g=g.replace(/<p><\/p>/g,""),g=g.replace(/<p>(<h[1-6][^>]*>)/g,"$1"),g=g.replace(/(<\/h[1-6]>)<\/p>/g,"$1"),g=g.replace(/<p>(<blockquote[^>]*>)/g,"$1"),g=g.replace(/(<\/blockquote>)<\/p>/g,"$1"),g=g.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"),g=g.replace(/(<\/ul>|<\/ol>)<\/p>/g,"$1"),g=g.replace(/<p>(<hr[^>]*>)<\/p>/g,"$1"),g=g.replace(/<p>(<table[^>]*>)/g,"$1"),g=g.replace(/(<\/table>)<\/p>/g,"$1"),g=g.replace(/<p>(<pre[^>]*>)/g,"$1"),g=g.replace(/(<\/pre>)<\/p>/g,"$1"),g=g.replace(/<p>(%%%CODEBLOCK\d+%%%)<\/p>/g,"$1"),u.forEach((e,t)=>{let r;if(e.custom&&o){if(r=o(e.code,e.lang),void 0===r){const t=!n&&e.lang?` class="language-${e.lang}"`:"",o=n?s("code"):t;r=`<pre${s("pre")}><code${o}>${p(e.code)}</code></pre>`}}else{const t=!n&&e.lang?` class="language-${e.lang}"`:"",o=n?s("code"):t;r=`<pre${s("pre")}><code${o}>${e.code}</code></pre>`}const l=`%%%CODEBLOCK${t}%%%`;g=g.replace(l,r)}),f.forEach((e,t)=>{const r=`%%%INLINECODE${t}%%%`;g=g.replace(r,`<code${s("code")}>${e}</code>`)}),g.trim()}function t(e,t,r){function o(e,o=""){if(t){const t=r[e]||"",n=o?`${t}; ${o}`:t;return n?` style="${n}"`:""}return` class="quikdown-${e}"`}return e=(e=(e=(e=(e=(e=e.replace(/\*\*(.+?)\*\*/g,`<strong${o("strong")}>$1</strong>`)).replace(/__(.+?)__/g,`<strong${o("strong")}>$1</strong>`)).replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${o("em")}>$1</em>`)).replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${o("em")}>$1</em>`)).replace(/~~(.+?)~~/g,`<del${o("del")}>$1</del>`)).replace(/`([^`]+)`/g,`<code${o("code")}>$1</code>`)}function r(e,r,o){function n(e,t=""){if(r){const r=o[e]||"",n=t?`${r}; ${t}`:r;return n?` style="${n}"`:""}return` class="quikdown-${e}"`}if(e.length<2)return null;let l=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){l=t;break}if(-1===l)return null;const i=e.slice(0,l),c=e.slice(l+1),a=e[l].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let s=`<table${n("table")}>\n`;return i.length>0&&(s+=`<thead${n("thead")}>\n`,i.forEach(e=>{s+=`<tr${n("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const i=a[l]&&"left"!==a[l]?`text-align: ${a[l]}`:"",c=t(e.trim(),r,o);s+=`<th${n("th",i)}>${c}</th>\n`}),s+="</tr>\n"}),s+="</thead>\n"),c.length>0&&(s+=`<tbody${n("tbody")}>\n`,c.forEach(e=>{s+=`<tr${n("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const i=a[l]&&"left"!==a[l]?`text-align: ${a[l]}`:"",c=t(e.trim(),r,o);s+=`<td${n("td",i)}>${c}</td>\n`}),s+="</tr>\n"}),s+="</tbody>\n"),s+="</table>",s}return e.emitStyles=function(){const e={h1:"margin-top: 0.5em; margin-bottom: 0.3em",h2:"margin-top: 0.5em; margin-bottom: 0.3em",h3:"margin-top: 0.5em; margin-bottom: 0.3em",h4:"margin-top: 0.5em; margin-bottom: 0.3em",h5:"margin-top: 0.5em; margin-bottom: 0.3em",h6:"margin-top: 0.5em; margin-bottom: 0.3em",pre:"background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto",code:"background: #f0f0f0; padding: 2px 4px; border-radius: 3px",blockquote:"border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666",table:"border-collapse: collapse; width: 100%; margin: 1em 0",th:"border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold",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: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:"margin: 0.5em 0; padding-left: 2em",ol:"margin: 0.5em 0; padding-left: 2em",li:"margin: 0.25em 0","task-item":"list-style: none","task-checkbox":"margin-right: 0.5em"};let t="";for(const[r,o]of Object.entries(e))o&&(t+=`.quikdown-${r} { ${o} }\n`);return t},e.configure=function(t){return function(r){return e(r,t)}},e.version="1.0.1","undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.quikdown=e),e});
7
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).quikdown=t()}(this,function(){"use strict";function e(e,t={}){if(!e||"string"!=typeof e)return"";const{fence_plugin:o,inline_styles:r=!1}=t,l={h1:"font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left",h2:"font-size: 1.5em; font-weight: 600; margin: 0.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: 0.875em; font-weight: 600; margin: 1.67em 0",h6:"font-size: 0.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",thead:"",tbody:"",tr:"",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: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:"margin: 0.5em 0; padding-left: 2em",ol:"margin: 0.5em 0; padding-left: 2em",li:"margin: 0.25em 0",br:""};function i(e,t=""){if(r){const n=l[e]||"",o=t?`${n}; ${t}`:n;return o?` style="${o}"`:""}return` class="quikdown-${e}"`}function a(e){const t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return e.replace(/[&<>"']/g,e=>t[e])}function s(e,t=!1){if(!e)return"";if(t)return e;const n=e.trim(),o=n.toLowerCase(),r=["javascript:","vbscript:","data:"];for(const e of r)if(o.startsWith(e))return"data:"===e&&o.startsWith("data:image/")?n:"#";return n}let c=e;const d=[],p=[];return c=c.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,t,n,r)=>{const l=`%%%CODEBLOCK${d.length}%%%`,i=n?n.trim():"";return o&&"function"==typeof o?d.push({lang:i,code:r.trimEnd(),custom:!0}):d.push({lang:i,code:a(r.trimEnd()),custom:!1}),l}),c=c.replace(/`([^`]+)`/g,(e,t)=>{const n=`%%%INLINECODE${p.length}%%%`;return p.push(a(t)),n}),c=a(c),c=function(e,t,o){const r=e.split("\n"),l=[];let i=!1,a=[];for(let e=0;e<r.length;e++){const s=r[e].trim();if(s.includes("|")&&(s.startsWith("|")||/[^\\|]/.test(s)))i||(i=!0,a=[]),a.push(s);else{if(i){const e=n(a,t,o);e?l.push(e):l.push(...a),i=!1,a=[]}l.push(r[e])}}if(i&&a.length>0){const e=n(a,t,o);e?l.push(e):l.push(...a)}return l.join("\n")}(c,r,l),c=c.replace(/^(#{1,6})\s+(.+?)\s*#*$/gm,(e,t,n)=>{const o=t.length;return`<h${o}${i("h"+o)}>${n}</h${o}>`}),c=c.replace(/^&gt;\s+(.+)$/gm,`<blockquote${i("blockquote")}>$1</blockquote>`),c=c.replace(/<\/blockquote>\n<blockquote>/g,"\n"),c=c.replace(/^---+$/gm,`<hr${i("hr")}>`),c=function(e,t,n){function o(e,o=""){if(t){const t=n[e]||"",r=o?`${t}; ${o}`:t;return r?` style="${r}"`:""}return` class="quikdown-${e}"`}const r=e.split("\n"),l=[];let i=[];for(let e=0;e<r.length;e++){const n=r[e],a=n.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(a){const[,e,n,r]=a,s=Math.floor(e.length/2),c=/^\d+\./.test(n),d=c?"ol":"ul";let p=r,g="";const f=r.match(/^\[([x ])\]\s+(.*)$/i);if(f&&!c){const[,e,n]=f,o="x"===e.toLowerCase();p=`<input type="checkbox"${t?' style="margin-right: 0.5em"':' class="quikdown-task-checkbox"'}${o?" checked":""} disabled> ${n}`,g=t?' style="list-style: none"':' class="quikdown-task-item"'}for(;i.length>s+1;){const e=i.pop();l.push(`</${e.type}>`)}if(i.length===s)i.push({type:d,level:s}),l.push(`<${d}${o(d)}>`);else if(i.length===s+1){const e=i[i.length-1];e.type!==d&&(l.push(`</${e.type}>`),i.pop(),i.push({type:d,level:s}),l.push(`<${d}${o(d)}>`))}const u=g||o("li");l.push(`<li${u}>${p}</li>`)}else{for(;i.length>0;){const e=i.pop();l.push(`</${e.type}>`)}l.push(n)}}for(;i.length>0;){const e=i.pop();l.push(`</${e.type}>`)}return l.join("\n")}(c,r,l),c=c.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,n,o)=>{const r=s(o,t.allow_unsafe_urls);return`<img${i("img")} src="${r}" alt="${n}">`}),c=c.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,n,o)=>{const r=s(o,t.allow_unsafe_urls),l=/^https?:\/\//i.test(r)?' rel="noopener noreferrer"':"";return`<a${i("a")} href="${r}"${l}>${n}</a>`}),c=c.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,n,o)=>{const r=s(o,t.allow_unsafe_urls);return`${n}<a${i("a")} href="${r}" rel="noopener noreferrer">${o}</a>`}),c=c.replace(/\*\*(.+?)\*\*/g,`<strong${i("strong")}>$1</strong>`),c=c.replace(/__(.+?)__/g,`<strong${i("strong")}>$1</strong>`),c=c.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${i("em")}>$1</em>`),c=c.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${i("em")}>$1</em>`),c=c.replace(/~~(.+?)~~/g,`<del${i("del")}>$1</del>`),c=c.replace(/ $/gm,`<br${i("br")}>`),c=c.replace(/\n\n+/g,"</p><p>"),c="<p>"+c+"</p>",c=c.replace(/<p><\/p>/g,""),c=c.replace(/<p>(<h[1-6][^>]*>)/g,"$1"),c=c.replace(/(<\/h[1-6]>)<\/p>/g,"$1"),c=c.replace(/<p>(<blockquote[^>]*>)/g,"$1"),c=c.replace(/(<\/blockquote>)<\/p>/g,"$1"),c=c.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"),c=c.replace(/(<\/ul>|<\/ol>)<\/p>/g,"$1"),c=c.replace(/<p>(<hr[^>]*>)<\/p>/g,"$1"),c=c.replace(/<p>(<table[^>]*>)/g,"$1"),c=c.replace(/(<\/table>)<\/p>/g,"$1"),c=c.replace(/<p>(<pre[^>]*>)/g,"$1"),c=c.replace(/(<\/pre>)<\/p>/g,"$1"),c=c.replace(/<p>(%%%CODEBLOCK\d+%%%)<\/p>/g,"$1"),d.forEach((e,t)=>{let n;if(e.custom&&o){if(n=o(e.code,e.lang),void 0===n){const t=!r&&e.lang?` class="language-${e.lang}"`:"",o=r?i("code"):t;n=`<pre${i("pre")}><code${o}>${a(e.code)}</code></pre>`}}else{const t=!r&&e.lang?` class="language-${e.lang}"`:"",o=r?i("code"):t;n=`<pre${i("pre")}><code${o}>${e.code}</code></pre>`}const l=`%%%CODEBLOCK${t}%%%`;c=c.replace(l,n)}),p.forEach((e,t)=>{const n=`%%%INLINECODE${t}%%%`;c=c.replace(n,`<code${i("code")}>${e}</code>`)}),c.trim()}function t(e,t,n){function o(e,o=""){if(t){const t=n[e]||"",r=o?`${t}; ${o}`:t;return r?` style="${r}"`:""}return` class="quikdown-${e}"`}return e=(e=(e=(e=(e=(e=e.replace(/\*\*(.+?)\*\*/g,`<strong${o("strong")}>$1</strong>`)).replace(/__(.+?)__/g,`<strong${o("strong")}>$1</strong>`)).replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${o("em")}>$1</em>`)).replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${o("em")}>$1</em>`)).replace(/~~(.+?)~~/g,`<del${o("del")}>$1</del>`)).replace(/`([^`]+)`/g,`<code${o("code")}>$1</code>`)}function n(e,n,o){function r(e,t=""){if(n){const n=o[e]||"",r=t?`${n}; ${t}`:n;return r?` style="${r}"`:""}return` class="quikdown-${e}"`}if(e.length<2)return null;let l=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){l=t;break}if(-1===l)return null;const i=e.slice(0,l),a=e.slice(l+1),s=e[l].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let c=`<table${r("table")}>\n`;return i.length>0&&(c+=`<thead${r("thead")}>\n`,i.forEach(e=>{c+=`<tr${r("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const i=s[l]&&"left"!==s[l]?`text-align: ${s[l]}`:"",a=t(e.trim(),n,o);c+=`<th${r("th",i)}>${a}</th>\n`}),c+="</tr>\n"}),c+="</thead>\n"),a.length>0&&(c+=`<tbody${r("tbody")}>\n`,a.forEach(e=>{c+=`<tr${r("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,l)=>{const i=s[l]&&"left"!==s[l]?`text-align: ${s[l]}`:"",a=t(e.trim(),n,o);c+=`<td${r("td",i)}>${a}</td>\n`}),c+="</tr>\n"}),c+="</tbody>\n"),c+="</table>",c}return e.emitStyles=function(){const e={h1:"font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left",h2:"font-size: 1.5em; font-weight: 600; margin: 0.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: 0.875em; font-weight: 600; margin: 1.67em 0",h6:"font-size: 0.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: #0066cc; text-decoration: underline",strong:"font-weight: bold",em:"font-style: italic",del:"text-decoration: line-through",ul:"margin: 0.5em 0; padding-left: 2em",ol:"margin: 0.5em 0; padding-left: 2em",li:"margin: 0.25em 0","task-item":"list-style: none","task-checkbox":"margin-right: 0.5em"};let t="";for(const[n,o]of Object.entries(e))o&&(t+=`.quikdown-${n} { ${o} }\n`);return t},e.configure=function(t){return function(n){return e(n,t)}},e.version="1.0.2","undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.quikdown=e),e});
8
8
  //# sourceMappingURL=quikdown.umd.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"quikdown.umd.min.js","sources":["../src/quikdown.js","../src/quikdown_version.js"],"sourcesContent":["/**\n * quikdown - A minimal markdown parser optimized for chat/LLM output\n * Supports tables, code blocks, lists, and common formatting\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @param {Function} options.fence_plugin - Custom renderer for fenced code blocks\n * (content, fence_string) => html string\n * @param {boolean} options.inline_styles - If true, uses inline styles instead of classes\n * @returns {string} - The rendered HTML\n */\n\nimport quikdownVersion from './quikdown_version.js';\n\nfunction quikdown(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return '';\n }\n \n const { fence_plugin, inline_styles = false } = options;\n\n // Style definitions - deduplicated to save space\n const headingStyle = 'margin-top: 0.5em; margin-bottom: 0.3em';\n const listStyle = 'margin: 0.5em 0; padding-left: 2em';\n const cellBorder = 'border: 1px solid #ddd; padding: 8px';\n \n const styles = {\n h1: headingStyle,\n h2: headingStyle,\n h3: headingStyle,\n h4: headingStyle,\n h5: headingStyle,\n h6: headingStyle,\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n thead: '',\n tbody: '',\n tr: '',\n th: cellBorder + '; background-color: #f2f2f2; font-weight: bold',\n td: cellBorder + '; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: listStyle,\n ol: listStyle,\n li: 'margin: 0.25em 0',\n br: ''\n };\n\n // Helper to get class or style attribute\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n\n // Escape HTML entities to prevent XSS\n function escapeHtml(text) {\n const map = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;'\n };\n return text.replace(/[&<>\"']/g, m => map[m]);\n }\n \n // Sanitize URLs to prevent XSS attacks\n function sanitizeUrl(url, allowUnsafe = false) {\n if (!url) return '';\n \n // If unsafe URLs are explicitly allowed, return as-is\n if (allowUnsafe) return url;\n \n // Trim and lowercase for checking\n const trimmedUrl = url.trim();\n const lowerUrl = trimmedUrl.toLowerCase();\n \n // Block dangerous protocols\n const dangerousProtocols = ['javascript:', 'vbscript:', 'data:'];\n \n for (const protocol of dangerousProtocols) {\n if (lowerUrl.startsWith(protocol)) {\n // Exception: Allow data:image/* for images\n if (protocol === 'data:' && lowerUrl.startsWith('data:image/')) {\n return trimmedUrl;\n }\n // Return safe empty link for dangerous protocols\n return '#';\n }\n }\n \n return trimmedUrl;\n }\n\n // Process the markdown in phases\n let html = markdown;\n \n // Phase 1: Extract and protect code blocks and inline code\n const codeBlocks = [];\n const inlineCodes = [];\n \n // Extract fenced code blocks first (supports both ``` and ~~~)\n html = html.replace(/(?:```|~~~)([^\\n]*)\\n([\\s\\S]*?)(?:```|~~~)/g, (match, lang, code) => {\n const placeholder = `%%%CODEBLOCK${codeBlocks.length}%%%`;\n \n // If custom fence plugin is provided, use it\n if (fence_plugin && typeof fence_plugin === 'function') {\n codeBlocks.push({\n lang: lang || '',\n code: code.trimEnd(),\n custom: true\n });\n } else {\n codeBlocks.push({\n lang: lang || '',\n code: escapeHtml(code.trimEnd()),\n custom: false\n });\n }\n return placeholder;\n });\n \n // Extract inline code\n html = html.replace(/`([^`]+)`/g, (match, code) => {\n const placeholder = `%%%INLINECODE${inlineCodes.length}%%%`;\n inlineCodes.push(escapeHtml(code));\n return placeholder;\n });\n \n // Now escape HTML in the rest of the content\n html = escapeHtml(html);\n \n // Phase 2: Process block elements\n \n // Process tables\n html = processTable(html, inline_styles, styles);\n \n // Process headings (supports optional trailing #'s)\n html = html.replace(/^(#{1,6})\\s+(.+?)\\s*#*$/gm, (match, hashes, content) => {\n const level = hashes.length;\n return `<h${level}${getAttr('h' + level)}>${content}</h${level}>`;\n });\n \n // Process blockquotes (must handle escaped > since we already escaped HTML)\n html = html.replace(/^&gt;\\s+(.+)$/gm, `<blockquote${getAttr('blockquote')}>$1</blockquote>`);\n // Merge consecutive blockquotes\n html = html.replace(/<\\/blockquote>\\n<blockquote>/g, '\\n');\n \n // Process horizontal rules\n html = html.replace(/^---+$/gm, `<hr${getAttr('hr')}>`);\n \n // Process lists\n html = processLists(html, inline_styles, styles);\n \n // Phase 3: Process inline elements\n \n // Images (must come before links, with URL sanitization)\n html = html.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (match, alt, src) => {\n const sanitizedSrc = sanitizeUrl(src, options.allow_unsafe_urls);\n return `<img${getAttr('img')} src=\"${sanitizedSrc}\" alt=\"${alt}\">`;\n });\n \n // Links (with URL sanitization)\n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (match, text, href) => {\n // Sanitize URL to prevent XSS\n const sanitizedHref = sanitizeUrl(href, options.allow_unsafe_urls);\n const isExternal = /^https?:\\/\\//i.test(sanitizedHref);\n const rel = isExternal ? ' rel=\"noopener noreferrer\"' : '';\n return `<a${getAttr('a')} href=\"${sanitizedHref}\"${rel}>${text}</a>`;\n });\n \n // Autolinks - convert bare URLs to clickable links\n html = html.replace(/(^|\\s)(https?:\\/\\/[^\\s<]+)/g, (match, prefix, url) => {\n const sanitizedUrl = sanitizeUrl(url, options.allow_unsafe_urls);\n return `${prefix}<a${getAttr('a')} href=\"${sanitizedUrl}\" rel=\"noopener noreferrer\">${url}</a>`;\n });\n \n // Bold (must use non-greedy matching)\n html = html.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n html = html.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Italic (must not match bold markers)\n html = html.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n html = html.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Strikethrough\n html = html.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Line breaks (two spaces at end of line)\n html = html.replace(/ $/gm, `<br${getAttr('br')}>`);\n \n // Paragraphs (double newlines)\n html = html.replace(/\\n\\n+/g, '</p><p>');\n html = '<p>' + html + '</p>';\n \n // Clean up empty paragraphs and unwrap block elements (account for attributes)\n html = html.replace(/<p><\\/p>/g, '');\n html = html.replace(/<p>(<h[1-6][^>]*>)/g, '$1');\n html = html.replace(/(<\\/h[1-6]>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<blockquote[^>]*>)/g, '$1');\n html = html.replace(/(<\\/blockquote>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g, '$1');\n html = html.replace(/(<\\/ul>|<\\/ol>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<hr[^>]*>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<table[^>]*>)/g, '$1');\n html = html.replace(/(<\\/table>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<pre[^>]*>)/g, '$1');\n html = html.replace(/(<\\/pre>)<\\/p>/g, '$1');\n // Also unwrap code block placeholders\n html = html.replace(/<p>(%%%CODEBLOCK\\d+%%%)<\\/p>/g, '$1');\n \n // Phase 4: Restore code blocks and inline code\n \n // Restore code blocks\n codeBlocks.forEach((block, i) => {\n let replacement;\n \n if (block.custom && fence_plugin) {\n // Use custom fence plugin\n replacement = fence_plugin(block.code, block.lang);\n // If plugin returns undefined, fall back to default rendering\n if (replacement === undefined) {\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${escapeHtml(block.code)}</code></pre>`;\n }\n } else {\n // Default rendering\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${block.code}</code></pre>`;\n }\n \n const placeholder = `%%%CODEBLOCK${i}%%%`;\n html = html.replace(placeholder, replacement);\n });\n \n // Restore inline code\n inlineCodes.forEach((code, i) => {\n const placeholder = `%%%INLINECODE${i}%%%`;\n html = html.replace(placeholder, `<code${getAttr('code')}>${code}</code>`);\n });\n \n return html.trim();\n}\n\n/**\n * Process inline markdown formatting\n */\nfunction processInlineMarkdown(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n // Process bold\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n text = text.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Process italic (must not match bold markers)\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n text = text.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Process strikethrough\n text = text.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Process inline code\n text = text.replace(/`([^`]+)`/g, `<code${getAttr('code')}>$1</code>`);\n \n return text;\n}\n\n/**\n * Process markdown tables\n */\nfunction processTable(text, inline_styles, styles) {\n const lines = text.split('\\n');\n const result = [];\n let inTable = false;\n let tableLines = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Check if this line looks like a table row (with or without trailing |)\n if (line.includes('|') && (line.startsWith('|') || /[^\\\\|]/.test(line))) {\n if (!inTable) {\n inTable = true;\n tableLines = [];\n }\n tableLines.push(line);\n } else {\n // Not a table line\n if (inTable) {\n // Process the accumulated table\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n // Not a valid table, restore original lines\n result.push(...tableLines);\n }\n inTable = false;\n tableLines = [];\n }\n result.push(lines[i]);\n }\n }\n \n // Handle table at end of text\n if (inTable && tableLines.length > 0) {\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n result.push(...tableLines);\n }\n }\n \n return result.join('\\n');\n}\n\n/**\n * Build an HTML table from markdown table lines\n */\nfunction buildTable(lines, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n if (lines.length < 2) return null;\n \n // Check for separator line (second line should be the separator)\n let separatorIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n // Support separator with or without leading/trailing pipes\n if (/^\\|?[\\s\\-:|]+\\|?$/.test(lines[i]) && lines[i].includes('-')) {\n separatorIndex = i;\n break;\n }\n }\n \n if (separatorIndex === -1) return null;\n \n const headerLines = lines.slice(0, separatorIndex);\n const bodyLines = lines.slice(separatorIndex + 1);\n \n // Parse alignment from separator\n const separator = lines[separatorIndex];\n // Handle pipes at start/end or not\n const separatorCells = separator.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n const alignments = separatorCells.map(cell => {\n const trimmed = cell.trim();\n if (trimmed.startsWith(':') && trimmed.endsWith(':')) return 'center';\n if (trimmed.endsWith(':')) return 'right';\n return 'left';\n });\n \n let html = `<table${getAttr('table')}>\\n`;\n \n // Build header\n if (headerLines.length > 0) {\n html += `<thead${getAttr('thead')}>\\n`;\n headerLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<th${getAttr('th', alignStyle)}>${processedCell}</th>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</thead>\\n';\n }\n \n // Build body\n if (bodyLines.length > 0) {\n html += `<tbody${getAttr('tbody')}>\\n`;\n bodyLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<td${getAttr('td', alignStyle)}>${processedCell}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n \n html += '</table>';\n return html;\n}\n\n/**\n * Process markdown lists (ordered and unordered)\n */\nfunction processLists(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n const lines = text.split('\\n');\n const result = [];\n let listStack = []; // Track nested lists\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.+)$/);\n \n if (match) {\n const [, indent, marker, content] = match;\n const level = Math.floor(indent.length / 2);\n const isOrdered = /^\\d+\\./.test(marker);\n const listType = isOrdered ? 'ol' : 'ul';\n \n // Check for task list items\n let listItemContent = content;\n let taskListClass = '';\n const taskMatch = content.match(/^\\[([x ])\\]\\s+(.*)$/i);\n if (taskMatch && !isOrdered) {\n const [, checked, taskContent] = taskMatch;\n const isChecked = checked.toLowerCase() === 'x';\n const checkboxAttr = inline_styles \n ? ' style=\"margin-right: 0.5em\"' \n : ' class=\"quikdown-task-checkbox\"';\n listItemContent = `<input type=\"checkbox\"${checkboxAttr}${isChecked ? ' checked' : ''} disabled> ${taskContent}`;\n taskListClass = inline_styles ? ' style=\"list-style: none\"' : ' class=\"quikdown-task-item\"';\n }\n \n // Close deeper levels\n while (listStack.length > level + 1) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n // Open new level if needed\n if (listStack.length === level) {\n // Need to open a new list\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n } else if (listStack.length === level + 1) {\n // Check if we need to switch list type\n const currentList = listStack[listStack.length - 1];\n if (currentList.type !== listType) {\n result.push(`</${currentList.type}>`);\n listStack.pop();\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n }\n }\n \n const liAttr = taskListClass || getAttr('li');\n result.push(`<li${liAttr}>${listItemContent}</li>`);\n } else {\n // Not a list item, close all lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n result.push(line);\n }\n }\n \n // Close any remaining lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n return result.join('\\n');\n}\n\n/**\n * Emit CSS styles for quikdown elements\n * @returns {string} CSS string with quikdown styles\n */\nquikdown.emitStyles = function() {\n const styles = {\n h1: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h2: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h3: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h4: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h5: 'margin-top: 0.5em; margin-bottom: 0.3em',\n h6: 'margin-top: 0.5em; margin-bottom: 0.3em',\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold',\n td: 'border: 1px solid #ddd; padding: 8px; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: 'margin: 0.5em 0; padding-left: 2em',\n ol: 'margin: 0.5em 0; padding-left: 2em',\n li: 'margin: 0.25em 0',\n 'task-item': 'list-style: none',\n 'task-checkbox': 'margin-right: 0.5em'\n };\n \n let css = '';\n for (const [tag, style] of Object.entries(styles)) {\n if (style) {\n css += `.quikdown-${tag} { ${style} }\\n`;\n }\n }\n \n return css;\n};\n\n/**\n * Configure quikdown with options and return a function\n * @param {Object} options - Configuration options\n * @returns {Function} Configured quikdown function\n */\nquikdown.configure = function(options) {\n return function(markdown) {\n return quikdown(markdown, options);\n };\n};\n\n/**\n * Version information\n */\nquikdown.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown;\n}\n\n// For browser global\nif (typeof window !== 'undefined') {\n window.quikdown = quikdown;\n}\n\nexport default quikdown;","// Auto-generated version file - DO NOT EDIT MANUALLY\n// This file is automatically updated by tools/updateVersion.js\n\nexport const quikdownVersion = \"1.0.1\";\n\nexport default quikdownVersion;"],"names":["quikdown","markdown","options","fence_plugin","inline_styles","headingStyle","listStyle","cellBorder","styles","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","thead","tbody","tr","th","td","hr","img","a","strong","em","del","ul","ol","li","br","getAttr","tag","additionalStyle","style","fullStyle","escapeHtml","text","map","replace","m","sanitizeUrl","url","allowUnsafe","trimmedUrl","trim","lowerUrl","toLowerCase","dangerousProtocols","protocol","startsWith","html","codeBlocks","inlineCodes","match","lang","placeholder","length","push","trimEnd","custom","lines","split","result","inTable","tableLines","i","line","includes","test","tableHtml","buildTable","join","processTable","hashes","content","level","listStack","indent","marker","Math","floor","isOrdered","listType","listItemContent","taskListClass","taskMatch","checked","taskContent","isChecked","list","pop","type","currentList","liAttr","processLists","alt","src","sanitizedSrc","allow_unsafe_urls","href","sanitizedHref","rel","prefix","sanitizedUrl","forEach","block","replacement","undefined","langClass","codeAttr","processInlineMarkdown","separatorIndex","headerLines","slice","bodyLines","alignments","cell","trimmed","endsWith","alignStyle","processedCell","emitStyles","css","Object","entries","configure","version","module","exports","window"],"mappings":"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"}
1
+ {"version":3,"file":"quikdown.umd.min.js","sources":["../src/quikdown.js","../src/quikdown_version.js"],"sourcesContent":["/**\n * quikdown - A minimal markdown parser optimized for chat/LLM output\n * Supports tables, code blocks, lists, and common formatting\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @param {Function} options.fence_plugin - Custom renderer for fenced code blocks\n * (content, fence_string) => html string\n * @param {boolean} options.inline_styles - If true, uses inline styles instead of classes\n * @returns {string} - The rendered HTML\n */\n\nimport quikdownVersion from './quikdown_version.js';\n\nfunction quikdown(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return '';\n }\n \n const { fence_plugin, inline_styles = false } = options;\n\n // Style definitions - minimal, matching emitStyles\n const styles = {\n h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',\n h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',\n h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',\n h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',\n h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',\n h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n thead: '',\n tbody: '',\n tr: '',\n th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',\n td: 'border: 1px solid #ddd; padding: 8px; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: 'margin: 0.5em 0; padding-left: 2em',\n ol: 'margin: 0.5em 0; padding-left: 2em',\n li: 'margin: 0.25em 0',\n br: ''\n };\n\n // Helper to get class or style attribute\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n\n // Escape HTML entities to prevent XSS\n function escapeHtml(text) {\n const map = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;'\n };\n return text.replace(/[&<>\"']/g, m => map[m]);\n }\n \n // Sanitize URLs to prevent XSS attacks\n function sanitizeUrl(url, allowUnsafe = false) {\n if (!url) return '';\n \n // If unsafe URLs are explicitly allowed, return as-is\n if (allowUnsafe) return url;\n \n // Trim and lowercase for checking\n const trimmedUrl = url.trim();\n const lowerUrl = trimmedUrl.toLowerCase();\n \n // Block dangerous protocols\n const dangerousProtocols = ['javascript:', 'vbscript:', 'data:'];\n \n for (const protocol of dangerousProtocols) {\n if (lowerUrl.startsWith(protocol)) {\n // Exception: Allow data:image/* for images\n if (protocol === 'data:' && lowerUrl.startsWith('data:image/')) {\n return trimmedUrl;\n }\n // Return safe empty link for dangerous protocols\n return '#';\n }\n }\n \n return trimmedUrl;\n }\n\n // Process the markdown in phases\n let html = markdown;\n \n // Phase 1: Extract and protect code blocks and inline code\n const codeBlocks = [];\n const inlineCodes = [];\n \n // Extract fenced code blocks first (supports both ``` and ~~~)\n // Match paired fences - ``` with ``` and ~~~ with ~~~\n // Fence must be at start of line\n html = html.replace(/^(```|~~~)([^\\n]*)\\n([\\s\\S]*?)^\\1$/gm, (match, fence, lang, code) => {\n const placeholder = `%%%CODEBLOCK${codeBlocks.length}%%%`;\n \n // Trim the language specification\n const langTrimmed = lang ? lang.trim() : '';\n \n // If custom fence plugin is provided, use it\n if (fence_plugin && typeof fence_plugin === 'function') {\n codeBlocks.push({\n lang: langTrimmed,\n code: code.trimEnd(),\n custom: true\n });\n } else {\n codeBlocks.push({\n lang: langTrimmed,\n code: escapeHtml(code.trimEnd()),\n custom: false\n });\n }\n return placeholder;\n });\n \n // Extract inline code\n html = html.replace(/`([^`]+)`/g, (match, code) => {\n const placeholder = `%%%INLINECODE${inlineCodes.length}%%%`;\n inlineCodes.push(escapeHtml(code));\n return placeholder;\n });\n \n // Now escape HTML in the rest of the content\n html = escapeHtml(html);\n \n // Phase 2: Process block elements\n \n // Process tables\n html = processTable(html, inline_styles, styles);\n \n // Process headings (supports optional trailing #'s)\n html = html.replace(/^(#{1,6})\\s+(.+?)\\s*#*$/gm, (match, hashes, content) => {\n const level = hashes.length;\n return `<h${level}${getAttr('h' + level)}>${content}</h${level}>`;\n });\n \n // Process blockquotes (must handle escaped > since we already escaped HTML)\n html = html.replace(/^&gt;\\s+(.+)$/gm, `<blockquote${getAttr('blockquote')}>$1</blockquote>`);\n // Merge consecutive blockquotes\n html = html.replace(/<\\/blockquote>\\n<blockquote>/g, '\\n');\n \n // Process horizontal rules\n html = html.replace(/^---+$/gm, `<hr${getAttr('hr')}>`);\n \n // Process lists\n html = processLists(html, inline_styles, styles);\n \n // Phase 3: Process inline elements\n \n // Images (must come before links, with URL sanitization)\n html = html.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (match, alt, src) => {\n const sanitizedSrc = sanitizeUrl(src, options.allow_unsafe_urls);\n return `<img${getAttr('img')} src=\"${sanitizedSrc}\" alt=\"${alt}\">`;\n });\n \n // Links (with URL sanitization)\n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (match, text, href) => {\n // Sanitize URL to prevent XSS\n const sanitizedHref = sanitizeUrl(href, options.allow_unsafe_urls);\n const isExternal = /^https?:\\/\\//i.test(sanitizedHref);\n const rel = isExternal ? ' rel=\"noopener noreferrer\"' : '';\n return `<a${getAttr('a')} href=\"${sanitizedHref}\"${rel}>${text}</a>`;\n });\n \n // Autolinks - convert bare URLs to clickable links\n html = html.replace(/(^|\\s)(https?:\\/\\/[^\\s<]+)/g, (match, prefix, url) => {\n const sanitizedUrl = sanitizeUrl(url, options.allow_unsafe_urls);\n return `${prefix}<a${getAttr('a')} href=\"${sanitizedUrl}\" rel=\"noopener noreferrer\">${url}</a>`;\n });\n \n // Bold (must use non-greedy matching)\n html = html.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n html = html.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Italic (must not match bold markers)\n html = html.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n html = html.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Strikethrough\n html = html.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Line breaks (two spaces at end of line)\n html = html.replace(/ $/gm, `<br${getAttr('br')}>`);\n \n // Paragraphs (double newlines)\n html = html.replace(/\\n\\n+/g, '</p><p>');\n html = '<p>' + html + '</p>';\n \n // Clean up empty paragraphs and unwrap block elements (account for attributes)\n html = html.replace(/<p><\\/p>/g, '');\n html = html.replace(/<p>(<h[1-6][^>]*>)/g, '$1');\n html = html.replace(/(<\\/h[1-6]>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<blockquote[^>]*>)/g, '$1');\n html = html.replace(/(<\\/blockquote>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g, '$1');\n html = html.replace(/(<\\/ul>|<\\/ol>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<hr[^>]*>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<table[^>]*>)/g, '$1');\n html = html.replace(/(<\\/table>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<pre[^>]*>)/g, '$1');\n html = html.replace(/(<\\/pre>)<\\/p>/g, '$1');\n // Also unwrap code block placeholders\n html = html.replace(/<p>(%%%CODEBLOCK\\d+%%%)<\\/p>/g, '$1');\n \n // Phase 4: Restore code blocks and inline code\n \n // Restore code blocks\n codeBlocks.forEach((block, i) => {\n let replacement;\n \n if (block.custom && fence_plugin) {\n // Use custom fence plugin\n replacement = fence_plugin(block.code, block.lang);\n // If plugin returns undefined, fall back to default rendering\n if (replacement === undefined) {\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${escapeHtml(block.code)}</code></pre>`;\n }\n } else {\n // Default rendering\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n replacement = `<pre${getAttr('pre')}><code${codeAttr}>${block.code}</code></pre>`;\n }\n \n const placeholder = `%%%CODEBLOCK${i}%%%`;\n html = html.replace(placeholder, replacement);\n });\n \n // Restore inline code\n inlineCodes.forEach((code, i) => {\n const placeholder = `%%%INLINECODE${i}%%%`;\n html = html.replace(placeholder, `<code${getAttr('code')}>${code}</code>`);\n });\n \n return html.trim();\n}\n\n/**\n * Process inline markdown formatting\n */\nfunction processInlineMarkdown(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n // Process bold\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong')}>$1</strong>`);\n text = text.replace(/__(.+?)__/g, `<strong${getAttr('strong')}>$1</strong>`);\n \n // Process italic (must not match bold markers)\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em')}>$1</em>`);\n text = text.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em')}>$1</em>`);\n \n // Process strikethrough\n text = text.replace(/~~(.+?)~~/g, `<del${getAttr('del')}>$1</del>`);\n \n // Process inline code\n text = text.replace(/`([^`]+)`/g, `<code${getAttr('code')}>$1</code>`);\n \n return text;\n}\n\n/**\n * Process markdown tables\n */\nfunction processTable(text, inline_styles, styles) {\n const lines = text.split('\\n');\n const result = [];\n let inTable = false;\n let tableLines = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Check if this line looks like a table row (with or without trailing |)\n if (line.includes('|') && (line.startsWith('|') || /[^\\\\|]/.test(line))) {\n if (!inTable) {\n inTable = true;\n tableLines = [];\n }\n tableLines.push(line);\n } else {\n // Not a table line\n if (inTable) {\n // Process the accumulated table\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n // Not a valid table, restore original lines\n result.push(...tableLines);\n }\n inTable = false;\n tableLines = [];\n }\n result.push(lines[i]);\n }\n }\n \n // Handle table at end of text\n if (inTable && tableLines.length > 0) {\n const tableHtml = buildTable(tableLines, inline_styles, styles);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n result.push(...tableLines);\n }\n }\n \n return result.join('\\n');\n}\n\n/**\n * Build an HTML table from markdown table lines\n */\nfunction buildTable(lines, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n if (lines.length < 2) return null;\n \n // Check for separator line (second line should be the separator)\n let separatorIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n // Support separator with or without leading/trailing pipes\n if (/^\\|?[\\s\\-:|]+\\|?$/.test(lines[i]) && lines[i].includes('-')) {\n separatorIndex = i;\n break;\n }\n }\n \n if (separatorIndex === -1) return null;\n \n const headerLines = lines.slice(0, separatorIndex);\n const bodyLines = lines.slice(separatorIndex + 1);\n \n // Parse alignment from separator\n const separator = lines[separatorIndex];\n // Handle pipes at start/end or not\n const separatorCells = separator.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n const alignments = separatorCells.map(cell => {\n const trimmed = cell.trim();\n if (trimmed.startsWith(':') && trimmed.endsWith(':')) return 'center';\n if (trimmed.endsWith(':')) return 'right';\n return 'left';\n });\n \n let html = `<table${getAttr('table')}>\\n`;\n \n // Build header\n if (headerLines.length > 0) {\n html += `<thead${getAttr('thead')}>\\n`;\n headerLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<th${getAttr('th', alignStyle)}>${processedCell}</th>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</thead>\\n';\n }\n \n // Build body\n if (bodyLines.length > 0) {\n html += `<tbody${getAttr('tbody')}>\\n`;\n bodyLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align: ${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), inline_styles, styles);\n html += `<td${getAttr('td', alignStyle)}>${processedCell}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n \n html += '</table>';\n return html;\n}\n\n/**\n * Process markdown lists (ordered and unordered)\n */\nfunction processLists(text, inline_styles, styles) {\n // Helper to get attributes\n function getAttr(tag, additionalStyle = '') {\n if (inline_styles) {\n const style = styles[tag] || '';\n const fullStyle = additionalStyle ? `${style}; ${additionalStyle}` : style;\n return fullStyle ? ` style=\"${fullStyle}\"` : '';\n } else {\n return ` class=\"quikdown-${tag}\"`;\n }\n }\n \n const lines = text.split('\\n');\n const result = [];\n let listStack = []; // Track nested lists\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.+)$/);\n \n if (match) {\n const [, indent, marker, content] = match;\n const level = Math.floor(indent.length / 2);\n const isOrdered = /^\\d+\\./.test(marker);\n const listType = isOrdered ? 'ol' : 'ul';\n \n // Check for task list items\n let listItemContent = content;\n let taskListClass = '';\n const taskMatch = content.match(/^\\[([x ])\\]\\s+(.*)$/i);\n if (taskMatch && !isOrdered) {\n const [, checked, taskContent] = taskMatch;\n const isChecked = checked.toLowerCase() === 'x';\n const checkboxAttr = inline_styles \n ? ' style=\"margin-right: 0.5em\"' \n : ' class=\"quikdown-task-checkbox\"';\n listItemContent = `<input type=\"checkbox\"${checkboxAttr}${isChecked ? ' checked' : ''} disabled> ${taskContent}`;\n taskListClass = inline_styles ? ' style=\"list-style: none\"' : ' class=\"quikdown-task-item\"';\n }\n \n // Close deeper levels\n while (listStack.length > level + 1) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n // Open new level if needed\n if (listStack.length === level) {\n // Need to open a new list\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n } else if (listStack.length === level + 1) {\n // Check if we need to switch list type\n const currentList = listStack[listStack.length - 1];\n if (currentList.type !== listType) {\n result.push(`</${currentList.type}>`);\n listStack.pop();\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n }\n }\n \n const liAttr = taskListClass || getAttr('li');\n result.push(`<li${liAttr}>${listItemContent}</li>`);\n } else {\n // Not a list item, close all lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n result.push(line);\n }\n }\n \n // Close any remaining lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n return result.join('\\n');\n}\n\n/**\n * Emit CSS styles for quikdown elements\n * @returns {string} CSS string with quikdown styles\n */\nquikdown.emitStyles = function() {\n const styles = {\n h1: 'font-size: 2em; font-weight: 600; margin: 0.67em 0; text-align: left',\n h2: 'font-size: 1.5em; font-weight: 600; margin: 0.83em 0',\n h3: 'font-size: 1.25em; font-weight: 600; margin: 1em 0',\n h4: 'font-size: 1em; font-weight: 600; margin: 1.33em 0',\n h5: 'font-size: 0.875em; font-weight: 600; margin: 1.67em 0',\n h6: 'font-size: 0.85em; font-weight: 600; margin: 2em 0',\n pre: 'background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; margin: 1em 0',\n code: 'background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace',\n blockquote: 'border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em',\n table: 'border-collapse: collapse; width: 100%; margin: 1em 0',\n th: 'border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold; text-align: left',\n td: 'border: 1px solid #ddd; padding: 8px; text-align: left',\n hr: 'border: none; border-top: 1px solid #ddd; margin: 1em 0',\n img: 'max-width: 100%; height: auto',\n a: 'color: #0066cc; text-decoration: underline',\n strong: 'font-weight: bold',\n em: 'font-style: italic',\n del: 'text-decoration: line-through',\n ul: 'margin: 0.5em 0; padding-left: 2em',\n ol: 'margin: 0.5em 0; padding-left: 2em',\n li: 'margin: 0.25em 0',\n 'task-item': 'list-style: none',\n 'task-checkbox': 'margin-right: 0.5em'\n };\n \n let css = '';\n for (const [tag, style] of Object.entries(styles)) {\n if (style) {\n css += `.quikdown-${tag} { ${style} }\\n`;\n }\n }\n \n return css;\n};\n\n/**\n * Configure quikdown with options and return a function\n * @param {Object} options - Configuration options\n * @returns {Function} Configured quikdown function\n */\nquikdown.configure = function(options) {\n return function(markdown) {\n return quikdown(markdown, options);\n };\n};\n\n/**\n * Version information\n */\nquikdown.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown;\n}\n\n// For browser global\nif (typeof window !== 'undefined') {\n window.quikdown = quikdown;\n}\n\nexport default quikdown;","// Auto-generated version file - DO NOT EDIT MANUALLY\n// This file is automatically updated by tools/updateVersion.js\n\nexport const quikdownVersion = \"1.0.2\";\n\nexport default quikdownVersion;"],"names":["quikdown","markdown","options","fence_plugin","inline_styles","styles","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","thead","tbody","tr","th","td","hr","img","a","strong","em","del","ul","ol","li","br","getAttr","tag","additionalStyle","style","fullStyle","escapeHtml","text","map","replace","m","sanitizeUrl","url","allowUnsafe","trimmedUrl","trim","lowerUrl","toLowerCase","dangerousProtocols","protocol","startsWith","html","codeBlocks","inlineCodes","match","fence","lang","placeholder","length","langTrimmed","push","trimEnd","custom","lines","split","result","inTable","tableLines","i","line","includes","test","tableHtml","buildTable","join","processTable","hashes","content","level","listStack","indent","marker","Math","floor","isOrdered","listType","listItemContent","taskListClass","taskMatch","checked","taskContent","isChecked","list","pop","type","currentList","liAttr","processLists","alt","src","sanitizedSrc","allow_unsafe_urls","href","sanitizedHref","rel","prefix","sanitizedUrl","forEach","block","replacement","undefined","langClass","codeAttr","processInlineMarkdown","separatorIndex","headerLines","slice","bodyLines","alignments","cell","trimmed","endsWith","alignStyle","processedCell","emitStyles","css","Object","entries","configure","version","module","exports","window"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quikdown",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "quikdown is a simple markdown to HTML parser that supports fences",
5
5
  "author": "deftio (https://github.com/deftio",
6
6
  "license": "BSD-2-Clause",