quikdown 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -499
- package/dist/quikdown.cjs +130 -48
- package/dist/quikdown.d.ts +40 -5
- package/dist/quikdown.dark.css +1 -1
- package/dist/quikdown.esm.js +130 -48
- package/dist/quikdown.esm.min.js +2 -2
- package/dist/quikdown.esm.min.js.map +1 -1
- package/dist/quikdown.light.css +1 -1
- package/dist/quikdown.umd.js +130 -48
- package/dist/quikdown.umd.min.js +2 -2
- package/dist/quikdown.umd.min.js.map +1 -1
- package/dist/quikdown_bd.cjs +652 -260
- package/dist/quikdown_bd.d.ts +53 -19
- package/dist/quikdown_bd.esm.js +652 -260
- package/dist/quikdown_bd.esm.min.js +2 -2
- package/dist/quikdown_bd.esm.min.js.map +1 -1
- package/dist/quikdown_bd.umd.js +652 -260
- package/dist/quikdown_bd.umd.min.js +2 -2
- package/dist/quikdown_bd.umd.min.js.map +1 -1
- package/dist/quikdown_edit.cjs +2474 -0
- package/dist/quikdown_edit.d.ts +195 -0
- package/dist/quikdown_edit.esm.js +2472 -0
- package/dist/quikdown_edit.esm.min.js +14 -0
- package/dist/quikdown_edit.esm.min.js.map +1 -0
- package/dist/quikdown_edit.umd.js +2480 -0
- package/dist/quikdown_edit.umd.min.js +14 -0
- package/dist/quikdown_edit.umd.min.js.map +1 -0
- package/package.json +71 -29
- package/dist/quikdown-lex.cjs +0 -810
- package/dist/quikdown-lex.esm.js +0 -808
- package/dist/quikdown-lex.esm.min.js +0 -8
- package/dist/quikdown-lex.esm.min.js.map +0 -1
- package/dist/quikdown-lex.umd.js +0 -816
- package/dist/quikdown-lex.umd.min.js +0 -8
- package/dist/quikdown-lex.umd.min.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,605 +4,235 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/quikdown)
|
|
5
5
|
[](https://github.com/deftio/quikdown)
|
|
6
6
|
[](https://opensource.org/licenses/BSD-2-Clause)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- [Features](#features)
|
|
20
|
-
- [Installation](#installation)
|
|
21
|
-
- [Quick Start](#quick-start)
|
|
22
|
-
- [Bidirectional Conversion](#bidirectional-conversion-new)
|
|
23
|
-
- [Supported Markdown](#supported-markdown)
|
|
24
|
-
- [Configuration Options](#configuration-options)
|
|
25
|
-
- [Plugin System](#plugin-system)
|
|
26
|
-
- [Framework Integration](#framework-integration)
|
|
27
|
-
- [API Reference](#api-reference)
|
|
28
|
-
- [Security](#security)
|
|
29
|
-
- [Contributing](#contributing)
|
|
7
|
+
|
|
8
|
+
Quikdown is a small, secure markdown parser with bidirectional conversion. Zero dependencies, XSS protection built-in, extensible via plugins for code highlighting and diagrams, and works in browser and Node.js.
|
|
9
|
+
|
|
10
|
+
For small and fast projects quikdown includes built-in inline styles for a "batteries included" rendering experience, but these can be overridden with themed css (see light and dark examples).
|
|
11
|
+
|
|
12
|
+
- **quikdown.js** (9.0KB) - Markdown to HTML Parser
|
|
13
|
+
- **quikdown_bd.js** (13.8KB) - Bidirectional (HTML ↔ Markdown) Parser
|
|
14
|
+
- **quikdown_edit.js** (37.8KB) - Drop-in editor component (HTML ↔ Markdown) with md/split/html views
|
|
15
|
+
|
|
16
|
+
🚀 **[Live Demo](https://deftio.github.io/quikdown/examples/quikdown-live.html)** | **[Editor Demo](https://deftio.github.io/quikdown/examples/qde/)** | **[Documentation](docs/)**
|
|
17
|
+
|
|
18
|
+
📍 **Quick Links:** [Installation](#installation) • [Quick Start](#quick-start) • [API](#api-reference) • [TypeScript](#typescript-support) • [Plugins](#fence-plugins) • [Examples](examples/)
|
|
30
19
|
|
|
31
20
|
## Features
|
|
32
21
|
|
|
33
22
|
- 📦 **Zero dependencies** - No external libraries required
|
|
34
23
|
- 🌐 **Universal** - Works in browsers and Node.js
|
|
35
|
-
- 🚀 **Lightweight** -
|
|
24
|
+
- 🚀 **Lightweight** - 9.0KB (core), 13.8KB (bidirectional), 37.8KB (editor)
|
|
36
25
|
- 🔒 **Secure by default** - Built-in XSS protection with URL sanitization
|
|
37
|
-
- 🎨 **Flexible styling** - Inline styles or CSS classes
|
|
26
|
+
- 🎨 **Flexible styling** - Inline styles or CSS classes with theme support
|
|
38
27
|
- 🔌 **Plugin system** - Extensible fence block handlers
|
|
39
28
|
- ⚡ **Fast** - Optimized regex-based parsing
|
|
40
|
-
- 📝 **CommonMark subset** -
|
|
29
|
+
- 📝 **CommonMark subset** - Essential markdown features
|
|
41
30
|
- ✅ **Task Lists** - GitHub-style checkboxes
|
|
42
31
|
- 🔗 **Autolinks** - Automatic URL detection
|
|
43
|
-
- 🔄 **Bidirectional** - Convert HTML back to Markdown (
|
|
32
|
+
- 🔄 **Bidirectional** - Convert HTML back to Markdown (quikdown_bd)
|
|
33
|
+
- 💬 **Lazy linefeeds** - Single newlines become line breaks (configurable)
|
|
34
|
+
- 📱 **Editor component** - Drop-in markdown editor with live preview
|
|
44
35
|
|
|
45
36
|
## Installation
|
|
46
37
|
|
|
38
|
+
Quikdown is available via [NPM](https://www.npmjs.com/package/quikdown) and related [unpkg](https://unpkg.com/quikdown) and [jsdelivr](https://cdn.jsdelivr.net/npm/quikdown)
|
|
39
|
+
|
|
40
|
+
### NPM package
|
|
47
41
|
```bash
|
|
48
42
|
npm install quikdown
|
|
49
43
|
```
|
|
50
44
|
|
|
51
|
-
|
|
45
|
+
### CDN using UNPKG
|
|
52
46
|
|
|
53
|
-
**ES Modules
|
|
47
|
+
**CDN (ES Modules):**
|
|
54
48
|
```html
|
|
55
49
|
<script type="module">
|
|
56
50
|
import quikdown from 'https://unpkg.com/quikdown/dist/quikdown.esm.min.js';
|
|
57
|
-
|
|
58
|
-
const html = quikdown('# Hello World');
|
|
59
|
-
document.body.innerHTML = html;
|
|
51
|
+
document.body.innerHTML = quikdown('# Hello World');
|
|
60
52
|
</script>
|
|
61
53
|
```
|
|
62
54
|
|
|
63
|
-
**
|
|
55
|
+
**CDN (UMD):**
|
|
64
56
|
```html
|
|
65
57
|
<script src="https://unpkg.com/quikdown/dist/quikdown.umd.min.js"></script>
|
|
66
58
|
<script>
|
|
67
|
-
|
|
68
|
-
const html = quikdown('# Hello World');
|
|
59
|
+
document.body.innerHTML = quikdown('# Hello World');
|
|
69
60
|
</script>
|
|
70
61
|
```
|
|
71
62
|
|
|
72
|
-
> **Production tip:** Pin to a specific version for stability (e.g., `https://unpkg.com/quikdown@1.0.4/dist/quikdown.esm.min.js`)
|
|
73
|
-
|
|
74
63
|
## Quick Start
|
|
75
64
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
```javascript
|
|
79
|
-
import quikdown from 'quikdown';
|
|
65
|
+
Quikdown is built in 3 versions. The smallest (quikdown) provides markdown to html conversion only. The next (quikdown_bd) provides markdown to html and html to markdown support. The lightweight editor quikdown_edit allows a bidirectional editor with lazy loading for common fences such as codeblocks, svg, and mermaid diagrams is also provided.
|
|
80
66
|
|
|
81
|
-
|
|
82
|
-
const html = quikdown(markdown);
|
|
83
|
-
console.log(html);
|
|
84
|
-
// Output: <h1>Hello World</h1><p>This is <strong>bold</strong> text.</p>
|
|
85
|
-
|
|
86
|
-
// Note: Regular quikdown does NOT support HTML to Markdown conversion
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Bidirectional Usage (Two-way conversion)
|
|
67
|
+
### Markdown → HTML (quikdown.js)
|
|
90
68
|
|
|
91
69
|
```javascript
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
70
|
+
// Basic conversion
|
|
71
|
+
const html = quikdown('# Hello World',
|
|
72
|
+
{inline_styles: true} // Use inline styles, more options in API docs
|
|
73
|
+
);
|
|
96
74
|
|
|
97
|
-
|
|
98
|
-
const html = quikdown_bd(markdown);
|
|
75
|
+
document.body.innerHTML = html;
|
|
99
76
|
|
|
100
|
-
// HTML back to Markdown (only available in quikdown_bd)
|
|
101
|
-
const recoveredMarkdown = quikdown_bd.toMarkdown(html);
|
|
102
|
-
console.log(recoveredMarkdown);
|
|
103
|
-
// Output: # Hello World\n\nThis is **bold** text.
|
|
104
77
|
```
|
|
105
78
|
|
|
106
|
-
###
|
|
79
|
+
### Bidirectional Markdown ↔ HTML (quikdown_bd.js)
|
|
107
80
|
|
|
108
81
|
```javascript
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
fence_plugin: myFenceHandler // Custom code fence handler
|
|
112
|
-
});
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### TypeScript Support
|
|
116
|
-
|
|
117
|
-
quikdown includes TypeScript definitions for better IDE support and type safety:
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
import quikdown, { QuikdownOptions } from 'quikdown';
|
|
82
|
+
// Convert with source tracking
|
|
83
|
+
const htmlString = quikdown_bd(markdown, options);
|
|
121
84
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
fence_plugin: (content: string, language: string) => {
|
|
125
|
-
return `<pre class="hljs ${language}">${content}</pre>`;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const html: string = quikdown(markdown, options);
|
|
85
|
+
// Convert HTML back to Markdown
|
|
86
|
+
const markdown = quikdown_bd.toMarkdown(htmlString);
|
|
130
87
|
```
|
|
131
88
|
|
|
132
|
-
|
|
89
|
+
Note: quikdown does not provide a *generic* html to markdown conversion but uses special tags and limited DOM parsing for HTML to markdown conversion. Standard markdown components such as headings, text styles, tables, quotes, etc are supported. For custom fences quikdown relies on its tag system or 3rd party handlers to provide reverse (html to md) conversion.
|
|
133
90
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
### Text Formatting
|
|
137
|
-
- **Bold**: `**text**` or `__text__`
|
|
138
|
-
- *Italic*: `*text*` or `_text_`
|
|
139
|
-
- ~~Strikethrough~~: `~~text~~`
|
|
140
|
-
- `Code`: `` `code` ``
|
|
141
|
-
|
|
142
|
-
### Headings
|
|
143
|
-
```markdown
|
|
144
|
-
# H1 Heading
|
|
145
|
-
## H2 Heading
|
|
146
|
-
### H3 Heading
|
|
147
|
-
#### H4 Heading
|
|
148
|
-
##### H5 Heading
|
|
149
|
-
###### H6 Heading
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Lists
|
|
91
|
+
### Editor (quikdown_edit.js)
|
|
153
92
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
-
|
|
159
|
-
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Ordered:
|
|
163
|
-
```markdown
|
|
164
|
-
1. First item
|
|
165
|
-
2. Second item
|
|
166
|
-
1. Nested item
|
|
167
|
-
```
|
|
93
|
+
```javascript
|
|
94
|
+
const editor = new QuikdownEditor('#container', {
|
|
95
|
+
mode: 'split', // 'source', 'split', 'preview'
|
|
96
|
+
theme: 'auto', // 'light', 'dark', 'auto'
|
|
97
|
+
plugins: { highlightjs: true, mermaid: true } // built-in fence handlers, see API docs for custom plugins
|
|
98
|
+
});
|
|
168
99
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- [x] Completed task
|
|
172
|
-
- [ ] Pending task
|
|
173
|
-
- [ ] Another todo
|
|
100
|
+
editor.setMarkdown('# Content \nTo be quik or not to be.'); // provide default content
|
|
101
|
+
const content = editor.getMarkdown(); // get source content, see APIs for getting / setting HTML
|
|
174
102
|
```
|
|
175
103
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
[Link text](https://example.com)
|
|
179
|
-

|
|
104
|
+
## Other Configuration Options
|
|
105
|
+
quikdown supports built-in styles for a "batteries included" experience or you can bring your own CSS themes. Example css files are provided for basic light and dark themes to get started.
|
|
180
106
|
|
|
181
|
-
// Autolinks - URLs are automatically linked
|
|
182
|
-
Visit https://github.com for more info
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### Code Blocks
|
|
186
|
-
````markdown
|
|
187
107
|
```javascript
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
````
|
|
196
|
-
|
|
197
|
-
### Tables
|
|
198
|
-
```markdown
|
|
199
|
-
| Header 1 | Header 2 |
|
|
200
|
-
|----------|----------|
|
|
201
|
-
| Cell 1 | Cell 2 |
|
|
202
|
-
| Cell 3 | Cell 4 |
|
|
108
|
+
const html = quikdown(markdown, {
|
|
109
|
+
lazy_linefeeds: true, // Single newlines become <br>
|
|
110
|
+
inline_styles: false, // Use class based CSS instead of inline styles
|
|
111
|
+
fence_plugin: { // Custom code block processor (v1.1.0+ API)
|
|
112
|
+
render: myHandler // Function to render fence blocks
|
|
113
|
+
}
|
|
114
|
+
});
|
|
203
115
|
```
|
|
204
116
|
|
|
205
|
-
###
|
|
206
|
-
- **Blockquotes**: `> Quote text`
|
|
207
|
-
- **Horizontal rules**: `---` or `***` or `___`
|
|
208
|
-
- **Line breaks**: Two spaces at end of line or `<br>`
|
|
209
|
-
|
|
210
|
-
## Configuration Options
|
|
211
|
-
|
|
212
|
-
### `inline_styles` (boolean)
|
|
213
|
-
When `true`, uses inline styles for formatting. When `false`, uses CSS classes.
|
|
117
|
+
### Styling Options
|
|
214
118
|
|
|
119
|
+
**Inline styles:** All formatting uses inline CSS
|
|
215
120
|
```javascript
|
|
216
|
-
// With inline_styles: true
|
|
217
121
|
quikdown('**bold**', { inline_styles: true });
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
// With inline_styles: false (default)
|
|
221
|
-
quikdown('**bold**', { inline_styles: false });
|
|
222
|
-
// Output: <strong>bold</strong>
|
|
122
|
+
// <strong style="font-weight: bold;">bold</strong>
|
|
223
123
|
```
|
|
224
124
|
|
|
225
|
-
|
|
226
|
-
Custom handler for fenced code blocks. Useful for syntax highlighting or diagrams.
|
|
227
|
-
|
|
125
|
+
**Class-based styling:** Uses CSS classes (default)
|
|
228
126
|
```javascript
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
// Return undefined to use default handling
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const html = quikdown(markdown, { fence_plugin: fencePlugin });
|
|
127
|
+
quikdown('**bold**');
|
|
128
|
+
// <strong>bold</strong>
|
|
129
|
+
// Requires CSS: .quikdown strong { font-weight: bold; }
|
|
130
|
+
// see included dist/quikdown.light.css or quikdown.dark.css
|
|
237
131
|
```
|
|
238
132
|
|
|
239
|
-
|
|
133
|
+
### Fence Plugins
|
|
240
134
|
|
|
241
|
-
|
|
135
|
+
Quikdown provides a callback for all fenced text such as code blocks, math, svg etc.
|
|
242
136
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
Fence plugins allow you to customize how code blocks are rendered:
|
|
137
|
+
Handle code blocks with custom languages:
|
|
246
138
|
|
|
247
139
|
```javascript
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (language === 'graph') {
|
|
251
|
-
return renderGraph(code);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Add syntax highlighting
|
|
255
|
-
if (language && hljs.getLanguage(language)) {
|
|
256
|
-
const highlighted = hljs.highlight(code, { language }).value;
|
|
257
|
-
return `<pre><code class="language-${language}">${highlighted}</code></pre>`;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Return undefined for default handling
|
|
261
|
-
return undefined;
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### Example: Mermaid Diagrams
|
|
266
|
-
|
|
267
|
-
```javascript
|
|
268
|
-
function mermaidPlugin(code, language) {
|
|
140
|
+
const fencePlugin = {
|
|
141
|
+
render: (code, language) => {
|
|
269
142
|
if (language === 'mermaid') {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}, 0);
|
|
277
|
-
return `<div id="${id}" class="mermaid">Loading diagram...</div>`;
|
|
143
|
+
// Process with mermaid library and return rendered diagram
|
|
144
|
+
const id = 'mermaid-' + Math.random().toString(36).substr(2, 9);
|
|
145
|
+
setTimeout(() => mermaid.render(id + '-svg', code).then(result => {
|
|
146
|
+
document.getElementById(id).innerHTML = result.svg;
|
|
147
|
+
}), 0);
|
|
148
|
+
return `<div id="${id}" class="mermaid">Loading diagram...</div>`;
|
|
278
149
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
fence_plugin: mermaidPlugin
|
|
283
|
-
});
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Security
|
|
287
|
-
|
|
288
|
-
For detailed security information, see [docs/security.md](docs/security.md)
|
|
289
|
-
|
|
290
|
-
quikdown includes built-in XSS protection:
|
|
291
|
-
|
|
292
|
-
- All HTML tags in markdown are escaped by default
|
|
293
|
-
- Attributes are sanitized
|
|
294
|
-
- JavaScript URLs are blocked
|
|
295
|
-
- Only safe markdown constructs are converted to HTML
|
|
150
|
+
// Return undefined for default handling
|
|
151
|
+
}
|
|
152
|
+
};
|
|
296
153
|
|
|
297
|
-
|
|
298
|
-
const unsafe = '<script>alert("XSS")</script> **bold**';
|
|
299
|
-
const safe = quikdown(unsafe);
|
|
300
|
-
// Output: <script>alert("XSS")</script> <strong>bold</strong>
|
|
154
|
+
const html = quikdown(markdown, { fence_plugin: fencePlugin });
|
|
301
155
|
```
|
|
302
156
|
|
|
303
|
-
## Bidirectional Conversion (1.0.4+)
|
|
304
157
|
|
|
305
|
-
|
|
158
|
+
## TypeScript Support
|
|
306
159
|
|
|
307
|
-
|
|
160
|
+
quikdown includes TypeScript definitions for better IDE support and type safety:
|
|
308
161
|
|
|
309
|
-
|
|
162
|
+
```typescript
|
|
163
|
+
import quikdown, { QuikdownOptions, FencePlugin } from 'quikdown';
|
|
310
164
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
165
|
+
const fencePlugin: FencePlugin = {
|
|
166
|
+
render: (content: string, language: string) => {
|
|
167
|
+
return `<pre class="hljs ${language}">${content}</pre>`;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
314
170
|
|
|
315
|
-
|
|
316
|
-
|
|
171
|
+
const options: QuikdownOptions = {
|
|
172
|
+
inline_styles: true,
|
|
173
|
+
fence_plugin: fencePlugin
|
|
174
|
+
};
|
|
317
175
|
|
|
318
|
-
|
|
319
|
-
<script src="https://unpkg.com/quikdown/dist/quikdown_bd.umd.min.js"></script>
|
|
320
|
-
<script>
|
|
321
|
-
// Available as window.quikdown_bd
|
|
322
|
-
const html = quikdown_bd(markdown);
|
|
323
|
-
</script>
|
|
176
|
+
const html: string = quikdown(markdown, options);
|
|
324
177
|
```
|
|
325
178
|
|
|
326
|
-
|
|
179
|
+
## Supported Markdown
|
|
327
180
|
|
|
328
|
-
|
|
329
|
-
// IMPORTANT: Use quikdown_bd for bidirectional support
|
|
330
|
-
import quikdown_bd from 'quikdown/bd';
|
|
181
|
+
**Text formatting:** `**bold**`, `*italic*`, `~~strikethrough~~`, `` `code` ``
|
|
331
182
|
|
|
332
|
-
|
|
333
|
-
const html = quikdown_bd('**Hello** world', { bidirectional: true });
|
|
334
|
-
console.log(html);
|
|
335
|
-
// <strong data-qd="**">Hello</strong> world
|
|
183
|
+
**Headings:** `# H1` through `###### H6`
|
|
336
184
|
|
|
337
|
-
|
|
338
|
-
const markdown = quikdown_bd.toMarkdown(html);
|
|
339
|
-
console.log(markdown);
|
|
340
|
-
// **Hello** world
|
|
185
|
+
**Lists:**
|
|
341
186
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
187
|
+
- Unordered lists
|
|
188
|
+
1. Ordered lists
|
|
189
|
+
- [x] Task lists
|
|
345
190
|
|
|
346
|
-
|
|
191
|
+
**Links:** `[text](url)` and automatic URL detection
|
|
347
192
|
|
|
348
|
-
|
|
349
|
-
- **Content Migration**: Convert existing HTML content to Markdown
|
|
350
|
-
- **Round-trip Preservation**: Maintain markdown source formatting through HTML conversion
|
|
351
|
-
- **Collaborative Editing**: Enable rich-text editing while storing content as Markdown
|
|
193
|
+
**Code blocks:**
|
|
352
194
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
```html
|
|
356
|
-
<div id="editor" contenteditable="true"></div>
|
|
357
|
-
<script type="module">
|
|
358
|
-
import quikdown_bd from 'https://unpkg.com/quikdown/dist/quikdown_bd.esm.min.js';
|
|
359
|
-
|
|
360
|
-
const editor = document.getElementById('editor');
|
|
361
|
-
const markdown = '# Edit me\n\n**Bold** and *italic*';
|
|
362
|
-
|
|
363
|
-
// Convert to HTML and display
|
|
364
|
-
editor.innerHTML = quikdown_bd(markdown, { bidirectional: true });
|
|
365
|
-
|
|
366
|
-
// Convert back to Markdown when needed
|
|
367
|
-
editor.addEventListener('blur', () => {
|
|
368
|
-
const updatedMarkdown = quikdown_bd.toMarkdown(editor);
|
|
369
|
-
console.log('Updated markdown:', updatedMarkdown);
|
|
370
|
-
});
|
|
371
|
-
</script>
|
|
195
|
+
```javascript
|
|
196
|
+
console.log('syntax highlighting support via plugins');
|
|
372
197
|
```
|
|
373
198
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
## Quikdown Lexer Version
|
|
377
|
-
|
|
378
|
-
An experimental lexer-based implementation is available for testing. See [docs/lexer-implementation.md](docs/lexer-implementation.md) for details.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
## Framework Integration
|
|
382
|
-
|
|
383
|
-
quikdown integrates seamlessly with modern JavaScript frameworks:
|
|
384
|
-
|
|
385
|
-
- **React** - Hooks, components, and Next.js support
|
|
386
|
-
- **Vue** - Composition API, Options API, and Nuxt support
|
|
387
|
-
- **Svelte** - Reactive statements and stores
|
|
388
|
-
- **Angular** - Components, services, and pipes
|
|
389
|
-
|
|
390
|
-
See the [Framework Integration Guide](docs/framework-integration.md) for detailed examples and best practices.
|
|
199
|
+
**Tables, blockquotes, horizontal rules** - See [documentation](docs/) for complete syntax reference
|
|
391
200
|
|
|
392
201
|
## API Reference
|
|
393
202
|
|
|
394
203
|
For complete API documentation, see [docs/api-reference.md](docs/api-reference.md)
|
|
395
204
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
#### `quikdown(markdown, options?)`
|
|
399
|
-
|
|
400
|
-
Main function to convert markdown to HTML.
|
|
401
|
-
|
|
402
|
-
**Parameters:**
|
|
403
|
-
- `markdown` (string): The markdown text to convert
|
|
404
|
-
- `options` (object, optional):
|
|
405
|
-
- `inline_styles` (boolean): Use inline styles instead of classes
|
|
406
|
-
- `fence_plugin` (function): Custom fence block handler
|
|
407
|
-
|
|
408
|
-
**Returns:** HTML string
|
|
409
|
-
|
|
410
|
-
#### `quikdown.configure(options)`
|
|
411
|
-
|
|
412
|
-
Creates a configured instance of the parser.
|
|
413
|
-
|
|
414
|
-
```javascript
|
|
415
|
-
const myParser = quikdown.configure({
|
|
416
|
-
inline_styles: true,
|
|
417
|
-
fence_plugin: myPlugin
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
// Use the configured parser
|
|
421
|
-
const html = myParser(markdown);
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
#### `quikdown.emitStyles(prefix?, theme?)`
|
|
425
|
-
|
|
426
|
-
Returns CSS styles for quikdown HTML output when not using inline styles.
|
|
427
|
-
|
|
428
|
-
```javascript
|
|
429
|
-
// Get light theme CSS
|
|
430
|
-
const lightStyles = quikdown.emitStyles();
|
|
431
|
-
|
|
432
|
-
// Get dark theme CSS
|
|
433
|
-
const darkStyles = quikdown.emitStyles('quikdown-', 'dark');
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
### Bidirectional API
|
|
437
|
-
|
|
438
|
-
**⚠️ These methods are only available in `quikdown_bd`, not in regular `quikdown`:**
|
|
439
|
-
|
|
440
|
-
#### `quikdown_bd(markdown, options?)`
|
|
441
|
-
|
|
442
|
-
Converts markdown to HTML with source tracking for bidirectional conversion.
|
|
443
|
-
|
|
444
|
-
#### `quikdown_bd.toMarkdown(htmlOrElement)`
|
|
445
|
-
|
|
446
|
-
Converts HTML back to Markdown. **This method only exists in `quikdown_bd`.**
|
|
447
|
-
|
|
448
|
-
**Parameters:**
|
|
449
|
-
- `htmlOrElement` (string | HTMLElement): HTML string or DOM element
|
|
450
|
-
|
|
451
|
-
**Returns:** Markdown string
|
|
452
|
-
|
|
453
|
-
```javascript
|
|
454
|
-
// ✅ Correct - using quikdown_bd
|
|
455
|
-
import quikdown_bd from 'quikdown/bd';
|
|
456
|
-
const markdown = quikdown_bd.toMarkdown(html);
|
|
457
|
-
|
|
458
|
-
// ❌ Wrong - regular quikdown doesn't have toMarkdown
|
|
459
|
-
import quikdown from 'quikdown';
|
|
460
|
-
const markdown = quikdown.toMarkdown(html); // Error: toMarkdown is not a function
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
See [API Reference](docs/api-reference.md) for complete documentation.
|
|
464
|
-
|
|
465
|
-
## Theming
|
|
466
|
-
|
|
467
|
-
QuikDown supports flexible theming through container-based CSS scoping:
|
|
468
|
-
|
|
469
|
-
### Using Pre-built Themes
|
|
470
|
-
|
|
471
|
-
```html
|
|
472
|
-
<!-- Load theme CSS files -->
|
|
473
|
-
<link rel="stylesheet" href="quikdown.light.css">
|
|
474
|
-
<link rel="stylesheet" href="quikdown.dark.css">
|
|
475
|
-
|
|
476
|
-
<!-- Apply themes via container classes -->
|
|
477
|
-
<div class="quikdown-light">
|
|
478
|
-
<!-- Light themed content -->
|
|
479
|
-
</div>
|
|
480
|
-
|
|
481
|
-
<div class="quikdown-dark">
|
|
482
|
-
<!-- Dark themed content -->
|
|
483
|
-
</div>
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
### Theme Architecture
|
|
487
|
-
|
|
488
|
-
- **Structural styles**: Shared across all themes (margins, padding, font-sizes)
|
|
489
|
-
- **Theme colors**: Scoped to container classes (`.quikdown-light`, `.quikdown-dark`)
|
|
490
|
-
- **No conflicts**: Multiple themes can coexist on the same page
|
|
491
|
-
- **No default theme**: Without a container class, only structural styles apply
|
|
492
|
-
|
|
493
|
-
### Inline Styles
|
|
494
|
-
|
|
495
|
-
For a batteries-included approach without CSS files:
|
|
496
|
-
|
|
497
|
-
```javascript
|
|
498
|
-
// Use inline styles (always light theme currently)
|
|
499
|
-
const html = quikdown(markdown, { inline_styles: true });
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
## Browser Usage
|
|
503
|
-
|
|
504
|
-
### ES Modules (Recommended)
|
|
505
|
-
|
|
506
|
-
```html
|
|
507
|
-
<!DOCTYPE html>
|
|
508
|
-
<html>
|
|
509
|
-
<head>
|
|
510
|
-
<meta charset="UTF-8">
|
|
511
|
-
</head>
|
|
512
|
-
<body>
|
|
513
|
-
<div id="output"></div>
|
|
514
|
-
<script type="module">
|
|
515
|
-
import quikdown from 'https://unpkg.com/quikdown/dist/quikdown.esm.min.js';
|
|
516
|
-
|
|
517
|
-
const markdown = '# Hello quikdown!\n\nSupports **bold** and *italic* text.';
|
|
518
|
-
const html = quikdown(markdown, { inline_styles: true });
|
|
519
|
-
document.getElementById('output').innerHTML = html;
|
|
520
|
-
</script>
|
|
521
|
-
</body>
|
|
522
|
-
</html>
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
### UMD Script Tag (Legacy)
|
|
526
|
-
|
|
527
|
-
```html
|
|
528
|
-
<!DOCTYPE html>
|
|
529
|
-
<html>
|
|
530
|
-
<head>
|
|
531
|
-
<script src="https://unpkg.com/quikdown/dist/quikdown.umd.min.js"></script>
|
|
532
|
-
</head>
|
|
533
|
-
<body>
|
|
534
|
-
<div id="output"></div>
|
|
535
|
-
<script>
|
|
536
|
-
const markdown = '# Hello quikdown!';
|
|
537
|
-
const html = quikdown(markdown, { inline_styles: true });
|
|
538
|
-
document.getElementById('output').innerHTML = html;
|
|
539
|
-
</script>
|
|
540
|
-
</body>
|
|
541
|
-
</html>
|
|
542
|
-
```
|
|
205
|
+
## Security
|
|
543
206
|
|
|
544
|
-
|
|
207
|
+
All HTML is escaped by default. Only safe markdown constructs become HTML:
|
|
545
208
|
|
|
546
209
|
```javascript
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
const html = quikdown(markdown);
|
|
551
|
-
|
|
552
|
-
// Use in Express, etc.
|
|
553
|
-
res.send(html);
|
|
210
|
+
const unsafe = '<script>alert("XSS")</script> **bold**';
|
|
211
|
+
const safe = quikdown(unsafe);
|
|
212
|
+
// <script>alert("XSS")</script> <strong>bold</strong>
|
|
554
213
|
```
|
|
555
214
|
|
|
556
|
-
##
|
|
557
|
-
|
|
558
|
-
quikdown is optimized for speed:
|
|
559
|
-
|
|
560
|
-
- Single-pass regex parsing
|
|
561
|
-
- Minimal memory allocation
|
|
562
|
-
- No AST generation
|
|
563
|
-
- Efficient string operations
|
|
215
|
+
## Framework Integration
|
|
564
216
|
|
|
565
|
-
|
|
217
|
+
Works with React, Vue, Svelte, Angular. See [Framework Integration Guide](docs/framework-integration.md) for examples.
|
|
566
218
|
|
|
567
219
|
## Limitations
|
|
568
220
|
|
|
569
|
-
quikdown
|
|
570
|
-
|
|
571
|
-
- HTML blocks (for security)
|
|
572
|
-
- Reference-style links
|
|
221
|
+
For size and security, quikdown doesn't support:
|
|
222
|
+
- Reference-style links
|
|
573
223
|
- Footnotes
|
|
574
224
|
- Definition lists
|
|
575
|
-
- Complex table alignment
|
|
576
|
-
- Nested blockquotes with different markers
|
|
577
|
-
|
|
578
|
-
These omissions keep the parser small, fast, and secure.
|
|
579
225
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
1. Fork the repository
|
|
585
|
-
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
586
|
-
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
587
|
-
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
588
|
-
5. Open a Pull Request
|
|
589
|
-
|
|
590
|
-
## Testing
|
|
591
|
-
|
|
592
|
-
```bash
|
|
593
|
-
# Run tests
|
|
594
|
-
npm test
|
|
595
|
-
|
|
596
|
-
# Watch mode
|
|
597
|
-
npm run test:watch
|
|
598
|
-
|
|
599
|
-
# Coverage report
|
|
600
|
-
npm run test:coverage
|
|
226
|
+
Note that raw html, svg, etc can be rendered using appropriate fences
|
|
227
|
+
```html
|
|
228
|
+
<h1>My HTML Content</h1>
|
|
229
|
+
<p>Some HTML</p>
|
|
601
230
|
```
|
|
231
|
+
as long as an appropriate fence plugin is provided. See API docs for example or try out in quikdown_edit.js which has built-in support for HTML with XSS prevention.
|
|
602
232
|
|
|
603
233
|
## License
|
|
604
234
|
|
|
605
|
-
BSD 2-Clause
|
|
235
|
+
BSD 2-Clause - see [LICENSE.txt](LICENSE.txt)
|
|
606
236
|
|
|
607
237
|
## Acknowledgments
|
|
608
238
|
|
|
@@ -611,14 +241,9 @@ BSD 2-Clause License - see [LICENSE.txt](LICENSE.txt) file for details.
|
|
|
611
241
|
- CommonMark spec for markdown standardization
|
|
612
242
|
|
|
613
243
|
|
|
614
|
-
Choose quikdown when you need:
|
|
615
|
-
- A lightweight solution
|
|
616
|
-
- Built-in security
|
|
617
|
-
- Simple plugin system
|
|
618
|
-
- Zero dependencies
|
|
619
|
-
|
|
620
|
-
|
|
621
244
|
## Support
|
|
622
245
|
|
|
623
|
-
-
|
|
246
|
+
- 📖 [Documentation](docs/)
|
|
247
|
+
- 🐛 [Issues](https://github.com/deftio/quikdown/issues)
|
|
248
|
+
- 📦 [Examples](examples/)
|
|
624
249
|
|