@astrojs/markdown-remark 2.0.0-beta.2 → 2.0.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.
@@ -1,5 +1,5 @@
1
- @astrojs/markdown-remark:build: cache hit, replaying output 1c75f68e5ab1d40c
1
+ @astrojs/markdown-remark:build: cache hit, replaying output a66e40aa1dc7052c
2
2
  @astrojs/markdown-remark:build: 
3
- @astrojs/markdown-remark:build: > @astrojs/markdown-remark@2.0.0-beta.2 build /home/runner/work/astro/astro/packages/markdown/remark
3
+ @astrojs/markdown-remark:build: > @astrojs/markdown-remark@2.0.1 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,7 +1,125 @@
1
1
  # @astrojs/markdown-remark
2
2
 
3
+ ## 2.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#5978](https://github.com/withastro/astro/pull/5978) [`7abb1e905`](https://github.com/withastro/astro/commit/7abb1e9056c4b4fd0abfced347df32a41cdfbf28) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fix MDX heading IDs generation when using a frontmatter reference
8
+
9
+ - Updated dependencies [[`b53e0717b`](https://github.com/withastro/astro/commit/b53e0717b7f6b042baaeec7f87999e99c76c031c), [`60b32d585`](https://github.com/withastro/astro/commit/60b32d58565d87e87573eb268408293fc28ec657), [`883e0cc29`](https://github.com/withastro/astro/commit/883e0cc29968d51ed6c7515be035a40b28bafdad), [`dabce6b8c`](https://github.com/withastro/astro/commit/dabce6b8c684f851c3535f8acead06cbef6dce2a), [`aedf23f85`](https://github.com/withastro/astro/commit/aedf23f8582e32a6b94b81ddba9b323831f2b22a)]:
10
+ - astro@2.0.2
11
+
12
+ ## 2.0.0
13
+
14
+ ### Major Changes
15
+
16
+ - [#5687](https://github.com/withastro/astro/pull/5687) [`e2019be6f`](https://github.com/withastro/astro/commit/e2019be6ffa46fa33d92cfd346f9ecbe51bb7144) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Give remark and rehype plugins access to user frontmatter via frontmatter injection. This means `data.astro.frontmatter` is now the _complete_ Markdown or MDX document's frontmatter, rather than an empty object.
17
+
18
+ This allows plugin authors to modify existing frontmatter, or compute new properties based on other properties. For example, say you want to compute a full image URL based on an `imageSrc` slug in your document frontmatter:
19
+
20
+ ```ts
21
+ export function remarkInjectSocialImagePlugin() {
22
+ return function (tree, file) {
23
+ const { frontmatter } = file.data.astro;
24
+ frontmatter.socialImageSrc = new URL(frontmatter.imageSrc, 'https://my-blog.com/').pathname;
25
+ };
26
+ }
27
+ ```
28
+
29
+ When using Content Collections, you can access this modified frontmatter using the `remarkPluginFrontmatter` property returned when rendering an entry.
30
+
31
+ **Migration instructions**
32
+
33
+ Plugin authors should now **check for user frontmatter when applying defaults.**
34
+
35
+ For example, say a remark plugin wants to apply a default `title` if none is present. Add a conditional to check if the property is present, and update if none exists:
36
+
37
+ ```diff
38
+ export function remarkInjectTitlePlugin() {
39
+ return function (tree, file) {
40
+ const { frontmatter } = file.data.astro;
41
+ + if (!frontmatter.title) {
42
+ frontmatter.title = 'Default title';
43
+ + }
44
+ }
45
+ }
46
+ ```
47
+
48
+ This differs from previous behavior, where a Markdown file's frontmatter would _always_ override frontmatter injected via remark or reype.
49
+
50
+ - [#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
51
+
52
+ - [#5684](https://github.com/withastro/astro/pull/5684) [`a9c292026`](https://github.com/withastro/astro/commit/a9c2920264e36cc5dc05f4adc1912187979edb0d) & [#5769](https://github.com/withastro/astro/pull/5769) [`93e633922`](https://github.com/withastro/astro/commit/93e633922c2e449df3bb2357b3683af1d3c0e07b) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Refine Markdown and MDX configuration options for ease-of-use.
53
+
54
+ - **Markdown**
55
+
56
+ - **Replace the `extendDefaultPlugins` option** with a `gfm` boolean and a `smartypants` boolean. These are enabled by default, and can be disabled to remove GitHub-Flavored Markdown and SmartyPants.
57
+
58
+ - Ensure GitHub-Flavored Markdown and SmartyPants are applied whether or not custom `remarkPlugins` or `rehypePlugins` are configured. If you want to apply custom plugins _and_ remove Astro's default plugins, manually set `gfm: false` and `smartypants: false` in your config.
59
+
60
+ - **Migrate `extendDefaultPlugins` to `gfm` and `smartypants`**
61
+
62
+ 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:
63
+
64
+ - `markdown.gfm` to disable GitHub-Flavored Markdown
65
+ - `markdown.smartypants` to disable SmartyPants
66
+
67
+ ```diff
68
+ // astro.config.mjs
69
+ import { defineConfig } from 'astro/config';
70
+
71
+ export default defineConfig({
72
+ markdown: {
73
+ - extendDefaultPlugins: false,
74
+ + smartypants: false,
75
+ + gfm: false,
76
+ }
77
+ });
78
+ ```
79
+
80
+ Additionally, applying remark and rehype plugins **no longer disables** `gfm` and `smartypants`. You will need to opt-out manually by setting `gfm` and `smartypants` to `false`.
81
+
82
+ - **MDX**
83
+
84
+ - Support _all_ Markdown configuration options (except `drafts`) from your MDX integration config. This includes `syntaxHighlighting` and `shikiConfig` options to further customize the MDX renderer.
85
+
86
+ - Simplify `extendPlugins` to an `extendMarkdownConfig` option. MDX options will default to their equivalent in your Markdown config. By setting `extendMarkdownConfig` to false, you can "eject" to set your own syntax highlighting, plugins, and more.
87
+
88
+ - **Migrate MDX's `extendPlugins` to `extendMarkdownConfig`**
89
+
90
+ You may have used the `extendPlugins` option to manage plugin defaults in MDX. This has been replaced by 3 flags:
91
+
92
+ - `extendMarkdownConfig` (`true` by default) to toggle Markdown config inheritance. This replaces the `extendPlugins: 'markdown'` option.
93
+ - `gfm` (`true` by default) and `smartypants` (`true` by default) to toggle GitHub-Flavored Markdown and SmartyPants in MDX. This replaces the `extendPlugins: 'defaults'` option.
94
+
95
+ - [#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!
96
+
97
+ ```diff
98
+ import { defineConfig } from 'astro/config';
99
+
100
+ export default defineConfig({
101
+ - experimental: { contentCollections: true }
102
+ })
103
+
104
+ ```
105
+
106
+ - [#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
107
+
108
+ 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.
109
+
110
+ **Patch Changes**
111
+
112
+ - [#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
113
+
114
+ - Updated dependencies [[`93e633922`](https://github.com/withastro/astro/commit/93e633922c2e449df3bb2357b3683af1d3c0e07b), [`16dc36a87`](https://github.com/withastro/astro/commit/16dc36a870df47a4151a8ed2d91d0bd1bb812458), [`01f3f463b`](https://github.com/withastro/astro/commit/01f3f463bf2918b310d130a9fabbf3ee21d14029), [`e2019be6f`](https://github.com/withastro/astro/commit/e2019be6ffa46fa33d92cfd346f9ecbe51bb7144), [`05caf445d`](https://github.com/withastro/astro/commit/05caf445d4d2728f1010aeb2179a9e756c2fd17d), [`49ab4f231`](https://github.com/withastro/astro/commit/49ab4f231c23b34891c3ee86f4b92bf8d6d267a3), [`a342a486c`](https://github.com/withastro/astro/commit/a342a486c2831461e24e6c2f1ca8a9d3e15477b6), [`8fb28648f`](https://github.com/withastro/astro/commit/8fb28648f66629741cb976bfe34ccd9d8f55661e), [`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), [`ce5c5dbd4`](https://github.com/withastro/astro/commit/ce5c5dbd46afbe738b03600758bf5c35113de522), [`ec09bb664`](https://github.com/withastro/astro/commit/ec09bb6642064dbd7d2f3369afb090363ae18de2), [`665a2c222`](https://github.com/withastro/astro/commit/665a2c2225e42881f5a9550599e8f3fc1deea0b4), [`259a539d7`](https://github.com/withastro/astro/commit/259a539d7d70c783330c797794b15716921629cf), [`f7aa1ec25`](https://github.com/withastro/astro/commit/f7aa1ec25d1584f7abd421903fbef66b1c050e2a), [`4987d6f44`](https://github.com/withastro/astro/commit/4987d6f44cfd0d81d88f21f5c380503403dc1e6a), [`304823811`](https://github.com/withastro/astro/commit/304823811eddd8e72aa1d8e2d39b40ab5cda3565), [`302e0ef8f`](https://github.com/withastro/astro/commit/302e0ef8f5d5232e3348afe680e599f3e537b5c5), [`55cea0a9d`](https://github.com/withastro/astro/commit/55cea0a9d8c8df91a46590fc04a9ac28089b3432), [`dd56c1941`](https://github.com/withastro/astro/commit/dd56c19411b126439b8bc42d681b6fa8c06e8c61), [`9963c6e4d`](https://github.com/withastro/astro/commit/9963c6e4d50c392c3d1ac4492237020f15ccb1de), [`be901dc98`](https://github.com/withastro/astro/commit/be901dc98c4a7f6b5536540aa8f7ba5108e939a0), [`f6cf92b48`](https://github.com/withastro/astro/commit/f6cf92b48317a19a3840ad781b77d6d3cae143bb), [`e818cc046`](https://github.com/withastro/astro/commit/e818cc0466a942919ea3c41585e231c8c80cb3d0), [`8c100a6fe`](https://github.com/withastro/astro/commit/8c100a6fe6cc652c3799d1622e12c2c969f30510), [`116d8835c`](https://github.com/withastro/astro/commit/116d8835ca9e78f8b5e477ee5a3d737b69f80706), [`840412128`](https://github.com/withastro/astro/commit/840412128b00a04515156e92c314a929d6b94f6d), [`1f49cddf9`](https://github.com/withastro/astro/commit/1f49cddf9e9ffc651efc171b2cbde9fbe9e8709d), [`7325df412`](https://github.com/withastro/astro/commit/7325df412107fc0e65cd45c1b568fb686708f723), [`16c7d0bfd`](https://github.com/withastro/astro/commit/16c7d0bfd49d2b9bfae45385f506bcd642f9444a), [`a9c292026`](https://github.com/withastro/astro/commit/a9c2920264e36cc5dc05f4adc1912187979edb0d), [`2a5786419`](https://github.com/withastro/astro/commit/2a5786419599b8674473c699300172b9aacbae2e), [`4a1cabfe6`](https://github.com/withastro/astro/commit/4a1cabfe6b9ef8a6fbbcc0727a0dc6fa300cedaa), [`a8d3e7924`](https://github.com/withastro/astro/commit/a8d3e79246605d252dcddad159e358e2d79bd624), [`fa8c131f8`](https://github.com/withastro/astro/commit/fa8c131f88ef67d14c62f1c00c97ed74d43a80ac), [`64b8082e7`](https://github.com/withastro/astro/commit/64b8082e776b832f1433ed288e6f7888adb626d0), [`c4b0cb8bf`](https://github.com/withastro/astro/commit/c4b0cb8bf2b41887d9106440bb2e70d421a5f481), [`23dc9ea96`](https://github.com/withastro/astro/commit/23dc9ea96a10343852d965efd41fe6665294f1fb), [`63a6ceb38`](https://github.com/withastro/astro/commit/63a6ceb38d88331451dca64d0034c7c58e3d26f1), [`a3a7fc929`](https://github.com/withastro/astro/commit/a3a7fc9298e6d88abb4b7bee1e58f05fa9558cf1), [`52209ca2a`](https://github.com/withastro/astro/commit/52209ca2ad72a30854947dcb3a90ab4db0ac0a6f), [`5fd9208d4`](https://github.com/withastro/astro/commit/5fd9208d447f5ab8909a2188b6c2491a0debd49d), [`5eba34fcc`](https://github.com/withastro/astro/commit/5eba34fcc663def20bdf6e0daad02a6a5472776b), [`899214298`](https://github.com/withastro/astro/commit/899214298cee5f0c975c7245e623c649e1842d73), [`3a00ecb3e`](https://github.com/withastro/astro/commit/3a00ecb3eb4bc44be758c064f2bde6e247e8a593), [`5eba34fcc`](https://github.com/withastro/astro/commit/5eba34fcc663def20bdf6e0daad02a6a5472776b), [`2303f9514`](https://github.com/withastro/astro/commit/2303f95142aa740c99213a098f82b99dd37d74a0), [`1ca81c16b`](https://github.com/withastro/astro/commit/1ca81c16b8b66236e092e6eb6ec3f73f5668421c), [`b66d7195c`](https://github.com/withastro/astro/commit/b66d7195c17a55ea0931bc3744888bd4f5f01ce6)]:
115
+ - astro@2.0.0
116
+ - @astrojs/prism@2.0.0
117
+
3
118
  ## 2.0.0-beta.2
4
119
 
120
+ <details>
121
+ <summary>See changes in 2.0.0-beta.2</summary>
122
+
5
123
  ### Major Changes
6
124
 
7
125
  - [#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
@@ -29,8 +147,13 @@
29
147
  - astro@2.0.0-beta.2
30
148
  - @astrojs/prism@2.0.0-beta.0
31
149
 
150
+ </details>
151
+
32
152
  ## 2.0.0-beta.1
33
153
 
154
+ <details>
155
+ <summary>See changes in 2.0.0-beta.1</summary>
156
+
34
157
  ### Minor Changes
35
158
 
36
159
  - [#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.
@@ -63,8 +186,13 @@
63
186
  });
64
187
  ```
65
188
 
189
+ </details>
190
+
66
191
  ## 2.0.0-beta.0
67
192
 
193
+ <details>
194
+ <summary>See changes in 2.0.0-beta.0</summary>
195
+
68
196
  ### Major Changes
69
197
 
70
198
  - [#5687](https://github.com/withastro/astro/pull/5687) [`e2019be6f`](https://github.com/withastro/astro/commit/e2019be6ffa46fa33d92cfd346f9ecbe51bb7144) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Give remark and rehype plugins access to user frontmatter via frontmatter injection. This means `data.astro.frontmatter` is now the _complete_ Markdown or MDX document's frontmatter, rather than an empty object.
@@ -163,6 +291,8 @@
163
291
  - `extendMarkdownConfig` (`true` by default) to toggle Markdown config inheritance. This replaces the `extendPlugins: 'markdown'` option.
164
292
  - `gfm` (`true` by default) to toggle GitHub-Flavored Markdown in MDX. This replaces the `extendPlugins: 'defaults'` option.
165
293
 
294
+ </details>
295
+
166
296
  ## 1.2.0
167
297
 
168
298
  ### Minor Changes
@@ -1,5 +1,6 @@
1
1
  import Slugger from "github-slugger";
2
2
  import { visit } from "unist-util-visit";
3
+ import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js";
3
4
  const rawNodeTypes = /* @__PURE__ */ new Set(["text", "raw", "mdxTextExpression"]);
4
5
  const codeTagNames = /* @__PURE__ */ new Set(["code", "pre"]);
5
6
  function rehypeHeadingIds() {
@@ -7,6 +8,7 @@ function rehypeHeadingIds() {
7
8
  const headings = [];
8
9
  const slugger = new Slugger();
9
10
  const isMDX = isMDXFile(file);
11
+ const astroData = safelyGetAstroData(file.data);
10
12
  visit(tree, (node) => {
11
13
  if (node.type !== "element")
12
14
  return;
@@ -29,7 +31,17 @@ function rehypeHeadingIds() {
29
31
  }
30
32
  if (rawNodeTypes.has(child.type)) {
31
33
  if (isMDX || codeTagNames.has(parent.tagName)) {
32
- text += child.value;
34
+ let value = child.value;
35
+ if (isMdxTextExpression(child) && !(astroData instanceof InvalidAstroDataError)) {
36
+ const frontmatterPath = getMdxFrontmatterVariablePath(child);
37
+ if (Array.isArray(frontmatterPath) && frontmatterPath.length > 0) {
38
+ const frontmatterValue = getMdxFrontmatterVariableValue(astroData, frontmatterPath);
39
+ if (typeof frontmatterValue === "string") {
40
+ value = frontmatterValue;
41
+ }
42
+ }
43
+ }
44
+ text += value;
33
45
  } else {
34
46
  text += child.value.replace(/\{/g, "${");
35
47
  }
@@ -51,6 +63,37 @@ function isMDXFile(file) {
51
63
  var _a;
52
64
  return Boolean((_a = file.history[0]) == null ? void 0 : _a.endsWith(".mdx"));
53
65
  }
66
+ function getMdxFrontmatterVariablePath(node) {
67
+ var _a;
68
+ if (!((_a = node.data) == null ? void 0 : _a.estree) || node.data.estree.body.length !== 1)
69
+ return new Error();
70
+ const statement = node.data.estree.body[0];
71
+ if ((statement == null ? void 0 : statement.type) !== "ExpressionStatement" || statement.expression.type !== "MemberExpression")
72
+ return new Error();
73
+ let expression = statement.expression;
74
+ const expressionPath = [];
75
+ while (expression.type === "MemberExpression" && expression.property.type === (expression.computed ? "Literal" : "Identifier")) {
76
+ expressionPath.push(
77
+ expression.property.type === "Literal" ? String(expression.property.value) : expression.property.name
78
+ );
79
+ expression = expression.object;
80
+ }
81
+ if (expression.type !== "Identifier" || expression.name !== "frontmatter")
82
+ return new Error();
83
+ return expressionPath.reverse();
84
+ }
85
+ function getMdxFrontmatterVariableValue(astroData, path) {
86
+ let value = astroData.frontmatter;
87
+ for (const key of path) {
88
+ if (!value[key])
89
+ return void 0;
90
+ value = value[key];
91
+ }
92
+ return value;
93
+ }
94
+ function isMdxTextExpression(node) {
95
+ return node.type === "mdxTextExpression";
96
+ }
54
97
  export {
55
98
  rehypeHeadingIds
56
99
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.1",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",
@@ -17,10 +17,10 @@
17
17
  "./dist/internal.js": "./dist/internal.js"
18
18
  },
19
19
  "peerDependencies": {
20
- "astro": "^2.0.0-beta.2"
20
+ "astro": "^2.0.2"
21
21
  },
22
22
  "dependencies": {
23
- "@astrojs/prism": "^2.0.0-beta.0",
23
+ "@astrojs/prism": "^2.0.0",
24
24
  "github-slugger": "^1.4.0",
25
25
  "import-meta-resolve": "^2.1.0",
26
26
  "rehype-raw": "^6.1.1",
@@ -36,13 +36,15 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/chai": "^4.3.1",
39
+ "@types/estree": "^1.0.0",
39
40
  "@types/github-slugger": "^1.3.0",
40
41
  "@types/hast": "^2.3.4",
41
42
  "@types/mdast": "^3.0.10",
42
43
  "@types/mocha": "^9.1.1",
43
44
  "@types/unist": "^2.0.6",
44
- "astro-scripts": "0.0.10-beta.0",
45
+ "astro-scripts": "0.0.10",
45
46
  "chai": "^4.3.6",
47
+ "mdast-util-mdx-expression": "^1.3.1",
46
48
  "mocha": "^9.2.2"
47
49
  },
48
50
  "scripts": {
@@ -1,7 +1,10 @@
1
+ import { type Expression, type Super } from 'estree';
1
2
  import Slugger from 'github-slugger';
2
- import { visit } from 'unist-util-visit';
3
+ import { type MdxTextExpression } from 'mdast-util-mdx-expression';
4
+ import { visit, type Node } from 'unist-util-visit';
3
5
 
4
- import type { MarkdownHeading, MarkdownVFile, RehypePlugin } from './types.js';
6
+ import { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';
7
+ import type { MarkdownAstroData, MarkdownHeading, MarkdownVFile, RehypePlugin } from './types.js';
5
8
 
6
9
  const rawNodeTypes = new Set(['text', 'raw', 'mdxTextExpression']);
7
10
  const codeTagNames = new Set(['code', 'pre']);
@@ -11,6 +14,7 @@ export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
11
14
  const headings: MarkdownHeading[] = [];
12
15
  const slugger = new Slugger();
13
16
  const isMDX = isMDXFile(file);
17
+ const astroData = safelyGetAstroData(file.data);
14
18
  visit(tree, (node) => {
15
19
  if (node.type !== 'element') return;
16
20
  const { tagName } = node;
@@ -31,7 +35,17 @@ export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
31
35
  }
32
36
  if (rawNodeTypes.has(child.type)) {
33
37
  if (isMDX || codeTagNames.has(parent.tagName)) {
34
- text += child.value;
38
+ let value = child.value;
39
+ if (isMdxTextExpression(child) && !(astroData instanceof InvalidAstroDataError)) {
40
+ const frontmatterPath = getMdxFrontmatterVariablePath(child);
41
+ if (Array.isArray(frontmatterPath) && frontmatterPath.length > 0) {
42
+ const frontmatterValue = getMdxFrontmatterVariableValue(astroData, frontmatterPath);
43
+ if (typeof frontmatterValue === 'string') {
44
+ value = frontmatterValue;
45
+ }
46
+ }
47
+ }
48
+ text += value;
35
49
  } else {
36
50
  text += child.value.replace(/\{/g, '${');
37
51
  }
@@ -57,3 +71,58 @@ export function rehypeHeadingIds(): ReturnType<RehypePlugin> {
57
71
  function isMDXFile(file: MarkdownVFile) {
58
72
  return Boolean(file.history[0]?.endsWith('.mdx'));
59
73
  }
74
+
75
+ /**
76
+ * Check if an ESTree entry is `frontmatter.*.VARIABLE`.
77
+ * If it is, return the variable path (i.e. `["*", ..., "VARIABLE"]`) minus the `frontmatter` prefix.
78
+ */
79
+ function getMdxFrontmatterVariablePath(node: MdxTextExpression): string[] | Error {
80
+ if (!node.data?.estree || node.data.estree.body.length !== 1) return new Error();
81
+
82
+ const statement = node.data.estree.body[0];
83
+
84
+ // Check for "[ANYTHING].[ANYTHING]".
85
+ if (statement?.type !== 'ExpressionStatement' || statement.expression.type !== 'MemberExpression')
86
+ return new Error();
87
+
88
+ let expression: Expression | Super = statement.expression;
89
+ const expressionPath: string[] = [];
90
+
91
+ // Traverse the expression, collecting the variable path.
92
+ while (
93
+ expression.type === 'MemberExpression' &&
94
+ expression.property.type === (expression.computed ? 'Literal' : 'Identifier')
95
+ ) {
96
+ expressionPath.push(
97
+ expression.property.type === 'Literal'
98
+ ? String(expression.property.value)
99
+ : expression.property.name
100
+ );
101
+
102
+ expression = expression.object;
103
+ }
104
+
105
+ // Check for "frontmatter.[ANYTHING]".
106
+ if (expression.type !== 'Identifier' || expression.name !== 'frontmatter') return new Error();
107
+
108
+ return expressionPath.reverse();
109
+ }
110
+
111
+ function getMdxFrontmatterVariableValue(astroData: MarkdownAstroData, path: string[]) {
112
+ let value: MdxFrontmatterVariableValue = astroData.frontmatter;
113
+
114
+ for (const key of path) {
115
+ if (!value[key]) return undefined;
116
+
117
+ value = value[key];
118
+ }
119
+
120
+ return value;
121
+ }
122
+
123
+ function isMdxTextExpression(node: Node): node is MdxTextExpression {
124
+ return node.type === 'mdxTextExpression';
125
+ }
126
+
127
+ type MdxFrontmatterVariableValue =
128
+ MarkdownAstroData['frontmatter'][keyof MarkdownAstroData['frontmatter']];