diff --git a/.changeset/block-argument-type.md b/.changeset/block-argument-type.md new file mode 100644 index 000000000..a92e859f4 --- /dev/null +++ b/.changeset/block-argument-type.md @@ -0,0 +1,6 @@ +--- +'@shopify/liquid-html-parser': minor +'@shopify/theme-language-server-common': patch +--- + +Type `{% block %}` and `{% section %}` arguments as one `BlockArgument`, whose value is a scalar or a single-level array literal, instead of a `LiquidNamedArgument | BlockArrayArgument` union. Completions narrow on the argument's value. diff --git a/.changeset/html-comment-children.md b/.changeset/html-comment-children.md new file mode 100644 index 000000000..e9ebe2782 --- /dev/null +++ b/.changeset/html-comment-children.md @@ -0,0 +1,25 @@ +--- +'@shopify/liquid-html-parser': minor +'@shopify/prettier-plugin-liquid': patch +'@shopify/theme-check-common': patch +'@shopify/theme-language-server-common': patch +--- + +Parse the Liquid inside HTML comments. Liquid renders it, and its tags can open, branch and close blocks, so `{% if a %}` no longer fails with an unclosed `if`. + +- `HtmlComment` has `children` (text and Liquid) and `blockStartPosition`/`blockEndPosition` for its delimiters. +- A comment that crosses a Liquid block boundary is split there, and each part has an empty delimiter range on the split side. +- A comment that never closes ends at the end of the file, as in a browser. +- An end tag in a comment that closes no block is a parse error, as in Liquid. +- The `opaqueHtmlComments` option keeps comment bodies opaque. + +**Behavior changes** + +- Code that walks `children` now visits the Liquid and text inside HTML comments. +- `
x
` is one comment whose `if` holds `x
` as text, not two comments around a `` element.
+- `` with no open `if` no longer parses. An unclosed `` now parse.
+- Code that creates `HtmlComment` nodes must set `children`, `blockStartPosition` and `blockEndPosition`.
+
+Pass `opaqueHtmlComments: true` to get the previous tree for these templates.
+
+Checks now see the Liquid in HTML comments, and completions work inside them. Prettier prints an unclosed comment as written, and can move whitespace and line breaks inside a comment that holds a Liquid block or is split by one.
diff --git a/.changeset/html-comment-mode.md b/.changeset/html-comment-mode.md
new file mode 100644
index 000000000..45689b679
--- /dev/null
+++ b/.changeset/html-comment-mode.md
@@ -0,0 +1,12 @@
+---
+'@shopify/liquid-html-parser': minor
+---
+
+Tokenize HTML comments as a browser does. In a comment only Liquid and the comment's close count, so a ``. A comment closes on `-->` or `--!>`, and `` and `` are empty comments. Outside a comment, `-->` is text. The bodies of Liquid raw tags like `{% comment %}` are opaque to the tokenizer too, so a ` b {{ x }} {{ x }} }
+ blockEndPosition: { start: [0, 59], text: {{ x }} after after
after
} + name: + - type: TextNode + value: p + position: { start: [0, 50], text: p } + attributes: [] + children: + - type: TextNode + value: after + position: { start: [0, 52], text: after } + - name: closes a script body after a raw {{ and a later }} around a loop + source:after
+ parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text: 'after
' } + children: + - type: HtmlRawNode + name: script + blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: '' } + attributes: [] + body: + type: RawMarkup + kind: javascript + value: var o="{% raw %}{{{% endraw %}"; for(i=0;iafter
} + name: + - type: TextNode + value: p + position: { start: [0, 81], text: p } + attributes: [] + children: + - type: TextNode + value: after + position: { start: [0, 83], text: after } + - name: closes a script body after raw {{ and }} split across two raw tags + source:after
+ parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text: "after
" } + children: + - type: HtmlRawNode + name: script + blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: "" } + attributes: [] + body: + type: RawMarkup + kind: javascript + value: "{% raw %}{{{% endraw %} x {% raw %}}}{% endraw %}; if(a } + blockEndPosition: { start: [0, 85], text: } + position: { start: [0, 77], text:after
} + name: + - type: TextNode + value: p + position: { start: [0, 78], text: p } + attributes: [] + children: + - type: TextNode + value: after + position: { start: [0, 80], text: after } + - name: rejects a script body whose comment has a {{ that swallows the endcomment, as Liquid::Tokenizer does + source:after
+ parse: [html] + error: + message: Attempting to end parsing before HtmlRawNode 'script' was closed + start: [0, 0] + text:after
+ parse: [html] + error: + message: Attempting to end parsing before HtmlRawNode 'script' was closed + start: [0, 0] + text: + parse: [html] + error: + message: Attempting to end parsing before LiquidRawTag 'comment' was closed + start: [0, 17] + text: "{% comment %}" + - name: rejects a script with a < comparison that is never closed + source: | + + parse: [html] + error: + message: Attempting to end parsing before HtmlRawNode 'script' was closed + start: [0, 0] + text: + parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text: } + children: + - type: HtmlRawNode + name: script + blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: } + attributes: [] + body: + type: RawMarkup + kind: javascript + value: + position: { start: [0, 8], text: } + nodes: + - type: TextNode + value: + position: { start: [0, 8], text: } + - name: keeps an HTML comment in a style body as text + source: "" + parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text: "" } + children: + - type: HtmlRawNode + name: style + blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: "" } + attributes: [] + body: + type: RawMarkup + kind: css + value: "" + position: { start: [0, 7], text: "" } + nodes: + - type: TextNode + value: "" + position: { start: [0, 7], text: "" } + - name: keeps an HTML comment in an svg body as text + source:after
+ parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text:after
} + children: + - type: HtmlRawNode + name: script + blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: } + attributes: [] + body: + type: RawMarkup + kind: javascript + value: const s = "after
+ parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text: "after
" } + children: + - type: HtmlRawNode + name: script + blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: "" } + attributes: [] + body: + type: RawMarkup + kind: javascript + value: /* y) {} + position: { start: [0, 8], text: "/* y) {}" } + nodes: + - type: TextNode + value: /* y) {} + position: { start: [0, 8], text: "/* y) {}" } + - type: HtmlComment + body: + blockStartPosition: { start: [0, 46], text: } + position: { start: [0, 46], text: } + children: + - type: TextNode + value: + position: { start: [0, 51], text: } + - type: HtmlElement + blockStartPosition: { start: [0, 61], text:} + blockEndPosition: { start: [0, 69], text:
} + position: { start: [0, 61], text:after
} + name: + - type: TextNode + value: p + position: { start: [0, 62], text: p } + attributes: [] + children: + - type: TextNode + value: after + position: { start: [0, 64], text: after } + - name: parses an HTML comment after a style whose body holds an unpaired /* b {}after
+ parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text: "after
" } + children: + - type: HtmlRawNode + name: style + blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: "" } + attributes: [] + body: + type: RawMarkup + kind: css + value: /* b {} + position: { start: [0, 7], text: "/* b {}" } + nodes: + - type: TextNode + value: /* b {} + position: { start: [0, 7], text: "/* b {}" } + - type: HtmlComment + body: + blockStartPosition: { start: [0, 39], text: } + position: { start: [0, 39], text: } + children: + - type: TextNode + value: + position: { start: [0, 44], text: } + - type: HtmlElement + blockStartPosition: { start: [0, 54], text:} + blockEndPosition: { start: [0, 62], text:
} + position: { start: [0, 54], text:after
} + name: + - type: TextNode + value: p + position: { start: [0, 55], text: p } + attributes: [] + children: + - type: TextNode + value: after + position: { start: [0, 57], text: after } + - name: closes an svg whose open tag has a glued Liquid attribute + source:after
+ parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text:after
} + children: + - type: HtmlRawNode + name: svg + blockStartPosition: { start: [0, 0], text:} + blockEndPosition: { start: [0, 45], text:
} + position: { start: [0, 37], text:after
} + name: + - type: TextNode + value: p + position: { start: [0, 38], text: p } + attributes: [] + children: + - type: TextNode + value: after + position: { start: [0, 40], text: after } + - name: parses the Liquid inside an HTML comment as text and Liquid + source: + parse: [html] + ast: + type: Document + name: "#document" + position: { start: [0, 0], text: "" } + children: + - type: HtmlComment + body: a {{ b }}+ blockStartPosition: { start: [0, 0], text: } + position: { start: [0, 0], text: "" } + children: + - type: TextNode + value: a + position: { start: [0, 5], text: a } + - type: LiquidVariableOutput + whitespaceStart: "" + whitespaceEnd: "" + markupPosition: { start: [0, 9], text: " b " } + position: { start: [0, 7], text: "{{ b }}" } + markup: + type: LiquidVariable + rawSource: b + position: { start: [0, 10], text: "b " } + expression: + type: VariableLookup + name: b + position: { start: [0, 10], text: b } + lookups: [] + lookupModes: [] + filters: [] + - type: TextNode + value:
+ position: { start: [0, 15], text:
}
+ - name: splits an HTML comment at the tag that closes an enclosing block
+ source: "{% for x in xs %}{% if x %}{% endfor %}"
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position: { start: [0, 0], text: "{% for x in xs %}{% if x %}{% endfor %}" }
+ children:
+ - type: LiquidTag
+ name: for
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [0, 0], text: "{% for x in xs %}" }
+ blockEndPosition: { start: [0, 51], text: "{% endfor %}" }
+ markupPosition: { start: [0, 7], text: "x in xs " }
+ position: { start: [0, 0], text: "{% for x in xs %}{% if x %}{% endfor %}" }
+ markup:
+ type: ForMarkup
+ variableName: x
+ reversed: false
+ position: { start: [0, 7], text: "x in xs " }
+ collection:
+ type: VariableLookup
+ name: xs
+ position: { start: [0, 12], text: xs }
+ lookups: []
+ lookupModes: []
+ args: []
+ children:
+ - type: LiquidBranch
+ name: null
+ markup: ""
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ markupPosition: { start: [0, 17], text: "" }
+ blockStartPosition: { start: [0, 17], text: "" }
+ blockEndPosition: { start: [0, 51], text: "" }
+ position: { start: [0, 17], text: "{% if x %}" }
+ children:
+ - type: LiquidTag
+ name: if
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [0, 17], text: "{% if x %}" }
+ blockEndPosition: { start: [0, 34], text: "{% endif %}" }
+ markupPosition: { start: [0, 23], text: "x " }
+ position: { start: [0, 17], text: "{% if x %} }
+ position: { start: [0, 45], text: " b -->" }
+ children:
+ - type: TextNode
+ value: b
+ position: { start: [0, 46], text: b }
+ - name: ends an HTML comment with a block opened inside it that closes after it
+ source: a {% endif %}c
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position: { start: [0, 0], text: " a {% endif %}c" }
+ children:
+ - type: HtmlComment
+ body: "{% if x %} --> a {% endif %}"
+ blockStartPosition: { start: [0, 0], text: a {% endif %}" }
+ children:
+ - type: LiquidTag
+ name: if
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [0, 5], text: "{% if x %}" }
+ blockEndPosition: { start: [0, 22], text: "{% endif %}" }
+ markupPosition: { start: [0, 11], text: "x " }
+ position: { start: [0, 5], text: "{% if x %} --> a {% endif %}" }
+ markup:
+ type: VariableLookup
+ name: x
+ position: { start: [0, 11], text: x }
+ lookups: []
+ lookupModes: []
+ children:
+ - type: LiquidBranch
+ name: null
+ markup: ""
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ markupPosition: { start: [0, 15], text: "" }
+ blockStartPosition: { start: [0, 15], text: "" }
+ blockEndPosition: { start: [0, 22], text: "" }
+ position: { start: [0, 15], text: " --> a " }
+ children:
+ - type: TextNode
+ value: --> a
+ position: { start: [0, 16], text: --> a }
+ - type: HtmlElement
+ blockStartPosition: { start: [0, 33], text: }
+ blockEndPosition: { start: [0, 37], text: }
+ position: { start: [0, 33], text: c }
+ name:
+ - type: TextNode
+ value: b
+ position: { start: [0, 34], text: b }
+ attributes: []
+ children:
+ - type: TextNode
+ value: c
+ position: { start: [0, 36], text: c }
+ - name: ends an HTML comment that never closes at the end of the source, as a browser does
+ source: a after
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position: { start: [0, 0], text: "after" }
+ children:
+ - type: HtmlComment
+ body: "{% if true %}--> }
+ position: { start: [0, 0], text: "" }
+ children:
+ - type: LiquidTag
+ name: if
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [0, 4], text: "{% if true %}" }
+ blockEndPosition: { start: [0, 24], text: "{% endif %}" }
+ markupPosition: { start: [0, 10], text: "true " }
+ position: { start: [0, 4], text: "{% if true %}-->{% endif %}"
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position: { start: [0, 0], text: "{% if a %}{% endif %}" }
+ children:
+ - type: LiquidTag
+ name: if
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [0, 0], text: "{% if a %}" }
+ blockEndPosition: { start: [0, 33], text: "{% endif %}" }
+ markupPosition: { start: [0, 6], text: "a " }
+ position: { start: [0, 0], text: "{% if a %}{% endif %}" }
+ markup:
+ type: VariableLookup
+ name: a
+ position: { start: [0, 6], text: a }
+ lookups: []
+ lookupModes: []
+ children:
+ - type: LiquidBranch
+ name: null
+ markup: ""
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ markupPosition: { start: [0, 10], text: "" }
+ blockStartPosition: { start: [0, 10], text: "" }
+ blockEndPosition: { start: [0, 17], text: "" }
+ position: { start: [0, 10], text: "" }
+ children:
+ - type: HtmlComment
+ body: y
+ blockStartPosition: { start: [0, 27], text: "" }
+ blockEndPosition: { start: [0, 30], text: --> }
+ position: { start: [0, 27], text: " y -->" }
+ children:
+ - type: TextNode
+ value: y
+ position: { start: [0, 28], text: y }
+ - name: rejects an orphan end tag inside an HTML comment, as Liquid does
+ source:
+ parse: [html]
+ error:
+ message: Attempting to close LiquidTag 'if' before it was opened without a matching 'if'
+ start: [0, 5]
+ text: "{% endif %}"
+ - name: rejects an unclosed block inside an HTML comment, as Liquid does
+ source:
+ parse: [html]
+ error:
+ message: Attempting to end parsing before LiquidTag 'if' was closed
+ start: [0, 5]
+ text: "{% if a %}"
+ - name: parses a raw tag inside an HTML comment as a raw tag
+ source: {% endraw %} -->
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position: { start: [0, 0], text: "{% endraw %} -->" }
+ children:
+ - type: HtmlComment
+ body: "{% raw %}{{ a }} -->{% endraw %}"
+ blockStartPosition: { start: [0, 0], text: }
+ position: { start: [0, 0], text: "{% endraw %} -->" }
+ children:
+ - type: LiquidRawTag
+ name: raw
+ markup: ""
+ markupPosition: { start: [0, 12], text: "" }
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [0, 5], text: "{% raw %}" }
+ blockEndPosition: { start: [0, 25], text: "{% endraw %}" }
+ position: { start: [0, 5], text: "{% raw %}{{ a }} -->{% endraw %}" }
+ body:
+ type: RawMarkup
+ kind: text
+ value: "{{ a }} -->"
+ position: { start: [0, 14], text: "{{ a }} -->" }
+ nodes:
+ - type: TextNode
+ value: "{{ a }} -->"
+ position: { start: [0, 14], text: "{{ a }} -->" }
diff --git a/specs/parser/liquid-lines.yml b/specs/parser/liquid-lines.yml
index 6abbf566a..830b7de80 100644
--- a/specs/parser/liquid-lines.yml
+++ b/specs/parser/liquid-lines.yml
@@ -1931,7 +1931,7 @@ cases:
comment
inner
endcomment
- - name: should carve out a nested raw so a literal endcomment inside it does not close early
+ - name: should leave a comment unclosed when a raw inside it cannot close in {% liquid %}
source: |-
{% liquid
comment
@@ -1961,6 +1961,14 @@ cases:
children:
- type: LiquidTag
name: liquid
+ markup: |-
+ comment
+ before
+ raw
+ endcomment
+ endraw
+ after
+ endcomment
whitespaceStart: ""
whitespaceEnd: ""
blockStartPosition:
@@ -1998,6 +2006,69 @@ cases:
after
endcomment
%}
+ reason: Unclosed raw tag 'comment' in {% liquid %} block
+ - name: should close a nested comment at the endcomment of its outer level
+ source: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'X'
+ endcomment
+ echo 'Y'
+ %}
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'X'
+ endcomment
+ echo 'Y'
+ %}
+ children:
+ - type: LiquidTag
+ name: liquid
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'X'
+ endcomment
+ echo 'Y'
+ %}
+ markupPosition:
+ start: [0, 9]
+ text: |
+
+ comment
+ comment
+ endcomment
+ echo 'X'
+ endcomment
+ echo 'Y'
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'X'
+ endcomment
+ echo 'Y'
+ %}
markup:
- type: LiquidRawTag
name: comment
@@ -2008,48 +2079,355 @@ cases:
delimiterWhitespaceStart: ""
delimiterWhitespaceEnd: ""
blockStartPosition: { start: [1, 0], text: comment }
- blockEndPosition: { start: [7, 0], text: endcomment }
+ blockEndPosition: { start: [5, 0], text: endcomment }
position:
start: [1, 0]
text: |-
comment
- before
- raw
+ comment
endcomment
- endraw
- after
+ echo 'X'
endcomment
body:
type: RawMarkup
kind: text
value: |
- before
- raw
+ comment
endcomment
- endraw
- after
+ echo 'X'
position:
start: [1, 7]
text: |
- before
- raw
+ comment
endcomment
- endraw
- after
+ echo 'X'
nodes:
- type: TextNode
value: |-
- before
- raw
+ comment
endcomment
- endraw
- after
+ echo 'X'
position:
start: [2, 0]
text: |-
- before
- raw
+ comment
endcomment
- endraw
- after
+ echo 'X'
+ - type: LiquidTag
+ name: echo
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition: { start: [6, 0], text: echo 'Y' }
+ markupPosition: { start: [6, 5], text: "'Y'" }
+ position: { start: [6, 0], text: echo 'Y' }
+ markup:
+ type: LiquidVariable
+ rawSource: "'Y'"
+ position: { start: [6, 5], text: "'Y'" }
+ expression:
+ type: String
+ single: true
+ value: Y
+ position: { start: [6, 5], text: "'Y'" }
+ filters: []
+ - name: should not count a comment line indented with non-ASCII whitespace
+ source: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'Y'
+ %}
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'Y'
+ %}
+ children:
+ - type: LiquidTag
+ name: liquid
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'Y'
+ %}
+ markupPosition:
+ start: [0, 9]
+ text: |
+
+ comment
+ comment
+ endcomment
+ echo 'Y'
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ comment
+ endcomment
+ echo 'Y'
+ %}
+ markup:
+ - type: LiquidRawTag
+ name: comment
+ markup: ""
+ markupPosition: { start: [1, 7], text: "" }
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [1, 0], text: comment }
+ blockEndPosition: { start: [3, 0], text: endcomment }
+ position:
+ start: [1, 0]
+ text: |-
+ comment
+ comment
+ endcomment
+ body:
+ type: RawMarkup
+ kind: text
+ value: |
+ comment
+ position:
+ start: [1, 7]
+ text: |
+
+ comment
+ nodes:
+ - type: TextNode
+ value: comment
+ position: { start: [2, 1], text: comment }
+ - type: LiquidTag
+ name: echo
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition: { start: [4, 0], text: echo 'Y' }
+ markupPosition: { start: [4, 5], text: "'Y'" }
+ position: { start: [4, 0], text: echo 'Y' }
+ markup:
+ type: LiquidVariable
+ rawSource: "'Y'"
+ position: { start: [4, 5], text: "'Y'" }
+ expression:
+ type: String
+ single: true
+ value: Y
+ position: { start: [4, 5], text: "'Y'" }
+ filters: []
+ - name: should not count a raw line indented with non-ASCII whitespace
+ source: |-
+ {% liquid
+ comment
+ raw
+ endcomment
+ echo 'Y'
+ %}
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ raw
+ endcomment
+ echo 'Y'
+ %}
+ children:
+ - type: LiquidTag
+ name: liquid
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ raw
+ endcomment
+ echo 'Y'
+ %}
+ markupPosition:
+ start: [0, 9]
+ text: |
+
+ comment
+ raw
+ endcomment
+ echo 'Y'
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ raw
+ endcomment
+ echo 'Y'
+ %}
+ markup:
+ - type: LiquidRawTag
+ name: comment
+ markup: ""
+ markupPosition: { start: [1, 7], text: "" }
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [1, 0], text: comment }
+ blockEndPosition: { start: [3, 0], text: endcomment }
+ position:
+ start: [1, 0]
+ text: |-
+ comment
+ raw
+ endcomment
+ body:
+ type: RawMarkup
+ kind: text
+ value: |
+ raw
+ position:
+ start: [1, 7]
+ text: |
+
+ raw
+ nodes:
+ - type: TextNode
+ value: raw
+ position: { start: [2, 1], text: raw }
+ - type: LiquidTag
+ name: echo
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition: { start: [4, 0], text: echo 'Y' }
+ markupPosition: { start: [4, 5], text: "'Y'" }
+ position: { start: [4, 0], text: echo 'Y' }
+ markup:
+ type: LiquidVariable
+ rawSource: "'Y'"
+ position: { start: [4, 5], text: "'Y'" }
+ expression:
+ type: String
+ single: true
+ value: Y
+ position: { start: [4, 5], text: "'Y'" }
+ filters: []
+ - name: should not count an endcomment line indented with non-ASCII whitespace
+ source: |-
+ {% liquid
+ comment
+ endcomment
+ endcomment
+ echo 'Y'
+ %}
+ parse: [html]
+ ast:
+ type: Document
+ name: "#document"
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ endcomment
+ endcomment
+ echo 'Y'
+ %}
+ children:
+ - type: LiquidTag
+ name: liquid
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ endcomment
+ endcomment
+ echo 'Y'
+ %}
+ markupPosition:
+ start: [0, 9]
+ text: |
+
+ comment
+ endcomment
+ endcomment
+ echo 'Y'
+ position:
+ start: [0, 0]
+ text: |-
+ {% liquid
+ comment
+ endcomment
+ endcomment
+ echo 'Y'
+ %}
+ markup:
+ - type: LiquidRawTag
+ name: comment
+ markup: ""
+ markupPosition: { start: [1, 7], text: "" }
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ delimiterWhitespaceStart: ""
+ delimiterWhitespaceEnd: ""
+ blockStartPosition: { start: [1, 0], text: comment }
+ blockEndPosition: { start: [3, 0], text: endcomment }
+ position:
+ start: [1, 0]
+ text: |-
+ comment
+ endcomment
+ endcomment
+ body:
+ type: RawMarkup
+ kind: text
+ value: |
+ endcomment
+ position:
+ start: [1, 7]
+ text: |
+
+ endcomment
+ nodes:
+ - type: TextNode
+ value: endcomment
+ position: { start: [2, 1], text: endcomment }
+ - type: LiquidTag
+ name: echo
+ whitespaceStart: ""
+ whitespaceEnd: ""
+ blockStartPosition: { start: [4, 0], text: echo 'Y' }
+ markupPosition: { start: [4, 5], text: "'Y'" }
+ position: { start: [4, 0], text: echo 'Y' }
+ markup:
+ type: LiquidVariable
+ rawSource: "'Y'"
+ position: { start: [4, 5], text: "'Y'" }
+ expression:
+ type: String
+ single: true
+ value: Y
+ position: { start: [4, 5], text: "'Y'" }
+ filters: []
diff --git a/specs/parser/liquid-raw.yml b/specs/parser/liquid-raw.yml
index 31febb4d9..33acdff5c 100644
--- a/specs/parser/liquid-raw.yml
+++ b/specs/parser/liquid-raw.yml
@@ -667,7 +667,7 @@ cases:
- type: TextNode
value:
position: { start: [0, 18], text: }
- - name: should depth-balance nested same-name raw tags and close at the outer tag (issue 156) (1)
+ - name: should depth-balance nested same-name raw tags and close at the outer tag (issue 156)
source: