shopware-twig-parser 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ type Tree = {
3
3
  };
4
4
  type TemplateNode = {
5
5
  type: "template";
6
- children: (TwigStatementDirectiveNode | HtmlElementNode | ContentNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
6
+ children: (TwigStatementDirectiveNode | HtmlElementNode | ContentNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode | TwigCommentNode | VueInterpolationNode)[];
7
7
  };
8
8
  type TwigStatementDirectiveNode = {
9
9
  type: "twig_statement_directive";
@@ -11,7 +11,7 @@ type TwigStatementDirectiveNode = {
11
11
  variable?: TwigVariableNode;
12
12
  function?: TwigFunctionNode;
13
13
  condition?: TwigConditionNode;
14
- children?: (TwigStatementDirectiveNode | ContentNode | HtmlElementNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
14
+ children?: (TwigStatementDirectiveNode | ContentNode | HtmlElementNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode | TwigCommentNode | VueInterpolationNode)[];
15
15
  };
16
16
  type TwigConditionNode = {
17
17
  type: "twig_condition";
@@ -46,7 +46,7 @@ type HtmlElementNode = {
46
46
  type: "html_element";
47
47
  name: string;
48
48
  attributes?: HtmlAttributeNode[];
49
- children: (HtmlElementNode | ContentNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
49
+ children: (HtmlElementNode | ContentNode | HtmlNamedEntityNode | HtmlNumericEntityNode | TwigCommentNode | VueInterpolationNode | TwigStatementDirectiveNode)[];
50
50
  void?: boolean;
51
51
  };
52
52
  type HtmlDoctypeNode = {
@@ -60,6 +60,14 @@ type HtmlNumericEntityNode = {
60
60
  type: "html_numeric_entity";
61
61
  content: string;
62
62
  };
63
+ type TwigCommentNode = {
64
+ type: "twig_comment";
65
+ content: string;
66
+ };
67
+ type VueInterpolationNode = {
68
+ type: "vue_interpolation";
69
+ expression: string;
70
+ };
63
71
  export declare function parse(content: string): Tree;
64
72
  export {};
65
73
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,KAAK,IAAI,GAAG;IACV,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,CACN,0BAA0B,GAC1B,eAAe,GACf,WAAW,GACX,eAAe,GACf,mBAAmB,GACnB,qBAAqB,CACxB,EAAE,CAAC;CACL,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,IAAI,EAAE,0BAA0B,CAAC;IACjC,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,QAAQ,CAAC,EAAE,CACP,0BAA0B,GAC1B,WAAW,GACX,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,qBAAqB,CACxB,EAAE,CAAC;CACL,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,kBAAkB,CAAC;CAChC,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,EAAE,CACN,eAAe,GACf,WAAW,GACX,mBAAmB,GACnB,qBAAqB,CACxB,EAAE,CAAC;IACJ,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAMF,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAwf3C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,KAAK,IAAI,GAAG;IACV,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,CACN,0BAA0B,GAC1B,eAAe,GACf,WAAW,GACX,eAAe,GACf,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,oBAAoB,CACvB,EAAE,CAAC;CACL,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,IAAI,EAAE,0BAA0B,CAAC;IACjC,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,QAAQ,CAAC,EAAE,CACP,0BAA0B,GAC1B,WAAW,GACX,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,oBAAoB,CACvB,EAAE,CAAC;CACL,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,kBAAkB,CAAC;CAChC,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,EAAE,CACN,eAAe,GACf,WAAW,GACX,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,oBAAoB,GACpB,0BAA0B,CAC7B,EAAE,CAAC;IACJ,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAkFF,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA6tB3C"}
@@ -9,58 +9,58 @@ const tree_sitter_shopware_twig_1 = __importDefault(require("tree-sitter-shopwar
9
9
  const parser = new tree_sitter_1.default();
10
10
  // @ts-expect-error
11
11
  parser.setLanguage(tree_sitter_shopware_twig_1.default);
12
- function parse(content) {
13
- const tree = parser.parse(content);
14
- function convertNode(node) {
15
- if (node.type === "statement_directive") {
16
- // Check for if_statement
17
- const ifStatement = node.children.find((child) => child.type === "if_statement");
18
- if (ifStatement) {
19
- const conditionalNode = ifStatement.children.find((child) => child.type === "conditional");
20
- const variableNode = ifStatement.children.find((child) => child.type === "variable");
21
- if (conditionalNode && conditionalNode.text === "if" && variableNode) {
22
- return {
23
- type: "if",
24
- expression: variableNode.text,
25
- };
26
- }
27
- }
28
- // Check for tag_statement
29
- const tagStatement = node.children.find((child) => child.type === "tag_statement");
30
- const functionCall = node.children.find((child) => child.type === "function_call");
31
- if (tagStatement) {
32
- const tagNode = tagStatement.children.find((child) => child.type === "tag");
33
- const conditionalNode = tagStatement.children.find((child) => child.type === "conditional");
34
- const variableNode = tagStatement.children.find((child) => child.type === "variable");
35
- if (tagNode && tagNode.text === "block" && variableNode) {
36
- return {
37
- type: "block",
38
- name: variableNode.text,
39
- };
40
- }
41
- else if (tagNode && tagNode.text === "endblock") {
42
- return {
43
- type: "endblock",
44
- };
45
- }
46
- else if (conditionalNode && conditionalNode.text === "endif") {
47
- return {
48
- type: "endif",
49
- };
50
- }
51
- }
52
- else if (functionCall) {
53
- const functionIdentifier = functionCall.children.find((child) => child.type === "function_identifier");
54
- if (functionIdentifier) {
55
- return {
56
- type: "function",
57
- functionName: functionIdentifier.text,
58
- };
59
- }
12
+ function convertStatementDirective(node) {
13
+ if (node.type === "statement_directive") {
14
+ // Check for if_statement
15
+ const ifStatement = node.children.find((child) => child.type === "if_statement");
16
+ if (ifStatement) {
17
+ const conditionalNode = ifStatement.children.find((child) => child.type === "conditional");
18
+ const variableNode = ifStatement.children.find((child) => child.type === "variable");
19
+ if (conditionalNode && conditionalNode.text === "if" && variableNode) {
20
+ return {
21
+ type: "if",
22
+ expression: variableNode.text,
23
+ };
24
+ }
25
+ }
26
+ // Check for tag_statement
27
+ const tagStatement = node.children.find((child) => child.type === "tag_statement");
28
+ const functionCall = node.children.find((child) => child.type === "function_call");
29
+ if (tagStatement) {
30
+ const tagNode = tagStatement.children.find((child) => child.type === "tag");
31
+ const conditionalNode = tagStatement.children.find((child) => child.type === "conditional");
32
+ const variableNode = tagStatement.children.find((child) => child.type === "variable");
33
+ if (tagNode && tagNode.text === "block" && variableNode) {
34
+ return {
35
+ type: "block",
36
+ name: variableNode.text,
37
+ };
38
+ }
39
+ else if (tagNode && tagNode.text === "endblock") {
40
+ return {
41
+ type: "endblock",
42
+ };
43
+ }
44
+ else if (conditionalNode && conditionalNode.text === "endif") {
45
+ return {
46
+ type: "endif",
47
+ };
48
+ }
49
+ }
50
+ else if (functionCall) {
51
+ const functionIdentifier = functionCall.children.find((child) => child.type === "function_identifier");
52
+ if (functionIdentifier) {
53
+ return {
54
+ type: "function",
55
+ functionName: functionIdentifier.text,
56
+ };
60
57
  }
61
58
  }
62
- return null;
63
59
  }
60
+ return null;
61
+ }
62
+ function parse(content) {
63
+ const tree = parser.parse(content);
64
64
  // First pass: convert all nodes to intermediate format
65
65
  const rawNodes = [];
66
66
  // Also collect content nodes
@@ -84,6 +84,182 @@ function parse(content) {
84
84
  }
85
85
  return null;
86
86
  }
87
+ function convertTwigComment(node) {
88
+ if (node.type === "twig_comment") {
89
+ // Extract content between {# and #}
90
+ const text = node.text;
91
+ const content = text.slice(2, -2).trim();
92
+ return {
93
+ type: "twig_comment",
94
+ content,
95
+ };
96
+ }
97
+ return null;
98
+ }
99
+ function convertVueInterpolation(node) {
100
+ if (node.type === "vue_interpolation") {
101
+ // Find the interpolation_content child
102
+ const contentNode = node.children.find((child) => child.type === "interpolation_content");
103
+ return {
104
+ type: "vue_interpolation",
105
+ expression: contentNode ? contentNode.text.trim() : "",
106
+ };
107
+ }
108
+ return null;
109
+ }
110
+ function buildNestedStructureForElement(nodes) {
111
+ const result = [];
112
+ const stack = [];
113
+ for (const node of nodes) {
114
+ if (node.type === "block") {
115
+ const blockNode = {
116
+ type: "twig_statement_directive",
117
+ tag: {
118
+ type: "twig_tag",
119
+ name: "block",
120
+ },
121
+ variable: {
122
+ type: "twig_variable",
123
+ content: node.name,
124
+ },
125
+ children: [],
126
+ };
127
+ if (stack.length > 0) {
128
+ const parent = stack[stack.length - 1];
129
+ if (parent && parent.children) {
130
+ parent.children.push(blockNode);
131
+ }
132
+ }
133
+ else {
134
+ result.push(blockNode);
135
+ }
136
+ stack.push(blockNode);
137
+ }
138
+ else if (node.type === "endblock") {
139
+ stack.pop();
140
+ }
141
+ else if (node.type === "if") {
142
+ const ifNode = {
143
+ type: "twig_statement_directive",
144
+ condition: {
145
+ type: "twig_condition",
146
+ expression: {
147
+ type: "twig_expression",
148
+ content: node.expression,
149
+ },
150
+ },
151
+ children: [],
152
+ };
153
+ if (stack.length > 0) {
154
+ const parent = stack[stack.length - 1];
155
+ if (parent && parent.children) {
156
+ parent.children.push(ifNode);
157
+ }
158
+ }
159
+ else {
160
+ result.push(ifNode);
161
+ }
162
+ stack.push(ifNode);
163
+ }
164
+ else if (node.type === "endif") {
165
+ stack.pop();
166
+ }
167
+ else if (node.type === "function") {
168
+ const functionNode = {
169
+ type: "twig_statement_directive",
170
+ function: {
171
+ type: "twig_function",
172
+ name: node.functionName,
173
+ },
174
+ };
175
+ if (stack.length > 0) {
176
+ const parent = stack[stack.length - 1];
177
+ if (parent && parent.children) {
178
+ parent.children.push(functionNode);
179
+ }
180
+ }
181
+ else {
182
+ result.push(functionNode);
183
+ }
184
+ }
185
+ else if (node.type === "content") {
186
+ const contentNode = {
187
+ type: "content",
188
+ content: node.content,
189
+ };
190
+ if (stack.length > 0) {
191
+ const parent = stack[stack.length - 1];
192
+ if (parent && parent.children) {
193
+ parent.children.push(contentNode);
194
+ }
195
+ }
196
+ else {
197
+ result.push(contentNode);
198
+ }
199
+ }
200
+ else if (node.type === "html_element" && "name" in node) {
201
+ const htmlNode = node;
202
+ if (stack.length > 0) {
203
+ const parent = stack[stack.length - 1];
204
+ if (parent && parent.children) {
205
+ parent.children.push(htmlNode);
206
+ }
207
+ }
208
+ else {
209
+ result.push(htmlNode);
210
+ }
211
+ }
212
+ else if (node.type === "html_named_entity" && "content" in node) {
213
+ const entityNode = node;
214
+ if (stack.length > 0) {
215
+ const parent = stack[stack.length - 1];
216
+ if (parent && parent.children) {
217
+ parent.children.push(entityNode);
218
+ }
219
+ }
220
+ else {
221
+ result.push(entityNode);
222
+ }
223
+ }
224
+ else if (node.type === "html_numeric_entity" && "content" in node) {
225
+ const entityNode = node;
226
+ if (stack.length > 0) {
227
+ const parent = stack[stack.length - 1];
228
+ if (parent && parent.children) {
229
+ parent.children.push(entityNode);
230
+ }
231
+ }
232
+ else {
233
+ result.push(entityNode);
234
+ }
235
+ }
236
+ else if (node.type === "twig_comment" && "content" in node) {
237
+ const commentNode = node;
238
+ if (stack.length > 0) {
239
+ const parent = stack[stack.length - 1];
240
+ if (parent && parent.children) {
241
+ parent.children.push(commentNode);
242
+ }
243
+ }
244
+ else {
245
+ result.push(commentNode);
246
+ }
247
+ }
248
+ else if (node.type === "vue_interpolation" && "expression" in node) {
249
+ const interpolationNode = node;
250
+ if (stack.length > 0) {
251
+ const parent = stack[stack.length - 1];
252
+ if (parent && parent.children) {
253
+ parent.children.push(interpolationNode);
254
+ }
255
+ }
256
+ else {
257
+ result.push(interpolationNode);
258
+ }
259
+ }
260
+ }
261
+ return result;
262
+ }
87
263
  function convertHtmlElement(node) {
88
264
  if (node.type === "html_element") {
89
265
  // Check for self-closing tag first
@@ -114,7 +290,18 @@ function parse(content) {
114
290
  const isVoid = hasVoidTag || hasSelfClosingTag;
115
291
  // Parse attributes from the tag (either self-closing or start tag)
116
292
  const attributes = [];
117
- const attributeNodes = tagToUse.children.filter((child) => child.type === "html_attribute");
293
+ let attributeNodes;
294
+ if (voidTag) {
295
+ // For void tags, attributes are in the nested html_start_tag
296
+ const voidStartTag = voidTag.children.find((child) => child.type === "html_start_tag");
297
+ attributeNodes = voidStartTag
298
+ ? voidStartTag.children.filter((child) => child.type === "html_attribute")
299
+ : [];
300
+ }
301
+ else {
302
+ // For regular and self-closing tags, attributes are directly in the tag
303
+ attributeNodes = tagToUse.children.filter((child) => child.type === "html_attribute");
304
+ }
118
305
  for (const attrNode of attributeNodes) {
119
306
  const nameNode = attrNode.children.find((child) => child.type === "html_attribute_name");
120
307
  if (!nameNode)
@@ -140,11 +327,12 @@ function parse(content) {
140
327
  }
141
328
  attributes.push(attribute);
142
329
  }
143
- const elementChildren = [];
330
+ // Collect raw children first (before nesting processing)
331
+ const rawChildren = [];
144
332
  // Process all children that are not start/end tags
145
333
  for (const child of node.children) {
146
334
  if (child.type === "content") {
147
- elementChildren.push({
335
+ rawChildren.push({
148
336
  type: "content",
149
337
  content: child.text,
150
338
  });
@@ -152,16 +340,36 @@ function parse(content) {
152
340
  else if (child.type === "html_element") {
153
341
  const nestedElement = convertHtmlElement(child);
154
342
  if (nestedElement) {
155
- elementChildren.push(nestedElement);
343
+ rawChildren.push(nestedElement);
156
344
  }
157
345
  }
158
346
  else if (child.type === "html_entity") {
159
347
  const entityNode = convertHtmlEntity(child);
160
348
  if (entityNode) {
161
- elementChildren.push(entityNode);
349
+ rawChildren.push(entityNode);
350
+ }
351
+ }
352
+ else if (child.type === "twig_comment") {
353
+ const commentNode = convertTwigComment(child);
354
+ if (commentNode) {
355
+ rawChildren.push(commentNode);
356
+ }
357
+ }
358
+ else if (child.type === "vue_interpolation") {
359
+ const interpolationNode = convertVueInterpolation(child);
360
+ if (interpolationNode) {
361
+ rawChildren.push(interpolationNode);
362
+ }
363
+ }
364
+ else if (child.type === "statement_directive") {
365
+ const converted = convertStatementDirective(child);
366
+ if (converted) {
367
+ rawChildren.push(converted);
162
368
  }
163
369
  }
164
370
  }
371
+ // Apply block nesting within this HTML element's scope
372
+ const elementChildren = buildNestedStructureForElement(rawChildren);
165
373
  const result = {
166
374
  type: "html_element",
167
375
  name: tagName.text,
@@ -201,8 +409,20 @@ function parse(content) {
201
409
  allNodes.push(entityNode);
202
410
  }
203
411
  }
412
+ else if (child.type === "twig_comment") {
413
+ const commentNode = convertTwigComment(child);
414
+ if (commentNode) {
415
+ allNodes.push(commentNode);
416
+ }
417
+ }
418
+ else if (child.type === "vue_interpolation") {
419
+ const interpolationNode = convertVueInterpolation(child);
420
+ if (interpolationNode) {
421
+ allNodes.push(interpolationNode);
422
+ }
423
+ }
204
424
  else {
205
- const converted = convertNode(child);
425
+ const converted = convertStatementDirective(child);
206
426
  if (converted) {
207
427
  rawNodes.push(converted);
208
428
  allNodes.push(converted);
@@ -375,6 +595,34 @@ function parse(content) {
375
595
  result.push(entityNode);
376
596
  }
377
597
  }
598
+ else if (node.type === "twig_comment" && "content" in node) {
599
+ const commentNode = node;
600
+ if (stack.length > 0) {
601
+ // Add to the current parent's children
602
+ const parent = stack[stack.length - 1];
603
+ if (parent && parent.children) {
604
+ parent.children.push(commentNode);
605
+ }
606
+ }
607
+ else {
608
+ // Add to root level
609
+ result.push(commentNode);
610
+ }
611
+ }
612
+ else if (node.type === "vue_interpolation" && "expression" in node) {
613
+ const interpolationNode = node;
614
+ if (stack.length > 0) {
615
+ // Add to the current parent's children
616
+ const parent = stack[stack.length - 1];
617
+ if (parent && parent.children) {
618
+ parent.children.push(interpolationNode);
619
+ }
620
+ }
621
+ else {
622
+ // Add to root level
623
+ result.push(interpolationNode);
624
+ }
625
+ }
378
626
  }
379
627
  return result;
380
628
  }