fix(multiparser): respect 0-indent markdown-in-js (#3676)

* fix(multiparser): respect 0-indent markdown-in-js

* fix: use literalline for 0-indent

* test: add unexpected case

* fix: 0-indent

* test: add failing test

* refactor: simplify

* fix(doc): literallines respect `ind.root`

* docs: update commands

* fix: what a magic...
master
Ika 2018-01-17 12:52:42 +08:00 committed by GitHub
parent 2dd311d554
commit de6bc4448f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 235 additions and 46 deletions

View File

@ -201,6 +201,22 @@ declare function align(n: number, doc: Doc): Doc;
This is similar to indent but it increases the level of indentation by a fixed number. When using tabs, it's going to print spaces. You should prefer using `indent` whenever possible.
### markAsRoot
```ts
declare function markAsRoot(doc: Doc): Doc;
```
This marks the current indentation as root for `dedentToRoot` and `literalline`s.
#### dedentToRoot
```ts
declare function dedentToRoot(doc: Doc): Doc;
```
This will dedent the current indentation to the root marked by `markAsRoot`.
### cursor
```ts

View File

@ -56,6 +56,14 @@ function group(contents, opts) {
};
}
function dedentToRoot(contents) {
return align(-Infinity, contents);
}
function markAsRoot(contents) {
return align(Infinity, contents);
}
function conditionalGroup(states, opts) {
return group(
states[0],
@ -149,5 +157,7 @@ module.exports = {
ifBreak,
indent,
align,
addAlignmentToDoc
addAlignmentToDoc,
markAsRoot,
dedentToRoot
};

View File

@ -68,7 +68,15 @@ function printDoc(doc) {
}
if (doc.type === "align") {
return "align(" + doc.n + ", " + printDoc(doc.contents) + ")";
return doc.n === -Infinity
? "dedentToRoot(" + printDoc(doc.contents) + ")"
: doc.n === Infinity
? "markAsRoot(" + printDoc(doc.contents) + ")"
: "align(" +
JSON.stringify(doc.n) +
", " +
printDoc(doc.contents) +
")";
}
if (doc.type === "if-break") {

View File

@ -19,24 +19,33 @@ function rootIndent() {
function makeIndent(ind, options) {
return {
length: ind.length + options.tabWidth,
value: ind.value + (options.useTabs ? "\t" : " ".repeat(options.tabWidth))
value: ind.value + (options.useTabs ? "\t" : " ".repeat(options.tabWidth)),
root: ind.root
};
}
function makeAlign(ind, n, options) {
return n === -Infinity
? rootIndent()
: typeof n === "string"
? ind.root ? ind.root : rootIndent()
: n === Infinity
? {
length: ind.length + n.length,
value: ind.value + n
length: ind.length,
value: ind.value,
root: ind
}
: options.useTabs && n > 0
? makeIndent(ind, options)
: {
length: ind.length + n,
value: ind.value + " ".repeat(n)
};
: typeof n === "string"
? {
length: ind.length + n.length,
value: ind.value + n,
root: ind.root
}
: options.useTabs && n > 0
? makeIndent(ind, options)
: {
length: ind.length + n,
value: ind.value + " ".repeat(n),
root: ind.root
};
}
function fits(next, restCommands, width, options, mustBeFlat) {
@ -380,8 +389,13 @@ function printDocToString(doc, options) {
}
if (doc.literal) {
out.push(newLine);
pos = 0;
if (ind.root) {
out.push(newLine, ind.root.value);
pos = ind.root.length;
} else {
out.push(newLine);
pos = 0;
}
} else {
if (out.length > 0) {
// Trim whitespace at the end of line

View File

@ -8,7 +8,9 @@ const indent = docBuilders.indent;
const join = docBuilders.join;
const hardline = docBuilders.hardline;
const softline = docBuilders.softline;
const literalline = docBuilders.literalline;
const concat = docBuilders.concat;
const dedentToRoot = docBuilders.dedentToRoot;
function embed(path, print, textToDoc /*, options */) {
const node = path.getValue();
@ -143,21 +145,20 @@ function embed(path, print, textToDoc /*, options */) {
(parentParent.tag.name === "md" ||
parentParent.tag.name === "markdown")))
) {
const doc = textToDoc(
// leading whitespaces matter in markdown
dedent(parent.quasis[0].value.cooked),
{
parser: "markdown",
__inJsTemplate: true
}
);
const text = parent.quasis[0].value.cooked;
const indentation = getIndentation(text);
const hasIndent = indentation !== "";
return concat([
indent(
concat([
softline,
docUtils.stripTrailingHardline(escapeBackticks(doc))
])
),
hasIndent
? indent(
concat([
softline,
printMarkdown(
text.replace(new RegExp(`^${indentation}`, "gm"), "")
)
])
)
: concat([literalline, dedentToRoot(printMarkdown(text))]),
softline
]);
}
@ -165,12 +166,16 @@ function embed(path, print, textToDoc /*, options */) {
break;
}
}
function printMarkdown(text) {
const doc = textToDoc(text, { parser: "markdown", __inJsTemplate: true });
return docUtils.stripTrailingHardline(escapeBackticks(doc));
}
}
function dedent(str) {
const firstMatchedIndent = str.match(/\n^( *)/m);
const spaces = firstMatchedIndent === null ? 0 : firstMatchedIndent[1].length;
return str.replace(new RegExp(`^ {${spaces}}`, "gm"), "").trim();
function getIndentation(str) {
const firstMatchedIndent = str.match(/^([^\S\n]*)\S/m);
return firstMatchedIndent === null ? "" : firstMatchedIndent[1];
}
function escapeBackticks(doc) {

View File

@ -6,6 +6,7 @@ const doc = require("../doc");
const docBuilders = doc.builders;
const hardline = docBuilders.hardline;
const concat = docBuilders.concat;
const markAsRoot = docBuilders.markAsRoot;
function embed(path, print, textToDoc, options) {
const node = path.getValue();
@ -18,13 +19,15 @@ function embed(path, print, textToDoc, options) {
Math.max(3, util.getMaxContinuousCount(node.value, styleUnit) + 1)
);
const doc = textToDoc(node.value, { parser });
return concat([
style,
node.lang,
hardline,
replaceNewlinesWithHardlines(doc),
style
]);
return markAsRoot(
concat([
style,
node.lang,
hardline,
replaceNewlinesWithHardlines(doc),
style
])
);
}
}

View File

@ -0,0 +1,20 @@
- 1
- 2
- 3
```js
md`
# this is the root indent
# this is the root indent
# this is the root indent
`
something`
asd
asd
asd
`
```

View File

@ -1,5 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`0-indent-js.md 1`] = `
- 1
- 2
- 3
\`\`\`js
md\`
# this is the root indent
# this is the root indent
# this is the root indent
\`
something\`
asd
asd
asd
\`
\`\`\`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 1
* 2
* 3
\`\`\`js
md\`
# this is the root indent
# this is the root indent
# this is the root indent
\`;
something\`
asd
asd
asd
\`;
\`\`\`
`;
exports[`additional-space.md 1`] = `
1. Fork the repo and create your branch from \`master\`.

View File

@ -0,0 +1,19 @@
md`
This line shouldn't be indented at all in the resulting output.
`
if (true) {
md`
text1
- 123
- 456
text2
- 123
- 456
text3
- 123
- 456
`;
}

View File

@ -1,5 +1,51 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`0-indent.js 1`] = `
md\`
This line shouldn't be indented at all in the resulting output.
\`
if (true) {
md\`
text1
- 123
- 456
text2
- 123
- 456
text3
- 123
- 456
\`;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
md\`
This line shouldn't be indented at all in the resulting output.
\`;
if (true) {
md\`
text1
* 123
* 456
text2
* 123
* 456
text3
* 123
* 456
\`;
}
`;
exports[`codeblock.js 1`] = `
md\`
\\\`\\\`\\\`js
@ -12,13 +58,13 @@ markdown\\\`
\`;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
md\`
~~~js
markdown\\\`
~~~js
markdown\\\`
~~~js
console.log("hi");
~~~
\\\`;
console.log("hi");
~~~
\\\`;
~~~
\`;
`;
@ -80,7 +126,7 @@ exports[`single-line.js 1`] = `
markdown\`# hello\`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
markdown\`
# hello
# hello
\`;
`;