diff options
author | 2021-04-01 16:34:11 -0400 | |
---|---|---|
committer | 2021-04-01 16:34:11 -0400 | |
commit | 54ba9f5ee17a68f0e5a917011ce696de397220dc (patch) | |
tree | 84f71153562f42c42870058b3d717f52cd338fa3 /src | |
parent | 397b7145cc5d6008165af74a020ff7af3a8cace7 (diff) | |
download | astro-54ba9f5ee17a68f0e5a917011ce696de397220dc.tar.gz astro-54ba9f5ee17a68f0e5a917011ce696de397220dc.tar.zst astro-54ba9f5ee17a68f0e5a917011ce696de397220dc.zip |
Fix complex MDX parsing (#50)
* Fix complex MDX parsing
This allows fully MDX support using the micromark MDX extension. One caveat is that if you do something like use the less than sign, you need to escape it because the parser expects these to be tags otherwise.
* Move micromark definition
Diffstat (limited to 'src')
-rw-r--r-- | src/@types/micromark.ts | 12 | ||||
-rw-r--r-- | src/compiler/index.ts | 10 | ||||
-rw-r--r-- | src/compiler/markdown/micromark-collect-headers.ts (renamed from src/micromark-collect-headers.ts) | 0 | ||||
-rw-r--r-- | src/compiler/markdown/micromark-encode.ts (renamed from src/micromark-encode.ts) | 13 | ||||
-rw-r--r-- | src/compiler/markdown/micromark-mdx-astro.ts | 23 | ||||
-rw-r--r-- | src/compiler/markdown/micromark.d.ts | 11 |
6 files changed, 58 insertions, 11 deletions
diff --git a/src/@types/micromark.ts b/src/@types/micromark.ts new file mode 100644 index 000000000..0e0dc2465 --- /dev/null +++ b/src/@types/micromark.ts @@ -0,0 +1,12 @@ + +export interface MicromarkExtensionContext { + sliceSerialize(node: any): string; + raw(value: string): void; +} + +export type MicromarkExtensionCallback = (this: MicromarkExtensionContext, node: any) => void; + +export interface MicromarkExtension { + enter?: Record<string, MicromarkExtensionCallback>; + exit?: Record<string, MicromarkExtensionCallback>; +}
\ No newline at end of file diff --git a/src/compiler/index.ts b/src/compiler/index.ts index 541bae21e..112b7881e 100644 --- a/src/compiler/index.ts +++ b/src/compiler/index.ts @@ -8,8 +8,9 @@ import matter from 'gray-matter'; import gfmHtml from 'micromark-extension-gfm/html.js'; import { parse } from '../parser/index.js'; -import { createMarkdownHeadersCollector } from '../micromark-collect-headers.js'; -import { encodeMarkdown } from '../micromark-encode.js'; +import { createMarkdownHeadersCollector } from './markdown/micromark-collect-headers.js'; +import { encodeMarkdown } from './markdown/micromark-encode.js'; +import { encodeAstroMdx } from './markdown/micromark-mdx-astro.js'; import { optimize } from './optimize/index.js'; import { codegen } from './codegen.js'; @@ -56,10 +57,11 @@ async function convertMdToJsx( ): Promise<TransformResult> { const { data: frontmatterData, content } = matter(contents); const { headers, headersExtension } = createMarkdownHeadersCollector(); + const { htmlAstro, mdAstro } = encodeAstroMdx(); const mdHtml = micromark(content, { allowDangerousHtml: true, - extensions: [gfmSyntax()], - htmlExtensions: [gfmHtml, encodeMarkdown, headersExtension], + extensions: [gfmSyntax(), ...htmlAstro], + htmlExtensions: [gfmHtml, encodeMarkdown, headersExtension, mdAstro], }); // TODO: Warn if reserved word is used in "frontmatterData" diff --git a/src/micromark-collect-headers.ts b/src/compiler/markdown/micromark-collect-headers.ts index 69781231a..69781231a 100644 --- a/src/micromark-collect-headers.ts +++ b/src/compiler/markdown/micromark-collect-headers.ts diff --git a/src/micromark-encode.ts b/src/compiler/markdown/micromark-encode.ts index f9e863fdd..635ab3b54 100644 --- a/src/micromark-encode.ts +++ b/src/compiler/markdown/micromark-encode.ts @@ -1,4 +1,5 @@ -import type { HtmlExtension, Token, Tokenize } from 'micromark/dist/shared-types'; +import type { Token } from 'micromark/dist/shared-types'; +import type { MicromarkExtension, MicromarkExtensionContext } from '../../@types/micromark'; const characterReferences = { '"': 'quot', @@ -19,15 +20,13 @@ function encode(value: string): string { } /** Encode Markdown node */ -function encodeToken(this: Record<string, () => void>) { +function encodeToken(this: MicromarkExtensionContext) { const token: Token = arguments[0]; - const serialize = (this.sliceSerialize as unknown) as (t: Token) => string; - const raw = (this.raw as unknown) as (s: string) => void; - const value = serialize(token); - raw(encode(value)); + const value = this.sliceSerialize(token); + this.raw(encode(value)); } -const plugin: HtmlExtension = { +const plugin: MicromarkExtension = { exit: { codeTextData: encodeToken, codeFlowValue: encodeToken, diff --git a/src/compiler/markdown/micromark-mdx-astro.ts b/src/compiler/markdown/micromark-mdx-astro.ts new file mode 100644 index 000000000..0ffd69fb1 --- /dev/null +++ b/src/compiler/markdown/micromark-mdx-astro.ts @@ -0,0 +1,23 @@ +import type { MicromarkExtension } from '../../@types/micromark'; +import mdxExpression from 'micromark-extension-mdx-expression'; +import mdxJsx from 'micromark-extension-mdx-jsx'; + + +/** + * Keep MDX. + */ +export function encodeAstroMdx() { + const extension: MicromarkExtension = { + enter: { + mdxJsxFlowTag(node: any) { + const mdx = this.sliceSerialize(node); + this.raw(mdx); + } + } + }; + + return { + htmlAstro: [mdxExpression(), mdxJsx()], + mdAstro: extension + }; +}
\ No newline at end of file diff --git a/src/compiler/markdown/micromark.d.ts b/src/compiler/markdown/micromark.d.ts new file mode 100644 index 000000000..1f389e473 --- /dev/null +++ b/src/compiler/markdown/micromark.d.ts @@ -0,0 +1,11 @@ +declare module 'micromark-extension-mdx-expression' { + import type { HtmlExtension } from 'micromark/dist/shared-types'; + + export default function(): HtmlExtension; +} + +declare module 'micromark-extension-mdx-jsx' { + import type { HtmlExtension } from 'micromark/dist/shared-types'; + + export default function(): HtmlExtension; +}
\ No newline at end of file |