comark 0.3.1 → 0.4.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.
Files changed (93) hide show
  1. package/dist/internal/frontmatter.d.ts +1 -0
  2. package/dist/internal/frontmatter.js +4 -2
  3. package/dist/internal/parse/auto-close/index.js +69 -31
  4. package/dist/internal/parse/auto-close/table.js +12 -9
  5. package/dist/internal/parse/auto-unwrap.js +6 -10
  6. package/dist/internal/parse/html/html_block_rule.js +10 -16
  7. package/dist/internal/parse/html/html_inline_rule.js +3 -7
  8. package/dist/internal/parse/html/html_re.js +1 -1
  9. package/dist/internal/parse/html/index.d.ts +1 -0
  10. package/dist/internal/parse/html/index.js +15 -3
  11. package/dist/internal/parse/syntax/block-params.d.ts +9 -0
  12. package/dist/internal/parse/syntax/block-params.js +48 -0
  13. package/dist/internal/parse/syntax/brackets.d.ts +8 -0
  14. package/dist/internal/parse/syntax/brackets.js +20 -0
  15. package/dist/internal/parse/syntax/props.d.ts +5 -0
  16. package/dist/internal/parse/syntax/props.js +119 -0
  17. package/dist/internal/parse/token-processor.js +89 -50
  18. package/dist/internal/props-validation.js +4 -9
  19. package/dist/internal/stringify/attributes.d.ts +7 -0
  20. package/dist/internal/stringify/attributes.js +56 -1
  21. package/dist/internal/stringify/handlers/a.js +1 -3
  22. package/dist/internal/stringify/handlers/blockquote.js +19 -4
  23. package/dist/internal/stringify/handlers/code.js +1 -3
  24. package/dist/internal/stringify/handlers/emphesis.js +1 -3
  25. package/dist/internal/stringify/handlers/heading.js +6 -1
  26. package/dist/internal/stringify/handlers/html.js +34 -18
  27. package/dist/internal/stringify/handlers/img.js +1 -3
  28. package/dist/internal/stringify/handlers/li.js +18 -9
  29. package/dist/internal/stringify/handlers/mdc.js +3 -4
  30. package/dist/internal/stringify/handlers/ol.js +12 -2
  31. package/dist/internal/stringify/handlers/p.d.ts +1 -1
  32. package/dist/internal/stringify/handlers/p.js +8 -1
  33. package/dist/internal/stringify/handlers/pre.js +20 -14
  34. package/dist/internal/stringify/handlers/strong.js +1 -3
  35. package/dist/internal/stringify/handlers/table.js +14 -5
  36. package/dist/internal/stringify/handlers/template.js +5 -2
  37. package/dist/internal/stringify/handlers/ul.js +12 -2
  38. package/dist/internal/stringify/state.js +1 -1
  39. package/dist/internal/yaml.js +1 -1
  40. package/dist/parse.d.ts +4 -4
  41. package/dist/parse.js +20 -10
  42. package/dist/plugins/alert.d.ts +1 -1
  43. package/dist/plugins/alert.js +1 -1
  44. package/dist/plugins/binding.d.ts +1 -1
  45. package/dist/plugins/binding.js +1 -3
  46. package/dist/plugins/breaks.d.ts +1 -1
  47. package/dist/plugins/breaks.js +1 -1
  48. package/dist/plugins/emoji.d.ts +1 -1
  49. package/dist/plugins/emoji.js +8 -8
  50. package/dist/plugins/footnotes.d.ts +1 -1
  51. package/dist/plugins/footnotes.js +19 -13
  52. package/dist/plugins/headings.d.ts +19 -8
  53. package/dist/plugins/headings.js +27 -19
  54. package/dist/plugins/highlight.d.ts +2 -12
  55. package/dist/plugins/highlight.js +201 -103
  56. package/dist/plugins/json-render.d.ts +1 -1
  57. package/dist/plugins/json-render.js +5 -9
  58. package/dist/plugins/math.d.ts +1 -1
  59. package/dist/plugins/math.js +4 -6
  60. package/dist/plugins/mermaid.d.ts +1 -1
  61. package/dist/plugins/mermaid.js +6 -20
  62. package/dist/plugins/punctuation.d.ts +1 -1
  63. package/dist/plugins/punctuation.js +5 -6
  64. package/dist/plugins/security.d.ts +1 -1
  65. package/dist/plugins/security.js +2 -2
  66. package/dist/plugins/summary.d.ts +4 -1
  67. package/dist/plugins/syntax.d.ts +49 -0
  68. package/dist/plugins/syntax.js +558 -0
  69. package/dist/plugins/task-list.d.ts +2 -2
  70. package/dist/plugins/task-list.js +11 -8
  71. package/dist/plugins/toc.d.ts +3 -1
  72. package/dist/plugins/toc.js +1 -1
  73. package/dist/types.d.ts +57 -12
  74. package/dist/utils/comark.tmLanguage.d.ts +335 -0
  75. package/dist/utils/comark.tmLanguage.js +597 -0
  76. package/dist/utils/helpers.d.ts +16 -4
  77. package/dist/utils/helpers.js +16 -6
  78. package/dist/utils/index.d.ts +5 -0
  79. package/dist/utils/index.js +25 -3
  80. package/package.json +40 -40
  81. package/skills/comark/references/rendering-svelte.md +51 -7
  82. package/dist/internal/stringify/indent.d.ts +0 -5
  83. package/dist/internal/stringify/indent.js +0 -9
  84. package/dist/vite.d.ts +0 -1
  85. package/dist/vite.js +0 -1
  86. package/skills/skills/comark/AGENTS.md +0 -261
  87. package/skills/skills/comark/SKILL.md +0 -489
  88. package/skills/skills/comark/references/markdown-syntax.md +0 -599
  89. package/skills/skills/comark/references/parsing-ast.md +0 -378
  90. package/skills/skills/comark/references/rendering-react.md +0 -445
  91. package/skills/skills/comark/references/rendering-svelte.md +0 -453
  92. package/skills/skills/comark/references/rendering-vue.md +0 -462
  93. /package/skills/{skills/migrate-mdc-to-comark → migrate-mdc-to-comark}/SKILL.md +0 -0
@@ -1,445 +0,0 @@
1
- # React Rendering Guide
2
-
3
- Complete guide for rendering Comark AST in React applications.
4
-
5
- ## Table of Contents
6
-
7
- - [Basic Usage](#basic-usage)
8
- - [Custom Components](#custom-components)
9
- - [Dynamic Component Resolution](#dynamic-component-resolution)
10
- - [Props Conversion](#props-conversion)
11
- - [Streaming Mode](#streaming-mode)
12
- - [Prose Components](#prose-components)
13
- - [Custom Props Handling](#custom-props-handling)
14
- - [CSS Class Name](#css-class-name)
15
-
16
- ---
17
-
18
- ## Basic Usage
19
-
20
- Use the `Comark` component to render markdown:
21
-
22
- ```tsx
23
- import { Comark } from '@comark/react'
24
-
25
- const content = `
26
- # Hello World
27
-
28
- This is **markdown** content.
29
-
30
- ::alert{type="info"}
31
- Important message
32
- ::
33
- `
34
-
35
- export default function App() {
36
- return <Comark>{content}</Comark>
37
- }
38
- ```
39
-
40
- ---
41
-
42
- ## Custom Components
43
-
44
- Map custom React components to Comark elements:
45
-
46
- ```tsx
47
- import { Comark } from '@comark/react'
48
- import CustomHeading from './CustomHeading'
49
- import CustomAlert from './CustomAlert'
50
- import CustomCard from './CustomCard'
51
-
52
- const customComponents = {
53
- h1: CustomHeading,
54
- h2: CustomHeading,
55
- alert: CustomAlert,
56
- card: CustomCard,
57
- }
58
-
59
- export default function App({ content }) {
60
- return (
61
- <Comark
62
- components={customComponents}
63
- >{content}</Comark>
64
- )
65
- }
66
- ```
67
-
68
- ### Custom Component Example
69
-
70
- ```tsx
71
- // CustomHeading.tsx
72
- import React from 'react'
73
-
74
- interface Props {
75
- __node: any // Comark node
76
- id?: string
77
- children: React.ReactNode
78
- }
79
-
80
- export default function CustomHeading({ __node, id, children }: Props) {
81
- const tag = __node[0] // h1, h2, etc.
82
- const Component = tag as keyof JSX.IntrinsicElements
83
-
84
- return (
85
- <Component id={id} className="custom-heading">
86
- {children}
87
- </Component>
88
- )
89
- }
90
- ```
91
-
92
- **Styled Component:**
93
-
94
- ```tsx
95
- import styled from 'styled-components'
96
-
97
- const StyledHeading = styled.h1<{ level: number }>`
98
- font-family: 'Inter', sans-serif;
99
- font-weight: 700;
100
- font-size: ${props => 3 - props.level * 0.25}rem;
101
- margin-bottom: 1rem;
102
- color: #1a202c;
103
- `
104
-
105
- export default function CustomHeading({ __node, children }: Props) {
106
- const tag = __node[0]
107
- const level = parseInt(tag[1]) // Extract level from 'h1', 'h2', etc.
108
-
109
- return (
110
- <StyledHeading as={tag} level={level}>
111
- {children}
112
- </StyledHeading>
113
- )
114
- }
115
- ```
116
-
117
- ### Alert Component Example
118
-
119
- ```tsx
120
- // CustomAlert.tsx
121
- import React from 'react'
122
- import './Alert.css'
123
-
124
- interface AlertProps {
125
- type?: 'info' | 'warning' | 'error' | 'success'
126
- children: React.ReactNode
127
- }
128
-
129
- export default function CustomAlert({ type = 'info', children }: AlertProps) {
130
- const icons = {
131
- info: 'ℹ️',
132
- warning: '⚠️',
133
- error: '❌',
134
- success: '✅',
135
- }
136
-
137
- return (
138
- <div className={`alert alert-${type}`} role="alert">
139
- <div className="alert-icon">{icons[type]}</div>
140
- <div className="alert-content">{children}</div>
141
- </div>
142
- )
143
- }
144
- ```
145
-
146
- ---
147
-
148
- ## Dynamic Component Resolution
149
-
150
- Load components dynamically using `componentsManifest`:
151
-
152
- ```tsx
153
- import { Comark } from '@comark/react'
154
-
155
- const componentMap = {
156
- 'alert': () => import('./Alert'),
157
- 'card': () => import('./Card'),
158
- 'button': () => import('./Button'),
159
- }
160
-
161
- async function loadComponent(name: string) {
162
- if (componentMap[name]) {
163
- return componentMap[name]()
164
- }
165
- throw new Error(`Component ${name} not found`)
166
- }
167
-
168
- export default function App({ content }) {
169
- return (
170
- <Comark
171
- componentsManifest={loadComponent}
172
- >{content}</Comark>
173
- )
174
- }
175
- ```
176
-
177
- ---
178
-
179
- ## Props Conversion
180
-
181
- React renderer handles HTML attribute conversion automatically:
182
-
183
- ### Attribute Mapping
184
-
185
- ```tsx
186
- // Markdown attribute → React prop
187
- {class="foo"} → className="foo"
188
- {tabindex="0"} → tabIndex={0}
189
- {style="..."} → style={{...}} (converted to object)
190
- {:bool="true"} → bool={true} (parsed from string)
191
- {:count="5"} → count={5} (parsed as number)
192
- {:data='{"key":"val"}'} → data={{key:"val"}} (parsed as object)
193
- ```
194
-
195
- ### Style Conversion
196
-
197
- ```tsx
198
- // Input: style="color: red; font-size: 16px"
199
- // Output: style={{ color: 'red', fontSize: '16px' }}
200
-
201
- // Custom CSS properties preserved:
202
- // Input: style="--custom-color: blue"
203
- // Output: style={{ '--custom-color': 'blue' }}
204
- ```
205
-
206
- ### Boolean Props
207
-
208
- ```tsx
209
- // Markdown: **text**{:disabled}
210
- // React prop: disabled={true}
211
-
212
- // Markdown: [link](url){:external}
213
- // React prop: external={true}
214
- ```
215
-
216
- ### Number Props
217
-
218
- ```tsx
219
- // Markdown: ::component{:count="5"}
220
- // React prop: count={5}
221
-
222
- // Markdown: ::component{:max="100"}
223
- // React prop: max={100}
224
- ```
225
-
226
- ### Object/Array Props
227
-
228
- ```tsx
229
- // Markdown: ::component{:config='{"theme":"dark"}'}
230
- // React prop: config={{theme:"dark"}}
231
-
232
- // Markdown: ::component{:items='["a","b","c"]'}
233
- // React prop: items={["a","b","c"]}
234
- ```
235
-
236
- ---
237
-
238
- ## Streaming Mode
239
-
240
- Use the `Comark` component with reactive state for streaming content:
241
-
242
- ```tsx
243
- import { useState, useEffect } from 'react'
244
- import { Comark } from '@comark/react'
245
-
246
- export default function StreamingContent() {
247
- const [content, setContent] = useState('')
248
- const [isLoading, setIsLoading] = useState(true)
249
-
250
- useEffect(() => {
251
- async function loadContent() {
252
- const response = await fetch('/api/content.md')
253
- const reader = response.body!.getReader()
254
- const decoder = new TextDecoder()
255
-
256
- while (true) {
257
- const { done, value } = await reader.read()
258
- if (done) break
259
- setContent(prev => prev + decoder.decode(value))
260
- }
261
-
262
- setIsLoading(false)
263
- }
264
-
265
- loadContent()
266
- }, [])
267
-
268
- return (
269
- <>
270
- {isLoading && <div>Loading...</div>}
271
- <Comark>{content}</Comark>
272
- </>
273
- )
274
- }
275
- ```
276
-
277
- ---
278
-
279
- ## Prose Components
280
-
281
- The `Comark` component uses built-in prose styling automatically. You can override with custom components:
282
-
283
- ```tsx
284
- import { Comark } from '@comark/react'
285
- import CustomAlert from './CustomAlert'
286
-
287
- const components = {
288
- alert: CustomAlert, // Override or add custom components
289
- }
290
-
291
- export default function App({ content }) {
292
- return <Comark components={components}>{content}</Comark>
293
- }
294
- ```
295
-
296
- ### Tailwind CSS Prose
297
-
298
- ```tsx
299
- import { Comark } from '@comark/react'
300
-
301
- export default function App({ content }) {
302
- return (
303
- <article className="prose prose-lg dark:prose-dark max-w-none">
304
- <Comark>{content}</Comark>
305
- </article>
306
- )
307
- }
308
- ```
309
-
310
- ---
311
-
312
- ## Custom Props Handling
313
-
314
- Access props in custom components:
315
-
316
- ```tsx
317
- // CustomAlert.tsx
318
- interface AlertProps {
319
- type?: string // From {type="info"}
320
- bool?: boolean // From {bool} → :bool="true"
321
- count?: number // From {:count="5"}
322
- data?: object // From {:data='{"key":"val"}'}
323
- __node?: any // Original Comark node
324
- children: React.ReactNode
325
- }
326
-
327
- export default function CustomAlert({
328
- type = 'info',
329
- bool,
330
- count,
331
- data,
332
- __node,
333
- children
334
- }: AlertProps) {
335
- return (
336
- <div
337
- className={`alert alert-${type}`}
338
- data-bool={bool}
339
- data-count={count}
340
- data-info={JSON.stringify(data)}
341
- role="alert"
342
- >
343
- {children}
344
- </div>
345
- )
346
- }
347
- ```
348
-
349
- ### Property Types
350
-
351
- - `:bool="true"` → `bool={true}` (boolean)
352
- - `:count="5"` → `count={5}` (number)
353
- - `:obj='{"key":"val"}'` → `obj={{key:"val"}}` (object)
354
- - `attr="value"` → `attr="value"` (string)
355
-
356
- ### Accessing Node Structure
357
-
358
- ```tsx
359
- interface Props {
360
- __node?: any
361
- children: React.ReactNode
362
- }
363
-
364
- export default function Component({ __node, children }: Props) {
365
- // Node structure: [tag, props, ...children]
366
- const tag = __node?.[0]
367
- const nodeProps = __node?.[1] || {}
368
- const nodeChildren = __node?.slice(2) || []
369
-
370
- return (
371
- <div data-tag={tag}>
372
- {children}
373
- </div>
374
- )
375
- }
376
- ```
377
-
378
- ### Working with Complex Props
379
-
380
- ```tsx
381
- // DataTable.tsx
382
- interface DataTableProps {
383
- columns?: string[] // From {:columns='["Name","Age"]'}
384
- sortable?: boolean // From {sortable}
385
- striped?: boolean // From {striped}
386
- children: React.ReactNode
387
- }
388
-
389
- export default function DataTable({
390
- columns = [],
391
- sortable = false,
392
- striped = false,
393
- children
394
- }: DataTableProps) {
395
- return (
396
- <table className={striped ? 'table-striped' : ''}>
397
- {columns.length > 0 && (
398
- <thead>
399
- <tr>
400
- {columns.map((col, i) => (
401
- <th key={i}>
402
- {col}
403
- {sortable && <button>↕</button>}
404
- </th>
405
- ))}
406
- </tr>
407
- </thead>
408
- )}
409
- <tbody>{children}</tbody>
410
- </table>
411
- )
412
- }
413
- ```
414
-
415
- **Usage in Markdown:**
416
-
417
- ```markdown
418
- ::data-table{:columns='["Name", "Age", "Email"]' sortable striped}
419
- Table content here
420
- ::
421
- ```
422
-
423
- ---
424
-
425
- ## CSS Class Name
426
-
427
- Add custom wrapper class:
428
-
429
- ```tsx
430
- <Comark
431
- className="prose dark:prose-dark"
432
- >{content}</Comark>
433
- ```
434
-
435
- ### With Tailwind CSS
436
-
437
- ```tsx
438
- <Comark
439
- className="prose prose-slate lg:prose-xl dark:prose-invert max-w-none"
440
- >{content}</Comark>
441
- ```
442
-
443
- ---
444
-
445
- [← Back to Main Skills Guide](../SKILL.md)