safe-mdx 1.3.2 → 1.3.6
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 +14 -14
- package/dist/assets/HtmlToJsxConverter-Ds0bTjpw.js +24 -0
- package/dist/assets/_commonjsHelpers-CqkleIqs.js +1 -0
- package/dist/assets/index-B5fPOjPt.css +1 -0
- package/dist/assets/index-B7ATSoRE.js +9 -0
- package/dist/assets/index-BwZ2FTRd.js +146 -0
- package/dist/assets/index-R1UqLMGJ.js +1 -0
- package/dist/assets/index-c0qeY2gs.js +9 -0
- package/dist/assets/jsx-runtime-BhZZLbvw.js +9 -0
- package/dist/assets/jsx-runtime-NArryeSM.js +1 -0
- package/dist/assets/react-Ca6JzGpx.js +1 -0
- package/dist/assets/react-dom-BYRHYqYl.js +1 -0
- package/dist/html/attributes.d.ts +19 -0
- package/dist/html/attributes.d.ts.map +1 -0
- package/dist/html/attributes.js +289 -0
- package/dist/html/attributes.js.map +1 -0
- package/dist/html/convert-attributes.d.ts +6 -0
- package/dist/html/convert-attributes.d.ts.map +1 -0
- package/dist/html/convert-attributes.js +43 -0
- package/dist/html/convert-attributes.js.map +1 -0
- package/dist/html/domparser-browser.d.ts +4 -0
- package/dist/html/domparser-browser.d.ts.map +1 -0
- package/dist/html/domparser-browser.js +7 -0
- package/dist/html/domparser-browser.js.map +1 -0
- package/dist/html/domparser.d.ts +2 -0
- package/dist/html/domparser.d.ts.map +1 -0
- package/dist/html/domparser.js +5 -0
- package/dist/html/domparser.js.map +1 -0
- package/dist/html/html-to-mdx-ast.d.ts +25 -0
- package/dist/html/html-to-mdx-ast.d.ts.map +1 -0
- package/dist/html/html-to-mdx-ast.js +247 -0
- package/dist/html/html-to-mdx-ast.js.map +1 -0
- package/dist/html/html-to-mdx-ast.test.d.ts +2 -0
- package/dist/html/html-to-mdx-ast.test.d.ts.map +1 -0
- package/dist/html/html-to-mdx-ast.test.js +411 -0
- package/dist/html/html-to-mdx-ast.test.js.map +1 -0
- package/dist/html/remark-mdx-jsx-normalize.d.ts +10 -0
- package/dist/html/remark-mdx-jsx-normalize.d.ts.map +1 -0
- package/dist/html/remark-mdx-jsx-normalize.js +194 -0
- package/dist/html/remark-mdx-jsx-normalize.js.map +1 -0
- package/dist/html/valid-html-elements.d.ts +10 -0
- package/dist/html/valid-html-elements.d.ts.map +1 -0
- package/dist/html/valid-html-elements.js +50 -0
- package/dist/html/valid-html-elements.js.map +1 -0
- package/dist/index.html +19 -0
- package/dist/parse.d.ts +2 -0
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +2 -0
- package/dist/parse.js.map +1 -1
- package/dist/safe-mdx.d.ts +2 -2
- package/dist/safe-mdx.d.ts.map +1 -1
- package/dist/safe-mdx.js +24 -76
- package/dist/safe-mdx.js.map +1 -1
- package/dist/safe-mdx.test.js +161 -8
- package/dist/safe-mdx.test.js.map +1 -1
- package/package.json +28 -6
- package/src/html/README +17 -0
- package/src/html/attributes.ts +297 -0
- package/src/html/convert-attributes.ts +59 -0
- package/src/html/domparser-browser.ts +6 -0
- package/src/html/domparser.ts +5 -0
- package/src/html/html-to-mdx-ast.test.ts +459 -0
- package/src/html/html-to-mdx-ast.ts +327 -0
- package/src/html/remark-mdx-jsx-normalize.ts +209 -0
- package/src/html/valid-html-elements.ts +65 -0
- package/src/parse.ts +3 -0
- package/src/safe-mdx.test.tsx +178 -12
- package/src/safe-mdx.tsx +25 -84
- package/dist/HtmlToJsxConverter.d.ts +0 -10
- package/dist/HtmlToJsxConverter.d.ts.map +0 -1
- package/dist/HtmlToJsxConverter.js +0 -22
- package/dist/HtmlToJsxConverter.js.map +0 -1
- package/dist/plugins.d.ts +0 -12
- package/dist/plugins.d.ts.map +0 -1
- package/dist/plugins.js +0 -68
- package/dist/plugins.js.map +0 -1
- package/src/HtmlToJsxConverter.tsx +0 -37
package/src/safe-mdx.test.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import dedent from 'dedent'
|
|
2
|
-
import { htmlToJsx } from 'html-to-jsx-transform'
|
|
3
2
|
import React from 'react'
|
|
4
3
|
import { renderToStaticMarkup } from 'react-dom/server'
|
|
5
4
|
import { expect, test } from 'vitest'
|
|
@@ -29,16 +28,6 @@ function render(code, componentPropsSchema?: ComponentPropsSchema, allowClientEs
|
|
|
29
28
|
return { result, errors: visitor.errors || [], html }
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
test('htmlToJsx', () => {
|
|
33
|
-
expect(htmlToJsx('<p x="y">')).toMatchInlineSnapshot(`"<p x="y" />"`)
|
|
34
|
-
expect(htmlToJsx('<p>text</p>')).toMatchInlineSnapshot(`"<p>text</p>"`)
|
|
35
|
-
expect(htmlToJsx('before <p>text</p>')).toMatchInlineSnapshot(
|
|
36
|
-
`"<>before <p>text</p></>"`,
|
|
37
|
-
)
|
|
38
|
-
expect(htmlToJsx('<nonexisting>text</nonexisting>')).toMatchInlineSnapshot(
|
|
39
|
-
`"<nonexisting>text</nonexisting>"`,
|
|
40
|
-
)
|
|
41
|
-
})
|
|
42
31
|
|
|
43
32
|
test('reference links with titles', () => {
|
|
44
33
|
const code = dedent`
|
|
@@ -2269,6 +2258,66 @@ test('kitchen sink', () => {
|
|
|
2269
2258
|
`)
|
|
2270
2259
|
})
|
|
2271
2260
|
|
|
2261
|
+
test('mdx jsx with unknown components are ignored', () => {
|
|
2262
|
+
// Note: In MDX, <custom-element> is treated as MDX JSX, not raw HTML
|
|
2263
|
+
// Unknown JSX components are ignored completely (including their content)
|
|
2264
|
+
const code = dedent`
|
|
2265
|
+
# Heading with JSX
|
|
2266
|
+
|
|
2267
|
+
This is a paragraph with some JSX components.
|
|
2268
|
+
|
|
2269
|
+
<div>This is a valid div</div>
|
|
2270
|
+
|
|
2271
|
+
<CustomElement>This unknown component should be ignored</CustomElement>
|
|
2272
|
+
|
|
2273
|
+
<span className="highlight">This span is valid</span>
|
|
2274
|
+
|
|
2275
|
+
<AnotherUnknown>Another unknown component content</AnotherUnknown>
|
|
2276
|
+
|
|
2277
|
+
More text after JSX.
|
|
2278
|
+
`
|
|
2279
|
+
|
|
2280
|
+
const { html, result, errors } = render(code)
|
|
2281
|
+
|
|
2282
|
+
// Check that valid HTML elements are present
|
|
2283
|
+
expect(html).toContain('<div>This is a valid div</div>')
|
|
2284
|
+
expect(html).toContain('<span')
|
|
2285
|
+
expect(html).toContain('This span is valid</span>')
|
|
2286
|
+
|
|
2287
|
+
// Check that unknown components are completely ignored
|
|
2288
|
+
expect(html).not.toContain('CustomElement')
|
|
2289
|
+
expect(html).not.toContain('AnotherUnknown')
|
|
2290
|
+
expect(html).not.toContain('This unknown component should be ignored')
|
|
2291
|
+
expect(html).not.toContain('Another unknown component content')
|
|
2292
|
+
|
|
2293
|
+
// Check that errors were generated for unknown components
|
|
2294
|
+
expect(errors).toHaveLength(2)
|
|
2295
|
+
expect(errors[0].message).toContain('Unsupported jsx component CustomElement')
|
|
2296
|
+
expect(errors[1].message).toContain('Unsupported jsx component AnotherUnknown')
|
|
2297
|
+
|
|
2298
|
+
expect(result).toMatchInlineSnapshot(`
|
|
2299
|
+
<React.Fragment>
|
|
2300
|
+
<h1>
|
|
2301
|
+
Heading with JSX
|
|
2302
|
+
</h1>
|
|
2303
|
+
<p>
|
|
2304
|
+
This is a paragraph with some JSX components.
|
|
2305
|
+
</p>
|
|
2306
|
+
<div>
|
|
2307
|
+
This is a valid div
|
|
2308
|
+
</div>
|
|
2309
|
+
<span
|
|
2310
|
+
className="highlight"
|
|
2311
|
+
>
|
|
2312
|
+
This span is valid
|
|
2313
|
+
</span>
|
|
2314
|
+
<p>
|
|
2315
|
+
More text after JSX.
|
|
2316
|
+
</p>
|
|
2317
|
+
</React.Fragment>
|
|
2318
|
+
`)
|
|
2319
|
+
})
|
|
2320
|
+
|
|
2272
2321
|
test('code block rendering', () => {
|
|
2273
2322
|
const code = dedent`
|
|
2274
2323
|
`
|
|
@@ -2904,7 +2953,7 @@ test('ESM imports from https URLs', () => {
|
|
|
2904
2953
|
|
|
2905
2954
|
// Since these are dynamic imports that only work on client, the server render should return null
|
|
2906
2955
|
const html = renderToStaticMarkup(result)
|
|
2907
|
-
expect(html).toMatchInlineSnapshot(`"<h1>Hello</h1>"`)
|
|
2956
|
+
expect(html).toMatchInlineSnapshot(`"<link href="https://esm.sh" rel="dns-prefetch"/><link rel="preconnect" href="https://esm.sh"/><h1>Hello</h1>"`)
|
|
2908
2957
|
|
|
2909
2958
|
expect(visitor.errors).toEqual([])
|
|
2910
2959
|
})
|
|
@@ -3334,3 +3383,120 @@ test('jsx component with complex array props should show clear error message', (
|
|
|
3334
3383
|
expect(expressionError!.message).toContain('Functions are not supported')
|
|
3335
3384
|
expect(expressionError!.line).toBe(1)
|
|
3336
3385
|
})
|
|
3386
|
+
|
|
3387
|
+
test('override renderNode to wrap bold text in colored span', () => {
|
|
3388
|
+
const code = dedent`
|
|
3389
|
+
This is **bold text** and this is regular text.
|
|
3390
|
+
|
|
3391
|
+
Another line with **more bold** content.
|
|
3392
|
+
`
|
|
3393
|
+
|
|
3394
|
+
const mdast = mdxParse(code)
|
|
3395
|
+
const visitor = new MdastToJsx({
|
|
3396
|
+
markdown: code,
|
|
3397
|
+
mdast,
|
|
3398
|
+
components,
|
|
3399
|
+
renderNode: (node, transform) => {
|
|
3400
|
+
if (node.type === 'strong') {
|
|
3401
|
+
return (
|
|
3402
|
+
<span style={{ color: 'red', fontWeight: 'bold' }}>
|
|
3403
|
+
{node.children?.map(child => transform(child))}
|
|
3404
|
+
</span>
|
|
3405
|
+
)
|
|
3406
|
+
}
|
|
3407
|
+
// Return undefined to use default rendering
|
|
3408
|
+
return undefined
|
|
3409
|
+
}
|
|
3410
|
+
})
|
|
3411
|
+
|
|
3412
|
+
const result = visitor.run()
|
|
3413
|
+
const html = renderToStaticMarkup(result)
|
|
3414
|
+
|
|
3415
|
+
expect(html).toMatchInlineSnapshot(`"<p>This is <span style="color:red;font-weight:bold">bold text</span> and this is regular text.</p><p>Another line with <span style="color:red;font-weight:bold">more bold</span> content.</p>"`)
|
|
3416
|
+
})
|
|
3417
|
+
|
|
3418
|
+
test("skip unknown elements in raw HTML content", () => {
|
|
3419
|
+
const { html } = render(`
|
|
3420
|
+
Some text before
|
|
3421
|
+
<html><body>
|
|
3422
|
+
<p>Valid paragraph</p>
|
|
3423
|
+
<unknonw>This content should be preserved</unknonw>
|
|
3424
|
+
<div>Valid div</div>
|
|
3425
|
+
<faketag>Another preserved content</faketag>
|
|
3426
|
+
</body></html>
|
|
3427
|
+
Some text after
|
|
3428
|
+
`);
|
|
3429
|
+
expect(html).toMatchInlineSnapshot(`"<p>Some text before</p><p>Some text after</p>"`);
|
|
3430
|
+
});
|
|
3431
|
+
|
|
3432
|
+
test("skip unknown elements in complex nested HTML structures", () => {
|
|
3433
|
+
const { html } = render(`
|
|
3434
|
+
# Main Title
|
|
3435
|
+
|
|
3436
|
+
<article>
|
|
3437
|
+
<header>
|
|
3438
|
+
<h1>Article Title</h1>
|
|
3439
|
+
<customheader>
|
|
3440
|
+
<p>This paragraph should be preserved</p>
|
|
3441
|
+
<time>2024-01-01</time>
|
|
3442
|
+
</customheader>
|
|
3443
|
+
</header>
|
|
3444
|
+
|
|
3445
|
+
<section>
|
|
3446
|
+
<blockquote>
|
|
3447
|
+
<p>A famous quote</p>
|
|
3448
|
+
<customcite>
|
|
3449
|
+
<strong>- Author Name</strong>
|
|
3450
|
+
<unknowntag>
|
|
3451
|
+
<em>from a book</em>
|
|
3452
|
+
<span>published in <b>2024</b></span>
|
|
3453
|
+
</unknowntag>
|
|
3454
|
+
</customcite>
|
|
3455
|
+
</blockquote>
|
|
3456
|
+
|
|
3457
|
+
<fakesection>
|
|
3458
|
+
<h2>Nested Heading</h2>
|
|
3459
|
+
<ul>
|
|
3460
|
+
<li>First item with <invalidtag>nested <code>code</code></invalidtag></li>
|
|
3461
|
+
<li>Second item</li>
|
|
3462
|
+
<customli>Third item should show</customli>
|
|
3463
|
+
</ul>
|
|
3464
|
+
</fakesection>
|
|
3465
|
+
</section>
|
|
3466
|
+
|
|
3467
|
+
<footer>
|
|
3468
|
+
<customfooter>
|
|
3469
|
+
<nav>
|
|
3470
|
+
<a href="#top">Back to top</a>
|
|
3471
|
+
<fakelink>
|
|
3472
|
+
<span>Contact us</span>
|
|
3473
|
+
</fakelink>
|
|
3474
|
+
</nav>
|
|
3475
|
+
</customfooter>
|
|
3476
|
+
</footer>
|
|
3477
|
+
</article>
|
|
3478
|
+
|
|
3479
|
+
## Another Section
|
|
3480
|
+
|
|
3481
|
+
<div>
|
|
3482
|
+
<customelement>
|
|
3483
|
+
<table>
|
|
3484
|
+
<thead>
|
|
3485
|
+
<tr>
|
|
3486
|
+
<th>Header 1</th>
|
|
3487
|
+
<customth>Header 2 content</customth>
|
|
3488
|
+
</tr>
|
|
3489
|
+
</thead>
|
|
3490
|
+
<tbody>
|
|
3491
|
+
<customrow>
|
|
3492
|
+
<td>Cell 1</td>
|
|
3493
|
+
<td>Cell 2</td>
|
|
3494
|
+
</customrow>
|
|
3495
|
+
</tbody>
|
|
3496
|
+
</table>
|
|
3497
|
+
</customelement>
|
|
3498
|
+
</div>
|
|
3499
|
+
`);
|
|
3500
|
+
|
|
3501
|
+
expect(html).toMatchInlineSnapshot(`"<h1>Main Title</h1><article><header><h1>Article Title</h1></header><section><blockquote><p>A famous quote</p></blockquote></section><footer></footer></article><h2>Another Section</h2><div></div>"`);
|
|
3502
|
+
});
|
package/src/safe-mdx.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { cloneElement } from 'react'
|
|
2
2
|
|
|
3
3
|
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
4
4
|
import type { JSXElement } from 'estree-jsx'
|
|
@@ -9,12 +9,8 @@ import type { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx'
|
|
|
9
9
|
import { Fragment, ReactNode } from 'react'
|
|
10
10
|
import { DynamicEsmComponent } from './dynamic-esm-component.js'
|
|
11
11
|
import { extractComponentInfo, parseEsmImports } from './esm-parser.js'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import('./HtmlToJsxConverter.js').then((module) => ({
|
|
15
|
-
default: module.HtmlToJsxConverter,
|
|
16
|
-
})),
|
|
17
|
-
)
|
|
12
|
+
import { htmlToMdxAst } from './html/html-to-mdx-ast.js'
|
|
13
|
+
import { validHtmlElements, nativeTags } from './html/valid-html-elements.js'
|
|
18
14
|
|
|
19
15
|
export type MyRootContent = RootContent | Root
|
|
20
16
|
|
|
@@ -190,7 +186,7 @@ export class MdastToJsx {
|
|
|
190
186
|
|
|
191
187
|
mapMdastChildren(node: any) {
|
|
192
188
|
const res = node.children
|
|
193
|
-
?.flatMap((child) => this.mdastTransformer(child))
|
|
189
|
+
?.flatMap((child) => this.mdastTransformer(child, node.type))
|
|
194
190
|
.filter(Boolean)
|
|
195
191
|
if (Array.isArray(res)) {
|
|
196
192
|
if (!res.length) {
|
|
@@ -291,7 +287,7 @@ export class MdastToJsx {
|
|
|
291
287
|
)
|
|
292
288
|
}
|
|
293
289
|
default: {
|
|
294
|
-
return this.mdastTransformer(node)
|
|
290
|
+
return this.mdastTransformer(node, 'mdxJsxElement')
|
|
295
291
|
}
|
|
296
292
|
}
|
|
297
293
|
}
|
|
@@ -568,14 +564,14 @@ export class MdastToJsx {
|
|
|
568
564
|
}
|
|
569
565
|
|
|
570
566
|
run() {
|
|
571
|
-
const res = this.mdastTransformer(this.mdast) as ReactNode
|
|
567
|
+
const res = this.mdastTransformer(this.mdast, 'root') as ReactNode
|
|
572
568
|
if (Array.isArray(res) && res.length === 1) {
|
|
573
569
|
return res[0]
|
|
574
570
|
}
|
|
575
571
|
return res
|
|
576
572
|
}
|
|
577
573
|
|
|
578
|
-
mdastTransformer(node: MyRootContent): ReactNode {
|
|
574
|
+
mdastTransformer(node: MyRootContent, parentType?: string): ReactNode {
|
|
579
575
|
if (!node) {
|
|
580
576
|
return []
|
|
581
577
|
}
|
|
@@ -584,7 +580,7 @@ export class MdastToJsx {
|
|
|
584
580
|
if (this.renderNode) {
|
|
585
581
|
const customResult = this.renderNode(
|
|
586
582
|
node,
|
|
587
|
-
this.mdastTransformer.
|
|
583
|
+
(n: MyRootContent) => this.mdastTransformer(n, node.type),
|
|
588
584
|
)
|
|
589
585
|
if (customResult !== undefined) {
|
|
590
586
|
return customResult
|
|
@@ -932,15 +928,23 @@ export class MdastToJsx {
|
|
|
932
928
|
return []
|
|
933
929
|
}
|
|
934
930
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
931
|
+
// Parse HTML to MDX AST using the new approach - always returns an array
|
|
932
|
+
const mdxAst = htmlToMdxAst({
|
|
933
|
+
html: text,
|
|
934
|
+
parentType: parentType || 'root',
|
|
935
|
+
convertTagName: ({ tagName }) => {
|
|
936
|
+
const lowerTag = tagName.toLowerCase()
|
|
937
|
+
// Only keep valid HTML elements
|
|
938
|
+
if (validHtmlElements.has(lowerTag)) {
|
|
939
|
+
return lowerTag
|
|
940
|
+
}
|
|
941
|
+
// Return empty string for non-HTML elements
|
|
942
|
+
return ''
|
|
943
|
+
}
|
|
944
|
+
})
|
|
945
|
+
|
|
946
|
+
// Process the MDX AST nodes
|
|
947
|
+
return mdxAst.map(child => this.mdastTransformer(child, parentType))
|
|
944
948
|
}
|
|
945
949
|
case 'imageReference': {
|
|
946
950
|
return []
|
|
@@ -1002,69 +1006,6 @@ function safeJsonParse(str: string) {
|
|
|
1002
1006
|
}
|
|
1003
1007
|
}
|
|
1004
1008
|
|
|
1005
|
-
const nativeTags = [
|
|
1006
|
-
'blockquote',
|
|
1007
|
-
'strong',
|
|
1008
|
-
'em',
|
|
1009
|
-
'del',
|
|
1010
|
-
'hr',
|
|
1011
|
-
'a',
|
|
1012
|
-
'b',
|
|
1013
|
-
'br',
|
|
1014
|
-
'button',
|
|
1015
|
-
'div',
|
|
1016
|
-
'form',
|
|
1017
|
-
'h1',
|
|
1018
|
-
'h2',
|
|
1019
|
-
'h3',
|
|
1020
|
-
'h4',
|
|
1021
|
-
'head',
|
|
1022
|
-
'iframe',
|
|
1023
|
-
'img',
|
|
1024
|
-
'input',
|
|
1025
|
-
'label',
|
|
1026
|
-
'li',
|
|
1027
|
-
'link',
|
|
1028
|
-
'ol',
|
|
1029
|
-
'p',
|
|
1030
|
-
'path',
|
|
1031
|
-
'picture',
|
|
1032
|
-
'script',
|
|
1033
|
-
'section',
|
|
1034
|
-
'source',
|
|
1035
|
-
'span',
|
|
1036
|
-
'sub',
|
|
1037
|
-
'sup',
|
|
1038
|
-
'svg',
|
|
1039
|
-
'table',
|
|
1040
|
-
'tbody',
|
|
1041
|
-
'td',
|
|
1042
|
-
'tfoot',
|
|
1043
|
-
'th',
|
|
1044
|
-
'thead',
|
|
1045
|
-
'tr',
|
|
1046
|
-
'ul',
|
|
1047
|
-
'video',
|
|
1048
|
-
'code',
|
|
1049
|
-
'pre',
|
|
1050
|
-
'figure',
|
|
1051
|
-
'canvas',
|
|
1052
|
-
'details',
|
|
1053
|
-
'dl',
|
|
1054
|
-
'dt',
|
|
1055
|
-
'dd',
|
|
1056
|
-
'fieldset',
|
|
1057
|
-
'footer',
|
|
1058
|
-
'header',
|
|
1059
|
-
'legend',
|
|
1060
|
-
'main',
|
|
1061
|
-
'mark',
|
|
1062
|
-
'nav',
|
|
1063
|
-
'progress',
|
|
1064
|
-
'summary',
|
|
1065
|
-
'time',
|
|
1066
|
-
] as const
|
|
1067
|
-
|
|
1068
1009
|
type ComponentsMap = { [k in (typeof nativeTags)[number]]?: any } & {
|
|
1069
1010
|
[key: string]: any
|
|
1070
1011
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { MdastToJsx, MyRootContent } from './safe-mdx.js';
|
|
3
|
-
interface HtmlToJsxConverterProps {
|
|
4
|
-
htmlText: string;
|
|
5
|
-
instance: MdastToJsx;
|
|
6
|
-
node: MyRootContent;
|
|
7
|
-
}
|
|
8
|
-
export declare function HtmlToJsxConverter({ htmlText, instance, node, }: HtmlToJsxConverterProps): string | number | bigint | true | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode>>;
|
|
9
|
-
export {};
|
|
10
|
-
//# sourceMappingURL=HtmlToJsxConverter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HtmlToJsxConverter.d.ts","sourceRoot":"","sources":["../src/HtmlToJsxConverter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAI9D,UAAU,uBAAuB;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,UAAU,CAAA;IACpB,IAAI,EAAE,aAAa,CAAA;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAC/B,QAAQ,EACR,QAAQ,EACR,IAAI,GACP,EAAE,uBAAuB,+SAoBzB"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { htmlToJsx } from 'html-to-jsx-transform';
|
|
3
|
-
React;
|
|
4
|
-
export function HtmlToJsxConverter({ htmlText, instance, node, }) {
|
|
5
|
-
try {
|
|
6
|
-
const jsx = htmlToJsx(htmlText);
|
|
7
|
-
const originalJsxStr = instance.jsxStr;
|
|
8
|
-
instance.jsxStr = jsx;
|
|
9
|
-
const result = instance.jsxTransformer(node);
|
|
10
|
-
instance.jsxStr = originalJsxStr;
|
|
11
|
-
if (Array.isArray(result)) {
|
|
12
|
-
console.log(`Unexpected array result`);
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
return result || null;
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
console.error('Error converting HTML to JSX:', error);
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
//# sourceMappingURL=HtmlToJsxConverter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HtmlToJsxConverter.js","sourceRoot":"","sources":["../src/HtmlToJsxConverter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAGjD,KAAK,CAAA;AAQL,MAAM,UAAU,kBAAkB,CAAC,EAC/B,QAAQ,EACR,QAAQ,EACR,IAAI,GACkB;IACtB,IAAI;QACA,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC/B,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAA;QACtC,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAA;QAErB,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAE5C,QAAQ,CAAC,MAAM,GAAG,cAAc,CAAA;QAEhC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;YACtC,OAAO,IAAI,CAAA;SACd;QAED,OAAO,MAAM,IAAI,IAAI,CAAA;KACxB;IAAC,OAAO,KAAK,EAAE;QACZ,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;QACrD,OAAO,IAAI,CAAA;KACd;AACL,CAAC"}
|
package/dist/plugins.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Root } from 'mdast';
|
|
2
|
-
/**
|
|
3
|
-
* https://github.com/mdx-js/mdx/blob/b3351fadcb6f78833a72757b7135dcfb8ab646fe/packages/mdx/lib/plugin/remark-mark-and-unravel.js
|
|
4
|
-
* A tiny plugin that unravels `<p><h1>x</h1></p>` but also
|
|
5
|
-
* `<p><Component /></p>` (so it has no knowledge of "HTML").
|
|
6
|
-
*
|
|
7
|
-
* It also marks JSX as being explicitly JSX, so when a user passes a `h1`
|
|
8
|
-
* component, it is used for `# heading` but not for `<h1>heading</h1>`.
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
export declare function remarkMarkAndUnravel(): (tree: Root) => void;
|
|
12
|
-
//# sourceMappingURL=plugins.d.ts.map
|
package/dist/plugins.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAe,MAAM,OAAO,CAAA;AAKzC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,WACT,IAAI,UAuE9B"}
|
package/dist/plugins.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { collapseWhiteSpace } from 'collapse-white-space';
|
|
2
|
-
import { visit } from 'unist-util-visit';
|
|
3
|
-
/**
|
|
4
|
-
* https://github.com/mdx-js/mdx/blob/b3351fadcb6f78833a72757b7135dcfb8ab646fe/packages/mdx/lib/plugin/remark-mark-and-unravel.js
|
|
5
|
-
* A tiny plugin that unravels `<p><h1>x</h1></p>` but also
|
|
6
|
-
* `<p><Component /></p>` (so it has no knowledge of "HTML").
|
|
7
|
-
*
|
|
8
|
-
* It also marks JSX as being explicitly JSX, so when a user passes a `h1`
|
|
9
|
-
* component, it is used for `# heading` but not for `<h1>heading</h1>`.
|
|
10
|
-
*
|
|
11
|
-
*/
|
|
12
|
-
export function remarkMarkAndUnravel() {
|
|
13
|
-
return function (tree) {
|
|
14
|
-
visit(tree, function (node, index, parent) {
|
|
15
|
-
let offset = -1;
|
|
16
|
-
let all = true;
|
|
17
|
-
let oneOrMore = false;
|
|
18
|
-
if (parent &&
|
|
19
|
-
typeof index === 'number' &&
|
|
20
|
-
node.type === 'paragraph') {
|
|
21
|
-
const children = node.children;
|
|
22
|
-
while (++offset < children.length) {
|
|
23
|
-
const child = children[offset];
|
|
24
|
-
if (child.type === 'mdxJsxTextElement' ||
|
|
25
|
-
child.type === 'mdxTextExpression') {
|
|
26
|
-
oneOrMore = true;
|
|
27
|
-
}
|
|
28
|
-
else if (child.type === 'text' &&
|
|
29
|
-
collapseWhiteSpace(child.value, {
|
|
30
|
-
style: 'html',
|
|
31
|
-
trim: true,
|
|
32
|
-
}) === '') {
|
|
33
|
-
// Empty.
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
all = false;
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (all && oneOrMore) {
|
|
41
|
-
offset = -1;
|
|
42
|
-
const newChildren = [];
|
|
43
|
-
while (++offset < children.length) {
|
|
44
|
-
const child = children[offset];
|
|
45
|
-
if (child.type === 'mdxJsxTextElement') {
|
|
46
|
-
// @ts-expect-error: mutate because it is faster; content model is fine.
|
|
47
|
-
child.type = 'mdxJsxFlowElement';
|
|
48
|
-
}
|
|
49
|
-
if (child.type === 'mdxTextExpression') {
|
|
50
|
-
// @ts-expect-error: mutate because it is faster; content model is fine.
|
|
51
|
-
child.type = 'mdxFlowExpression';
|
|
52
|
-
}
|
|
53
|
-
if (child.type === 'text' &&
|
|
54
|
-
/^[\t\r\n ]+$/.test(String(child.value))) {
|
|
55
|
-
// Empty.
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
newChildren.push(child);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
parent.children.splice(index, 1, ...newChildren);
|
|
62
|
-
return index;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=plugins.js.map
|
package/dist/plugins.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAGxC;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAChC,OAAO,UAAU,IAAU;QAEvB,KAAK,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,KAAK,EAAE,MAAM;YACrC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAA;YACf,IAAI,GAAG,GAAG,IAAI,CAAA;YACd,IAAI,SAAS,GAAG,KAAK,CAAA;YAGrB,IACI,MAAM;gBACN,OAAO,KAAK,KAAK,QAAQ;gBACzB,IAAI,CAAC,IAAI,KAAK,WAAW,EAC3B;gBACE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;gBAE9B,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE;oBAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;oBAE9B,IACI,KAAK,CAAC,IAAI,KAAK,mBAAmB;wBAClC,KAAK,CAAC,IAAI,KAAK,mBAAmB,EACpC;wBACE,SAAS,GAAG,IAAI,CAAA;qBACnB;yBAAM,IACH,KAAK,CAAC,IAAI,KAAK,MAAM;wBACrB,kBAAkB,CAAC,KAAK,CAAC,KAAK,EAAE;4BAC5B,KAAK,EAAE,MAAM;4BACb,IAAI,EAAE,IAAI;yBACb,CAAC,KAAK,EAAE,EACX;wBACE,SAAS;qBACZ;yBAAM;wBACH,GAAG,GAAG,KAAK,CAAA;wBACX,MAAK;qBACR;iBACJ;gBAED,IAAI,GAAG,IAAI,SAAS,EAAE;oBAClB,MAAM,GAAG,CAAC,CAAC,CAAA;oBAEX,MAAM,WAAW,GAAkB,EAAE,CAAA;oBAErC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE;wBAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;wBAE9B,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE;4BACpC,wEAAwE;4BACxE,KAAK,CAAC,IAAI,GAAG,mBAAmB,CAAA;yBACnC;wBAED,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE;4BACpC,wEAAwE;4BACxE,KAAK,CAAC,IAAI,GAAG,mBAAmB,CAAA;yBACnC;wBAED,IACI,KAAK,CAAC,IAAI,KAAK,MAAM;4BACrB,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAC1C;4BACE,SAAS;yBACZ;6BAAM;4BACH,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;yBAC1B;qBACJ;oBAED,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,CAAA;oBAChD,OAAO,KAAK,CAAA;iBACf;aACJ;QACL,CAAC,CAAC,CAAA;IACN,CAAC,CAAA;AACL,CAAC"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { htmlToJsx } from 'html-to-jsx-transform'
|
|
3
|
-
import type { MdastToJsx, MyRootContent } from './safe-mdx.js'
|
|
4
|
-
|
|
5
|
-
React
|
|
6
|
-
|
|
7
|
-
interface HtmlToJsxConverterProps {
|
|
8
|
-
htmlText: string
|
|
9
|
-
instance: MdastToJsx
|
|
10
|
-
node: MyRootContent
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function HtmlToJsxConverter({
|
|
14
|
-
htmlText,
|
|
15
|
-
instance,
|
|
16
|
-
node,
|
|
17
|
-
}: HtmlToJsxConverterProps) {
|
|
18
|
-
try {
|
|
19
|
-
const jsx = htmlToJsx(htmlText)
|
|
20
|
-
const originalJsxStr = instance.jsxStr
|
|
21
|
-
instance.jsxStr = jsx
|
|
22
|
-
|
|
23
|
-
const result = instance.jsxTransformer(node)
|
|
24
|
-
|
|
25
|
-
instance.jsxStr = originalJsxStr
|
|
26
|
-
|
|
27
|
-
if (Array.isArray(result)) {
|
|
28
|
-
console.log(`Unexpected array result`)
|
|
29
|
-
return null
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return result || null
|
|
33
|
-
} catch (error) {
|
|
34
|
-
console.error('Error converting HTML to JSX:', error)
|
|
35
|
-
return null
|
|
36
|
-
}
|
|
37
|
-
}
|