fix(markdown): correctly determine count of backticks in inline code (#6110)

master
Mykola Bilochub 2019-05-14 18:51:31 +03:00 committed by Lucas Duailibe
parent 48d542ec1e
commit c95b81dd3d
5 changed files with 73 additions and 2 deletions

View File

@ -126,11 +126,37 @@ const v = /** @type{string} */ value;
const v = /** @type{string} */ (value);
```
### Markdown: correctly determine count of backticks in inline code ([#6110] by [@belochub])
By the CommonMark spec, it is required to 'choose a string of `n` backtick characters as delimiters, where the code does not contain any strings of exactly `n` backtick characters.'
This changes the method of finding the required count of backticks from using 2 backticks, when there is a backtick string of length 1 inside the inline code block, and using 1 backtick in all other cases, to finding a minimum length backtick string that can correctly be used as a delimiter.
<!-- prettier-ignore -->
````md
<!-- Input -->
``` 3 ``22`` `1` ```
`` 2 ```123``` `1` ``
<!-- Output (Prettier stable) -->
` 3 ``22`` `1` `
` 2 ```123``` `1` `
<!-- Output (Prettier master) -->
``` 3 ``22`` `1` ```
`` 2 ```123``` `1` ``
````
[#5979]: https://github.com/prettier/prettier/pull/5979
[#6115]: https://github.com/prettier/prettier/pull/6115
[#6106]: https://github.com/prettier/prettier/pull/6106
[#6116]: https://github.com/prettier/prettier/pull/6116
[#6110]: https://github.com/prettier/prettier/pull/6110
[@jridgewell]: https://github.com/jridgewell
[@jwbay]: https://github.com/jwbay
[@brainkim]: https://github.com/brainkim
[@sosukesuzuki]: https://github.com/sosukesuzuki
[@belochub]: https://github.com/belochub

View File

@ -578,6 +578,35 @@ function getMaxContinuousCount(str, target) {
);
}
function getMinNotPresentContinuousCount(str, target) {
const matches = str.match(
new RegExp(`(${escapeStringRegexp(target)})+`, "g")
);
if (matches === null) {
return 0;
}
const countPresent = new Map();
let max = 0;
for (const match of matches) {
const count = match.length / target.length;
countPresent.set(count, true);
if (count > max) {
max = count;
}
}
for (let i = 1; i < max; i++) {
if (!countPresent.get(i)) {
return i;
}
}
return max + 1;
}
function getStringWidth(text) {
if (!text) {
return 0;
@ -681,6 +710,7 @@ module.exports = {
replaceEndOfLineWith,
getStringWidth,
getMaxContinuousCount,
getMinNotPresentContinuousCount,
getPrecedence,
shouldFlatten,
isBitwiseOperator,

View File

@ -130,8 +130,11 @@ function genericPrint(path, options, print) {
case "delete":
return concat(["~~", printChildren(path, options, print), "~~"]);
case "inlineCode": {
const backtickCount = privateUtil.getMaxContinuousCount(node.value, "`");
const style = backtickCount === 1 ? "``" : "`";
const backtickCount = privateUtil.getMinNotPresentContinuousCount(
node.value,
"`"
);
const style = "`".repeat(backtickCount || 1);
const gap = backtickCount ? " " : "";
return concat([style, gap, node.value, gap, style]);
}

View File

@ -17,6 +17,10 @@ proseWrap: "always"
\`\` \`\`\`123\`\`\` \`\`
\`\`\` 3 \`\`22\`\` \`1\` \`\`\`
\`\` 2 \`\`\`123\`\`\` \`1\` \`\`
=====================================output=====================================
\`\` \`123\` \`\`
@ -28,6 +32,10 @@ proseWrap: "always"
\` \`\`\`123\`\`\` \`
\`\`\` 3 \`\`22\`\` \`1\` \`\`\`
\`\` 2 \`\`\`123\`\`\` \`1\` \`\`
================================================================================
`;

View File

@ -7,3 +7,7 @@
``34` ``
`` ```123``` ``
``` 3 ``22`` `1` ```
`` 2 ```123``` `1` ``