diff options
author | 2023-05-17 09:13:10 -0400 | |
---|---|---|
committer | 2023-05-17 09:13:10 -0400 | |
commit | fb84622af04f795de8d17f24192de105f70fe910 (patch) | |
tree | 11a99efdb90c17207d3adc1095e88fa8daddd7e4 /packages/integrations/markdoc/src/index.ts | |
parent | c91e837e961043e92253148f0f4291856653b993 (diff) | |
download | astro-fb84622af04f795de8d17f24192de105f70fe910.tar.gz astro-fb84622af04f795de8d17f24192de105f70fe910.tar.zst astro-fb84622af04f795de8d17f24192de105f70fe910.zip |
[Markdoc] `headings` and heading IDs (#7095)
* deps: markdown-remark
* wip: heading-ids function
* chore: add `@astrojs/markdoc` to external
* feat: `headings` support
* fix: allow `render` config on headings
* fix: nonexistent `userConfig`
* test: headings, toc, astro component render
* docs: README
* chore: changeset
* refactor: expose Markdoc helpers from runtime
* fix: bad named exports (commonjsssss)
* refactor: defaultNodes -> nodes
* deps: github-slugger
* fix: reset slugger cache on each render
* fix: bad astroNodes import
* docs: explain headingSlugger export
* docs: add back double stringify comment
* chore: bump to minor for internal exports change
Diffstat (limited to 'packages/integrations/markdoc/src/index.ts')
-rw-r--r-- | packages/integrations/markdoc/src/index.ts | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/packages/integrations/markdoc/src/index.ts b/packages/integrations/markdoc/src/index.ts index 5b3568992..65f81644a 100644 --- a/packages/integrations/markdoc/src/index.ts +++ b/packages/integrations/markdoc/src/index.ts @@ -9,7 +9,7 @@ import { isValidUrl, MarkdocError, parseFrontmatter, prependForwardSlash } from import { emitESMImage } from 'astro/assets'; import { bold, red, yellow } from 'kleur/colors'; import type * as rollup from 'rollup'; -import { applyDefaultConfig } from './default-config.js'; +import { applyDefaultConfig } from './runtime.js'; import { loadMarkdocConfig, type MarkdocConfigResult } from './load-config.js'; type SetupHookParams = HookParameters<'astro:config:setup'> & { @@ -52,7 +52,7 @@ export default function markdocIntegration(legacyConfig?: any): AstroIntegration async getRenderModule({ entry, viteId }) { const ast = Markdoc.parse(entry.body); const pluginContext = this; - const markdocConfig = applyDefaultConfig(userMarkdocConfig, { entry }); + const markdocConfig = applyDefaultConfig(userMarkdocConfig, entry); const validationErrors = Markdoc.validate(ast, markdocConfig).filter((e) => { return ( @@ -88,36 +88,46 @@ export default function markdocIntegration(legacyConfig?: any): AstroIntegration }); } - return { - code: `import { jsx as h } from 'astro/jsx-runtime'; -import { applyDefaultConfig } from '@astrojs/markdoc/default-config'; -import { Renderer } from '@astrojs/markdoc/components'; -import * as entry from ${JSON.stringify(viteId + '?astroContent')};${ - markdocConfigResult - ? `\nimport userConfig from ${JSON.stringify( - markdocConfigResult.fileUrl.pathname - )};` - : '' - }${ - astroConfig.experimental.assets - ? `\nimport { experimentalAssetsConfig } from '@astrojs/markdoc/experimental-assets-config';` - : '' - } -const stringifiedAst = ${JSON.stringify( - /* Double stringify to encode *as* stringified JSON */ JSON.stringify(ast) - )}; + const res = `import { jsx as h } from 'astro/jsx-runtime'; + import { Renderer } from '@astrojs/markdoc/components'; + import { collectHeadings, applyDefaultConfig, Markdoc, headingSlugger } from '@astrojs/markdoc/runtime'; +import * as entry from ${JSON.stringify(viteId + '?astroContent')}; +${ + markdocConfigResult + ? `import _userConfig from ${JSON.stringify( + markdocConfigResult.fileUrl.pathname + )};\nconst userConfig = _userConfig ?? {};` + : 'const userConfig = {};' +}${ + astroConfig.experimental.assets + ? `\nimport { experimentalAssetsConfig } from '@astrojs/markdoc/experimental-assets-config';\nuserConfig.nodes = { ...experimentalAssetsConfig.nodes, ...userConfig.nodes };` + : '' + } +const stringifiedAst = ${JSON.stringify(/* Double stringify to encode *as* stringified JSON */ JSON.stringify(ast))}; +export function getHeadings() { + ${ + /* Yes, we are transforming twice (once from `getHeadings()` and again from <Content /> in case of variables). + TODO: propose new `render()` API to allow Markdoc variable passing to `render()` itself, + instead of the Content component. Would remove double-transform and unlock variable resolution in heading slugs. */ + '' + } + headingSlugger.reset(); + const headingConfig = userConfig.nodes?.heading; + const config = applyDefaultConfig(headingConfig ? { nodes: { heading: headingConfig } } : {}, entry); + const ast = Markdoc.Ast.fromJSON(stringifiedAst); + const content = Markdoc.transform(ast, config); + return collectHeadings(Array.isArray(content) ? content : content.children); +} export async function Content (props) { - const config = applyDefaultConfig(${ - markdocConfigResult - ? '{ ...userConfig, variables: { ...userConfig.variables, ...props } }' - : '{ variables: props }' - }, { entry });${ - astroConfig.experimental.assets - ? `\nconfig.nodes = { ...experimentalAssetsConfig.nodes, ...config.nodes };` - : '' - } - return h(Renderer, { stringifiedAst, config }); };`, - }; + headingSlugger.reset(); + const config = applyDefaultConfig({ + ...userConfig, + variables: { ...userConfig.variables, ...props }, + }, entry); + + return h(Renderer, { config, stringifiedAst }); +}`; + return { code: res }; }, contentModuleTypes: await fs.promises.readFile( new URL('../template/content-module-types.d.ts', import.meta.url), |