safe-mdx 1.3.2 → 1.3.3
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 +23 -0
- package/dist/html/html-to-mdx-ast.d.ts.map +1 -0
- package/dist/html/html-to-mdx-ast.js +227 -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 +324 -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 +117 -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 +1 -1
- package/dist/safe-mdx.d.ts.map +1 -1
- package/dist/safe-mdx.js +23 -71
- 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 +27 -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 +365 -0
- package/src/html/html-to-mdx-ast.ts +304 -0
- package/src/html/remark-mdx-jsx-normalize.ts +128 -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 +23 -79
- 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
|
|
|
@@ -932,15 +928,26 @@ 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
|
|
932
|
+
const mdxAst = htmlToMdxAst({
|
|
933
|
+
html: text,
|
|
934
|
+
convertTagName: ({ tagName }) => {
|
|
935
|
+
const lowerTag = tagName.toLowerCase()
|
|
936
|
+
// Only keep valid HTML elements
|
|
937
|
+
if (validHtmlElements.has(lowerTag)) {
|
|
938
|
+
return lowerTag
|
|
939
|
+
}
|
|
940
|
+
// Return empty string for non-HTML elements
|
|
941
|
+
return ''
|
|
942
|
+
}
|
|
943
|
+
})
|
|
944
|
+
|
|
945
|
+
// Process the MDX AST nodes
|
|
946
|
+
if (Array.isArray(mdxAst)) {
|
|
947
|
+
return mdxAst.map(child => this.mdastTransformer(child))
|
|
948
|
+
} else {
|
|
949
|
+
return this.mdastTransformer(mdxAst)
|
|
950
|
+
}
|
|
944
951
|
}
|
|
945
952
|
case 'imageReference': {
|
|
946
953
|
return []
|
|
@@ -1002,69 +1009,6 @@ function safeJsonParse(str: string) {
|
|
|
1002
1009
|
}
|
|
1003
1010
|
}
|
|
1004
1011
|
|
|
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
1012
|
type ComponentsMap = { [k in (typeof nativeTags)[number]]?: any } & {
|
|
1069
1013
|
[key: string]: any
|
|
1070
1014
|
}
|
|
@@ -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
|
-
}
|