Fix adjacent markdown syntax in blockquote (#16596)
Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
1 parent
36b346c9f4
commit
91c563e323
5 files changed
+641
-16
No files matched your search
@@ -0,0 +1,35 @@
|
||||
#### Fix adjacent markdown syntax in blockquote (#16596 by @fiji-flo)
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```md
|
||||
<!-- Input -->
|
||||
> `x`
|
||||
> `y`
|
||||
|
||||
> _x_
|
||||
> _y_
|
||||
|
||||
> [foo](http://foo)
|
||||
> [bar](http://bar)
|
||||
|
||||
> `this` behaves
|
||||
> `correctly`
|
||||
|
||||
<!-- Prettier stable -->
|
||||
> `x` > `y`
|
||||
|
||||
> _x_ > _y_
|
||||
|
||||
> [foo](http://foo) > [bar](http://bar)
|
||||
|
||||
> `this` behaves `correctly`
|
||||
|
||||
<!-- Prettier main -->
|
||||
> `x` `y`
|
||||
|
||||
> _x_ _y_
|
||||
|
||||
> [foo](http://foo) [bar](http://bar)
|
||||
|
||||
> `this` behaves `correctly`
|
||||
```
|
||||
@@ -2,7 +2,8 @@ import htmlWhitespaceUtils from "../utils/html-whitespace-utils.js";
|
||||
import { getOrderedListItemInfo, mapAst, splitText } from "./utils.js";
|
||||
|
||||
// 0x0 ~ 0x10ffff
|
||||
const isSingleCharRegex = /^.$/su;
|
||||
const isSingleCharRegex = /^\\?.$/su;
|
||||
const isNewLineBlockquoteRegex = /^\n *>[ >]*$/u;
|
||||
|
||||
function preprocess(ast, options) {
|
||||
ast = restoreUnescapedCharacter(ast, options);
|
||||
@@ -14,21 +15,33 @@ function preprocess(ast, options) {
|
||||
}
|
||||
|
||||
function restoreUnescapedCharacter(ast, options) {
|
||||
return mapAst(ast, (node) =>
|
||||
node.type !== "text" ||
|
||||
node.value === "*" ||
|
||||
node.value === "_" || // handle these cases in printer
|
||||
!isSingleCharRegex.test(node.value) ||
|
||||
node.position.end.offset - node.position.start.offset === node.value.length
|
||||
? node
|
||||
: {
|
||||
...node,
|
||||
value: options.originalText.slice(
|
||||
node.position.start.offset,
|
||||
node.position.end.offset,
|
||||
),
|
||||
},
|
||||
);
|
||||
return mapAst(ast, (node) => {
|
||||
if (node.type !== "text") {
|
||||
return node;
|
||||
}
|
||||
|
||||
const { value } = node;
|
||||
|
||||
if (
|
||||
value === "*" ||
|
||||
value === "_" || // handle these cases in printer
|
||||
!isSingleCharRegex.test(value) ||
|
||||
node.position.end.offset - node.position.start.offset === value.length
|
||||
) {
|
||||
return node;
|
||||
}
|
||||
|
||||
const text = options.originalText.slice(
|
||||
node.position.start.offset,
|
||||
node.position.end.offset,
|
||||
);
|
||||
|
||||
if (isNewLineBlockquoteRegex.test(text)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return { ...node, value: text };
|
||||
});
|
||||
}
|
||||
|
||||
function mergeChildren(ast, shouldMerge, mergeNode) {
|
||||
|
||||
@@ -43,6 +43,90 @@ proseWrap: "always"
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`code.md - {"proseWrap":"never"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "never"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> NOTE: To use \`unobtrusive\`, \`unobtrusive/import\`, \`unobtrusive/react\`, and \`unobtrusive/flowtype\` together, your eslint config would look like this:
|
||||
>\`\`\`json
|
||||
>{
|
||||
> "extends": [
|
||||
> "unobtrusive",
|
||||
> "unobtrusive/import",
|
||||
> "unobtrusive/react",
|
||||
> "unobtrusive/flowtype"
|
||||
> ],
|
||||
> "env": {
|
||||
> "browser": true
|
||||
> }
|
||||
>}
|
||||
>\`\`\`
|
||||
|
||||
=====================================output=====================================
|
||||
> NOTE: To use \`unobtrusive\`, \`unobtrusive/import\`, \`unobtrusive/react\`, and \`unobtrusive/flowtype\` together, your eslint config would look like this:
|
||||
>
|
||||
> \`\`\`json
|
||||
> {
|
||||
> "extends": [
|
||||
> "unobtrusive",
|
||||
> "unobtrusive/import",
|
||||
> "unobtrusive/react",
|
||||
> "unobtrusive/flowtype"
|
||||
> ],
|
||||
> "env": {
|
||||
> "browser": true
|
||||
> }
|
||||
> }
|
||||
> \`\`\`
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`code.md - {"proseWrap":"preserve"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "preserve"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> NOTE: To use \`unobtrusive\`, \`unobtrusive/import\`, \`unobtrusive/react\`, and \`unobtrusive/flowtype\` together, your eslint config would look like this:
|
||||
>\`\`\`json
|
||||
>{
|
||||
> "extends": [
|
||||
> "unobtrusive",
|
||||
> "unobtrusive/import",
|
||||
> "unobtrusive/react",
|
||||
> "unobtrusive/flowtype"
|
||||
> ],
|
||||
> "env": {
|
||||
> "browser": true
|
||||
> }
|
||||
>}
|
||||
>\`\`\`
|
||||
|
||||
=====================================output=====================================
|
||||
> NOTE: To use \`unobtrusive\`, \`unobtrusive/import\`, \`unobtrusive/react\`, and \`unobtrusive/flowtype\` together, your eslint config would look like this:
|
||||
>
|
||||
> \`\`\`json
|
||||
> {
|
||||
> "extends": [
|
||||
> "unobtrusive",
|
||||
> "unobtrusive/import",
|
||||
> "unobtrusive/react",
|
||||
> "unobtrusive/flowtype"
|
||||
> ],
|
||||
> "env": {
|
||||
> "browser": true
|
||||
> }
|
||||
> }
|
||||
> \`\`\`
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`ignore-code.md - {"proseWrap":"always"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
@@ -158,6 +242,236 @@ proseWrap: "always"
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`ignore-code.md - {"proseWrap":"never"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "never"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> \`\`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> \`\`\`js
|
||||
> ugly ( code ) ;
|
||||
> \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
> - test
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
\`\`\`\`md
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
\`\`\`\`
|
||||
|
||||
> \`\`\`\`md
|
||||
> > \`\`\`md
|
||||
> > <!-- prettier-ignore -->
|
||||
> > - This is a long long
|
||||
> > long long long long
|
||||
> > long long paragraph.
|
||||
> > \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
>
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
>
|
||||
|
||||
> \`\`\`\`js
|
||||
> // prettier-ignore
|
||||
> const x = 1,
|
||||
> b = 2
|
||||
> \`\`\`\`
|
||||
|
||||
=====================================output=====================================
|
||||
> \`\`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> \`\`\`js
|
||||
> ugly ( code ) ;
|
||||
> \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
> - test
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
\`\`\`\`md
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
\`\`\`\`
|
||||
|
||||
> \`\`\`\`md
|
||||
> > \`\`\`md
|
||||
> > <!-- prettier-ignore -->
|
||||
> > - This is a long long
|
||||
> > long long long long
|
||||
> > long long paragraph.
|
||||
> > \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
|
||||
> \`\`\`js
|
||||
> // prettier-ignore
|
||||
> const x = 1,
|
||||
> b = 2
|
||||
> \`\`\`
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`ignore-code.md - {"proseWrap":"preserve"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "preserve"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> \`\`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> \`\`\`js
|
||||
> ugly ( code ) ;
|
||||
> \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
> - test
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
\`\`\`\`md
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
\`\`\`\`
|
||||
|
||||
> \`\`\`\`md
|
||||
> > \`\`\`md
|
||||
> > <!-- prettier-ignore -->
|
||||
> > - This is a long long
|
||||
> > long long long long
|
||||
> > long long paragraph.
|
||||
> > \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
>
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
>
|
||||
|
||||
> \`\`\`\`js
|
||||
> // prettier-ignore
|
||||
> const x = 1,
|
||||
> b = 2
|
||||
> \`\`\`\`
|
||||
|
||||
=====================================output=====================================
|
||||
> \`\`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> \`\`\`js
|
||||
> ugly ( code ) ;
|
||||
> \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
> - test
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
|
||||
\`\`\`\`md
|
||||
> \`\`\`md
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
> \`\`\`
|
||||
\`\`\`\`
|
||||
|
||||
> \`\`\`\`md
|
||||
> > \`\`\`md
|
||||
> > <!-- prettier-ignore -->
|
||||
> > - This is a long long
|
||||
> > long long long long
|
||||
> > long long paragraph.
|
||||
> > \`\`\`
|
||||
> \`\`\`\`
|
||||
|
||||
> <!-- prettier-ignore -->
|
||||
> - This is a long long
|
||||
> long long long long
|
||||
> long long paragraph.
|
||||
|
||||
> \`\`\`js
|
||||
> // prettier-ignore
|
||||
> const x = 1,
|
||||
> b = 2
|
||||
> \`\`\`
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`nested.md - {"proseWrap":"always"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
@@ -173,6 +487,185 @@ proseWrap: "always"
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`nested.md - {"proseWrap":"never"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "never"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
>>> 123
|
||||
|
||||
=====================================output=====================================
|
||||
> > > 123
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`nested.md - {"proseWrap":"preserve"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "preserve"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
>>> 123
|
||||
|
||||
=====================================output=====================================
|
||||
> > > 123
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`notext-end.md - {"proseWrap":"always"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "always"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> [!NOTE]
|
||||
> \`DOOM\`
|
||||
|
||||
> _b_
|
||||
>> \`A\`
|
||||
>> \`B\`
|
||||
|
||||
> *a*
|
||||
>> # foo
|
||||
>> \`a\` > \`b\`
|
||||
|
||||
|
||||
> This is a quote with an italic _across multuple lines
|
||||
> which should just work_. So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
> This is a quote with a link [across multuple lines
|
||||
> which should just work](). So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
=====================================output=====================================
|
||||
> [!NOTE] \`DOOM\`
|
||||
|
||||
> _b_
|
||||
>
|
||||
> > \`A\` \`B\`
|
||||
|
||||
> _a_
|
||||
>
|
||||
> > # foo
|
||||
> >
|
||||
> > \`a\` > \`b\`
|
||||
|
||||
> This is a quote with an italic _across multuple lines which should just work_.
|
||||
> So make sure there is no > if we set proseWrap to \`never\`
|
||||
|
||||
> This is a quote with a link [across multuple lines which should just work]().
|
||||
> So make sure there is no > if we set proseWrap to \`never\`
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`notext-end.md - {"proseWrap":"never"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "never"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> [!NOTE]
|
||||
> \`DOOM\`
|
||||
|
||||
> _b_
|
||||
>> \`A\`
|
||||
>> \`B\`
|
||||
|
||||
> *a*
|
||||
>> # foo
|
||||
>> \`a\` > \`b\`
|
||||
|
||||
|
||||
> This is a quote with an italic _across multuple lines
|
||||
> which should just work_. So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
> This is a quote with a link [across multuple lines
|
||||
> which should just work](). So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
=====================================output=====================================
|
||||
> [!NOTE] \`DOOM\`
|
||||
|
||||
> _b_
|
||||
>
|
||||
> > \`A\` \`B\`
|
||||
|
||||
> _a_
|
||||
>
|
||||
> > # foo
|
||||
> >
|
||||
> > \`a\` > \`b\`
|
||||
|
||||
> This is a quote with an italic _across multuple lines which should just work_. So make sure there is no > if we set proseWrap to \`never\`
|
||||
|
||||
> This is a quote with a link [across multuple lines which should just work](). So make sure there is no > if we set proseWrap to \`never\`
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`notext-end.md - {"proseWrap":"preserve"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "preserve"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> [!NOTE]
|
||||
> \`DOOM\`
|
||||
|
||||
> _b_
|
||||
>> \`A\`
|
||||
>> \`B\`
|
||||
|
||||
> *a*
|
||||
>> # foo
|
||||
>> \`a\` > \`b\`
|
||||
|
||||
|
||||
> This is a quote with an italic _across multuple lines
|
||||
> which should just work_. So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
> This is a quote with a link [across multuple lines
|
||||
> which should just work](). So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
=====================================output=====================================
|
||||
> [!NOTE]
|
||||
> \`DOOM\`
|
||||
|
||||
> _b_
|
||||
>
|
||||
> > \`A\`
|
||||
> > \`B\`
|
||||
|
||||
> _a_
|
||||
>
|
||||
> > # foo
|
||||
> >
|
||||
> > \`a\` > \`b\`
|
||||
|
||||
> This is a quote with an italic _across multuple lines
|
||||
> which should just work_. So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
> This is a quote with a link [across multuple lines
|
||||
> which should just work](). So make sure there is no > if we set
|
||||
> proseWrap to \`never\`
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`paragraph.md - {"proseWrap":"always"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
@@ -191,6 +684,39 @@ proseWrap: "always"
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`paragraph.md - {"proseWrap":"never"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "never"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> This is a long long long long long long long long long long long long long long long paragraph.
|
||||
> This is a long long long long long long long long long long long long long long long paragraph.
|
||||
|
||||
=====================================output=====================================
|
||||
> This is a long long long long long long long long long long long long long long long paragraph. This is a long long long long long long long long long long long long long long long paragraph.
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`paragraph.md - {"proseWrap":"preserve"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "preserve"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> This is a long long long long long long long long long long long long long long long paragraph.
|
||||
> This is a long long long long long long long long long long long long long long long paragraph.
|
||||
|
||||
=====================================output=====================================
|
||||
> This is a long long long long long long long long long long long long long long long paragraph.
|
||||
> This is a long long long long long long long long long long long long long long long paragraph.
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`simple.md - {"proseWrap":"always"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
@@ -205,3 +731,33 @@ proseWrap: "always"
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`simple.md - {"proseWrap":"never"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "never"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> 123
|
||||
|
||||
=====================================output=====================================
|
||||
> 123
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`simple.md - {"proseWrap":"preserve"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "preserve"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
> 123
|
||||
|
||||
=====================================output=====================================
|
||||
> 123
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -1 +1,3 @@
|
||||
runFormatTest(import.meta, ["markdown"], { proseWrap: "always" });
|
||||
runFormatTest(import.meta, ["markdown"], { proseWrap: "preserve" });
|
||||
runFormatTest(import.meta, ["markdown"], { proseWrap: "never" });
|
||||
@@ -0,0 +1,19 @@
|
||||
> [!NOTE]
|
||||
> `DOOM`
|
||||
|
||||
> _b_
|
||||
>> `A`
|
||||
>> `B`
|
||||
|
||||
> *a*
|
||||
>> # foo
|
||||
>> `a` > `b`
|
||||
|
||||
|
||||
> This is a quote with an italic _across multuple lines
|
||||
> which should just work_. So make sure there is no > if we set
|
||||
> proseWrap to `never`
|
||||
|
||||
> This is a quote with a link [across multuple lines
|
||||
> which should just work](). So make sure there is no > if we set
|
||||
> proseWrap to `never`
|
||||
Reference in new issue
Block a user