From c95b81dd3d86f003009ba607b4d46f26f0111d1d Mon Sep 17 00:00:00 2001 From: Mykola Bilochub Date: Tue, 14 May 2019 18:51:31 +0300 Subject: [PATCH] fix(markdown): correctly determine count of backticks in inline code (#6110) --- CHANGELOG.unreleased.md | 26 ++++++++++++++++ src/common/util.js | 30 +++++++++++++++++++ src/language-markdown/printer-markdown.js | 7 +++-- .../__snapshots__/jsfmt.spec.js.snap | 8 +++++ tests/markdown_inlineCode/backtick.md | 4 +++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 14ac7de6..ac954688 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -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. + + +````md + +``` 3 ``22`` `1` ``` + +`` 2 ```123``` `1` `` + + +` 3 ``22`` `1` ` + +` 2 ```123``` `1` ` + + +``` 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 diff --git a/src/common/util.js b/src/common/util.js index ae40a448..10c0a81b 100644 --- a/src/common/util.js +++ b/src/common/util.js @@ -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, diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index 9b7ba4b8..b3fbc1eb 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -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]); } diff --git a/tests/markdown_inlineCode/__snapshots__/jsfmt.spec.js.snap b/tests/markdown_inlineCode/__snapshots__/jsfmt.spec.js.snap index cb9edd40..3d82ebce 100644 --- a/tests/markdown_inlineCode/__snapshots__/jsfmt.spec.js.snap +++ b/tests/markdown_inlineCode/__snapshots__/jsfmt.spec.js.snap @@ -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\` \`\` + ================================================================================ `; diff --git a/tests/markdown_inlineCode/backtick.md b/tests/markdown_inlineCode/backtick.md index 0d5e9ab9..7af55fca 100644 --- a/tests/markdown_inlineCode/backtick.md +++ b/tests/markdown_inlineCode/backtick.md @@ -7,3 +7,7 @@ ``34` `` `` ```123``` `` + +``` 3 ``22`` `1` ``` + +`` 2 ```123``` `1` ``