markdown-to-jsx 7.7.17 → 9.0.0-rc.1

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
@@ -1,11 +1,26 @@
1
- **markdown-to-jsx**
1
+ [![npm version](https://badge.fury.io/js/markdown-to-jsx.svg)](https://badge.fury.io/js/markdown-to-jsx) [![downloads](https://badgen.net/npm/dy/markdown-to-jsx)](https://npm-stat.com/charts.html?package=markdown-to-jsx)
2
2
 
3
- The most lightweight, customizable React markdown component.
3
+ `markdown-to-jsx` is a gfm+commonmark compliant markdown parser and compiler toolchain for JavaScript and TypeScript-based projects. It is extremely fast, capable of processing large documents fast enough for real-time interactivity.
4
4
 
5
- [![npm version](https://badge.fury.io/js/markdown-to-jsx.svg)](https://badge.fury.io/js/markdown-to-jsx) [![downloads](https://badgen.net/npm/dy/markdown-to-jsx)](https://npm-stat.com/charts.html?package=markdown-to-jsx)
5
+ Some special features of the library:
6
+
7
+ - Arbitrary HTML is supported and parsed into the appropriate JSX representation
8
+ without `dangerouslySetInnerHTML`
9
+
10
+ - Any HTML tags rendered by the compiler and/or `<Markdown>` component can be overridden to include additional props or even a different HTML representation entirely.
11
+
12
+ - All GFM special syntaxes are supported, including tables, task lists, strikethrough, autolinks, and more.
13
+
14
+ - Fenced code blocks with [highlight.js](https://highlightjs.org/) support; see [Syntax highlighting](#syntax-highlighting) for instructions on setting up highlight.js.
15
+
16
+ ## Table of Contents
6
17
 
7
18
  <!-- TOC -->
8
19
 
20
+ - [Table of Contents](#table-of-contents)
21
+ - [Upgrading](#upgrading)
22
+ - [From v8.x to v9.x](#from-v8x-to-v9x)
23
+ - [From v7.x to v8.x](#from-v7x-to-v8x)
9
24
  - [Installation](#installation)
10
25
  - [Usage](#usage)
11
26
  - [Parsing Options](#parsing-options)
@@ -22,7 +37,6 @@ The most lightweight, customizable React markdown component.
22
37
  - [options.renderRule](#optionsrenderrule)
23
38
  - [options.sanitizer](#optionssanitizer)
24
39
  - [options.slugify](#optionsslugify)
25
- - [options.namedCodesToUnicode](#optionsnamedcodestounicode)
26
40
  - [options.disableAutoLink](#optionsdisableautolink)
27
41
  - [options.disableParsingRawHTML](#optionsdisableparsingrawhtml)
28
42
  - [Syntax highlighting](#syntax-highlighting)
@@ -33,29 +47,132 @@ The most lightweight, customizable React markdown component.
33
47
  - [Passing props to stringified React components](#passing-props-to-stringified-react-components)
34
48
  - [Significant indentation inside arbitrary HTML](#significant-indentation-inside-arbitrary-html)
35
49
  - [Code blocks](#code-blocks)
36
- - [Using The Compiler Directly](#using-the-compiler-directly)
50
+ - [Entry Points](#entry-points)
51
+ - [Main](#main)
52
+ - [React](#react)
53
+ - [HTML](#html)
54
+ - [Markdown](#markdown)
55
+ - [Using The Parser Low-Level AST API](#using-the-parser-low-level-ast-api)
56
+ - [AST Anatomy](#ast-anatomy)
57
+ - [Node Types](#node-types)
58
+ - [Example AST Structure](#example-ast-structure)
59
+ - [Type Checking](#type-checking)
37
60
  - [Changelog](#changelog)
38
61
  - [Donate](#donate)
39
62
 
40
63
  <!-- /TOC -->
41
64
 
42
- ---
65
+ ## Upgrading
43
66
 
44
- `markdown-to-jsx` offers the following additional benefits over simple markdown parsing:
67
+ ### From v8.x to v9.x
45
68
 
46
- - Arbitrary HTML is supported and parsed into the appropriate JSX representation
47
- without `dangerouslySetInnerHTML`
69
+ **Breaking Changes:**
48
70
 
49
- - Any HTML tags rendered by the compiler and/or `<Markdown>` component can be overridden to include additional
50
- props or even a different HTML representation entirely.
71
+ - **`ast` option removed**: The `ast: true` option on `compiler()` has been removed. Use the new `parser()` function instead to access the AST directly.
51
72
 
52
- - GFM task list support.
73
+ ```typescript
74
+ // Before (v8)
75
+ import { compiler } from 'markdown-to-jsx'
76
+ const ast = compiler('# Hello world', { ast: true })
53
77
 
54
- - Fenced code blocks with [highlight.js](https://highlightjs.org/) support; see [Syntax highlighting](#syntax-highlighting) for instructions on setting up highlight.js.
78
+ // After (v9)
79
+ import { parser } from 'markdown-to-jsx'
80
+ const ast = parser('# Hello world')
81
+ ```
82
+
83
+ - **`namedCodesToUnicode` option removed**: The `namedCodesToUnicode` option has been removed. All named HTML entities are now supported by default via the full entity list, so custom entity mappings are no longer needed.
84
+
85
+ ```typescript
86
+ // Before (v8)
87
+ import { compiler } from 'markdown-to-jsx'
88
+ compiler('&le; symbol', { namedCodesToUnicode: { le: '\u2264' } })
89
+
90
+ // After (v9)
91
+ import { compiler } from 'markdown-to-jsx'
92
+ compiler('&le; symbol') // All entities supported automatically
93
+ ```
55
94
 
56
- All this clocks in at around 6 kB gzipped, which is a fraction of the size of most other React markdown components.
95
+ **New Features:**
96
+
97
+ - **New `parser` function**: Provides direct access to the parsed AST without rendering. This is the recommended way to get AST nodes.
98
+
99
+ - **New entry points**: React-specific, HTML-specific, and markdown-specific entry points are now available for better tree-shaking and separation of concerns.
100
+
101
+ ```typescript
102
+ // React-specific usage
103
+ import Markdown, { compiler, parser } from 'markdown-to-jsx/react'
104
+
105
+ // HTML string output
106
+ import { compiler, astToHTML, parser } from 'markdown-to-jsx/html'
107
+
108
+ // Markdown string output (round-trip compilation)
109
+ import { compiler, astToMarkdown, parser } from 'markdown-to-jsx/markdown'
110
+ ```
111
+
112
+ **Migration Guide:**
113
+
114
+ 1. **Replace `compiler(..., { ast: true })` with `parser()`**:
115
+
116
+ ```typescript
117
+ // Before
118
+ import { compiler } from 'markdown-to-jsx'
119
+ const ast = compiler(markdown, { ast: true })
120
+
121
+ // After
122
+ import { parser } from 'markdown-to-jsx'
123
+ const ast = parser(markdown)
124
+ ```
125
+
126
+ 2. **Migrate React imports to `/react` entry point** (optional but recommended):
127
+
128
+ ```typescript
129
+ // Before
130
+ import Markdown, { compiler } from 'markdown-to-jsx'
131
+
132
+ // After (recommended)
133
+ import Markdown, { compiler } from 'markdown-to-jsx/react'
134
+ ```
135
+
136
+ 3. **Remove `namedCodesToUnicode` option**: All named HTML entities are now supported automatically, so you can remove any custom entity mappings.
137
+
138
+ ```typescript
139
+ // Before
140
+ compiler('&le; symbol', { namedCodesToUnicode: { le: '\u2264' } })
141
+
142
+ // After
143
+ compiler('&le; symbol') // Works automatically
144
+ ```
57
145
 
58
- Requires React >= 0.14.
146
+ **Note:** The main entry point (`markdown-to-jsx`) continues to work for backward compatibility, but React code there is deprecated and will be removed in a future major release. Consider migrating to `markdown-to-jsx/react` for React-specific usage.
147
+
148
+ <details>
149
+ <summary>### Older Migration Guides</summary>
150
+
151
+ ### From v7.x to v8.x
152
+
153
+ **Breaking Changes:**
154
+
155
+ - Type `ParserResult` renamed to `ASTNode` - If you were using `MarkdownToJSX.ParserResult` in your code, update to `MarkdownToJSX.ASTNode`
156
+
157
+ ```typescript
158
+ // Before
159
+ const nodes: MarkdownToJSX.ParserResult[] = parse(markdown)
160
+
161
+ // After
162
+ const nodes: MarkdownToJSX.ASTNode[] = parse(markdown)
163
+ ```
164
+
165
+ - Multiple `RuleType` enums consolidated into `RuleType.textFormatted` - If you were checking for `RuleType.textBolded`, `RuleType.textEmphasized`, `RuleType.textMarked`, or `RuleType.textStrikethroughed`, update to check for `RuleType.textFormatted` and inspect the node's boolean flags:
166
+
167
+ ```typescript
168
+ // Before
169
+ if (node.type === RuleType.textBolded) { ... }
170
+
171
+ // After
172
+ if (node.type === RuleType.textFormatted && node.bold) { ... }
173
+ ```
174
+
175
+ </details>
59
176
 
60
177
  ## Installation
61
178
 
@@ -71,7 +188,7 @@ npm i markdown-to-jsx
71
188
 
72
189
  ES6-style usage\*:
73
190
 
74
- ```jsx
191
+ ```tsx
75
192
  import Markdown from 'markdown-to-jsx'
76
193
  import React from 'react'
77
194
  import { render } from 'react-dom'
@@ -105,37 +222,36 @@ But this string would be considered "block" due to the existence of a header tag
105
222
 
106
223
  However, if you really want all input strings to be treated as "block" layout, simply pass `options.forceBlock = true` like this:
107
224
 
108
- ```jsx
109
- ;<Markdown options={{ forceBlock: true }}>Hello there old chap!</Markdown>
225
+ ```tsx
226
+ <Markdown options={{ forceBlock: true }}>Hello there old chap!</Markdown>
110
227
 
111
228
  // or
112
229
 
113
230
  compiler('Hello there old chap!', { forceBlock: true })
114
231
 
115
232
  // renders
116
- ;<p>Hello there old chap!</p>
233
+ <p>Hello there old chap!</p>
117
234
  ```
118
235
 
119
236
  #### options.forceInline
120
237
 
121
238
  The inverse is also available by passing `options.forceInline = true`:
122
239
 
123
- ```jsx
124
- ;<Markdown options={{ forceInline: true }}># You got it babe!</Markdown>
240
+ ```tsx
241
+ <Markdown options={{ forceInline: true }}># You got it babe!</Markdown>
125
242
 
126
243
  // or
127
-
128
244
  compiler('# You got it babe!', { forceInline: true })
129
245
 
130
246
  // renders
131
- ;<span># You got it babe!</span>
247
+ <span># You got it babe!</span>
132
248
  ```
133
249
 
134
250
  #### options.wrapper
135
251
 
136
252
  When there are multiple children to be rendered, the compiler will wrap the output in a `div` by default. You can override this default by setting the `wrapper` option to either a string (React Element) or a component.
137
253
 
138
- ```jsx
254
+ ```tsx
139
255
  const str = '# Heck Yes\n\nThis is great!'
140
256
 
141
257
  <Markdown options={{ wrapper: 'article' }}>
@@ -158,7 +274,7 @@ compiler(str, { wrapper: 'article' });
158
274
 
159
275
  To get an array of children back without a wrapper, set `wrapper` to `null`. This is particularly useful when using `compiler(…)` directly.
160
276
 
161
- ```jsx
277
+ ```tsx
162
278
  compiler('One\n\nTwo\n\nThree', { wrapper: null })
163
279
 
164
280
  // returns
@@ -171,7 +287,7 @@ To render children at the same DOM level as `<Markdown>` with no HTML wrapper, s
171
287
 
172
288
  By default, the compiler does not wrap the rendered contents if there is only a single child. You can change this by setting `forceWrapper` to `true`. If the child is inline, it will not necessarily be wrapped in a `span`.
173
289
 
174
- ```jsx
290
+ ```tsx
175
291
  // Using `forceWrapper` with a single, inline child…
176
292
  <Markdown options={{ wrapper: 'aside', forceWrapper: true }}>
177
293
  Mumble, mumble…
@@ -207,7 +323,7 @@ The library does not void any tags by default to avoid surprising behavior for p
207
323
 
208
324
  Pass the `options.overrides` prop to the compiler or `<Markdown>` component to seamlessly revise the rendered representation of any HTML tag. You can choose to change the component itself, add/change props, or both.
209
325
 
210
- ```jsx
326
+ ```tsx
211
327
  import Markdown from 'markdown-to-jsx'
212
328
  import React from 'react'
213
329
  import { render } from 'react-dom'
@@ -275,7 +391,7 @@ One of the most interesting use cases enabled by the HTML syntax processing in `
275
391
 
276
392
  By adding an override for the components you plan to use in markdown documents, it's possible to dynamically render almost anything. One possible scenario could be writing documentation:
277
393
 
278
- ```jsx
394
+ ```tsx
279
395
  import Markdown from 'markdown-to-jsx'
280
396
  import React from 'react'
281
397
  import { render } from 'react-dom'
@@ -310,7 +426,7 @@ render(
310
426
 
311
427
  In the following case, `DatePicker` could simply run `parseInt()` on the passed `startTime` for example:
312
428
 
313
- ```jsx
429
+ ```tsx
314
430
  import Markdown from 'markdown-to-jsx'
315
431
  import React from 'react'
316
432
  import { render } from 'react-dom'
@@ -347,7 +463,7 @@ render(
347
463
 
348
464
  Another possibility is to use something like [recompose's `withProps()` HOC](https://github.com/acdlite/recompose/blob/main/docs/API.md#withprops) to create various pregenerated scenarios and then reference them by name in the markdown:
349
465
 
350
- ```jsx
466
+ ```tsx
351
467
  import Markdown from 'markdown-to-jsx'
352
468
  import React from 'react'
353
469
  import { render } from 'react-dom'
@@ -467,7 +583,7 @@ By default a lightweight URL sanitizer function is provided to avoid common atta
467
583
 
468
584
  This can be overridden and replaced with a custom sanitizer if desired via `options.sanitizer`:
469
585
 
470
- ```jsx
586
+ ```tsx
471
587
  // sanitizer in this situation would receive:
472
588
  // ('javascript:alert("foo")', 'a', 'href')
473
589
 
@@ -484,9 +600,9 @@ compiler('[foo](javascript:alert("foo"))', {
484
600
 
485
601
  #### options.slugify
486
602
 
487
- By default, a [lightweight deburring function](https://github.com/probablyup/markdown-to-jsx/blob/bc2f57412332dc670f066320c0f38d0252e0f057/index.js#L261-L275) is used to generate an HTML id from headings. You can override this by passing a function to `options.slugify`. This is helpful when you are using non-alphanumeric characters (e.g. Chinese or Japanese characters) in headings. For example:
603
+ By default, a [lightweight deburring function](https://github.com/quantizor/markdown-to-jsx/blob/bc2f57412332dc670f066320c0f38d0252e0f057/index.js#L261-L275) is used to generate an HTML id from headings. You can override this by passing a function to `options.slugify`. This is helpful when you are using non-alphanumeric characters (e.g. Chinese or Japanese characters) in headings. For example:
488
604
 
489
- ```jsx
605
+ ```tsx
490
606
  <Markdown options={{ slugify: str => str }}># 中文</Markdown>
491
607
 
492
608
  // or
@@ -499,44 +615,11 @@ compiler('# 中文', { slugify: str => str })
499
615
 
500
616
  The original function is available as a library export called `slugify`.
501
617
 
502
- #### options.namedCodesToUnicode
503
-
504
- By default only a couple of named html codes are converted to unicode characters:
505
-
506
- - `&` (`&amp;`)
507
- - `'` (`&apos;`)
508
- - `>` (`&gt;`)
509
- - `<` (`&lt;`)
510
- - ` ` (`&nbsp;`)
511
- - `"` (`&quot;`)
512
-
513
- Some projects require to extend this map of named codes and unicode characters. To customize this list with additional html codes pass the option namedCodesToUnicode as object with the code names needed as in the example below:
514
-
515
- ```jsx
516
- <Markdown options={{ namedCodesToUnicode: {
517
- le: '\u2264',
518
- ge: '\u2265',
519
- '#39': '\u0027',
520
- } }}>This text is &le; than this text.</Markdown>;
521
-
522
- // or
523
-
524
- compiler('This text is &le; than this text.', namedCodesToUnicode: {
525
- le: '\u2264',
526
- ge: '\u2265',
527
- '#39': '\u0027',
528
- });
529
-
530
- // renders:
531
-
532
- <p>This text is ≤ than this text.</p>
533
- ```
534
-
535
618
  #### options.disableAutoLink
536
619
 
537
620
  By default, bare URLs in the markdown document will be converted into an anchor tag. This behavior can be disabled if desired.
538
621
 
539
- ```jsx
622
+ ```tsx
540
623
  <Markdown options={{ disableAutoLink: true }}>
541
624
  The URL https://quantizor.dev will not be rendered as an anchor tag.
542
625
  </Markdown>
@@ -559,7 +642,7 @@ compiler(
559
642
 
560
643
  By default, raw HTML is parsed to JSX. This behavior can be disabled if desired.
561
644
 
562
- ```jsx
645
+ ```tsx
563
646
  <Markdown options={{ disableParsingRawHTML: true }}>
564
647
  This text has <span>html</span> in it but it won't be rendered
565
648
  </Markdown>;
@@ -577,7 +660,20 @@ compiler('This text has <span>html</span> in it but it won't be rendered', { dis
577
660
 
578
661
  When using [fenced code blocks](https://www.markdownguide.org/extended-syntax/#syntax-highlighting) with language annotation, that language will be added to the `<code>` element as `class="lang-${language}"`. For best results, you can use `options.overrides` to provide an appropriate syntax highlighting integration like this one using `highlight.js`:
579
662
 
580
- ````jsx
663
+ ```html
664
+ <!-- Add the following tags to your page <head> to automatically load hljs and styles: -->
665
+ <link
666
+ rel="stylesheet"
667
+ href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/obsidian.min.css"
668
+ />
669
+
670
+ <script
671
+ crossorigin
672
+ src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"
673
+ ></script>
674
+ ```
675
+
676
+ ````tsx
581
677
  import { Markdown, RuleType } from 'markdown-to-jsx'
582
678
 
583
679
  const mdContainingFencedCodeBlock = '```js\nconsole.log("Hello world!");\n```\n'
@@ -595,23 +691,6 @@ function App() {
595
691
  )
596
692
  }
597
693
 
598
- /**
599
- * Add the following tags to your page <head> to automatically load hljs and styles:
600
-
601
- <link
602
- rel="stylesheet"
603
- href="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/styles/nord.min.css"
604
- />
605
-
606
- * NOTE: for best performance, load individual languages you need instead of all
607
- of them. See their docs for more info: https://highlightjs.org/
608
-
609
- <script
610
- crossorigin
611
- src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"
612
- ></script>
613
- */
614
-
615
694
  function SyntaxHighlightedCode(props) {
616
695
  const ref = (React.useRef < HTMLElement) | (null > null)
617
696
 
@@ -776,40 +855,267 @@ The two leading spaces in front of "# Hello" would be left-trimmed from all line
776
855
  <div>
777
856
  ```js
778
857
  var some = code();
779
- ``\`
858
+ ```
780
859
  </div>
781
860
  ````
782
861
 
783
- ## Using The Compiler Directly
862
+ ## Entry Points
784
863
 
785
- If desired, the compiler function is a "named" export on the `markdown-to-jsx` module:
864
+ `markdown-to-jsx` provides multiple entry points for different use cases:
786
865
 
787
- ```jsx
788
- import { compiler } from 'markdown-to-jsx'
789
- import React from 'react'
790
- import { render } from 'react-dom'
866
+ ### Main
791
867
 
792
- render(compiler('# Hello world!'), document.body)
868
+ The legacy\*default entry point exports everything, including the React compiler and component:
793
869
 
794
- /*
795
- renders:
870
+ ```tsx
871
+ import Markdown, { compiler, parser } from 'markdown-to-jsx'
872
+ ```
796
873
 
797
- <h1>Hello world!</h1>
798
- */
874
+ _The React code in this entry point is deprecated and will be removed in a future major release, migrate to `markdown-to-jsx/react`._
875
+
876
+ ### React
877
+
878
+ For React-specific usage, import from the `/react` entry point:
879
+
880
+ ```tsx
881
+ import Markdown, { compiler, parser, astToJSX } from 'markdown-to-jsx/react'
882
+
883
+ // Use compiler for markdown → JSX
884
+ const jsxElement = compiler('# Hello world')
885
+
886
+ const markdown = `# Hello world`
887
+
888
+ function App() {
889
+ return <Markdown children={markdown} />
890
+ }
891
+
892
+ // Or use parser + astToJSX for total control
893
+ const ast = parser('# Hello world')
894
+ const jsxElement2 = astToJSX(ast)
799
895
  ```
800
896
 
801
- It accepts the following arguments:
897
+ ### HTML
802
898
 
803
- ```js
804
- compiler(markdown: string, options: object?)
899
+ For HTML string output (server-side rendering), import from the `/html` entry point:
900
+
901
+ ```tsx
902
+ import { compiler, html, parser } from 'markdown-to-jsx/html'
903
+
904
+ // Convenience function that combines parsing and HTML rendering
905
+ const htmlString = compiler('# Hello world')
906
+ // Returns: '<h1>Hello world</h1>'
907
+
908
+ // Or use parser + html separately for more control
909
+ const ast = parser('# Hello world')
910
+ const htmlString2 = html(ast)
911
+ ```
912
+
913
+ ### Markdown
914
+
915
+ For markdown-to-markdown compilation (normalization and formatting), import from the `/markdown` entry point:
916
+
917
+ ```typescript
918
+ import { compiler, astToMarkdown, parser } from 'markdown-to-jsx/markdown'
919
+
920
+ // Convenience function that parses and recompiles markdown
921
+ const normalizedMarkdown = compiler('# Hello world\n\nExtra spaces!')
922
+ // Returns: '# Hello world\n\nExtra spaces!\n'
923
+
924
+ // Or work with AST directly
925
+ const ast = parser('# Hello world')
926
+ const normalizedMarkdown2 = astToMarkdown(ast)
927
+ // Returns: '# Hello world\n'
928
+ ```
929
+
930
+ ## Using The Parser (Low-Level AST API)
931
+
932
+ The `parser` function provides direct access to the parsed AST without rendering:
933
+
934
+ ```tsx
935
+ import { parser } from 'markdown-to-jsx'
936
+ import type { MarkdownToJSX } from 'markdown-to-jsx'
937
+
938
+ // Parse markdown to AST
939
+ const ast = parser('# Hello world')
940
+
941
+ // TypeScript: AST is MarkdownToJSX.ASTNode[]
942
+ console.log(ast) // Array of parsed nodes
943
+
944
+ // You can then render with html() or compiler()
945
+ ```
946
+
947
+ The `parser` function accepts:
948
+
949
+ - `source: string` - markdown source
950
+ - `state?: MarkdownToJSX.State` - parsing state (defaults: `{ inline: false, refs: {} }`)
951
+ - `options?: MarkdownToJSX.Options` - parsing options
952
+
953
+ Use `parser` when you need:
954
+
955
+ - Direct AST access without React rendering
956
+ - Custom rendering logic
957
+ - AST manipulation before rendering
958
+
959
+ ## AST Anatomy
960
+
961
+ The Abstract Syntax Tree (AST) is a structured representation of parsed markdown. Each node in the AST has a `type` property that identifies its kind, and type-specific properties.
962
+
963
+ **Important:** The first node in the AST is typically a `RuleType.refCollection` node that contains all reference definitions found in the document, including footnotes (stored with keys prefixed with `^`). This node is skipped during rendering but is useful for accessing reference data. Footnotes are automatically extracted from the refCollection and rendered in a `<footer>` element by both `compiler()` and `astToJSX()`.
964
+
965
+ ### Node Types
966
+
967
+ The AST consists of the following node types (use `RuleType` to check node types):
968
+
969
+ **Block-level nodes:**
970
+
971
+ - `RuleType.heading` - Headings (`# Heading`)
972
+ ```tsx
973
+ { type: RuleType.heading, level: 1, id: "heading", children: [...] }
974
+ ```
975
+ - `RuleType.paragraph` - Paragraphs
976
+ ```tsx
977
+ { type: RuleType.paragraph, children: [...] }
978
+ ```
979
+ - `RuleType.codeBlock` - Fenced code blocks (```)
980
+ ```tsx
981
+ { type: RuleType.codeBlock, lang: "javascript", text: "code content" }
982
+ ```
983
+ - `RuleType.blockQuote` - Blockquotes (`>`)
984
+ ```tsx
985
+ { type: RuleType.blockQuote, children: [...], alert?: "note" }
986
+ ```
987
+ - `RuleType.orderedList` / `RuleType.unorderedList` - Lists
988
+ ```tsx
989
+ { type: RuleType.orderedList, items: [[...]], start?: 1 }
990
+ { type: RuleType.unorderedList, items: [[...]], ordered: false }
991
+ ```
992
+ - `RuleType.table` - Tables
993
+ ```tsx
994
+ { type: RuleType.table, header: [...], cells: [[...]], align: [...] }
995
+ ```
996
+ - `RuleType.htmlBlock` - HTML blocks
997
+ ```tsx
998
+ { type: RuleType.htmlBlock, tag: "div", attrs: {}, children: [...] }
999
+ ```
1000
+
1001
+ **Inline nodes:**
1002
+
1003
+ - `RuleType.text` - Plain text
1004
+ ```tsx
1005
+ { type: RuleType.text, text: "Hello world" }
1006
+ ```
1007
+ - `RuleType.textFormatted` - Bold, italic, etc.
1008
+ ```tsx
1009
+ { type: RuleType.textFormatted, tag: "strong", children: [...] }
1010
+ ```
1011
+ - `RuleType.codeInline` - Inline code (`` ` ``)
1012
+ ```tsx
1013
+ { type: RuleType.codeInline, text: "code" }
1014
+ ```
1015
+ - `RuleType.link` - Links
1016
+ ```tsx
1017
+ { type: RuleType.link, target: "https://example.com", children: [...] }
1018
+ ```
1019
+ - `RuleType.image` - Images
1020
+ ```tsx
1021
+ { type: RuleType.image, target: "image.png", alt: "description" }
1022
+ ```
1023
+ - `RuleType.refLink` / `RuleType.refImage` - Reference-style links/images
1024
+ ```tsx
1025
+ { type: RuleType.refLink, ref: "linkref", children: [...] }
1026
+ ```
1027
+
1028
+ **Other nodes:**
1029
+
1030
+ - `RuleType.breakLine` - Hard line breaks (` `)
1031
+ - `RuleType.breakThematic` - Horizontal rules (`---`)
1032
+ - `RuleType.gfmTask` - GFM task list items (`- [ ]`)
1033
+ - `RuleType.refCollection` - Reference definitions collection (appears at AST root, includes footnotes with `^` prefix)
1034
+ - `RuleType.footnote` - Footnote definition node (not rendered, stored in refCollection)
1035
+ - `RuleType.footnoteReference` - Footnote reference (`[^identifier]`)
1036
+
1037
+ ### Example AST Structure
1038
+
1039
+ ````tsx
1040
+ import { parser, RuleType } from 'markdown-to-jsx'
1041
+
1042
+ const ast = parser(`# Hello World
1043
+
1044
+ This is a **paragraph** with [a link](https://example.com).
1045
+
1046
+ [linkref]: https://example.com
1047
+
1048
+ ```javascript
1049
+ console.log('code')
1050
+ ```
1051
+
1052
+ `)
1053
+
1054
+ // AST structure:
1055
+ [
1056
+ // Reference collection (first node, if references exist)
1057
+ {
1058
+ type: RuleType.refCollection,
1059
+ refs: {
1060
+ linkref: { target: 'https://example.com', title: undefined },
1061
+ },
1062
+ },
1063
+ {
1064
+ type: RuleType.heading,
1065
+ level: 1,
1066
+ id: 'hello-world',
1067
+ children: [{ type: RuleType.text, text: 'Hello World' }],
1068
+ },
1069
+ {
1070
+ type: RuleType.paragraph,
1071
+ children: [
1072
+ { type: RuleType.text, text: 'This is a ' },
1073
+ {
1074
+ type: RuleType.textFormatted,
1075
+ tag: 'strong',
1076
+ children: [{ type: RuleType.text, text: 'paragraph' }],
1077
+ },
1078
+ { type: RuleType.text, text: ' with ' },
1079
+ {
1080
+ type: RuleType.link,
1081
+ target: 'https://example.com',
1082
+ children: [{ type: RuleType.text, text: 'a link' }],
1083
+ },
1084
+ { type: RuleType.text, text: '.' },
1085
+ ],
1086
+ },
1087
+ {
1088
+ type: RuleType.codeBlock,
1089
+ lang: 'javascript',
1090
+ text: "console.log('code')",
1091
+ },
1092
+ ]
1093
+
1094
+ ````
1095
+
1096
+ ### Type Checking
1097
+
1098
+ Use `RuleType` constants to check node types:
1099
+
1100
+ ```tsx
1101
+ import { RuleType } from 'markdown-to-jsx'
1102
+
1103
+ if (node.type === RuleType.heading) {
1104
+ const heading = node as MarkdownToJSX.HeadingNode
1105
+ console.log(`Heading level ${heading.level}: ${heading.id}`)
1106
+ }
805
1107
  ```
806
1108
 
1109
+ **When to use `compiler` vs `parser` vs `<Markdown>`:**
1110
+
1111
+ - Use `<Markdown>` when you need a simple React component that renders markdown to JSX.
1112
+ - Use `compiler` when you need React JSX output from markdown (the component uses this internally).
1113
+ - Use `parser` + `astToJSX` when you need the AST for custom processing before rendering to JSX, or just the AST itself.
1114
+
807
1115
  ## Changelog
808
1116
 
809
- See [Github Releases](https://github.com/probablyup/markdown-to-jsx/releases).
1117
+ See [Github Releases](https://github.com/quantizor/markdown-to-jsx/releases).
810
1118
 
811
1119
  ## Donate
812
1120
 
813
- Like this library? It's developed entirely on a volunteer basis; chip in a few bucks if you can via the Sponsor link!
814
-
815
- MIT
1121
+ Like this library? It's developed entirely on a volunteer basis; chip in a few bucks if you can via the [Sponsor link](https://github.com/sponsors/quantizor)!