Skip to content

Commit 8b495a3

Browse files
authored
Fix error docgen script for updated error data (withastro#2905)
1 parent 33d8072 commit 8b495a3

File tree

6 files changed

+257
-269
lines changed

6 files changed

+257
-269
lines changed

integrations/astro-asides.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import remarkDirective from 'remark-directive';
44
import type * as unified from 'unified';
55
import { remove } from 'unist-util-remove';
66
import { visit } from 'unist-util-visit';
7-
import { isMDXFile } from './utils/isMDX';
87
import { makeComponentNode } from './utils/makeComponentNode';
98

109
const AsideTagname = 'AutoImportedAside';
@@ -36,7 +35,7 @@ export const asideAutoImport: Record<string, [string, string][]> = {
3635
function remarkAsides(): unified.Plugin<[], mdast.Root> {
3736
const variants = new Set(['note', 'tip', 'caution', 'danger']);
3837

39-
const transformer: unified.Transformer<mdast.Root> = (tree, file) => {
38+
const transformer: unified.Transformer<mdast.Root> = (tree) => {
4039
// @ts-expect-error Possibly infinite type instantiation we can’t do anything about.
4140
visit(tree, (node, index, parent) => {
4241
if (!parent || index === null || node.type !== 'containerDirective') return;
@@ -60,7 +59,7 @@ function remarkAsides(): unified.Plugin<[], mdast.Root> {
6059
// Replace this node with the aside component it represents.
6160
parent.children[index] = makeComponentNode(
6261
AsideTagname,
63-
{ mdx: isMDXFile(file), attributes: { type, title } },
62+
{ attributes: { type, title } },
6463
...node.children
6564
);
6665
});

integrations/astro-code-snippets.ts

+66-77
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { BlockContent, Parent, Root } from 'mdast';
33
import type { Plugin, Transformer } from 'unified';
44
import { visit } from 'unist-util-visit';
55
import type { BuildVisitor } from 'unist-util-visit/complex-types';
6-
import { isMDXFile } from './utils/isMDX';
76
import { makeComponentNode } from './utils/makeComponentNode';
87

98
const CodeSnippetTagname = 'AutoImportedCodeSnippet';
@@ -59,88 +58,78 @@ declare module 'mdast' {
5958
}
6059

6160
export function remarkCodeSnippets(): Plugin<[], Root> {
62-
const makeVisitor =
63-
(format: 'md' | 'mdx'): BuildVisitor<Root, 'code'> =>
64-
(code, index, parent) => {
65-
if (index === null || parent === null) return;
66-
const isMDX = format === 'mdx';
67-
68-
// Parse optional meta information after the opening code fence,
69-
// trying to get a meta title and an array of highlighted lines
70-
const { title: metaTitle, lineMarkings, inlineMarkings } = parseMeta(code.meta || '');
71-
let title = metaTitle;
72-
73-
// Preprocess the code
74-
const { preprocessedCode, extractedFileName, removedLineIndex, removedLineCount } =
75-
preprocessCode(
76-
code.value,
77-
code.lang || '',
78-
// Only try to extract a file name from the code if no meta title was found above
79-
title === undefined
80-
);
81-
code.value = preprocessedCode;
82-
if (extractedFileName) {
83-
title = extractedFileName;
84-
}
85-
86-
// If there was no title in the meta information or in the code, check if the previous
87-
// Markdown paragraph contains a file name that we can use as a title
88-
if (title === undefined && index > 0) {
89-
// Check the previous node to see if it matches our requirements
90-
const prev = parent.children[index - 1];
91-
const strongContent =
92-
// The previous node must be a paragraph...
93-
prev.type === 'paragraph' &&
94-
// ...it must contain exactly one child with strong formatting...
95-
prev.children.length === 1 &&
96-
prev.children[0].type === 'strong' &&
97-
// ...this child must also contain exactly one child
98-
prev.children[0].children.length === 1 &&
99-
// ...which is the result of this expression
100-
prev.children[0].children[0];
101-
102-
// Require the strong content to be either raw text or inline code and retrieve its value
103-
const prevParaStrongTextValue =
104-
strongContent && strongContent.type === 'text' && strongContent.value;
105-
const prevParaStrongCodeValue =
106-
strongContent && strongContent.type === 'inlineCode' && strongContent.value;
107-
const potentialFileName = prevParaStrongTextValue || prevParaStrongCodeValue;
61+
const visitor: BuildVisitor<Root, 'code'> = (code, index, parent) => {
62+
if (index === null || parent === null) return;
63+
64+
// Parse optional meta information after the opening code fence,
65+
// trying to get a meta title and an array of highlighted lines
66+
const { title: metaTitle, lineMarkings, inlineMarkings } = parseMeta(code.meta || '');
67+
let title = metaTitle;
68+
69+
// Preprocess the code
70+
const { preprocessedCode, extractedFileName, removedLineIndex, removedLineCount } =
71+
preprocessCode(
72+
code.value,
73+
code.lang || '',
74+
// Only try to extract a file name from the code if no meta title was found above
75+
title === undefined
76+
);
77+
code.value = preprocessedCode;
78+
if (extractedFileName) {
79+
title = extractedFileName;
80+
}
10881

109-
// Check if it's a file name
110-
const matches = potentialFileName && FileNameCommentRegExp.exec(`// ${potentialFileName}`);
111-
if (matches) {
112-
// Yes, store the file name and replace the paragraph with an empty node
113-
title = matches[2];
114-
parent.children[index - 1] = {
115-
type: 'html',
116-
value: '',
117-
};
118-
}
82+
// If there was no title in the meta information or in the code, check if the previous
83+
// Markdown paragraph contains a file name that we can use as a title
84+
if (title === undefined && index > 0) {
85+
// Check the previous node to see if it matches our requirements
86+
const prev = parent.children[index - 1];
87+
const strongContent =
88+
// The previous node must be a paragraph...
89+
prev.type === 'paragraph' &&
90+
// ...it must contain exactly one child with strong formatting...
91+
prev.children.length === 1 &&
92+
prev.children[0].type === 'strong' &&
93+
// ...this child must also contain exactly one child
94+
prev.children[0].children.length === 1 &&
95+
// ...which is the result of this expression
96+
prev.children[0].children[0];
97+
98+
// Require the strong content to be either raw text or inline code and retrieve its value
99+
const prevParaStrongTextValue =
100+
strongContent && strongContent.type === 'text' && strongContent.value;
101+
const prevParaStrongCodeValue =
102+
strongContent && strongContent.type === 'inlineCode' && strongContent.value;
103+
const potentialFileName = prevParaStrongTextValue || prevParaStrongCodeValue;
104+
105+
// Check if it's a file name
106+
const matches = potentialFileName && FileNameCommentRegExp.exec(`// ${potentialFileName}`);
107+
if (matches) {
108+
// Yes, store the file name and replace the paragraph with an empty node
109+
title = matches[2];
110+
parent.children[index - 1] = {
111+
type: 'html',
112+
value: '',
113+
};
119114
}
115+
}
120116

121-
const attributes = {
122-
lang: code.lang,
123-
title: encodeMarkdownStringProp(title),
124-
removedLineIndex,
125-
removedLineCount,
126-
lineMarkings: encodeMarkdownStringArrayProp(lineMarkings),
127-
inlineMarkings: encodeMarkdownStringArrayProp(inlineMarkings),
128-
};
129-
130-
const codeSnippetWrapper = makeComponentNode(
131-
CodeSnippetTagname,
132-
{ mdx: isMDX, attributes },
133-
code
134-
);
135-
136-
parent.children.splice(index, 1, codeSnippetWrapper);
117+
const attributes = {
118+
lang: code.lang,
119+
title: encodeMarkdownStringProp(title),
120+
removedLineIndex,
121+
removedLineCount,
122+
lineMarkings: encodeMarkdownStringArrayProp(lineMarkings),
123+
inlineMarkings: encodeMarkdownStringArrayProp(inlineMarkings),
137124
};
138125

139-
const mdVisitor = makeVisitor('md');
140-
const mdxVisitor = makeVisitor('mdx');
126+
const codeSnippetWrapper = makeComponentNode(CodeSnippetTagname, { attributes }, code);
127+
128+
parent.children.splice(index, 1, codeSnippetWrapper);
129+
};
141130

142-
const transformer: Transformer<Root> = (tree, file) => {
143-
visit(tree, 'code', isMDXFile(file) ? mdxVisitor : mdVisitor);
131+
const transformer: Transformer<Root> = (tree) => {
132+
visit(tree, 'code', visitor);
144133
};
145134

146135
return function attacher() {
+15-37
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,33 @@
11
import type { BlockContent } from 'mdast';
2+
import type { MdxJsxAttribute, MdxJsxFlowElement } from 'mdast-util-mdx-jsx';
23

34
interface NodeProps {
45
attributes?: Record<string, string | boolean | number | undefined | null>;
56
}
67

7-
function makeAFMDComponentNode(
8-
hName: string,
9-
{ attributes }: NodeProps,
10-
...children: BlockContent[]
11-
) {
12-
return {
13-
type: 'afmdJsxFlowElement',
14-
data: { hName, hProperties: attributes },
15-
children,
16-
};
17-
}
18-
19-
export function makeMDXComponentNode(
8+
/**
9+
* Create AST node for a custom component injection.
10+
*
11+
* @example
12+
* makeComponentNode('MyComponent', { prop: 'val' }, h('p', 'Paragraph inside component'))
13+
*
14+
*/
15+
export function makeComponentNode(
2016
name: string,
2117
{ attributes = {} }: NodeProps = {},
2218
...children: BlockContent[]
23-
) {
19+
): MdxJsxFlowElement {
2420
return {
2521
type: 'mdxJsxFlowElement',
2622
name,
2723
attributes: Object.entries(attributes)
2824
// Filter out non-truthy attributes to avoid empty attrs being parsed as `true`.
2925
.filter(([_k, v]) => v !== false && Boolean(v))
30-
.map(([name, value]) => ({ type: 'mdxJsxAttribute', name, value })),
26+
.map(([name, value]) => ({
27+
type: 'mdxJsxAttribute',
28+
name,
29+
value: value as MdxJsxAttribute['value'],
30+
})),
3131
children,
3232
};
3333
}
34-
35-
interface ComponentNodeProps extends NodeProps {
36-
mdx: boolean;
37-
}
38-
39-
/**
40-
* Create AST node for a custom component injection. The data type differs
41-
* depending on if you need to inject into a MDX or Astro-flavored Markdown
42-
* context.
43-
*
44-
* @example
45-
* makeComponentNode('MyComponent', { mdx: true }, h('p', 'Paragraph inside component'))
46-
*
47-
*/
48-
export function makeComponentNode(
49-
tagName: string,
50-
{ mdx, ...opts }: ComponentNodeProps,
51-
...children: BlockContent[]
52-
) {
53-
const factory = mdx ? makeMDXComponentNode : makeAFMDComponentNode;
54-
return factory(tagName, opts, ...children);
55-
}

package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"@11ty/eleventy-fetch": "^3.0.0",
3333
"@actions/core": "^1.9.0",
3434
"@algolia/client-search": "^4.14.2",
35-
"@astrojs/mdx": "^0.17.2",
35+
"@astrojs/mdx": "^0.18.2",
3636
"@astrojs/preact": "^2.0.3",
3737
"@astrojs/sitemap": "1.0.1",
3838
"@babel/core": "^7.18.10",
@@ -46,7 +46,7 @@
4646
"@types/node": "^18.6.4",
4747
"@typescript-eslint/eslint-plugin": "^5.46.1",
4848
"@typescript-eslint/parser": "^5.46.1",
49-
"astro": "^2.0.17",
49+
"astro": "^2.1.4",
5050
"astro-auto-import": "^0.2.1",
5151
"astro-eslint-parser": "^0.9.2",
5252
"astro-og-canvas": "^0.1.7",
@@ -66,6 +66,7 @@
6666
"htmlparser2": "^7.2.0",
6767
"kleur": "^4.1.5",
6868
"mdast-util-from-markdown": "^1.2.0",
69+
"mdast-util-mdx-jsx": "^2.1.2",
6970
"mdast-util-to-hast": "^12.2.4",
7071
"mdast-util-to-string": "^3.1.1",
7172
"micromark-util-character": "^1.1.0",
@@ -82,8 +83,8 @@
8283
"remark": "^14.0.2",
8384
"remark-directive": "^2.0.1",
8485
"simple-git": "^3.11.0",
85-
"tsm": "^2.2.2",
86-
"typescript": "^4.7.4",
86+
"tsm": "^2.3.0",
87+
"typescript": "^5.0.2",
8788
"unified": "^10.1.2",
8889
"unist-util-remove": "^3.1.0",
8990
"unist-util-visit": "^4.1.0",

0 commit comments

Comments
 (0)