Skip to content

Commit 7bb0e71

Browse files
github-actions[bot]quantizor
authored andcommitted
Version Packages
1 parent 6e50f15 commit 7bb0e71

File tree

6 files changed

+141
-154
lines changed

6 files changed

+141
-154
lines changed

.changeset/context-providers-and-memoization.md

Lines changed: 0 additions & 56 deletions
This file was deleted.

.changeset/eval-unserializable-expressions-option.md

Lines changed: 0 additions & 30 deletions
This file was deleted.

.changeset/intelligent-jsx-prop-parsing.md

Lines changed: 0 additions & 43 deletions
This file was deleted.

.changeset/jsx-component-nesting-fix.md

Lines changed: 0 additions & 24 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,145 @@
11
# markdown-to-jsx
22

3+
## 9.4.0
4+
5+
### Minor Changes
6+
7+
- c1be885: Added context providers and memoization to all major renderers for better developer experience and performance.
8+
9+
**React:**
10+
- `MarkdownContext` - React context for default options
11+
- `MarkdownProvider` - Provider component to avoid prop-drilling
12+
- `useMemo` - 3-stage memoization (options, content, JSX)
13+
14+
**React Native:**
15+
- `MarkdownContext` - React context for default options
16+
- `MarkdownProvider` - Provider component to avoid prop-drilling
17+
- `useMemo` - 3-stage memoization (options, content, JSX)
18+
19+
**Vue:**
20+
- `MarkdownOptionsKey` - InjectionKey for provide/inject pattern
21+
- `MarkdownProvider` - Provider component using Vue's provide
22+
- `computed` - Reactive memoization for options, content, and JSX
23+
24+
**Benefits:**
25+
1. **Avoid prop-drilling** - Set options once at the top level:
26+
27+
```tsx
28+
<MarkdownProvider options={commonOptions}>
29+
<App>
30+
<Markdown>...</Markdown>
31+
<Markdown>...</Markdown>
32+
</App>
33+
</MarkdownProvider>
34+
```
35+
36+
2. **Performance optimization** - Content is only parsed when it actually changes, not on every render
37+
3. **Fully backwards compatible** - Existing usage works unchanged, providers are optional
38+
39+
**Example:**
40+
41+
```tsx
42+
import { MarkdownProvider } from 'markdown-to-jsx/react'
43+
44+
function App() {
45+
return (
46+
<MarkdownProvider options={{ wrapper: 'article', tagfilter: true }}>
47+
<Markdown># Page 1</Markdown>
48+
<Markdown># Page 2</Markdown>
49+
{/* Both inherit options from provider */}
50+
</MarkdownProvider>
51+
)
52+
}
53+
```
54+
55+
- ef8a002: Added opt-in `options.evalUnserializableExpressions` to eval function expressions and other unserializable JSX props from trusted markdown sources.
56+
57+
**⚠️ SECURITY WARNING: STRONGLY DISCOURAGED FOR USER INPUTS**
58+
59+
This option uses `eval()` and should ONLY be used with completely trusted markdown sources (e.g., your own documentation). Never enable this for user-submitted content.
60+
61+
**Usage:**
62+
63+
```tsx
64+
// For trusted sources only
65+
const markdown = `
66+
<Button onPress={() => alert('clicked!')} />
67+
<ApiEndpoint url={process.env.API_URL} />
68+
`
69+
70+
parser(markdown, { evalUnserializableExpressions: true })
71+
72+
// Components receive:
73+
// - onPress: actual function () => alert('clicked!')
74+
// - url: the value of process.env.API_URL from your environment
75+
// Without this option, these would be strings "() => alert('clicked!')" and "process.env.API_URL"
76+
```
77+
78+
**Safer alternative:** Use `renderRule` to handle stringified expressions on a case-by-case basis with your own validation and allowlists.
79+
80+
See the README for detailed security considerations and safe alternatives.
81+
82+
- ef8a002: JSX prop values are now intelligently parsed instead of always being strings:
83+
- **Arrays and objects** are parsed via `JSON.parse()`: `data={[1, 2, 3]}``attrs.data = [1, 2, 3]`
84+
- **Booleans** are parsed: `enabled={true}``attrs.enabled = true`
85+
- **Functions** are kept as strings for security: `onClick={() => ...}``attrs.onClick = "() => ..."`
86+
- **Complex expressions** are kept as strings: `value={someVar}``attrs.value = "someVar"`
87+
88+
The original raw attribute string is preserved in the `rawAttrs` field.
89+
90+
**Benefits:**
91+
- Type-safe access to structured data without manual parsing
92+
- Backwards compatible - check types before using
93+
- Secure by default - functions remain as strings
94+
95+
**Example:**
96+
97+
<!-- prettier-ignore -->
98+
```tsx
99+
// In markdown:
100+
<ApiTable
101+
rows={[
102+
['Name', 'Value'],
103+
['foo', 'bar'],
104+
]}
105+
/>
106+
107+
// In your component:
108+
const ApiTable = ({ rows }) => {
109+
// rows is already an array, no JSON.parse needed!
110+
return <table>...</table>
111+
}
112+
113+
// For backwards compatibility:
114+
const rows =
115+
typeof props.rows === 'string' ? JSON.parse(props.rows) : props.rows
116+
```
117+
118+
**Security:** Functions remain as strings by default. Use `renderRule` for case-by-case handling, or see the new `options.evalUnserializableExpressions` feature for opt-in eval (not recommended for user inputs).
119+
120+
### Patch Changes
121+
122+
- ef8a002: JSX components with double-newlines (blank lines) between opening and closing tags now properly nest children instead of creating sibling nodes. This fixes incorrect AST structure for JSX/MDX content.
123+
124+
**Before:**
125+
126+
<!-- prettier-ignore -->
127+
```jsx
128+
<Figure>
129+
130+
<div>content</div>
131+
132+
</Figure>
133+
```
134+
135+
Parsed as 3 siblings: `<Figure>`, `<div>`, `</Figure>`
136+
137+
**After:**
138+
139+
Parsed as parent-child: `<Figure>` contains `<div>` as a child
140+
141+
This was a bug where the parser incorrectly treated JSX components as siblings when double-newlines were present between the tags. The fix ensures proper parent-child relationships match expected JSX/MDX semantics.
142+
3143
## 9.3.5
4144

5145
### Patch Changes

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "A very fast and versatile markdown toolchain. AST, React, React Native, SolidJS, Vue, Markdown, and HTML output available with full customization.",
44
"homepage": "https://markdown-to-jsx.quantizor.dev",
55
"license": "MIT",
6-
"version": "9.3.5",
6+
"version": "9.4.0",
77
"publishConfig": {
88
"access": "public",
99
"mangle": {

0 commit comments

Comments
 (0)