Skip to content

Commit 4300b56

Browse files
authored
Merge pull request #82 from ony3000/fix-markdown
Leave Prettier's output as is for code blocks embedded in markdown and mdx
2 parents e190f16 + 8c127a0 commit 4300b56

30 files changed

+1239
-0
lines changed

src/packages/v2-plugin/parsers.ts

+30
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { parsers as babelParsers } from 'prettier/parser-babel';
55
import { parsers as htmlParsers } from 'prettier/parser-html';
66
import { parsers as typescriptParsers } from 'prettier/parser-typescript';
77

8+
const EOL = '\n';
9+
810
const addon = {
911
parseBabel: (text: string, options: ParserOptions) =>
1012
babelParsers.babel.parse(text, { babel: babelParsers.babel }, options),
@@ -25,6 +27,34 @@ function transformParser(
2527
parsers: { [parserName: string]: Parser },
2628
options: ParserOptions & ThisPluginOptions,
2729
): FormattedTextAST => {
30+
if (options.parentParser === 'markdown' || options.parentParser === 'mdx') {
31+
let codeblockStart = '```';
32+
const codeblockEnd = '```';
33+
34+
if (options.parser === 'babel') {
35+
codeblockStart = '```jsx';
36+
} else if (options.parser === 'typescript') {
37+
codeblockStart = '```tsx';
38+
}
39+
40+
const formattedCodeblock = format(`${codeblockStart}${EOL}${text}${EOL}${codeblockEnd}`, {
41+
...options,
42+
plugins: [],
43+
rangeEnd: Infinity,
44+
endOfLine: 'lf',
45+
parser: options.parentParser,
46+
parentParser: undefined,
47+
});
48+
const formattedText = formattedCodeblock
49+
.trim()
50+
.slice(`${codeblockStart}${EOL}`.length, -`${EOL}${codeblockEnd}`.length);
51+
52+
return {
53+
type: 'FormattedText',
54+
body: formattedText,
55+
};
56+
}
57+
2858
const plugins = options.plugins.filter((plugin) => typeof plugin !== 'string') as Plugin[];
2959

3060
let languageImplementedPlugin: Plugin | undefined;

src/packages/v3-plugin/parsers.ts

+33
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { parsers as babelParsers } from 'prettier/plugins/babel';
55
import { parsers as htmlParsers } from 'prettier/plugins/html';
66
import { parsers as typescriptParsers } from 'prettier/plugins/typescript';
77

8+
const EOL = '\n';
9+
810
const addon = {
911
parseBabel: (text: string, options: ParserOptions) => babelParsers.babel.parse(text, options),
1012
parseTypescript: (text: string, options: ParserOptions) =>
@@ -23,6 +25,37 @@ function transformParser(
2325
text: string,
2426
options: ParserOptions & ThisPluginOptions,
2527
): Promise<FormattedTextAST> => {
28+
if (options.parentParser === 'markdown' || options.parentParser === 'mdx') {
29+
let codeblockStart = '```';
30+
const codeblockEnd = '```';
31+
32+
if (options.parser === 'babel') {
33+
codeblockStart = '```jsx';
34+
} else if (options.parser === 'typescript') {
35+
codeblockStart = '```tsx';
36+
}
37+
38+
const formattedCodeblock = await format(
39+
`${codeblockStart}${EOL}${text}${EOL}${codeblockEnd}`,
40+
{
41+
...options,
42+
plugins: [],
43+
rangeEnd: Infinity,
44+
endOfLine: 'lf',
45+
parser: options.parentParser,
46+
parentParser: undefined,
47+
},
48+
);
49+
const formattedText = formattedCodeblock
50+
.trim()
51+
.slice(`${codeblockStart}${EOL}`.length, -`${EOL}${codeblockEnd}`.length);
52+
53+
return {
54+
type: 'FormattedText',
55+
body: formattedText,
56+
};
57+
}
58+
2659
const plugins = options.plugins.filter((plugin) => typeof plugin !== 'string') as Plugin[];
2760

2861
let languageImplementedPlugin: Plugin | undefined;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`'(1) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
4+
"\`\`\`jsx
5+
<div />
6+
\`\`\`
7+
"
8+
`;
9+
10+
exports[`'(2) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
11+
"\`\`\`jsx
12+
import foo from "foo";
13+
14+
<div />;
15+
\`\`\`
16+
"
17+
`;
18+
19+
exports[`'(3) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
20+
"\`\`\`jsx
21+
export function Foo({ children }) {
22+
return (
23+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
24+
{children}
25+
</div>
26+
);
27+
}
28+
\`\`\`
29+
"
30+
`;
31+
32+
exports[`'(4) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
33+
"\`\`\`tsx
34+
<div />
35+
\`\`\`
36+
"
37+
`;
38+
39+
exports[`'(5) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
40+
"\`\`\`tsx
41+
import foo from "foo";
42+
43+
<div />;
44+
\`\`\`
45+
"
46+
`;
47+
48+
exports[`'(6) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
49+
"\`\`\`tsx
50+
export function Foo({ children }) {
51+
return (
52+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
53+
{children}
54+
</div>
55+
);
56+
}
57+
\`\`\`
58+
"
59+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`'(1) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
4+
"\`\`\`jsx
5+
<div />
6+
\`\`\`
7+
"
8+
`;
9+
10+
exports[`'(2) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
11+
"\`\`\`jsx
12+
import foo from "foo";
13+
14+
<div />;
15+
\`\`\`
16+
"
17+
`;
18+
19+
exports[`'(3) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
20+
"\`\`\`jsx
21+
export function Foo({ children }) {
22+
return (
23+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
24+
{children}
25+
</div>
26+
);
27+
}
28+
\`\`\`
29+
"
30+
`;
31+
32+
exports[`'(4) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
33+
"\`\`\`tsx
34+
<div />
35+
\`\`\`
36+
"
37+
`;
38+
39+
exports[`'(5) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
40+
"\`\`\`tsx
41+
import foo from "foo";
42+
43+
<div />;
44+
\`\`\`
45+
"
46+
`;
47+
48+
exports[`'(6) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
49+
"\`\`\`tsx
50+
export function Foo({ children }) {
51+
return (
52+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
53+
{children}
54+
</div>
55+
);
56+
}
57+
\`\`\`
58+
"
59+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`'(1) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
4+
"\`\`\`jsx
5+
<div />
6+
\`\`\`
7+
"
8+
`;
9+
10+
exports[`'(2) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
11+
"\`\`\`jsx
12+
import foo from "foo";
13+
14+
<div />;
15+
\`\`\`
16+
"
17+
`;
18+
19+
exports[`'(3) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
20+
"\`\`\`jsx
21+
export function Foo({ children }) {
22+
return (
23+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
24+
{children}
25+
</div>
26+
);
27+
}
28+
\`\`\`
29+
"
30+
`;
31+
32+
exports[`'(4) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
33+
"\`\`\`tsx
34+
<div />
35+
\`\`\`
36+
"
37+
`;
38+
39+
exports[`'(5) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
40+
"\`\`\`tsx
41+
import foo from "foo";
42+
43+
<div />;
44+
\`\`\`
45+
"
46+
`;
47+
48+
exports[`'(6) This plugin doesn\\'t support markdown parser, so it leaves Prettier\\'s output as is.' > expectation 1`] = `
49+
"\`\`\`tsx
50+
export function Foo({ children }) {
51+
return (
52+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
53+
{children}
54+
</div>
55+
);
56+
}
57+
\`\`\`
58+
"
59+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { baseOptions } from 'test-settings';
2+
3+
import { thisPlugin, testSnapshotEach } from '../../adaptor';
4+
import { fixtures } from './fixtures';
5+
6+
const options = {
7+
...baseOptions,
8+
plugins: [thisPlugin],
9+
parser: 'markdown',
10+
endingPosition: 'absolute',
11+
};
12+
13+
testSnapshotEach(fixtures, options);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import type { Fixture } from 'test-settings';
2+
3+
export const fixtures: Omit<Fixture, 'output'>[] = [
4+
{
5+
name: "(1) This plugin doesn't support markdown parser, so it leaves Prettier's output as is.",
6+
input: `
7+
\`\`\`jsx
8+
<div />;
9+
\`\`\`
10+
`,
11+
options: {},
12+
},
13+
{
14+
name: "(2) This plugin doesn't support markdown parser, so it leaves Prettier's output as is.",
15+
input: `
16+
\`\`\`jsx
17+
import foo from 'foo'
18+
19+
<div />
20+
\`\`\`
21+
`,
22+
options: {},
23+
},
24+
{
25+
name: "(3) This plugin doesn't support markdown parser, so it leaves Prettier's output as is.",
26+
input: `
27+
\`\`\`jsx
28+
export function Foo({ children }) {
29+
return (
30+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
31+
{children}
32+
</div>
33+
);
34+
}
35+
\`\`\`
36+
`,
37+
options: {
38+
printWidth: 60,
39+
},
40+
},
41+
{
42+
name: "(4) This plugin doesn't support markdown parser, so it leaves Prettier's output as is.",
43+
input: `
44+
\`\`\`tsx
45+
<div />;
46+
\`\`\`
47+
`,
48+
options: {},
49+
},
50+
{
51+
name: "(5) This plugin doesn't support markdown parser, so it leaves Prettier's output as is.",
52+
input: `
53+
\`\`\`tsx
54+
import foo from 'foo'
55+
56+
<div />
57+
\`\`\`
58+
`,
59+
options: {},
60+
},
61+
{
62+
name: "(6) This plugin doesn't support markdown parser, so it leaves Prettier's output as is.",
63+
input: `
64+
\`\`\`tsx
65+
export function Foo({ children }) {
66+
return (
67+
<div className="lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque">
68+
{children}
69+
</div>
70+
);
71+
}
72+
\`\`\`
73+
`,
74+
options: {
75+
printWidth: 60,
76+
},
77+
},
78+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { baseOptions } from 'test-settings';
2+
3+
import { thisPlugin, testSnapshotEach } from '../../adaptor';
4+
import { fixtures } from './fixtures';
5+
6+
const options = {
7+
...baseOptions,
8+
plugins: [thisPlugin],
9+
parser: 'markdown',
10+
endingPosition: 'absolute-with-indent',
11+
};
12+
13+
testSnapshotEach(fixtures, options);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { baseOptions } from 'test-settings';
2+
3+
import { thisPlugin, testSnapshotEach } from '../../adaptor';
4+
import { fixtures } from './fixtures';
5+
6+
const options = {
7+
...baseOptions,
8+
plugins: [thisPlugin],
9+
parser: 'markdown',
10+
endingPosition: 'relative',
11+
};
12+
13+
testSnapshotEach(fixtures, options);

0 commit comments

Comments
 (0)