diff options
author | 2022-04-11 20:01:12 -0300 | |
---|---|---|
committer | 2022-04-11 16:01:12 -0700 | |
commit | b835e285defb4f31fc5ac1039c7f607c07f3c00b (patch) | |
tree | 71e4ba696d06e25fd6e42b556a384adf7e2d1a53 /packages/markdown | |
parent | 11766acec914ffc2639dfb228468ebab37de746d (diff) | |
download | astro-b835e285defb4f31fc5ac1039c7f607c07f3c00b.tar.gz astro-b835e285defb4f31fc5ac1039c7f607c07f3c00b.tar.zst astro-b835e285defb4f31fc5ac1039c7f607c07f3c00b.zip |
feat: markdown config typechecking (#2970)
* Added schemas to markdown plugin
* Added new schemas to main package
* Changesets
* typeraw
* Explaination about the weird type hack
* Added markdown.mode to config
* Added comment
* Formatted
* Moved validation to `astro` and added RemarkPlugin ad RehypePlugin
* Removed the ability to have a custom markdown renderer internally
* Fixed plugin type
* Removed unused renderMarkdownWithFrontmatter
* Added missing dependency
* Dynamically import astro markdown
* Cache import
Diffstat (limited to 'packages/markdown')
-rw-r--r-- | packages/markdown/remark/package.json | 4 | ||||
-rw-r--r-- | packages/markdown/remark/src/index.ts | 28 | ||||
-rw-r--r-- | packages/markdown/remark/src/load-plugins.ts | 5 | ||||
-rw-r--r-- | packages/markdown/remark/src/remark-shiki.ts | 31 | ||||
-rw-r--r-- | packages/markdown/remark/src/types.ts | 40 |
5 files changed, 45 insertions, 63 deletions
diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json index 764f6ffb9..8a6f88c15 100644 --- a/packages/markdown/remark/package.json +++ b/packages/markdown/remark/package.json @@ -26,7 +26,6 @@ "@astrojs/prism": "^0.4.1", "assert": "^2.0.0", "github-slugger": "^1.4.0", - "gray-matter": "^4.0.3", "mdast-util-mdx-expression": "^1.2.0", "mdast-util-mdx-jsx": "^1.2.0", "mdast-util-to-string": "^3.1.0", @@ -47,7 +46,10 @@ }, "devDependencies": { "@types/github-slugger": "^1.3.0", + "@types/hast": "^2.3.4", + "@types/mdast": "^3.0.10", "@types/prismjs": "^1.26.0", + "@types/unist": "^2.0.6", "astro-scripts": "workspace:*" } } diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts index dd9f95d58..2dfb81d23 100644 --- a/packages/markdown/remark/src/index.ts +++ b/packages/markdown/remark/src/index.ts @@ -1,4 +1,4 @@ -import type { AstroMarkdownOptions, MarkdownRenderingOptions, ShikiConfig, Plugin } from './types'; +import type { MarkdownRenderingOptions } from './types'; import createCollectHeaders from './rehype-collect-headers.js'; import scopedStyles from './remark-scoped-styles.js'; @@ -18,31 +18,17 @@ import markdown from 'remark-parse'; import markdownToHtml from 'remark-rehype'; import rehypeStringify from 'rehype-stringify'; import rehypeRaw from 'rehype-raw'; -import matter from 'gray-matter'; - -export { AstroMarkdownOptions, MarkdownRenderingOptions, ShikiConfig, Plugin }; - -/** Internal utility for rendering a full markdown file and extracting Frontmatter data */ -export async function renderMarkdownWithFrontmatter( - contents: string, - opts?: MarkdownRenderingOptions | null -) { - const { data: frontmatter, content } = matter(contents); - const value = await renderMarkdown(content, opts); - return { ...value, frontmatter }; -} + +export * from './types.js'; export const DEFAULT_REMARK_PLUGINS = ['remark-gfm', 'remark-smartypants']; export const DEFAULT_REHYPE_PLUGINS = ['rehype-slug']; /** Shared utility for rendering markdown */ -export async function renderMarkdown(content: string, opts?: MarkdownRenderingOptions | null) { - let { remarkPlugins = [], rehypePlugins = [] } = opts ?? {}; - const scopedClassName = opts?.$?.scopedClassName; - const mode = opts?.mode ?? 'mdx'; - const syntaxHighlight = opts?.syntaxHighlight ?? 'shiki'; - const shikiConfig = opts?.shikiConfig ?? {}; +export async function renderMarkdown(content: string, opts: MarkdownRenderingOptions) { + let { mode, syntaxHighlight, shikiConfig, remarkPlugins, rehypePlugins } = opts; + const scopedClassName = opts.$?.scopedClassName; const isMDX = mode === 'mdx'; const { headers, rehypeCollectHeaders } = createCollectHeaders(); @@ -111,5 +97,3 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp code: result.toString(), }; } - -export default renderMarkdownWithFrontmatter; diff --git a/packages/markdown/remark/src/load-plugins.ts b/packages/markdown/remark/src/load-plugins.ts index 139eeaf19..c64d13543 100644 --- a/packages/markdown/remark/src/load-plugins.ts +++ b/packages/markdown/remark/src/load-plugins.ts @@ -1,5 +1,4 @@ import * as unified from 'unified'; -import type { Plugin } from './types'; async function importPlugin(p: string | unified.Plugin): Promise<unified.Plugin> { if (typeof p === 'string') { @@ -10,7 +9,9 @@ async function importPlugin(p: string | unified.Plugin): Promise<unified.Plugin> return p; } -export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin, any?]>[] { +export function loadPlugins( + items: (string | [string, any] | unified.Plugin<any[], any> | [unified.Plugin<any[], any>, any])[] +): Promise<[unified.Plugin, any?]>[] { return items.map((p) => { return new Promise((resolve, reject) => { if (Array.isArray(p)) { diff --git a/packages/markdown/remark/src/remark-shiki.ts b/packages/markdown/remark/src/remark-shiki.ts index 314a0e38e..6f70bdf19 100644 --- a/packages/markdown/remark/src/remark-shiki.ts +++ b/packages/markdown/remark/src/remark-shiki.ts @@ -1,34 +1,7 @@ import type * as shiki from 'shiki'; import { getHighlighter } from 'shiki'; import { visit } from 'unist-util-visit'; - -export interface ShikiConfig { - /** - * The languages loaded to Shiki. - * Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages - * Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki - * - * @default [] - */ - langs?: shiki.ILanguageRegistration[]; - /** - * The styling theme. - * Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes - * Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme - * - * @default "github-dark" - */ - theme?: shiki.IThemeRegistration; - /** - * Enable word wrapping. - * - true: enabled. - * - false: enabled. - * - null: All overflow styling removed. Code will overflow the element by default. - * - * @default false - */ - wrap?: boolean | null; -} +import type { ShikiConfig } from './types.js'; /** * getHighlighter() is the most expensive step of Shiki. Instead of calling it on every page, @@ -38,7 +11,7 @@ export interface ShikiConfig { const highlighterCacheAsync = new Map<string, Promise<shiki.Highlighter>>(); const remarkShiki = async ( - { langs = [], theme = 'github-dark', wrap = false }: ShikiConfig, + { langs, theme, wrap }: ShikiConfig, scopedClassName?: string | null ) => { const cacheID: string = typeof theme === 'string' ? theme : theme.name; diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts index 43e8331b4..bba486921 100644 --- a/packages/markdown/remark/src/types.ts +++ b/packages/markdown/remark/src/types.ts @@ -1,18 +1,40 @@ import type * as unified from 'unified'; -import type { ShikiConfig } from './remark-shiki'; -export { ShikiConfig }; +import type * as mdast from 'mdast'; +import type * as hast from 'hast'; +import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki'; -export type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any]; +export type { Node } from 'unist'; + +export type RemarkPlugin<PluginParameters extends any[] = any[]> = unified.Plugin< + PluginParameters, + mdast.Root +>; + +export type RemarkPlugins = (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[]; + +export type RehypePlugin<PluginParameters extends any[] = any[]> = unified.Plugin< + PluginParameters, + hast.Root +>; + +export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[]; + +export interface ShikiConfig { + langs: ILanguageRegistration[]; + theme: Theme | IThemeRegistration; + wrap: boolean | null; +} export interface AstroMarkdownOptions { - mode?: 'md' | 'mdx'; - syntaxHighlight?: 'shiki' | 'prism' | false; - shikiConfig?: ShikiConfig; - remarkPlugins?: Plugin[]; - rehypePlugins?: Plugin[]; + mode: 'md' | 'mdx'; + drafts: boolean; + syntaxHighlight: 'shiki' | 'prism' | false; + shikiConfig: ShikiConfig; + remarkPlugins: RemarkPlugins; + rehypePlugins: RehypePlugins; } -export interface MarkdownRenderingOptions extends Partial<AstroMarkdownOptions> { +export interface MarkdownRenderingOptions extends AstroMarkdownOptions { /** @internal */ $?: { scopedClassName: string | null; |