Markdown: Fix liquid flow parsing (#19838)
Co-authored-by: codex <codex@openai.com> Co-authored-by: fisker Cheung <lionkay@gmail.com> Co-authored-by: wanxiankai <xiankai.wan@gmail.com> Co-authored-by: seiya <20365512+seiyab@users.noreply.github.com>
This commit is contained in:
5 files changed
+242
-10
No files matched your search
@@ -0,0 +1,27 @@
|
|||||||
|
#### Preserve Liquid blocks after Markdown tables (#19730 by @wanxiankai, @seiyab)
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
```markdown
|
||||||
|
<!-- Input -->
|
||||||
|
| Argument | Type |
|
||||||
|
| -------- | ---- |
|
||||||
|
{% set default_params = {
|
||||||
|
"model": ["str"],
|
||||||
|
} %}
|
||||||
|
|
||||||
|
<!-- Prettier stable -->
|
||||||
|
| Argument | Type |
|
||||||
|
| ------------------------- | ---- |
|
||||||
|
| {% set default_params = { |
|
||||||
|
|
||||||
|
"model": ["str"],
|
||||||
|
|
||||||
|
} %}
|
||||||
|
|
||||||
|
<!-- Prettier main -->
|
||||||
|
| Argument | Type |
|
||||||
|
| -------- | ---- |
|
||||||
|
{% set default_params = {
|
||||||
|
"model": ["str"],
|
||||||
|
} %}
|
||||||
|
```
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { markdownLineEnding } from "micromark-util-character";
|
import { markdownLineEnding, markdownSpace } from "micromark-util-character";
|
||||||
import { codes, types } from "micromark-util-symbol";
|
import { codes, types } from "micromark-util-symbol";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,6 +7,7 @@ import { codes, types } from "micromark-util-symbol";
|
|||||||
* @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext
|
* @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext
|
||||||
* @typedef {import('mdast-util-from-markdown').Handle} Handle
|
* @typedef {import('mdast-util-from-markdown').Handle} Handle
|
||||||
* @typedef {import('micromark-util-types').State} State
|
* @typedef {import('micromark-util-types').State} State
|
||||||
|
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const nodeType = "liquidNode";
|
const nodeType = "liquidNode";
|
||||||
@@ -46,15 +47,37 @@ function liquidFromMarkdown() {
|
|||||||
*/
|
*/
|
||||||
function liquidSyntax() {
|
function liquidSyntax() {
|
||||||
return {
|
return {
|
||||||
|
flow: {
|
||||||
|
[codes.leftCurlyBrace]: {
|
||||||
|
name: "liquidFlow",
|
||||||
|
tokenize: tokenizeFlow,
|
||||||
|
},
|
||||||
|
},
|
||||||
text: {
|
text: {
|
||||||
[codes.leftCurlyBrace]: {
|
[codes.leftCurlyBrace]: {
|
||||||
name: "liquid",
|
name: "liquidText",
|
||||||
tokenize,
|
tokenize: tokenizeText,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function tokenize(effects, ok, nok) {
|
/** @this {TokenizeContext} */
|
||||||
|
function tokenizeFlow(effects, ok, nok) {
|
||||||
|
return tokenize.call(this, effects, ok, nok, "flow");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @this {TokenizeContext} */
|
||||||
|
function tokenizeText(effects, ok, nok) {
|
||||||
|
return tokenize.call(this, effects, ok, nok, "text");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @this {TokenizeContext}
|
||||||
|
* @param mode {"text" | "flow"}
|
||||||
|
*/
|
||||||
|
function tokenize(effects, ok, nok, mode) {
|
||||||
|
const isFlow = mode === "flow";
|
||||||
|
const { interrupt, now, parser } = this;
|
||||||
/** @type {typeof codes.rightCurlyBrace | typeof codes.percentSign} */
|
/** @type {typeof codes.rightCurlyBrace | typeof codes.percentSign} */
|
||||||
let closingCode;
|
let closingCode;
|
||||||
|
|
||||||
@@ -74,7 +97,7 @@ function liquidSyntax() {
|
|||||||
? codes.percentSign
|
? codes.percentSign
|
||||||
: codes.rightCurlyBrace;
|
: codes.rightCurlyBrace;
|
||||||
effects.consume(code);
|
effects.consume(code);
|
||||||
return inside;
|
return isFlow && interrupt ? ok : inside;
|
||||||
default:
|
default:
|
||||||
return nok(code);
|
return nok(code);
|
||||||
}
|
}
|
||||||
@@ -95,6 +118,9 @@ function liquidSyntax() {
|
|||||||
effects.enter(types.lineEnding);
|
effects.enter(types.lineEnding);
|
||||||
effects.consume(code);
|
effects.consume(code);
|
||||||
effects.exit(types.lineEnding);
|
effects.exit(types.lineEnding);
|
||||||
|
if (isFlow) {
|
||||||
|
return afterLineEnding;
|
||||||
|
}
|
||||||
effects.enter(types.data);
|
effects.enter(types.data);
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
@@ -103,17 +129,63 @@ function liquidSyntax() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @type {State} */
|
||||||
|
function afterLineEnding(code) {
|
||||||
|
if (parser.lazy[now().line]) {
|
||||||
|
return nok(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (markdownLineEnding(code)) {
|
||||||
|
effects.enter(types.lineEnding);
|
||||||
|
effects.consume(code);
|
||||||
|
effects.exit(types.lineEnding);
|
||||||
|
return afterLineEnding;
|
||||||
|
}
|
||||||
|
|
||||||
|
effects.enter(types.data);
|
||||||
|
return inside(code);
|
||||||
|
}
|
||||||
|
|
||||||
/** @type {State} */
|
/** @type {State} */
|
||||||
function mayClose(code) {
|
function mayClose(code) {
|
||||||
if (code === codes.rightCurlyBrace) {
|
if (code === codes.rightCurlyBrace) {
|
||||||
effects.consume(code);
|
effects.consume(code);
|
||||||
effects.exit(types.data);
|
effects.exit(types.data);
|
||||||
effects.exit(nodeType);
|
effects.exit(nodeType);
|
||||||
return ok;
|
return isFlow ? afterClose : ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @type {State} */
|
||||||
|
function afterClose(code) {
|
||||||
|
if (markdownSpace(code)) {
|
||||||
|
effects.enter(types.whitespace);
|
||||||
|
effects.consume(code);
|
||||||
|
return afterWhitespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
return after(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {State} */
|
||||||
|
function afterWhitespace(code) {
|
||||||
|
if (markdownSpace(code)) {
|
||||||
|
effects.consume(code);
|
||||||
|
return afterWhitespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
effects.exit(types.whitespace);
|
||||||
|
return after(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {State} */
|
||||||
|
function after(code) {
|
||||||
|
return code === codes.eof || markdownLineEnding(code)
|
||||||
|
? ok(code)
|
||||||
|
: nok(code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,11 @@ function printChildren(path, options, print, events = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function shouldPrePrintHardline({ node, parent }) {
|
function shouldPrePrintHardline({ node, parent }) {
|
||||||
const isInlineNode = INLINE_NODE_TYPES.has(node.type);
|
const isInlineNode =
|
||||||
|
INLINE_NODE_TYPES.has(node.type) &&
|
||||||
|
!(
|
||||||
|
node.type === "liquidNode" && !INLINE_NODE_WRAPPER_TYPES.has(parent.type)
|
||||||
|
);
|
||||||
|
|
||||||
const isInlineHTML =
|
const isInlineHTML =
|
||||||
node.type === "html" && INLINE_NODE_WRAPPER_TYPES.has(parent.type);
|
node.type === "html" && INLINE_NODE_WRAPPER_TYPES.has(parent.type);
|
||||||
@@ -119,6 +123,9 @@ function shouldPrePrintDoubleHardline(path, options) {
|
|||||||
parent.type === "listItem" &&
|
parent.type === "listItem" &&
|
||||||
previous.type === "paragraph" &&
|
previous.type === "paragraph" &&
|
||||||
previous.position.end.line + 1 === node.position.start.line;
|
previous.position.end.line + 1 === node.position.start.line;
|
||||||
|
const isBlockLiquidWithoutBlankLine =
|
||||||
|
(node.type === "liquidNode" || previous.type === "liquidNode") &&
|
||||||
|
previous.position.end.line + 1 === node.position.start.line;
|
||||||
|
|
||||||
return !(
|
return !(
|
||||||
isSiblingNode ||
|
isSiblingNode ||
|
||||||
@@ -126,7 +133,8 @@ function shouldPrePrintDoubleHardline(path, options) {
|
|||||||
isPrevNodePrettierIgnore ||
|
isPrevNodePrettierIgnore ||
|
||||||
isBlockHtmlWithoutBlankLineBetweenPrevHtml ||
|
isBlockHtmlWithoutBlankLineBetweenPrevHtml ||
|
||||||
isBlockHtmlWithoutBlankLineBetweenPrevParagraph ||
|
isBlockHtmlWithoutBlankLineBetweenPrevParagraph ||
|
||||||
isHtmlDirectAfterListItem
|
isHtmlDirectAfterListItem ||
|
||||||
|
isBlockLiquidWithoutBlankLine
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ proseWrap: "always"
|
|||||||
|
|
||||||
{%
|
{%
|
||||||
if user
|
if user
|
||||||
%} Hello, {{ user }}! {% endif %}
|
%} Hello, {{ user }}!
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
@@ -84,7 +85,8 @@ where does it end }}
|
|||||||
|
|
||||||
# Userscripts <span>[{% img github.svg alt:"View on GitHub" title:"View on GitHub" %}](https://github.com/Charcoal-SE/Userscripts) [Build <span>status loading…</span>](//travis-ci.org/Charcoal-SE/userscripts){: .build}</span>
|
# Userscripts <span>[{% img github.svg alt:"View on GitHub" title:"View on GitHub" %}](https://github.com/Charcoal-SE/Userscripts) [Build <span>status loading…</span>](//travis-ci.org/Charcoal-SE/userscripts){: .build}</span>
|
||||||
|
|
||||||
{% css userscripts %} {% js userscripts %}
|
{% css userscripts %}
|
||||||
|
{% js userscripts %}
|
||||||
|
|
||||||
{{ foo
|
{{ foo
|
||||||
multiline
|
multiline
|
||||||
@@ -406,6 +408,109 @@ This input uses Hugo shortcode. Prettier doesn't support this explicitly but it
|
|||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`issue-19724.md - {"proseWrap":"always"} format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["markdown"]
|
||||||
|
proseWrap: "always"
|
||||||
|
printWidth: 80 (default) |
|
||||||
|
=====================================input======================================
|
||||||
|
{% macro param_table(params=None) -%}
|
||||||
|
| Argument | Type |
|
||||||
|
| -------- | ---- |
|
||||||
|
{% set default_params = {
|
||||||
|
"model": ["str"],
|
||||||
|
} %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> abc
|
||||||
|
{% abc %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Inline {{ liquid }} stays inline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
{% liquid %} followed by text
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
{% macro param_table(params=None) -%}
|
||||||
|
| Argument | Type |
|
||||||
|
| -------- | ---- |
|
||||||
|
{% set default_params = {
|
||||||
|
"model": ["str"],
|
||||||
|
} %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> abc
|
||||||
|
{% abc %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Inline {{ liquid }} stays inline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
{% liquid %} followed by text
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`issue-19724.md format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["markdown"]
|
||||||
|
printWidth: 80 (default) |
|
||||||
|
=====================================input======================================
|
||||||
|
{% macro param_table(params=None) -%}
|
||||||
|
| Argument | Type |
|
||||||
|
| -------- | ---- |
|
||||||
|
{% set default_params = {
|
||||||
|
"model": ["str"],
|
||||||
|
} %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> abc
|
||||||
|
{% abc %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Inline {{ liquid }} stays inline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
{% liquid %} followed by text
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
{% macro param_table(params=None) -%}
|
||||||
|
| Argument | Type |
|
||||||
|
| -------- | ---- |
|
||||||
|
{% set default_params = {
|
||||||
|
"model": ["str"],
|
||||||
|
} %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> abc
|
||||||
|
{% abc %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Inline {{ liquid }} stays inline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
{% liquid %} followed by text
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`unbalanced-mismatched-braces.md - {"proseWrap":"always"} format 1`] = `
|
exports[`unbalanced-mismatched-braces.md - {"proseWrap":"always"} format 1`] = `
|
||||||
====================================options=====================================
|
====================================options=====================================
|
||||||
parsers: ["markdown"]
|
parsers: ["markdown"]
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{% macro param_table(params=None) -%}
|
||||||
|
| Argument | Type |
|
||||||
|
| -------- | ---- |
|
||||||
|
{% set default_params = {
|
||||||
|
"model": ["str"],
|
||||||
|
} %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> abc
|
||||||
|
{% abc %}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Inline {{ liquid }} stays inline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
{% liquid %} followed by text
|
||||||
Reference in new issue
Block a user