@astrojs/markdown-remark 0.6.0 → 0.6.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @astrojs/markdown-remark
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#2534](https://github.com/withastro/astro/pull/2534) [`cfeaa941`](https://github.com/withastro/astro/commit/cfeaa9414acdecec6f5d66ee0e33fe4fde574eee) Thanks [@JuanM04](https://github.com/JuanM04)! - Now you can use local plugins by passing a function instead of an `import`
8
+
9
+ * [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added the ability to use custom themes and langs with Shiki (`<Code />` and `@astrojs/markdown-remark`)
10
+
11
+ - [#2497](https://github.com/withastro/astro/pull/2497) [`6fe1b027`](https://github.com/withastro/astro/commit/6fe1b0279fce5a7a0e90ff79746ea0b641da3e21) Thanks [@JuanM04](https://github.com/JuanM04)! - Add Shiki as an alternative to Prism
12
+
13
+ * [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added `wrap` to Shiki config
14
+
15
+ - [#2564](https://github.com/withastro/astro/pull/2564) [`d71c4620`](https://github.com/withastro/astro/commit/d71c46207af40de6811596ca4f5e10aa9006377b) Thanks [@JuanM04](https://github.com/JuanM04)! - Fixed curly braces inside Shiki codeblocks
16
+
17
+ ## 0.6.1-next.2
18
+
19
+ ### Patch Changes
20
+
21
+ - [#2564](https://github.com/withastro/astro/pull/2564) [`d71c4620`](https://github.com/withastro/astro/commit/d71c46207af40de6811596ca4f5e10aa9006377b) Thanks [@JuanM04](https://github.com/JuanM04)! - Fixed curly braces inside Shiki codeblocks
22
+
23
+ ## 0.6.1-next.1
24
+
25
+ ### Patch Changes
26
+
27
+ - [#2534](https://github.com/withastro/astro/pull/2534) [`cfeaa941`](https://github.com/withastro/astro/commit/cfeaa9414acdecec6f5d66ee0e33fe4fde574eee) Thanks [@JuanM04](https://github.com/JuanM04)! - Now you can use local plugins by passing a function instead of an `import`
28
+
29
+ * [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added the ability to use custom themes and langs with Shiki (`<Code />` and `@astrojs/markdown-remark`)
30
+
31
+ - [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added `wrap` to Shiki config
32
+
33
+ ## 0.6.1-next.0
34
+
35
+ ### Patch Changes
36
+
37
+ - [#2497](https://github.com/withastro/astro/pull/2497) [`6fe1b027`](https://github.com/withastro/astro/commit/6fe1b0279fce5a7a0e90ff79746ea0b641da3e21) Thanks [@JuanM04](https://github.com/JuanM04)! - Add Shiki as an alternative to Prism
38
+
3
39
  ## 0.6.0
4
40
 
5
41
  ### Minor Changes
@@ -105,10 +141,10 @@
105
141
 
106
142
  ```js
107
143
  export default {
108
- markdownOptions: {
109
- remarkPlugins: ['remark-slug', ['remark-autolink-headings', { behavior: 'prepend' }]],
110
- rehypePlugins: ['rehype-slug', ['rehype-autolink-headings', { behavior: 'prepend' }]],
111
- },
144
+ markdownOptions: {
145
+ remarkPlugins: ['remark-slug', ['remark-autolink-headings', { behavior: 'prepend' }]],
146
+ rehypePlugins: ['rehype-slug', ['rehype-autolink-headings', { behavior: 'prepend' }]],
147
+ },
112
148
  };
113
149
  ```
114
150
 
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ import { remarkJsx, loadRemarkJsx } from "./remark-jsx.js";
26
26
  import rehypeJsx from "./rehype-jsx.js";
27
27
  import rehypeEscape from "./rehype-escape.js";
28
28
  import remarkPrism from "./remark-prism.js";
29
+ import remarkShiki from "./remark-shiki.js";
29
30
  import remarkUnwrap from "./remark-unwrap.js";
30
31
  import { loadPlugins } from "./load-plugins.js";
31
32
  import { unified } from "unified";
@@ -42,10 +43,12 @@ async function renderMarkdownWithFrontmatter(contents, opts) {
42
43
  const DEFAULT_REMARK_PLUGINS = ["remark-gfm", "remark-smartypants"];
43
44
  const DEFAULT_REHYPE_PLUGINS = ["rehype-slug"];
44
45
  async function renderMarkdown(content, opts) {
45
- var _a, _b;
46
+ var _a, _b, _c, _d;
46
47
  let { remarkPlugins = [], rehypePlugins = [] } = opts != null ? opts : {};
47
48
  const scopedClassName = (_a = opts == null ? void 0 : opts.$) == null ? void 0 : _a.scopedClassName;
48
49
  const mode = (_b = opts == null ? void 0 : opts.mode) != null ? _b : "mdx";
50
+ const syntaxHighlight = (_c = opts == null ? void 0 : opts.syntaxHighlight) != null ? _c : "prism";
51
+ const shikiConfig = (_d = opts == null ? void 0 : opts.shikiConfig) != null ? _d : {};
49
52
  const isMDX = mode === "mdx";
50
53
  const { headers, rehypeCollectHeaders } = createCollectHeaders();
51
54
  await Promise.all([loadRemarkExpressions(), loadRemarkJsx()]);
@@ -62,7 +65,11 @@ async function renderMarkdown(content, opts) {
62
65
  if (scopedClassName) {
63
66
  parser.use([scopedStyles(scopedClassName)]);
64
67
  }
65
- parser.use([remarkPrism(scopedClassName)]);
68
+ if (syntaxHighlight === "prism") {
69
+ parser.use([remarkPrism(scopedClassName)]);
70
+ } else if (syntaxHighlight === "shiki") {
71
+ parser.use([await remarkShiki(shikiConfig)]);
72
+ }
66
73
  parser.use([[markdownToHtml, { allowDangerousHtml: true, passThrough: ["raw", "mdxTextExpression", "mdxJsxTextElement", "mdxJsxFlowElement"] }]]);
67
74
  loadedRehypePlugins.forEach(([plugin, opts2]) => {
68
75
  parser.use([[plugin, opts2]]);
@@ -89,4 +96,4 @@ export {
89
96
  renderMarkdown,
90
97
  renderMarkdownWithFrontmatter
91
98
  };
92
- //# sourceMappingURL=data:application/json;base64,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
99
+ //# sourceMappingURL=data:application/json;base64,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
@@ -1,3 +1,3 @@
1
1
  import * as unified from 'unified';
2
2
  import type { Plugin } from './types';
3
- export declare function loadPlugins(items: Plugin[]): Promise<[unified.Plugin] | [unified.Plugin, any]>[];
3
+ export declare function loadPlugins(items: Plugin[]): Promise<[unified.Plugin, any?]>[];
@@ -1,21 +1,22 @@
1
1
  async function importPlugin(p) {
2
2
  if (typeof p === "string") {
3
- return await import(p);
3
+ const importResult = await import(p);
4
+ return importResult.default;
4
5
  }
5
- return await p;
6
+ return p;
6
7
  }
7
8
  function loadPlugins(items) {
8
9
  return items.map((p) => {
9
10
  return new Promise((resolve, reject) => {
10
11
  if (Array.isArray(p)) {
11
12
  const [plugin, opts] = p;
12
- return importPlugin(plugin).then((m) => resolve([m.default, opts])).catch((e) => reject(e));
13
+ return importPlugin(plugin).then((m) => resolve([m, opts])).catch((e) => reject(e));
13
14
  }
14
- return importPlugin(p).then((m) => resolve([m.default])).catch((e) => reject(e));
15
+ return importPlugin(p).then((m) => resolve([m])).catch((e) => reject(e));
15
16
  });
16
17
  });
17
18
  }
18
19
  export {
19
20
  loadPlugins
20
21
  };
21
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2xvYWQtcGx1Z2lucy50cyJdLAogICJtYXBwaW5ncyI6ICJBQUdBLDRCQUE0QixHQUFzRDtBQUNqRixNQUFJLE9BQU8sTUFBTSxVQUFVO0FBQzFCLFdBQU8sTUFBTSxPQUFPO0FBQUE7QUFHckIsU0FBTyxNQUFNO0FBQUE7QUFHUCxxQkFBcUIsT0FBc0U7QUFDakcsU0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNO0FBQ3ZCLFdBQU8sSUFBSSxRQUFRLENBQUMsU0FBUyxXQUFXO0FBQ3ZDLFVBQUksTUFBTSxRQUFRLElBQUk7QUFDckIsY0FBTSxDQUFDLFFBQVEsUUFBUTtBQUN2QixlQUFPLGFBQWEsUUFDbEIsS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDLEVBQUUsU0FBUyxRQUNoQyxNQUFNLENBQUMsTUFBTSxPQUFPO0FBQUE7QUFHdkIsYUFBTyxhQUFhLEdBQ2xCLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQyxFQUFFLFdBQ3ZCLE1BQU0sQ0FBQyxNQUFNLE9BQU87QUFBQTtBQUFBO0FBQUE7IiwKICAibmFtZXMiOiBbXQp9Cg==
22
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2xvYWQtcGx1Z2lucy50cyJdLAogICJtYXBwaW5ncyI6ICJBQUdBLDRCQUE0QixHQUFxRDtBQUNoRixNQUFJLE9BQU8sTUFBTSxVQUFVO0FBQzFCLFVBQU0sZUFBZSxNQUFNLE9BQU87QUFDbEMsV0FBTyxhQUFhO0FBQUE7QUFHckIsU0FBTztBQUFBO0FBR0QscUJBQXFCLE9BQW9EO0FBQy9FLFNBQU8sTUFBTSxJQUFJLENBQUMsTUFBTTtBQUN2QixXQUFPLElBQUksUUFBUSxDQUFDLFNBQVMsV0FBVztBQUN2QyxVQUFJLE1BQU0sUUFBUSxJQUFJO0FBQ3JCLGNBQU0sQ0FBQyxRQUFRLFFBQVE7QUFDdkIsZUFBTyxhQUFhLFFBQ2xCLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQyxHQUFHLFFBQ3hCLE1BQU0sQ0FBQyxNQUFNLE9BQU87QUFBQTtBQUd2QixhQUFPLGFBQWEsR0FDbEIsS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDLEtBQ3JCLE1BQU0sQ0FBQyxNQUFNLE9BQU87QUFBQTtBQUFBO0FBQUE7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,30 @@
1
+ import shiki from 'shiki';
2
+ export interface ShikiConfig {
3
+ /**
4
+ * The languages loaded to Shiki.
5
+ * Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
6
+ * Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
7
+ *
8
+ * @default []
9
+ */
10
+ langs?: shiki.ILanguageRegistration[];
11
+ /**
12
+ * The styling theme.
13
+ * Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
14
+ * Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
15
+ *
16
+ * @default "github-dark"
17
+ */
18
+ theme?: shiki.IThemeRegistration;
19
+ /**
20
+ * Enable word wrapping.
21
+ * - true: enabled.
22
+ * - false: enabled.
23
+ * - null: All overflow styling removed. Code will overflow the element by default.
24
+ *
25
+ * @default false
26
+ */
27
+ wrap?: boolean | null;
28
+ }
29
+ declare const remarkShiki: ({ langs, theme, wrap }: ShikiConfig) => Promise<() => (tree: any) => void>;
30
+ export default remarkShiki;
@@ -0,0 +1,29 @@
1
+ import shiki from "shiki";
2
+ import { visit } from "unist-util-visit";
3
+ const remarkShiki = async ({ langs = [], theme = "github-dark", wrap = false }) => {
4
+ const highlighter = await shiki.getHighlighter({ theme });
5
+ for (const lang of langs) {
6
+ await highlighter.loadLanguage(lang);
7
+ }
8
+ return () => (tree) => {
9
+ visit(tree, "code", (node) => {
10
+ var _a;
11
+ let html = highlighter.codeToHtml(node.value, { lang: (_a = node.lang) != null ? _a : "plaintext" });
12
+ html = html.replace('<pre class="shiki"', '<pre data-astro-raw class="astro-code"');
13
+ html = html.replace(/style="(background-)?color: var\(--shiki-/g, 'style="$1color: var(--astro-code-');
14
+ if (wrap === false) {
15
+ html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"');
16
+ } else if (wrap === true) {
17
+ html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"');
18
+ }
19
+ node.type = "html";
20
+ node.value = html;
21
+ node.children = [];
22
+ });
23
+ };
24
+ };
25
+ var remark_shiki_default = remarkShiki;
26
+ export {
27
+ remark_shiki_default as default
28
+ };
29
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JlbWFyay1zaGlraS50cyJdLAogICJtYXBwaW5ncyI6ICJBQUFBO0FBQ0E7QUE4QkEsTUFBTSxjQUFjLE9BQU8sRUFBRSxRQUFRLElBQUksUUFBUSxlQUFlLE9BQU8sWUFBeUI7QUFDL0YsUUFBTSxjQUFjLE1BQU0sTUFBTSxlQUFlLEVBQUU7QUFFakQsYUFBVyxRQUFRLE9BQU87QUFDekIsVUFBTSxZQUFZLGFBQWE7QUFBQTtBQUdoQyxTQUFPLE1BQU0sQ0FBQyxTQUFjO0FBQzNCLFVBQU0sTUFBTSxRQUFRLENBQUMsU0FBUztBQXZDaEM7QUF3Q0csVUFBSSxPQUFPLFlBQVksV0FBVyxLQUFLLE9BQU8sRUFBRSxNQUFNLFdBQUssU0FBTCxZQUFhO0FBR25FLGFBQU8sS0FBSyxRQUFRLHNCQUFzQjtBQUUxQyxhQUFPLEtBQUssUUFBUSw4Q0FBOEM7QUFHbEUsVUFBSSxTQUFTLE9BQU87QUFDbkIsZUFBTyxLQUFLLFFBQVEsaUJBQWlCO0FBQUEsaUJBQzNCLFNBQVMsTUFBTTtBQUN6QixlQUFPLEtBQUssUUFBUSxpQkFBaUI7QUFBQTtBQUd0QyxXQUFLLE9BQU87QUFDWixXQUFLLFFBQVE7QUFDYixXQUFLLFdBQVc7QUFBQTtBQUFBO0FBQUE7QUFLbkIsSUFBTyx1QkFBUTsiLAogICJuYW1lcyI6IFtdCn0K
package/dist/types.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import * as unified from 'unified';
2
- export declare type UnifiedPluginImport = Promise<{
3
- default: unified.Plugin;
4
- }>;
5
- export declare type Plugin = string | [string, any] | UnifiedPluginImport | [UnifiedPluginImport, any];
1
+ import type * as unified from 'unified';
2
+ import type { ShikiConfig } from './remark-shiki';
3
+ export declare type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any];
6
4
  export interface AstroMarkdownOptions {
7
5
  mode?: 'md' | 'mdx';
6
+ syntaxHighlight?: 'prism' | 'shiki' | false;
7
+ shikiConfig?: ShikiConfig;
8
8
  remarkPlugins?: Plugin[];
9
9
  rehypePlugins?: Plugin[];
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",
@@ -38,6 +38,7 @@
38
38
  "remark-parse": "^10.0.1",
39
39
  "remark-rehype": "^10.0.1",
40
40
  "remark-smartypants": "^2.0.0",
41
+ "shiki": "^0.10.0",
41
42
  "unified": "^10.1.1",
42
43
  "unist-util-map": "^3.0.0",
43
44
  "unist-util-visit": "^4.1.0"
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ import { remarkJsx, loadRemarkJsx } from './remark-jsx.js';
9
9
  import rehypeJsx from './rehype-jsx.js';
10
10
  import rehypeEscape from './rehype-escape.js';
11
11
  import remarkPrism from './remark-prism.js';
12
+ import remarkShiki from './remark-shiki.js';
12
13
  import remarkUnwrap from './remark-unwrap.js';
13
14
  import { loadPlugins } from './load-plugins.js';
14
15
 
@@ -37,6 +38,8 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
37
38
  let { remarkPlugins = [], rehypePlugins = [] } = opts ?? {};
38
39
  const scopedClassName = opts?.$?.scopedClassName;
39
40
  const mode = opts?.mode ?? 'mdx';
41
+ const syntaxHighlight = opts?.syntaxHighlight ?? 'prism';
42
+ const shikiConfig = opts?.shikiConfig ?? {};
40
43
  const isMDX = mode === 'mdx';
41
44
  const { headers, rehypeCollectHeaders } = createCollectHeaders();
42
45
 
@@ -64,7 +67,12 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
64
67
  parser.use([scopedStyles(scopedClassName)]);
65
68
  }
66
69
 
67
- parser.use([remarkPrism(scopedClassName)]);
70
+ if (syntaxHighlight === 'prism') {
71
+ parser.use([remarkPrism(scopedClassName)]);
72
+ } else if (syntaxHighlight === 'shiki') {
73
+ parser.use([await remarkShiki(shikiConfig)]);
74
+ }
75
+
68
76
  parser.use([[markdownToHtml as any, { allowDangerousHtml: true, passThrough: ['raw', 'mdxTextExpression', 'mdxJsxTextElement', 'mdxJsxFlowElement'] }]]);
69
77
 
70
78
  loadedRehypePlugins.forEach(([plugin, opts]) => {
@@ -1,26 +1,27 @@
1
1
  import * as unified from 'unified';
2
- import type { Plugin, UnifiedPluginImport } from './types';
2
+ import type { Plugin } from './types';
3
3
 
4
- async function importPlugin(p: string | UnifiedPluginImport): UnifiedPluginImport {
4
+ async function importPlugin(p: string | unified.Plugin): Promise<unified.Plugin> {
5
5
  if (typeof p === 'string') {
6
- return await import(p);
6
+ const importResult = await import(p);
7
+ return importResult.default;
7
8
  }
8
9
 
9
- return await p;
10
+ return p;
10
11
  }
11
12
 
12
- export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin] | [unified.Plugin, any]>[] {
13
+ export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin, any?]>[] {
13
14
  return items.map((p) => {
14
15
  return new Promise((resolve, reject) => {
15
16
  if (Array.isArray(p)) {
16
17
  const [plugin, opts] = p;
17
18
  return importPlugin(plugin)
18
- .then((m) => resolve([m.default, opts]))
19
+ .then((m) => resolve([m, opts]))
19
20
  .catch((e) => reject(e));
20
21
  }
21
22
 
22
23
  return importPlugin(p)
23
- .then((m) => resolve([m.default]))
24
+ .then((m) => resolve([m]))
24
25
  .catch((e) => reject(e));
25
26
  });
26
27
  });
@@ -0,0 +1,62 @@
1
+ import shiki from 'shiki';
2
+ import { visit } from 'unist-util-visit';
3
+
4
+ export interface ShikiConfig {
5
+ /**
6
+ * The languages loaded to Shiki.
7
+ * Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
8
+ * Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
9
+ *
10
+ * @default []
11
+ */
12
+ langs?: shiki.ILanguageRegistration[];
13
+ /**
14
+ * The styling theme.
15
+ * Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
16
+ * Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
17
+ *
18
+ * @default "github-dark"
19
+ */
20
+ theme?: shiki.IThemeRegistration;
21
+ /**
22
+ * Enable word wrapping.
23
+ * - true: enabled.
24
+ * - false: enabled.
25
+ * - null: All overflow styling removed. Code will overflow the element by default.
26
+ *
27
+ * @default false
28
+ */
29
+ wrap?: boolean | null;
30
+ }
31
+
32
+ const remarkShiki = async ({ langs = [], theme = 'github-dark', wrap = false }: ShikiConfig) => {
33
+ const highlighter = await shiki.getHighlighter({ theme });
34
+
35
+ for (const lang of langs) {
36
+ await highlighter.loadLanguage(lang);
37
+ }
38
+
39
+ return () => (tree: any) => {
40
+ visit(tree, 'code', (node) => {
41
+ let html = highlighter.codeToHtml(node.value, { lang: node.lang ?? 'plaintext' });
42
+
43
+ // Replace "shiki" class naming with "astro" and add "data-astro-raw".
44
+ html = html.replace('<pre class="shiki"', '<pre data-astro-raw class="astro-code"');
45
+ // Replace "shiki" css variable naming with "astro".
46
+ html = html.replace(/style="(background-)?color: var\(--shiki-/g, 'style="$1color: var(--astro-code-');
47
+ // Handle code wrapping
48
+ // if wrap=null, do nothing.
49
+ if (wrap === false) {
50
+ html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"');
51
+ } else if (wrap === true) {
52
+ html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"');
53
+ }
54
+
55
+ node.type = 'html';
56
+ node.value = html;
57
+ node.children = [];
58
+ });
59
+ };
60
+ };
61
+
62
+ export default remarkShiki;
package/src/types.ts CHANGED
@@ -1,10 +1,12 @@
1
- import * as unified from 'unified';
1
+ import type * as unified from 'unified';
2
+ import type { ShikiConfig } from './remark-shiki';
2
3
 
3
- export type UnifiedPluginImport = Promise<{ default: unified.Plugin }>;
4
- export type Plugin = string | [string, any] | UnifiedPluginImport | [UnifiedPluginImport, any];
4
+ export type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any];
5
5
 
6
6
  export interface AstroMarkdownOptions {
7
7
  mode?: 'md' | 'mdx';
8
+ syntaxHighlight?: 'prism' | 'shiki' | false;
9
+ shikiConfig?: ShikiConfig;
8
10
  remarkPlugins?: Plugin[];
9
11
  rehypePlugins?: Plugin[];
10
12
  }