summaryrefslogtreecommitdiff
path: root/packages/markdown
diff options
context:
space:
mode:
authorGravatar Juan Martín Seery <me@juanm04.com> 2022-04-11 20:01:12 -0300
committerGravatar GitHub <noreply@github.com> 2022-04-11 16:01:12 -0700
commitb835e285defb4f31fc5ac1039c7f607c07f3c00b (patch)
tree71e4ba696d06e25fd6e42b556a384adf7e2d1a53 /packages/markdown
parent11766acec914ffc2639dfb228468ebab37de746d (diff)
downloadastro-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.json4
-rw-r--r--packages/markdown/remark/src/index.ts28
-rw-r--r--packages/markdown/remark/src/load-plugins.ts5
-rw-r--r--packages/markdown/remark/src/remark-shiki.ts31
-rw-r--r--packages/markdown/remark/src/types.ts40
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;