@astrojs/markdown-remark 6.2.1 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@ import type { Root } from 'hast';
2
2
  type Highlighter = (code: string, language: string, options?: {
3
3
  meta?: string;
4
4
  }) => Promise<Root | string>;
5
+ export declare const defaultExcludeLanguages: string[];
5
6
  /**
6
7
  * A hast utility to syntax highlight code blocks with a given syntax highlighter.
7
8
  *
@@ -11,5 +12,5 @@ type Highlighter = (code: string, language: string, options?: {
11
12
  * A function which receives the code and language, and returns the HTML of a syntax
12
13
  * highlighted `<pre>` element.
13
14
  */
14
- export declare function highlightCodeBlocks(tree: Root, highlighter: Highlighter): Promise<void>;
15
+ export declare function highlightCodeBlocks(tree: Root, highlighter: Highlighter, excludeLanguages?: string[]): Promise<void>;
15
16
  export {};
package/dist/highlight.js CHANGED
@@ -3,7 +3,8 @@ import { toText } from "hast-util-to-text";
3
3
  import { removePosition } from "unist-util-remove-position";
4
4
  import { visitParents } from "unist-util-visit-parents";
5
5
  const languagePattern = /\blanguage-(\S+)\b/;
6
- async function highlightCodeBlocks(tree, highlighter) {
6
+ const defaultExcludeLanguages = ["math"];
7
+ async function highlightCodeBlocks(tree, highlighter, excludeLanguages = []) {
7
8
  const nodes = [];
8
9
  visitParents(tree, { type: "element", tagName: "code" }, (node, ancestors) => {
9
10
  const parent = ancestors.at(-1);
@@ -28,12 +29,13 @@ async function highlightCodeBlocks(tree, highlighter) {
28
29
  }
29
30
  }
30
31
  }
31
- if (languageMatch?.[1] === "math") {
32
+ const language = languageMatch?.[1] || "plaintext";
33
+ if (excludeLanguages.includes(language) || defaultExcludeLanguages.includes(language)) {
32
34
  return;
33
35
  }
34
36
  nodes.push({
35
37
  node,
36
- language: languageMatch?.[1] || "plaintext",
38
+ language,
37
39
  parent,
38
40
  grandParent: ancestors.at(-2)
39
41
  });
@@ -54,5 +56,6 @@ async function highlightCodeBlocks(tree, highlighter) {
54
56
  }
55
57
  }
56
58
  export {
59
+ defaultExcludeLanguages,
57
60
  highlightCodeBlocks
58
61
  };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AstroMarkdownOptions, AstroMarkdownProcessorOptions, MarkdownProcessor } from './types.js';
1
+ import type { AstroMarkdownOptions, AstroMarkdownProcessorOptions, MarkdownProcessor, SyntaxHighlightConfig } from './types.js';
2
2
  export { rehypeHeadingIds } from './rehype-collect-headings.js';
3
3
  export { remarkCollectImages } from './remark-collect-images.js';
4
4
  export { rehypePrism } from './rehype-prism.js';
@@ -6,6 +6,7 @@ export { rehypeShiki } from './rehype-shiki.js';
6
6
  export { isFrontmatterValid, extractFrontmatter, parseFrontmatter, type ParseFrontmatterOptions, type ParseFrontmatterResult, } from './frontmatter.js';
7
7
  export { createShikiHighlighter, type ShikiHighlighter, type CreateShikiHighlighterOptions, type ShikiHighlighterHighlightOptions, } from './shiki.js';
8
8
  export * from './types.js';
9
+ export declare const syntaxHighlightDefaults: Required<SyntaxHighlightConfig>;
9
10
  export declare const markdownConfigDefaults: Required<AstroMarkdownOptions>;
10
11
  /**
11
12
  * Create a markdown preprocessor to render multiple markdown files
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import remarkRehype from "remark-rehype";
11
11
  import remarkSmartypants from "remark-smartypants";
12
12
  import { unified } from "unified";
13
13
  import { VFile } from "vfile";
14
+ import { defaultExcludeLanguages } from "./highlight.js";
14
15
  import { rehypeImages } from "./rehype-images.js";
15
16
  import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings.js";
16
17
  import { remarkCollectImages as remarkCollectImages2 } from "./remark-collect-images.js";
@@ -25,8 +26,12 @@ import {
25
26
  createShikiHighlighter
26
27
  } from "./shiki.js";
27
28
  export * from "./types.js";
29
+ const syntaxHighlightDefaults = {
30
+ type: "shiki",
31
+ excludeLangs: defaultExcludeLanguages
32
+ };
28
33
  const markdownConfigDefaults = {
29
- syntaxHighlight: "shiki",
34
+ syntaxHighlight: syntaxHighlightDefaults,
30
35
  shikiConfig: {
31
36
  langs: [],
32
37
  theme: "github-dark",
@@ -50,7 +55,8 @@ async function createMarkdownProcessor(opts) {
50
55
  rehypePlugins = markdownConfigDefaults.rehypePlugins,
51
56
  remarkRehype: remarkRehypeOptions = markdownConfigDefaults.remarkRehype,
52
57
  gfm = markdownConfigDefaults.gfm,
53
- smartypants = markdownConfigDefaults.smartypants
58
+ smartypants = markdownConfigDefaults.smartypants,
59
+ experimentalHeadingIdCompat = false
54
60
  } = opts ?? {};
55
61
  const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
56
62
  const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
@@ -74,11 +80,13 @@ async function createMarkdownProcessor(opts) {
74
80
  passThrough: [],
75
81
  ...remarkRehypeOptions
76
82
  });
77
- if (!isPerformanceBenchmark) {
78
- if (syntaxHighlight === "shiki") {
79
- parser.use(rehypeShiki, shikiConfig);
80
- } else if (syntaxHighlight === "prism") {
81
- parser.use(rehypePrism);
83
+ if (syntaxHighlight && !isPerformanceBenchmark) {
84
+ const syntaxHighlightType = typeof syntaxHighlight === "string" ? syntaxHighlight : syntaxHighlight?.type;
85
+ const excludeLangs = typeof syntaxHighlight === "object" ? syntaxHighlight?.excludeLangs : void 0;
86
+ if (syntaxHighlightType === "shiki") {
87
+ parser.use(rehypeShiki, shikiConfig, excludeLangs);
88
+ } else if (syntaxHighlightType === "prism") {
89
+ parser.use(rehypePrism, excludeLangs);
82
90
  }
83
91
  }
84
92
  for (const [plugin, pluginOpts] of loadedRehypePlugins) {
@@ -86,7 +94,7 @@ async function createMarkdownProcessor(opts) {
86
94
  }
87
95
  parser.use(rehypeImages);
88
96
  if (!isPerformanceBenchmark) {
89
- parser.use(rehypeHeadingIds);
97
+ parser.use(rehypeHeadingIds, { experimentalHeadingIdCompat });
90
98
  }
91
99
  parser.use(rehypeRaw).use(rehypeStringify, { allowDangerousHtml: true });
92
100
  return {
@@ -144,5 +152,6 @@ export {
144
152
  rehypeHeadingIds2 as rehypeHeadingIds,
145
153
  rehypePrism2 as rehypePrism,
146
154
  rehypeShiki2 as rehypeShiki,
147
- remarkCollectImages2 as remarkCollectImages
155
+ remarkCollectImages2 as remarkCollectImages,
156
+ syntaxHighlightDefaults
148
157
  };
@@ -1,2 +1,11 @@
1
1
  import type { RehypePlugin } from './types.js';
2
- export declare function rehypeHeadingIds(): ReturnType<RehypePlugin>;
2
+ /**
3
+ * Rehype plugin that adds `id` attributes to headings based on their text content.
4
+ *
5
+ * @param options Optional configuration object for the plugin.
6
+ *
7
+ * @see https://docs.astro.build/en/guides/markdown-content/#heading-ids-and-plugins
8
+ */
9
+ export declare function rehypeHeadingIds({ experimentalHeadingIdCompat, }?: {
10
+ experimentalHeadingIdCompat?: boolean;
11
+ }): ReturnType<RehypePlugin>;
@@ -2,7 +2,9 @@ import Slugger from "github-slugger";
2
2
  import { visit } from "unist-util-visit";
3
3
  const rawNodeTypes = /* @__PURE__ */ new Set(["text", "raw", "mdxTextExpression"]);
4
4
  const codeTagNames = /* @__PURE__ */ new Set(["code", "pre"]);
5
- function rehypeHeadingIds() {
5
+ function rehypeHeadingIds({
6
+ experimentalHeadingIdCompat
7
+ } = {}) {
6
8
  return function(tree, file) {
7
9
  const headings = [];
8
10
  const frontmatter = file.data.astro?.frontmatter;
@@ -49,7 +51,9 @@ function rehypeHeadingIds() {
49
51
  node.properties = node.properties || {};
50
52
  if (typeof node.properties.id !== "string") {
51
53
  let slug = slugger.slug(text);
52
- if (slug.endsWith("-")) slug = slug.slice(0, -1);
54
+ if (!experimentalHeadingIdCompat) {
55
+ if (slug.endsWith("-")) slug = slug.slice(0, -1);
56
+ }
53
57
  node.properties.id = slug;
54
58
  }
55
59
  headings.push({ depth, slug: node.properties.id, text });
@@ -1,3 +1,3 @@
1
1
  import type { Root } from 'hast';
2
2
  import type { Plugin } from 'unified';
3
- export declare const rehypePrism: Plugin<[], Root>;
3
+ export declare const rehypePrism: Plugin<[string[]?], Root>;
@@ -1,13 +1,17 @@
1
1
  import { runHighlighterWithAstro } from "@astrojs/prism/dist/highlighter";
2
2
  import { highlightCodeBlocks } from "./highlight.js";
3
- const rehypePrism = () => {
3
+ const rehypePrism = (excludeLangs) => {
4
4
  return async (tree) => {
5
- await highlightCodeBlocks(tree, (code, language) => {
6
- let { html, classLanguage } = runHighlighterWithAstro(language, code);
7
- return Promise.resolve(
8
- `<pre class="${classLanguage}" data-language="${language}"><code is:raw class="${classLanguage}">${html}</code></pre>`
9
- );
10
- });
5
+ await highlightCodeBlocks(
6
+ tree,
7
+ (code, language) => {
8
+ let { html, classLanguage } = runHighlighterWithAstro(language, code);
9
+ return Promise.resolve(
10
+ `<pre class="${classLanguage}" data-language="${language}"><code is:raw class="${classLanguage}">${html}</code></pre>`
11
+ );
12
+ },
13
+ excludeLangs
14
+ );
11
15
  };
12
16
  };
13
17
  export {
@@ -1,4 +1,4 @@
1
1
  import type { Root } from 'hast';
2
2
  import type { Plugin } from 'unified';
3
3
  import type { ShikiConfig } from './types.js';
4
- export declare const rehypeShiki: Plugin<[ShikiConfig?], Root>;
4
+ export declare const rehypeShiki: Plugin<[ShikiConfig, string[]?], Root>;
@@ -1,6 +1,6 @@
1
1
  import { highlightCodeBlocks } from "./highlight.js";
2
2
  import { createShikiHighlighter } from "./shiki.js";
3
- const rehypeShiki = (config) => {
3
+ const rehypeShiki = (config, excludeLangs) => {
4
4
  let highlighterAsync;
5
5
  return async (tree) => {
6
6
  highlighterAsync ??= createShikiHighlighter({
@@ -10,14 +10,18 @@ const rehypeShiki = (config) => {
10
10
  langAlias: config?.langAlias
11
11
  });
12
12
  const highlighter = await highlighterAsync;
13
- await highlightCodeBlocks(tree, (code, language, options) => {
14
- return highlighter.codeToHast(code, language, {
15
- meta: options?.meta,
16
- wrap: config?.wrap,
17
- defaultColor: config?.defaultColor,
18
- transformers: config?.transformers
19
- });
20
- });
13
+ await highlightCodeBlocks(
14
+ tree,
15
+ (code, language, options) => {
16
+ return highlighter.codeToHast(code, language, {
17
+ meta: options?.meta,
18
+ wrap: config?.wrap,
19
+ defaultColor: config?.defaultColor,
20
+ transformers: config?.transformers
21
+ });
22
+ },
23
+ excludeLangs
24
+ );
21
25
  };
22
26
  };
23
27
  export {
package/dist/types.d.ts CHANGED
@@ -22,13 +22,18 @@ export type RehypePlugin<PluginParameters extends any[] = any[]> = unified.Plugi
22
22
  export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
23
23
  export type RemarkRehype = RemarkRehypeOptions;
24
24
  export type ThemePresets = BuiltinTheme | 'css-variables';
25
+ export type SyntaxHighlightConfigType = 'shiki' | 'prism';
26
+ export interface SyntaxHighlightConfig {
27
+ type: SyntaxHighlightConfigType;
28
+ excludeLangs?: string[];
29
+ }
25
30
  export interface ShikiConfig extends Pick<CreateShikiHighlighterOptions, 'langs' | 'theme' | 'themes' | 'langAlias'>, Pick<ShikiHighlighterHighlightOptions, 'defaultColor' | 'wrap' | 'transformers'> {
26
31
  }
27
32
  /**
28
33
  * Configuration options that end up in the markdown section of AstroConfig
29
34
  */
30
35
  export interface AstroMarkdownOptions {
31
- syntaxHighlight?: 'shiki' | 'prism' | false;
36
+ syntaxHighlight?: SyntaxHighlightConfig | SyntaxHighlightConfigType | false;
32
37
  shikiConfig?: ShikiConfig;
33
38
  remarkPlugins?: RemarkPlugins;
34
39
  rehypePlugins?: RehypePlugins;
@@ -44,6 +49,7 @@ export interface AstroMarkdownProcessorOptions extends AstroMarkdownOptions {
44
49
  domains?: string[];
45
50
  remotePatterns?: RemotePattern[];
46
51
  };
52
+ experimentalHeadingIdCompat?: boolean;
47
53
  }
48
54
  export interface MarkdownProcessor {
49
55
  render: (content: string, opts?: MarkdownProcessorRenderOptions) => Promise<MarkdownProcessorRenderResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "6.2.1",
3
+ "version": "6.3.0",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",