diff options
author | 2021-06-04 14:19:01 -0400 | |
---|---|---|
committer | 2021-06-04 14:19:01 -0400 | |
commit | 50e6f491ad2258689ba8735a3f98a0d99e4ba336 (patch) | |
tree | cc2c1284b3632d6447d3c9bab3b5c1aa461c35cf /packages/markdown-support/src/index.ts | |
parent | a2594ef572c41ce05dd01ef095e8595ffcd35842 (diff) | |
download | astro-50e6f491ad2258689ba8735a3f98a0d99e4ba336.tar.gz astro-50e6f491ad2258689ba8735a3f98a0d99e4ba336.tar.zst astro-50e6f491ad2258689ba8735a3f98a0d99e4ba336.zip |
Use npm package names to load internal deps (#294)
* Use npm package names to load internal deps
This is necessary so that published Astro components work. These components will be built by esinstall and therefore they cannot rely on `_astro_internal`. The fix is to use npm specifiers everywhere.
* Move most of frontend to internal
* Mark astro/internal/markdown.js as external
* Move markdown stuff to its own package
This moves the markdown stuff to its own package so that we can externalize it in the markdown component.
* Add the changeset
Diffstat (limited to 'packages/markdown-support/src/index.ts')
-rw-r--r-- | packages/markdown-support/src/index.ts | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/packages/markdown-support/src/index.ts b/packages/markdown-support/src/index.ts new file mode 100644 index 000000000..4db3089ba --- /dev/null +++ b/packages/markdown-support/src/index.ts @@ -0,0 +1,69 @@ +import type { AstroMarkdownOptions } from './types'; + +import createCollectHeaders from './rehype-collect-headers.js'; +import scopedStyles from './remark-scoped-styles.js'; +import { remarkCodeBlock, rehypeCodeBlock } from './codeblock.js'; +import raw from 'rehype-raw'; + +import unified from 'unified'; +import markdown from 'remark-parse'; +import markdownToHtml from 'remark-rehype'; +// import smartypants from '@silvenon/remark-smartypants'; +import rehypeStringify from 'rehype-stringify'; + +export interface MarkdownRenderingOptions extends Partial<AstroMarkdownOptions> { + $?: { + scopedClassName: string | null; + }; + mode: 'md' | 'astro-md'; +} + +/** Internal utility for rendering a full markdown file and extracting Frontmatter data */ +export async function renderMarkdownWithFrontmatter(contents: string, opts?: MarkdownRenderingOptions | null) { + // Dynamic import to ensure that "gray-matter" isn't built by Snowpack + const { default: matter } = await import('gray-matter'); + const { data: frontmatter, content } = matter(contents); + const value = await renderMarkdown(content, { ...opts, mode: 'md' }); + return { ...value, frontmatter }; +} + +/** Shared utility for rendering markdown */ +export async function renderMarkdown(content: string, opts?: MarkdownRenderingOptions | null) { + const { $: { scopedClassName = null } = {}, mode = 'astro-md', footnotes: useFootnotes = true, gfm: useGfm = true } = opts ?? {}; + const { headers, rehypeCollectHeaders } = createCollectHeaders(); + + let parser = unified().use(markdown).use(remarkCodeBlock()); + + if (scopedClassName) { + parser = parser.use(scopedStyles(scopedClassName)); + } + + if (useGfm) { + const { default: gfm } = await import('remark-gfm'); + parser = parser.use(gfm); + } + + if (useFootnotes) { + const { default: footnotes } = await import('remark-footnotes'); + parser = parser.use(footnotes); + } + + let result: string; + try { + const vfile = await parser + .use(markdownToHtml, { allowDangerousHtml: true, passThrough: ['raw'] }) + .use(raw) + .use(rehypeCollectHeaders) + .use(rehypeCodeBlock()) + .use(rehypeStringify) + .process(content); + result = vfile.contents.toString(); + } catch (err) { + throw err; + } + + return { + astro: { headers, source: content }, + content: result.toString(), + }; +}
\ No newline at end of file |