@astrojs/markdown-remark 2.0.0-beta.0 → 2.0.0-beta.2

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.
Files changed (50) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/CHANGELOG.md +63 -0
  3. package/dist/index.js +11 -25
  4. package/dist/rehype-collect-headings.js +4 -14
  5. package/dist/remark-content-rel-image-error.js +2 -0
  6. package/dist/remark-shiki.js +2 -2
  7. package/dist/types.d.ts +1 -3
  8. package/package.json +7 -15
  9. package/src/index.ts +11 -30
  10. package/src/rehype-collect-headings.ts +3 -19
  11. package/src/remark-content-rel-image-error.ts +2 -0
  12. package/src/remark-shiki.ts +2 -2
  13. package/src/types.ts +1 -3
  14. package/test/autolinking.test.js +10 -75
  15. package/test/entities.test.js +5 -14
  16. package/test/plugins.test.js +2 -0
  17. package/test/test-utils.js +3 -0
  18. package/dist/mdast-util-mdxish.d.ts +0 -2
  19. package/dist/mdast-util-mdxish.js +0 -14
  20. package/dist/mdxjs.d.ts +0 -3
  21. package/dist/mdxjs.js +0 -20
  22. package/dist/rehype-escape.d.ts +0 -2
  23. package/dist/rehype-escape.js +0 -21
  24. package/dist/rehype-expressions.d.ts +0 -1
  25. package/dist/rehype-expressions.js +0 -20
  26. package/dist/rehype-islands.d.ts +0 -1
  27. package/dist/rehype-islands.js +0 -27
  28. package/dist/rehype-jsx.d.ts +0 -2
  29. package/dist/rehype-jsx.js +0 -51
  30. package/dist/remark-escape.d.ts +0 -1
  31. package/dist/remark-escape.js +0 -13
  32. package/dist/remark-mark-and-unravel.d.ts +0 -17
  33. package/dist/remark-mark-and-unravel.js +0 -45
  34. package/dist/remark-mdxish.d.ts +0 -1
  35. package/dist/remark-mdxish.js +0 -53
  36. package/dist/remark-unwrap.d.ts +0 -1
  37. package/dist/remark-unwrap.js +0 -31
  38. package/src/mdast-util-mdxish.ts +0 -12
  39. package/src/mdxjs.ts +0 -27
  40. package/src/rehype-escape.ts +0 -22
  41. package/src/rehype-expressions.ts +0 -18
  42. package/src/rehype-islands.ts +0 -43
  43. package/src/rehype-jsx.ts +0 -65
  44. package/src/remark-escape.ts +0 -15
  45. package/src/remark-mark-and-unravel.ts +0 -72
  46. package/src/remark-mdxish.ts +0 -61
  47. package/src/remark-unwrap.ts +0 -44
  48. package/test/components.test.js +0 -78
  49. package/test/expressions.test.js +0 -125
  50. package/test/strictness.test.js +0 -98
@@ -1,5 +1,5 @@
1
- @astrojs/markdown-remark:build: cache hit, replaying output 34663a00ad52a28a
1
+ @astrojs/markdown-remark:build: cache hit, replaying output 1c75f68e5ab1d40c
2
2
  @astrojs/markdown-remark:build: 
3
- @astrojs/markdown-remark:build: > @astrojs/markdown-remark@2.0.0-beta.0 build /home/runner/work/astro/astro/packages/markdown/remark
3
+ @astrojs/markdown-remark:build: > @astrojs/markdown-remark@2.0.0-beta.2 build /home/runner/work/astro/astro/packages/markdown/remark
4
4
  @astrojs/markdown-remark:build: > astro-scripts build "src/**/*.ts" && tsc -p tsconfig.json
5
5
  @astrojs/markdown-remark:build: 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # @astrojs/markdown-remark
2
2
 
3
+ ## 2.0.0-beta.2
4
+
5
+ ### Major Changes
6
+
7
+ - [#5785](https://github.com/withastro/astro/pull/5785) [`16107b6a1`](https://github.com/withastro/astro/commit/16107b6a10514ef1b563e585ec9add4b14f42b94) Thanks [@delucis](https://github.com/delucis)! - Drop support for legacy Astro-flavored Markdown
8
+
9
+ - [#5825](https://github.com/withastro/astro/pull/5825) [`52209ca2a`](https://github.com/withastro/astro/commit/52209ca2ad72a30854947dcb3a90ab4db0ac0a6f) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Baseline the experimental `contentCollections` flag. You're free to remove this from your astro config!
10
+
11
+ ```diff
12
+ import { defineConfig } from 'astro/config';
13
+
14
+ export default defineConfig({
15
+ - experimental: { contentCollections: true }
16
+ })
17
+
18
+ ```
19
+
20
+ - [#5806](https://github.com/withastro/astro/pull/5806) [`7572f7402`](https://github.com/withastro/astro/commit/7572f7402238da37de748be58d678fedaf863b53) Thanks [@matthewp](https://github.com/matthewp)! - Make astro a peerDependency of integrations
21
+
22
+ This marks `astro` as a peerDependency of several packages that are already getting `major` version bumps. This is so we can more properly track the dependency between them and what version of Astro they are being used with.
23
+
24
+ ### Patch Changes
25
+
26
+ - [#5837](https://github.com/withastro/astro/pull/5837) [`12f65a4d5`](https://github.com/withastro/astro/commit/12f65a4d55e3fd2993c2f67b18794dd536280c69) Thanks [@giuseppelt](https://github.com/giuseppelt)! - fix shiki css class replace logic
27
+
28
+ - Updated dependencies [[`01f3f463b`](https://github.com/withastro/astro/commit/01f3f463bf2918b310d130a9fabbf3ee21d14029), [`1f92d64ea`](https://github.com/withastro/astro/commit/1f92d64ea35c03fec43aff64eaf704dc5a9eb30a), [`c2180746b`](https://github.com/withastro/astro/commit/c2180746b4f6d9ef1b6f86924f21f52cc6ab4e63), [`ae8a012a7`](https://github.com/withastro/astro/commit/ae8a012a7b6884a03c50494332ee37b4505c2c3b), [`cf2de5422`](https://github.com/withastro/astro/commit/cf2de5422c26bfdea4c75f76e57b57299ded3e3a), [`ec09bb664`](https://github.com/withastro/astro/commit/ec09bb6642064dbd7d2f3369afb090363ae18de2), [`665a2c222`](https://github.com/withastro/astro/commit/665a2c2225e42881f5a9550599e8f3fc1deea0b4), [`f7aa1ec25`](https://github.com/withastro/astro/commit/f7aa1ec25d1584f7abd421903fbef66b1c050e2a), [`302e0ef8f`](https://github.com/withastro/astro/commit/302e0ef8f5d5232e3348afe680e599f3e537b5c5), [`840412128`](https://github.com/withastro/astro/commit/840412128b00a04515156e92c314a929d6b94f6d), [`1f49cddf9`](https://github.com/withastro/astro/commit/1f49cddf9e9ffc651efc171b2cbde9fbe9e8709d), [`4a1cabfe6`](https://github.com/withastro/astro/commit/4a1cabfe6b9ef8a6fbbcc0727a0dc6fa300cedaa), [`c4b0cb8bf`](https://github.com/withastro/astro/commit/c4b0cb8bf2b41887d9106440bb2e70d421a5f481), [`23dc9ea96`](https://github.com/withastro/astro/commit/23dc9ea96a10343852d965efd41fe6665294f1fb), [`63a6ceb38`](https://github.com/withastro/astro/commit/63a6ceb38d88331451dca64d0034c7c58e3d26f1), [`52209ca2a`](https://github.com/withastro/astro/commit/52209ca2ad72a30854947dcb3a90ab4db0ac0a6f), [`2303f9514`](https://github.com/withastro/astro/commit/2303f95142aa740c99213a098f82b99dd37d74a0)]:
29
+ - astro@2.0.0-beta.2
30
+ - @astrojs/prism@2.0.0-beta.0
31
+
32
+ ## 2.0.0-beta.1
33
+
34
+ ### Minor Changes
35
+
36
+ - [#5769](https://github.com/withastro/astro/pull/5769) [`93e633922`](https://github.com/withastro/astro/commit/93e633922c2e449df3bb2357b3683af1d3c0e07b) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Introduce a `smartypants` flag to opt-out of Astro's default SmartyPants plugin.
37
+
38
+ ```js
39
+ {
40
+ markdown: {
41
+ smartypants: false,
42
+ }
43
+ }
44
+ ```
45
+
46
+ #### Migration
47
+
48
+ You may have disabled Astro's built-in plugins (GitHub-Flavored Markdown and Smartypants) with the `extendDefaultPlugins` option. This has now been split into 2 flags to disable each plugin individually:
49
+
50
+ - `markdown.gfm` to disable GitHub-Flavored Markdown
51
+ - `markdown.smartypants` to disable SmartyPants
52
+
53
+ ```diff
54
+ // astro.config.mjs
55
+ import { defineConfig } from 'astro/config';
56
+
57
+ export default defineConfig({
58
+ markdown: {
59
+ - extendDefaultPlugins: false,
60
+ + smartypants: false,
61
+ + gfm: false,
62
+ }
63
+ });
64
+ ```
65
+
3
66
  ## 2.0.0-beta.0
4
67
 
5
68
  ### Major Changes
package/dist/index.js CHANGED
@@ -1,23 +1,16 @@
1
1
  import { toRemarkInitializeAstroData } from "./frontmatter-injection.js";
2
2
  import { loadPlugins } from "./load-plugins.js";
3
3
  import { rehypeHeadingIds } from "./rehype-collect-headings.js";
4
- import rehypeEscape from "./rehype-escape.js";
5
- import rehypeExpressions from "./rehype-expressions.js";
6
- import rehypeIslands from "./rehype-islands.js";
7
- import rehypeJsx from "./rehype-jsx.js";
8
4
  import toRemarkContentRelImageError from "./remark-content-rel-image-error.js";
9
- import remarkEscape from "./remark-escape.js";
10
- import remarkMarkAndUnravel from "./remark-mark-and-unravel.js";
11
- import remarkMdxish from "./remark-mdxish.js";
12
5
  import remarkPrism from "./remark-prism.js";
13
6
  import scopedStyles from "./remark-scoped-styles.js";
14
7
  import remarkShiki from "./remark-shiki.js";
15
- import remarkUnwrap from "./remark-unwrap.js";
16
8
  import rehypeRaw from "rehype-raw";
17
9
  import rehypeStringify from "rehype-stringify";
18
10
  import remarkGfm from "remark-gfm";
19
11
  import markdown from "remark-parse";
20
12
  import markdownToHtml from "remark-rehype";
13
+ import remarkSmartypants from "remark-smartypants";
21
14
  import { unified } from "unified";
22
15
  import { VFile } from "vfile";
23
16
  import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings.js";
@@ -32,7 +25,8 @@ const markdownConfigDefaults = {
32
25
  remarkPlugins: [],
33
26
  rehypePlugins: [],
34
27
  remarkRehype: {},
35
- gfm: true
28
+ gfm: true,
29
+ smartypants: true
36
30
  };
37
31
  async function renderMarkdown(content, opts) {
38
32
  var _a;
@@ -44,17 +38,19 @@ async function renderMarkdown(content, opts) {
44
38
  rehypePlugins = markdownConfigDefaults.rehypePlugins,
45
39
  remarkRehype = markdownConfigDefaults.remarkRehype,
46
40
  gfm = markdownConfigDefaults.gfm,
47
- isAstroFlavoredMd = false,
48
- isExperimentalContentCollections = false,
41
+ smartypants = markdownConfigDefaults.smartypants,
49
42
  contentDir,
50
43
  frontmatter: userFrontmatter = {}
51
44
  } = opts;
52
45
  const input = new VFile({ value: content, path: fileURL });
53
46
  const scopedClassName = (_a = opts.$) == null ? void 0 : _a.scopedClassName;
54
- let parser = unified().use(markdown).use(toRemarkInitializeAstroData({ userFrontmatter })).use(isAstroFlavoredMd ? [remarkMdxish, remarkMarkAndUnravel, remarkUnwrap, remarkEscape] : []);
47
+ let parser = unified().use(markdown).use(toRemarkInitializeAstroData({ userFrontmatter })).use([]);
55
48
  if (gfm) {
56
49
  parser.use(remarkGfm);
57
50
  }
51
+ if (smartypants) {
52
+ parser.use(remarkSmartypants);
53
+ }
58
54
  const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
59
55
  const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
60
56
  loadedRemarkPlugins.forEach(([plugin, pluginOpts]) => {
@@ -68,21 +64,13 @@ async function renderMarkdown(content, opts) {
68
64
  } else if (syntaxHighlight === "prism") {
69
65
  parser.use([remarkPrism(scopedClassName)]);
70
66
  }
71
- if (isExperimentalContentCollections) {
72
- parser.use([toRemarkContentRelImageError({ contentDir })]);
73
- }
67
+ parser.use([toRemarkContentRelImageError({ contentDir })]);
74
68
  parser.use([
75
69
  [
76
70
  markdownToHtml,
77
71
  {
78
72
  allowDangerousHtml: true,
79
- passThrough: isAstroFlavoredMd ? [
80
- "raw",
81
- "mdxFlowExpression",
82
- "mdxJsxFlowElement",
83
- "mdxJsxTextElement",
84
- "mdxTextExpression"
85
- ] : [],
73
+ passThrough: [],
86
74
  ...remarkRehype
87
75
  }
88
76
  ]
@@ -90,9 +78,7 @@ async function renderMarkdown(content, opts) {
90
78
  loadedRehypePlugins.forEach(([plugin, pluginOpts]) => {
91
79
  parser.use([[plugin, pluginOpts]]);
92
80
  });
93
- parser.use(
94
- isAstroFlavoredMd ? [rehypeJsx, rehypeExpressions, rehypeEscape, rehypeIslands, rehypeHeadingIds] : [rehypeHeadingIds, rehypeRaw]
95
- ).use(rehypeStringify, { allowDangerousHtml: true });
81
+ parser.use([rehypeHeadingIds, rehypeRaw]).use(rehypeStringify, { allowDangerousHtml: true });
96
82
  let vfile;
97
83
  try {
98
84
  vfile = await parser.process(input);
@@ -1,5 +1,4 @@
1
1
  import Slugger from "github-slugger";
2
- import { toHtml } from "hast-util-to-html";
3
2
  import { visit } from "unist-util-visit";
4
3
  const rawNodeTypes = /* @__PURE__ */ new Set(["text", "raw", "mdxTextExpression"]);
5
4
  const codeTagNames = /* @__PURE__ */ new Set(["code", "pre"]);
@@ -19,7 +18,6 @@ function rehypeHeadingIds() {
19
18
  return;
20
19
  const depth = Number.parseInt(level);
21
20
  let text = "";
22
- let isJSX = false;
23
21
  visit(node, (child, __, parent) => {
24
22
  if (child.type === "element" || parent == null) {
25
23
  return;
@@ -34,23 +32,15 @@ function rehypeHeadingIds() {
34
32
  text += child.value;
35
33
  } else {
36
34
  text += child.value.replace(/\{/g, "${");
37
- isJSX = isJSX || child.value.includes("{");
38
35
  }
39
36
  }
40
37
  });
41
38
  node.properties = node.properties || {};
42
39
  if (typeof node.properties.id !== "string") {
43
- if (isJSX) {
44
- const raw = toHtml(node.children, { allowDangerousHtml: true }).replace(/\n(<)/g, "<").replace(/(>)\n/g, ">");
45
- node.properties.id = `$$slug(\`${text}\`)`;
46
- node.type = "raw";
47
- node.value = `<${node.tagName} id={${node.properties.id}}>${raw}</${node.tagName}>`;
48
- } else {
49
- let slug = slugger.slug(text);
50
- if (slug.endsWith("-"))
51
- slug = slug.slice(0, -1);
52
- node.properties.id = slug;
53
- }
40
+ let slug = slugger.slug(text);
41
+ if (slug.endsWith("-"))
42
+ slug = slug.slice(0, -1);
43
+ node.properties.id = slug;
54
44
  }
55
45
  headings.push({ depth, slug: node.properties.id, text });
56
46
  });
@@ -3,6 +3,8 @@ import { pathToFileURL } from "url";
3
3
  function toRemarkContentRelImageError({ contentDir }) {
4
4
  return function remarkContentRelImageError() {
5
5
  return (tree, vfile) => {
6
+ if (typeof (vfile == null ? void 0 : vfile.path) !== "string")
7
+ return;
6
8
  const isContentFile = pathToFileURL(vfile.path).href.startsWith(contentDir.href);
7
9
  if (!isContentFile)
8
10
  return;
@@ -43,8 +43,8 @@ const remarkShiki = async ({ langs = [], theme = "github-dark", wrap = false },
43
43
  }
44
44
  let html = highlighter.codeToHtml(node.value, { lang });
45
45
  html = html.replace(
46
- '<pre class="shiki"',
47
- `<pre is:raw class="astro-code${scopedClassName ? " " + scopedClassName : ""}"`
46
+ /<pre class="(.*?)shiki(.*?)"/,
47
+ `<pre is:raw class="$1astro-code$2${scopedClassName ? " " + scopedClassName : ""}"`
48
48
  );
49
49
  if (node.lang === "diff") {
50
50
  html = html.replace(
package/dist/types.d.ts CHANGED
@@ -29,6 +29,7 @@ export interface AstroMarkdownOptions {
29
29
  rehypePlugins?: RehypePlugins;
30
30
  remarkRehype?: RemarkRehype;
31
31
  gfm?: boolean;
32
+ smartypants?: boolean;
32
33
  }
33
34
  export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
34
35
  /** @internal */
@@ -37,9 +38,6 @@ export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
37
38
  $?: {
38
39
  scopedClassName: string | null;
39
40
  };
40
- isAstroFlavoredMd?: boolean;
41
- /** Used to prevent relative image imports from `src/content/` */
42
- isExperimentalContentCollections?: boolean;
43
41
  /** Used to prevent relative image imports from `src/content/` */
44
42
  contentDir: URL;
45
43
  /** Used for frontmatter injection plugins */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0-beta.2",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",
@@ -16,28 +16,21 @@
16
16
  ".": "./dist/index.js",
17
17
  "./dist/internal.js": "./dist/internal.js"
18
18
  },
19
+ "peerDependencies": {
20
+ "astro": "^2.0.0-beta.2"
21
+ },
19
22
  "dependencies": {
20
- "@astrojs/micromark-extension-mdx-jsx": "^1.0.3",
21
- "@astrojs/prism": "^1.0.0",
22
- "acorn": "^8.7.1",
23
- "acorn-jsx": "^5.3.2",
23
+ "@astrojs/prism": "^2.0.0-beta.0",
24
24
  "github-slugger": "^1.4.0",
25
- "hast-util-to-html": "^8.0.3",
26
25
  "import-meta-resolve": "^2.1.0",
27
- "mdast-util-from-markdown": "^1.2.0",
28
- "mdast-util-mdx-expression": "^1.2.1",
29
- "mdast-util-mdx-jsx": "^1.2.0",
30
- "micromark-extension-mdx-expression": "^1.0.3",
31
- "micromark-extension-mdx-md": "^1.0.0",
32
- "micromark-util-combine-extensions": "^1.0.0",
33
26
  "rehype-raw": "^6.1.1",
34
27
  "rehype-stringify": "^9.0.3",
35
28
  "remark-gfm": "^3.0.1",
36
29
  "remark-parse": "^10.0.1",
37
30
  "remark-rehype": "^10.1.0",
31
+ "remark-smartypants": "^2.0.0",
38
32
  "shiki": "^0.11.1",
39
33
  "unified": "^10.1.2",
40
- "unist-util-map": "^3.1.1",
41
34
  "unist-util-visit": "^4.1.0",
42
35
  "vfile": "^5.3.2"
43
36
  },
@@ -48,9 +41,8 @@
48
41
  "@types/mdast": "^3.0.10",
49
42
  "@types/mocha": "^9.1.1",
50
43
  "@types/unist": "^2.0.6",
51
- "astro-scripts": "0.0.9",
44
+ "astro-scripts": "0.0.10-beta.0",
52
45
  "chai": "^4.3.6",
53
- "micromark-util-types": "^1.0.2",
54
46
  "mocha": "^9.2.2"
55
47
  },
56
48
  "scripts": {
package/src/index.ts CHANGED
@@ -8,24 +8,17 @@ import type {
8
8
  import { toRemarkInitializeAstroData } from './frontmatter-injection.js';
9
9
  import { loadPlugins } from './load-plugins.js';
10
10
  import { rehypeHeadingIds } from './rehype-collect-headings.js';
11
- import rehypeEscape from './rehype-escape.js';
12
- import rehypeExpressions from './rehype-expressions.js';
13
- import rehypeIslands from './rehype-islands.js';
14
- import rehypeJsx from './rehype-jsx.js';
15
11
  import toRemarkContentRelImageError from './remark-content-rel-image-error.js';
16
- import remarkEscape from './remark-escape.js';
17
- import remarkMarkAndUnravel from './remark-mark-and-unravel.js';
18
- import remarkMdxish from './remark-mdxish.js';
19
12
  import remarkPrism from './remark-prism.js';
20
13
  import scopedStyles from './remark-scoped-styles.js';
21
14
  import remarkShiki from './remark-shiki.js';
22
- import remarkUnwrap from './remark-unwrap.js';
23
15
 
24
16
  import rehypeRaw from 'rehype-raw';
25
17
  import rehypeStringify from 'rehype-stringify';
26
18
  import remarkGfm from 'remark-gfm';
27
19
  import markdown from 'remark-parse';
28
20
  import markdownToHtml from 'remark-rehype';
21
+ import remarkSmartypants from 'remark-smartypants';
29
22
  import { unified } from 'unified';
30
23
  import { VFile } from 'vfile';
31
24
 
@@ -43,6 +36,7 @@ export const markdownConfigDefaults: Omit<Required<AstroMarkdownOptions>, 'draft
43
36
  rehypePlugins: [],
44
37
  remarkRehype: {},
45
38
  gfm: true,
39
+ smartypants: true,
46
40
  };
47
41
 
48
42
  /** Shared utility for rendering markdown */
@@ -58,8 +52,7 @@ export async function renderMarkdown(
58
52
  rehypePlugins = markdownConfigDefaults.rehypePlugins,
59
53
  remarkRehype = markdownConfigDefaults.remarkRehype,
60
54
  gfm = markdownConfigDefaults.gfm,
61
- isAstroFlavoredMd = false,
62
- isExperimentalContentCollections = false,
55
+ smartypants = markdownConfigDefaults.smartypants,
63
56
  contentDir,
64
57
  frontmatter: userFrontmatter = {},
65
58
  } = opts;
@@ -69,12 +62,16 @@ export async function renderMarkdown(
69
62
  let parser = unified()
70
63
  .use(markdown)
71
64
  .use(toRemarkInitializeAstroData({ userFrontmatter }))
72
- .use(isAstroFlavoredMd ? [remarkMdxish, remarkMarkAndUnravel, remarkUnwrap, remarkEscape] : []);
65
+ .use([]);
73
66
 
74
67
  if (gfm) {
75
68
  parser.use(remarkGfm);
76
69
  }
77
70
 
71
+ if (smartypants) {
72
+ parser.use(remarkSmartypants);
73
+ }
74
+
78
75
  const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
79
76
  const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
80
77
 
@@ -93,24 +90,14 @@ export async function renderMarkdown(
93
90
  }
94
91
 
95
92
  // Apply later in case user plugins resolve relative image paths
96
- if (isExperimentalContentCollections) {
97
- parser.use([toRemarkContentRelImageError({ contentDir })]);
98
- }
93
+ parser.use([toRemarkContentRelImageError({ contentDir })]);
99
94
 
100
95
  parser.use([
101
96
  [
102
97
  markdownToHtml as any,
103
98
  {
104
99
  allowDangerousHtml: true,
105
- passThrough: isAstroFlavoredMd
106
- ? [
107
- 'raw',
108
- 'mdxFlowExpression',
109
- 'mdxJsxFlowElement',
110
- 'mdxJsxTextElement',
111
- 'mdxTextExpression',
112
- ]
113
- : [],
100
+ passThrough: [],
114
101
  ...remarkRehype,
115
102
  },
116
103
  ],
@@ -120,13 +107,7 @@ export async function renderMarkdown(
120
107
  parser.use([[plugin, pluginOpts]]);
121
108
  });
122
109
 
123
- parser
124
- .use(
125
- isAstroFlavoredMd
126
- ? [rehypeJsx, rehypeExpressions, rehypeEscape, rehypeIslands, rehypeHeadingIds]
127
- : [rehypeHeadingIds, rehypeRaw]
128
- )
129
- .use(rehypeStringify, { allowDangerousHtml: true });
110
+ parser.use([rehypeHeadingIds, rehypeRaw]).use(rehypeStringify, { allowDangerousHtml: true });
130
111
 
131
112
  let vfile: MarkdownVFile;
132
113
  try {
@@ -1,5 +1,4 @@
1
1
  import Slugger from 'github-slugger';
2
- import { toHtml } from 'hast-util-to-html';
3
2
  import { visit } from 'unist-util-visit';
4
3
 
5
4
  import type { MarkdownHeading, MarkdownVFile, RehypePlugin } from './types.js';
@@ -21,7 +20,6 @@ export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
21
20
  const depth = Number.parseInt(level);
22
21
 
23
22
  let text = '';
24
- let isJSX = false;
25
23
  visit(node, (child, __, parent) => {
26
24
  if (child.type === 'element' || parent == null) {
27
25
  return;
@@ -36,31 +34,17 @@ export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
36
34
  text += child.value;
37
35
  } else {
38
36
  text += child.value.replace(/\{/g, '${');
39
- isJSX = isJSX || child.value.includes('{');
40
37
  }
41
38
  }
42
39
  });
43
40
 
44
41
  node.properties = node.properties || {};
45
42
  if (typeof node.properties.id !== 'string') {
46
- if (isJSX) {
47
- // HACK: serialized JSX from internal plugins, ignore these for slug
48
- const raw = toHtml(node.children, { allowDangerousHtml: true })
49
- .replace(/\n(<)/g, '<')
50
- .replace(/(>)\n/g, '>');
51
- // HACK: for ids that have JSX content, use $$slug helper to generate slug at runtime
52
- node.properties.id = `$$slug(\`${text}\`)`;
53
- (node as any).type = 'raw';
54
- (
55
- node as any
56
- ).value = `<${node.tagName} id={${node.properties.id}}>${raw}</${node.tagName}>`;
57
- } else {
58
- let slug = slugger.slug(text);
43
+ let slug = slugger.slug(text);
59
44
 
60
- if (slug.endsWith('-')) slug = slug.slice(0, -1);
45
+ if (slug.endsWith('-')) slug = slug.slice(0, -1);
61
46
 
62
- node.properties.id = slug;
63
- }
47
+ node.properties.id = slug;
64
48
  }
65
49
 
66
50
  headings.push({ depth, slug: node.properties.id, text });
@@ -10,6 +10,8 @@ import type { VFile } from 'vfile';
10
10
  export default function toRemarkContentRelImageError({ contentDir }: { contentDir: URL }) {
11
11
  return function remarkContentRelImageError() {
12
12
  return (tree: any, vfile: VFile) => {
13
+ if (typeof vfile?.path !== 'string') return;
14
+
13
15
  const isContentFile = pathToFileURL(vfile.path).href.startsWith(contentDir.href);
14
16
  if (!isContentFile) return;
15
17
 
@@ -70,8 +70,8 @@ const remarkShiki = async (
70
70
 
71
71
  // Replace "shiki" class naming with "astro" and add "is:raw".
72
72
  html = html.replace(
73
- '<pre class="shiki"',
74
- `<pre is:raw class="astro-code${scopedClassName ? ' ' + scopedClassName : ''}"`
73
+ /<pre class="(.*?)shiki(.*?)"/,
74
+ `<pre is:raw class="$1astro-code$2${scopedClassName ? ' ' + scopedClassName : ''}"`
75
75
  );
76
76
  // Add "user-select: none;" for "+"/"-" diff symbols
77
77
  if (node.lang === 'diff') {
package/src/types.ts CHANGED
@@ -48,6 +48,7 @@ export interface AstroMarkdownOptions {
48
48
  rehypePlugins?: RehypePlugins;
49
49
  remarkRehype?: RemarkRehype;
50
50
  gfm?: boolean;
51
+ smartypants?: boolean;
51
52
  }
52
53
 
53
54
  export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
@@ -57,9 +58,6 @@ export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
57
58
  $?: {
58
59
  scopedClassName: string | null;
59
60
  };
60
- isAstroFlavoredMd?: boolean;
61
- /** Used to prevent relative image imports from `src/content/` */
62
- isExperimentalContentCollections?: boolean;
63
61
  /** Used to prevent relative image imports from `src/content/` */
64
62
  contentDir: URL;
65
63
  /** Used for frontmatter injection plugins */
@@ -1,10 +1,14 @@
1
1
  import { renderMarkdown } from '../dist/index.js';
2
2
  import chai from 'chai';
3
+ import { mockRenderMarkdownParams } from './test-utils.js';
3
4
 
4
5
  describe('autolinking', () => {
5
6
  describe('plain md', () => {
6
7
  it('autolinks URLs starting with a protocol in plain text', async () => {
7
- const { code } = await renderMarkdown(`See https://example.com for more.`, {});
8
+ const { code } = await renderMarkdown(
9
+ `See https://example.com for more.`,
10
+ mockRenderMarkdownParams
11
+ );
8
12
 
9
13
  chai
10
14
  .expect(code.replace(/\n/g, ''))
@@ -12,7 +16,10 @@ describe('autolinking', () => {
12
16
  });
13
17
 
14
18
  it('autolinks URLs starting with "www." in plain text', async () => {
15
- const { code } = await renderMarkdown(`See www.example.com for more.`, {});
19
+ const { code } = await renderMarkdown(
20
+ `See www.example.com for more.`,
21
+ mockRenderMarkdownParams
22
+ );
16
23
 
17
24
  chai
18
25
  .expect(code.trim())
@@ -22,7 +29,7 @@ describe('autolinking', () => {
22
29
  it('does not autolink URLs in code blocks', async () => {
23
30
  const { code } = await renderMarkdown(
24
31
  'See `https://example.com` or `www.example.com` for more.',
25
- {}
32
+ mockRenderMarkdownParams
26
33
  );
27
34
 
28
35
  chai
@@ -33,76 +40,4 @@ describe('autolinking', () => {
33
40
  );
34
41
  });
35
42
  });
36
-
37
- describe('astro-flavored md', () => {
38
- const renderAstroMd = (text) => renderMarkdown(text, { isAstroFlavoredMd: true });
39
-
40
- it('does not autolink URLs in code blocks', async () => {
41
- const { code } = await renderAstroMd(
42
- 'See `https://example.com` or `www.example.com` for more.',
43
- {}
44
- );
45
-
46
- chai
47
- .expect(code.trim())
48
- .to.equal(
49
- `<p>See <code is:raw>https://example.com</code> or ` +
50
- `<code is:raw>www.example.com</code> for more.</p>`
51
- );
52
- });
53
-
54
- it('does not autolink URLs in fenced code blocks', async () => {
55
- const { code } = await renderAstroMd(
56
- 'Example:\n```\nGo to https://example.com or www.example.com now.\n```'
57
- );
58
-
59
- chai
60
- .expect(code)
61
- .to.contain(`<pre is:raw`)
62
- .to.contain(`Go to https://example.com or www.example.com now.`);
63
- });
64
-
65
- it('does not autolink URLs starting with a protocol when nested inside links', async () => {
66
- const { code } = await renderAstroMd(
67
- `See [http://example.com](http://example.com) or ` +
68
- `<a test href="https://example.com">https://example.com</a>`
69
- );
70
-
71
- chai
72
- .expect(code.replace(/\n/g, ''))
73
- .to.equal(
74
- `<p>See <a href="http://example.com">http://example.com</a> or ` +
75
- `<a test href="https://example.com">https://example.com</a></p>`
76
- );
77
- });
78
-
79
- it('does not autolink URLs starting with "www." when nested inside links', async () => {
80
- const { code } = await renderAstroMd(
81
- `See [www.example.com](https://www.example.com) or ` +
82
- `<a test href="https://www.example.com">www.example.com</a>`
83
- );
84
-
85
- chai
86
- .expect(code.replace(/\n/g, ''))
87
- .to.equal(
88
- `<p>See <a href="https://www.example.com">www.example.com</a> or ` +
89
- `<a test href="https://www.example.com">www.example.com</a></p>`
90
- );
91
- });
92
-
93
- it('does not autolink URLs when nested several layers deep inside links', async () => {
94
- const { code } = await renderAstroMd(
95
- `<a href="https://www.example.com">**Visit _our www.example.com or ` +
96
- `http://localhost pages_ for more!**</a>`
97
- );
98
-
99
- chai
100
- .expect(code.replace(/\n/g, ''))
101
- .to.equal(
102
- `<a href="https://www.example.com"><strong>` +
103
- `Visit <em>our www.example.com or http://localhost pages</em> for more!` +
104
- `</strong></a>`
105
- );
106
- });
107
- });
108
43
  });
@@ -1,23 +1,14 @@
1
1
  import { renderMarkdown } from '../dist/index.js';
2
2
  import { expect } from 'chai';
3
+ import { mockRenderMarkdownParams } from './test-utils.js';
3
4
 
4
5
  describe('entities', () => {
5
6
  it('should not unescape entities in regular Markdown', async () => {
6
- const { code } = await renderMarkdown(`&lt;i&gt;This should NOT be italic&lt;/i&gt;`, {
7
- isAstroFlavoredMd: false,
8
- });
7
+ const { code } = await renderMarkdown(
8
+ `&lt;i&gt;This should NOT be italic&lt;/i&gt;`,
9
+ mockRenderMarkdownParams
10
+ );
9
11
 
10
12
  expect(code).to.equal(`<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>`);
11
13
  });
12
-
13
- it('should not escape entities in code blocks twice in Astro-flavored markdown', async () => {
14
- const { code } = await renderMarkdown(`\`\`\`astro\n<h1>{x && x.name || ''}!</h1>\n\`\`\``, {
15
- isAstroFlavoredMd: true,
16
- syntaxHighlight: false,
17
- });
18
-
19
- expect(code).to.equal(
20
- `<pre is:raw><code class="language-astro">&lt;h1&gt;{x &amp;&amp; x.name || ''}!&lt;/h1&gt;\n</code></pre>`
21
- );
22
- });
23
14
  });
@@ -1,4 +1,5 @@
1
1
  import { renderMarkdown } from '../dist/index.js';
2
+ import { mockRenderMarkdownParams } from './test-utils.js';
2
3
  import chai from 'chai';
3
4
 
4
5
  import { fileURLToPath } from 'node:url';
@@ -8,6 +9,7 @@ describe('plugins', () => {
8
9
  it('should be able to get file path when passing fileURL', async () => {
9
10
  let context;
10
11
  await renderMarkdown(`test`, {
12
+ ...mockRenderMarkdownParams,
11
13
  fileURL: new URL('virtual.md', import.meta.url),
12
14
  remarkPlugins: [
13
15
  function () {
@@ -0,0 +1,3 @@
1
+ export const mockRenderMarkdownParams = {
2
+ contentDir: new URL('file:///src/content/'),
3
+ };
@@ -1,2 +0,0 @@
1
- export declare function mdxFromMarkdown(): any;
2
- export declare function mdxToMarkdown(): any;