fix(markdown): preserve leading/trailing newlines in fenced code block (#5038)

master
Ika 2018-09-01 13:35:29 +08:00 committed by GitHub
parent 4ce28d3ef4
commit 165742014a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 3 deletions

View File

@ -6,6 +6,7 @@ const {
builders: { hardline, literalline, concat, markAsRoot },
utils: { mapDoc }
} = require("../doc");
const { getFencedCodeBlockValue } = require("./utils");
function embed(path, print, textToDoc, options) {
const node = path.getValue();
@ -20,7 +21,10 @@ function embed(path, print, textToDoc, options) {
const style = styleUnit.repeat(
Math.max(3, util.getMaxContinuousCount(node.value, styleUnit) + 1)
);
const doc = textToDoc(node.value, { parser });
const doc = textToDoc(
getFencedCodeBlockValue(node, options.originalText),
{ parser }
);
return markAsRoot(
concat([
style,

View File

@ -20,7 +20,7 @@ const {
utils: { mapDoc },
printer: { printDocToString }
} = require("../doc");
const { getOrderedListItemInfo } = require("./utils");
const { getOrderedListItemInfo, getFencedCodeBlockValue } = require("./utils");
const TRAILING_HARDLINE_NODES = ["importExport"];
@ -221,7 +221,10 @@ function genericPrint(path, options, print) {
style,
node.lang || "",
hardline,
join(hardline, node.value.split("\n")),
join(
hardline,
getFencedCodeBlockValue(node, options.originalText).split("\n")
),
hardline,
style
]);

View File

@ -11,6 +11,43 @@ function getOrderedListItemInfo(orderListItem, originalText) {
return { numberText, marker, leadingSpaces };
}
// workaround for https://github.com/remarkjs/remark/issues/351
// leading and trailing newlines are stripped by remark
function getFencedCodeBlockValue(node, originalText) {
const text = originalText.slice(
node.position.start.offset,
node.position.end.offset
);
const leadingSpaceCount = text.match(/^\s*/)[0].length;
const replaceRegex = new RegExp(`^\\s{0,${leadingSpaceCount}}`);
const lineContents = text.split("\n");
const markerStyle = text[leadingSpaceCount]; // ` or ~
const marker = text
.slice(leadingSpaceCount)
.match(new RegExp(`^[${markerStyle}]+`))[0];
// https://spec.commonmark.org/0.28/#example-104: Closing fences may be indented by 0-3 spaces
// https://spec.commonmark.org/0.28/#example-93: The closing code fence must be at least as long as the opening fence
const hasEndMarker = new RegExp(`^\\s{0,3}${marker}`).test(
lineContents[lineContents.length - 1].slice(
getIndent(lineContents.length - 1)
)
);
return lineContents
.slice(1, hasEndMarker ? -1 : undefined)
.map((x, i) => x.slice(getIndent(i + 1)).replace(replaceRegex, ""))
.join("\n");
function getIndent(lineIndex) {
return node.position.indent[lineIndex - 1] - 1;
}
}
module.exports = {
getFencedCodeBlockValue,
getOrderedListItemInfo
};

View File

@ -109,9 +109,11 @@ console.log("hello world!");
\`\`\`\`\`\`\`\`\`\`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\`\`\`\`
\`\`\`js
console.log("hello world!");
\`\`\`
\`\`\`\`
`;
@ -195,6 +197,25 @@ console.log("hello world");
`;
exports[`leading-trailing-newlines.md - markdown-verify 1`] = `
\`\`\`
123
\`\`\`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\`\`\`
123
\`\`\`
`;
exports[`simple.md - markdown-verify 1`] = `
\`\`\`
hello world

View File

@ -0,0 +1,7 @@
```
123
```

View File

@ -1000,6 +1000,7 @@ exports[`example-94.md - markdown-verify 1`] = `
aaa
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\`\`\`\`
\`\`\`
aaa
\`\`\`\`
@ -1028,6 +1029,7 @@ exports[`example-96.md - markdown-verify 1`] = `
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\`\`\`
\`\`\`
`;
@ -2545,6 +2547,7 @@ bar
bar
\`\`\`\`
- baz
+ \`\`\`