shopware-twig-parser 0.2.0 → 0.3.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[];
6
+ children: (TwigStatementDirectiveNode | HtmlElementNode | ContentNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
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)[];
14
+ children?: (TwigStatementDirectiveNode | ContentNode | HtmlElementNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
15
15
  };
16
16
  type TwigConditionNode = {
17
17
  type: "twig_condition";
@@ -37,6 +37,29 @@ type TwigFunctionNode = {
37
37
  type: "twig_function";
38
38
  name: string;
39
39
  };
40
+ type HtmlAttributeNode = {
41
+ type: "html_attribute";
42
+ name: string;
43
+ value?: string;
44
+ };
45
+ type HtmlElementNode = {
46
+ type: "html_element";
47
+ name: string;
48
+ attributes?: HtmlAttributeNode[];
49
+ children: (HtmlElementNode | ContentNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
50
+ void?: boolean;
51
+ };
52
+ type HtmlDoctypeNode = {
53
+ type: "doctype";
54
+ };
55
+ type HtmlNamedEntityNode = {
56
+ type: "html_named_entity";
57
+ content: string;
58
+ };
59
+ type HtmlNumericEntityNode = {
60
+ type: "html_numeric_entity";
61
+ content: string;
62
+ };
40
63
  export declare function parse(content: string): Tree;
41
64
  export {};
42
65
  //# 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,0BAA0B,EAAE,CAAC;CACxC,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,CAAC,0BAA0B,GAAG,WAAW,CAAC,EAAE,CAAC;CACzD,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;AAMF,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA6O3C"}
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,CAoe3C"}
@@ -65,6 +65,106 @@ function parse(content) {
65
65
  const rawNodes = [];
66
66
  // Also collect content nodes
67
67
  const allNodes = [];
68
+ function convertHtmlEntity(node) {
69
+ if (node.type === "html_entity") {
70
+ const entityText = node.text;
71
+ // Check if it's a numeric entity (starts with &#)
72
+ if (entityText.startsWith("&#")) {
73
+ return {
74
+ type: "html_numeric_entity",
75
+ content: entityText,
76
+ };
77
+ }
78
+ else if (entityText.startsWith("&")) {
79
+ return {
80
+ type: "html_named_entity",
81
+ content: entityText,
82
+ };
83
+ }
84
+ }
85
+ return null;
86
+ }
87
+ function convertHtmlElement(node) {
88
+ if (node.type === "html_element") {
89
+ // Check for self-closing tag first
90
+ const selfClosingTag = node.children.find((child) => child.type === "html_self_closing_tag");
91
+ // Find the start tag to get the element name
92
+ const startTag = node.children.find((child) => child.type === "html_start_tag");
93
+ // Use self-closing tag if available, otherwise start tag
94
+ const tagToUse = selfClosingTag || startTag;
95
+ if (!tagToUse)
96
+ return null;
97
+ const tagName = tagToUse.children.find((child) => child.type === "html_tag_name");
98
+ if (!tagName)
99
+ return null;
100
+ // Check if this is a void element (no end tag and not self-closing)
101
+ const hasEndTag = node.children.some((child) => child.type === "html_end_tag");
102
+ const isVoid = !hasEndTag;
103
+ // Parse attributes from the tag (either self-closing or start tag)
104
+ const attributes = [];
105
+ const attributeNodes = tagToUse.children.filter((child) => child.type === "html_attribute");
106
+ for (const attrNode of attributeNodes) {
107
+ const nameNode = attrNode.children.find((child) => child.type === "html_attribute_name");
108
+ if (!nameNode)
109
+ continue;
110
+ const valueNode = attrNode.children.find((child) => child.type === "html_attribute_value");
111
+ const quotedValueNode = attrNode.children.find((child) => child.type === "html_quoted_attribute_value");
112
+ let value;
113
+ if (quotedValueNode) {
114
+ // For quoted values, find the inner html_attribute_value
115
+ const innerValueNode = quotedValueNode.children.find((child) => child.type === "html_attribute_value");
116
+ value = innerValueNode ? innerValueNode.text : undefined;
117
+ }
118
+ else if (valueNode) {
119
+ value = valueNode.text;
120
+ }
121
+ const attribute = {
122
+ type: "html_attribute",
123
+ name: nameNode.text,
124
+ };
125
+ // Only include value property if there's actually a value
126
+ if (value !== undefined) {
127
+ attribute.value = value;
128
+ }
129
+ attributes.push(attribute);
130
+ }
131
+ const elementChildren = [];
132
+ // Process all children that are not start/end tags
133
+ for (const child of node.children) {
134
+ if (child.type === "content") {
135
+ elementChildren.push({
136
+ type: "content",
137
+ content: child.text,
138
+ });
139
+ }
140
+ else if (child.type === "html_element") {
141
+ const nestedElement = convertHtmlElement(child);
142
+ if (nestedElement) {
143
+ elementChildren.push(nestedElement);
144
+ }
145
+ }
146
+ else if (child.type === "html_entity") {
147
+ const entityNode = convertHtmlEntity(child);
148
+ if (entityNode) {
149
+ elementChildren.push(entityNode);
150
+ }
151
+ }
152
+ }
153
+ const result = {
154
+ type: "html_element",
155
+ name: tagName.text,
156
+ children: elementChildren,
157
+ };
158
+ if (attributes.length > 0) {
159
+ result.attributes = attributes;
160
+ }
161
+ if (isVoid) {
162
+ result.void = true;
163
+ }
164
+ return result;
165
+ }
166
+ return null;
167
+ }
68
168
  for (const child of tree.rootNode.children) {
69
169
  if (child.type === "content") {
70
170
  allNodes.push({
@@ -72,6 +172,23 @@ function parse(content) {
72
172
  content: child.text,
73
173
  });
74
174
  }
175
+ else if (child.type === "html_element") {
176
+ const htmlElement = convertHtmlElement(child);
177
+ if (htmlElement) {
178
+ allNodes.push(htmlElement);
179
+ }
180
+ }
181
+ else if (child.type === "html_doctype") {
182
+ allNodes.push({
183
+ type: "doctype",
184
+ });
185
+ }
186
+ else if (child.type === "html_entity") {
187
+ const entityNode = convertHtmlEntity(child);
188
+ if (entityNode) {
189
+ allNodes.push(entityNode);
190
+ }
191
+ }
75
192
  else {
76
193
  const converted = convertNode(child);
77
194
  if (converted) {
@@ -187,6 +304,65 @@ function parse(content) {
187
304
  });
188
305
  }
189
306
  }
307
+ else if (node.type === "html_element" && "name" in node) {
308
+ // HTML elements are already processed and can be added directly
309
+ const htmlNode = node;
310
+ if (stack.length > 0) {
311
+ // Add to the current parent's children
312
+ const parent = stack[stack.length - 1];
313
+ if (parent && parent.children) {
314
+ parent.children.push(htmlNode);
315
+ }
316
+ }
317
+ else {
318
+ // Add to root level
319
+ result.push(htmlNode);
320
+ }
321
+ }
322
+ else if (node.type === "doctype") {
323
+ const doctypeNode = {
324
+ type: "doctype",
325
+ };
326
+ if (stack.length > 0) {
327
+ // Add to the current parent's children
328
+ const parent = stack[stack.length - 1];
329
+ if (parent && parent.children) {
330
+ parent.children.push(doctypeNode);
331
+ }
332
+ }
333
+ else {
334
+ // Add to root level
335
+ result.push(doctypeNode);
336
+ }
337
+ }
338
+ else if (node.type === "html_named_entity" && "content" in node) {
339
+ const entityNode = node;
340
+ if (stack.length > 0) {
341
+ // Add to the current parent's children
342
+ const parent = stack[stack.length - 1];
343
+ if (parent && parent.children) {
344
+ parent.children.push(entityNode);
345
+ }
346
+ }
347
+ else {
348
+ // Add to root level
349
+ result.push(entityNode);
350
+ }
351
+ }
352
+ else if (node.type === "html_numeric_entity" && "content" in node) {
353
+ const entityNode = node;
354
+ if (stack.length > 0) {
355
+ // Add to the current parent's children
356
+ const parent = stack[stack.length - 1];
357
+ if (parent && parent.children) {
358
+ parent.children.push(entityNode);
359
+ }
360
+ }
361
+ else {
362
+ // Add to root level
363
+ result.push(entityNode);
364
+ }
365
+ }
190
366
  }
191
367
  return result;
192
368
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import Parser from \"tree-sitter\";\nimport ShopwareTwig from \"tree-sitter-shopware-twig\";\n\ntype Tree = {\n rootNode: TemplateNode;\n};\n\ntype TemplateNode = {\n type: \"template\";\n children: TwigStatementDirectiveNode[];\n};\n\ntype TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\";\n tag?: TwigTagNode;\n variable?: TwigVariableNode;\n function?: TwigFunctionNode;\n condition?: TwigConditionNode;\n children?: (TwigStatementDirectiveNode | ContentNode)[];\n};\n\ntype TwigConditionNode = {\n type: \"twig_condition\";\n expression: TwigExpressionNode;\n};\n\ntype TwigExpressionNode = {\n type: \"twig_expression\";\n content: string;\n};\n\ntype ContentNode = {\n type: \"content\";\n content: string;\n};\n\ntype TwigTagNode = {\n type: \"twig_tag\";\n name: string;\n};\n\ntype TwigVariableNode = {\n type: \"twig_variable\";\n content: string;\n};\n\ntype TwigFunctionNode = {\n type: \"twig_function\";\n name: string;\n};\n\nconst parser = new Parser();\n// @ts-expect-error\nparser.setLanguage(ShopwareTwig);\n\nexport function parse(content: string): Tree {\n const tree = parser.parse(content);\n\n function convertNode(node: any): {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n } | null {\n if (node.type === \"statement_directive\") {\n // Check for if_statement\n const ifStatement = node.children.find(\n (child: any) => child.type === \"if_statement\"\n );\n if (ifStatement) {\n const conditionalNode = ifStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = ifStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (conditionalNode && conditionalNode.text === \"if\" && variableNode) {\n return {\n type: \"if\",\n expression: variableNode.text,\n };\n }\n }\n\n // Check for tag_statement\n const tagStatement = node.children.find(\n (child: any) => child.type === \"tag_statement\"\n );\n const functionCall = node.children.find(\n (child: any) => child.type === \"function_call\"\n );\n\n if (tagStatement) {\n const tagNode = tagStatement.children.find(\n (child: any) => child.type === \"tag\"\n );\n const conditionalNode = tagStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = tagStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (tagNode && tagNode.text === \"block\" && variableNode) {\n return {\n type: \"block\",\n name: variableNode.text,\n };\n } else if (tagNode && tagNode.text === \"endblock\") {\n return {\n type: \"endblock\",\n };\n } else if (conditionalNode && conditionalNode.text === \"endif\") {\n return {\n type: \"endif\",\n };\n }\n } else if (functionCall) {\n const functionIdentifier = functionCall.children.find(\n (child: any) => child.type === \"function_identifier\"\n );\n\n if (functionIdentifier) {\n return {\n type: \"function\",\n functionName: functionIdentifier.text,\n };\n }\n }\n }\n return null;\n }\n\n // First pass: convert all nodes to intermediate format\n const rawNodes: {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n }[] = [];\n\n // Also collect content nodes\n const allNodes: Array<{\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\" | \"content\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }> = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === \"content\") {\n allNodes.push({\n type: \"content\",\n content: child.text,\n });\n } else {\n const converted = convertNode(child);\n if (converted) {\n rawNodes.push(converted);\n allNodes.push(converted);\n }\n }\n }\n\n // Second pass: build nested structure using a stack\n function buildNestedStructure(\n nodes: Array<{\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\" | \"content\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }>\n ): TwigStatementDirectiveNode[] {\n const result: TwigStatementDirectiveNode[] = [];\n const stack: TwigStatementDirectiveNode[] = [];\n\n for (const node of nodes) {\n if (node.type === \"block\") {\n const blockNode: TwigStatementDirectiveNode = {\n tag: {\n type: \"twig_tag\",\n name: \"block\",\n },\n type: \"twig_statement_directive\",\n variable: {\n type: \"twig_variable\",\n content: node.name!,\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(blockNode);\n }\n } else {\n // Add to root level\n result.push(blockNode);\n }\n\n // Push to stack for nesting\n stack.push(blockNode);\n } else if (node.type === \"endblock\") {\n // Pop from stack when we encounter an endblock\n stack.pop();\n } else if (node.type === \"if\") {\n const ifNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n condition: {\n type: \"twig_condition\",\n expression: {\n type: \"twig_expression\",\n content: node.expression!,\n },\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(ifNode);\n }\n } else {\n // Add to root level\n result.push(ifNode);\n }\n\n // Push to stack for nesting\n stack.push(ifNode);\n } else if (node.type === \"endif\") {\n // Pop from stack when we encounter an endif\n stack.pop();\n } else if (node.type === \"function\") {\n const functionNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n function: {\n type: \"twig_function\",\n name: node.functionName!,\n },\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(functionNode);\n }\n } else {\n // Add to root level\n result.push(functionNode);\n }\n } else if (node.type === \"content\") {\n const contentNode: ContentNode = {\n type: \"content\",\n content: node.content!,\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(contentNode);\n }\n } else {\n // Content at root level - this shouldn't happen in well-formed templates\n // but we'll handle it gracefully\n result.push({\n type: \"twig_statement_directive\",\n children: [contentNode],\n });\n }\n }\n }\n\n return result;\n }\n\n const children = buildNestedStructure(allNodes);\n\n return {\n rootNode: {\n type: \"template\",\n children,\n },\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import Parser from \"tree-sitter\";\nimport ShopwareTwig from \"tree-sitter-shopware-twig\";\n\ntype Tree = {\n rootNode: TemplateNode;\n};\n\ntype TemplateNode = {\n type: \"template\";\n children: (\n | TwigStatementDirectiveNode\n | HtmlElementNode\n | ContentNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[];\n};\n\ntype TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\";\n tag?: TwigTagNode;\n variable?: TwigVariableNode;\n function?: TwigFunctionNode;\n condition?: TwigConditionNode;\n children?: (\n | TwigStatementDirectiveNode\n | ContentNode\n | HtmlElementNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[];\n};\n\ntype TwigConditionNode = {\n type: \"twig_condition\";\n expression: TwigExpressionNode;\n};\n\ntype TwigExpressionNode = {\n type: \"twig_expression\";\n content: string;\n};\n\ntype ContentNode = {\n type: \"content\";\n content: string;\n};\n\ntype TwigTagNode = {\n type: \"twig_tag\";\n name: string;\n};\n\ntype TwigVariableNode = {\n type: \"twig_variable\";\n content: string;\n};\n\ntype TwigFunctionNode = {\n type: \"twig_function\";\n name: string;\n};\n\ntype HtmlAttributeNode = {\n type: \"html_attribute\";\n name: string;\n value?: string;\n};\n\ntype HtmlElementNode = {\n type: \"html_element\";\n name: string;\n attributes?: HtmlAttributeNode[];\n children: (\n | HtmlElementNode\n | ContentNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[];\n void?: boolean;\n};\n\ntype HtmlDoctypeNode = {\n type: \"doctype\";\n};\n\ntype HtmlNamedEntityNode = {\n type: \"html_named_entity\";\n content: string;\n};\n\ntype HtmlNumericEntityNode = {\n type: \"html_numeric_entity\";\n content: string;\n};\n\nconst parser = new Parser();\n// @ts-expect-error\nparser.setLanguage(ShopwareTwig);\n\nexport function parse(content: string): Tree {\n const tree = parser.parse(content);\n\n function convertNode(node: any): {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n } | null {\n if (node.type === \"statement_directive\") {\n // Check for if_statement\n const ifStatement = node.children.find(\n (child: any) => child.type === \"if_statement\"\n );\n if (ifStatement) {\n const conditionalNode = ifStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = ifStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (conditionalNode && conditionalNode.text === \"if\" && variableNode) {\n return {\n type: \"if\",\n expression: variableNode.text,\n };\n }\n }\n\n // Check for tag_statement\n const tagStatement = node.children.find(\n (child: any) => child.type === \"tag_statement\"\n );\n const functionCall = node.children.find(\n (child: any) => child.type === \"function_call\"\n );\n\n if (tagStatement) {\n const tagNode = tagStatement.children.find(\n (child: any) => child.type === \"tag\"\n );\n const conditionalNode = tagStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = tagStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (tagNode && tagNode.text === \"block\" && variableNode) {\n return {\n type: \"block\",\n name: variableNode.text,\n };\n } else if (tagNode && tagNode.text === \"endblock\") {\n return {\n type: \"endblock\",\n };\n } else if (conditionalNode && conditionalNode.text === \"endif\") {\n return {\n type: \"endif\",\n };\n }\n } else if (functionCall) {\n const functionIdentifier = functionCall.children.find(\n (child: any) => child.type === \"function_identifier\"\n );\n\n if (functionIdentifier) {\n return {\n type: \"function\",\n functionName: functionIdentifier.text,\n };\n }\n }\n }\n return null;\n }\n\n // First pass: convert all nodes to intermediate format\n const rawNodes: {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n }[] = [];\n\n // Also collect content nodes\n const allNodes: Array<\n | {\n type:\n | \"block\"\n | \"endblock\"\n | \"function\"\n | \"if\"\n | \"endif\"\n | \"content\"\n | \"html_element\"\n | \"doctype\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }\n | HtmlElementNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n > = [];\n\n function convertHtmlEntity(\n node: any\n ): HtmlNamedEntityNode | HtmlNumericEntityNode | null {\n if (node.type === \"html_entity\") {\n const entityText = node.text;\n\n // Check if it's a numeric entity (starts with &#)\n if (entityText.startsWith(\"&#\")) {\n return {\n type: \"html_numeric_entity\",\n content: entityText,\n };\n } else if (entityText.startsWith(\"&\")) {\n return {\n type: \"html_named_entity\",\n content: entityText,\n };\n }\n }\n return null;\n }\n\n function convertHtmlElement(node: any): HtmlElementNode | null {\n if (node.type === \"html_element\") {\n // Check for self-closing tag first\n const selfClosingTag = node.children.find(\n (child: any) => child.type === \"html_self_closing_tag\"\n );\n\n // Find the start tag to get the element name\n const startTag = node.children.find(\n (child: any) => child.type === \"html_start_tag\"\n );\n\n // Use self-closing tag if available, otherwise start tag\n const tagToUse = selfClosingTag || startTag;\n if (!tagToUse) return null;\n\n const tagName = tagToUse.children.find(\n (child: any) => child.type === \"html_tag_name\"\n );\n if (!tagName) return null;\n\n // Check if this is a void element (no end tag and not self-closing)\n const hasEndTag = node.children.some(\n (child: any) => child.type === \"html_end_tag\"\n );\n const isVoid = !hasEndTag;\n\n // Parse attributes from the tag (either self-closing or start tag)\n const attributes: HtmlAttributeNode[] = [];\n const attributeNodes = tagToUse.children.filter(\n (child: any) => child.type === \"html_attribute\"\n );\n\n for (const attrNode of attributeNodes) {\n const nameNode = attrNode.children.find(\n (child: any) => child.type === \"html_attribute_name\"\n );\n if (!nameNode) continue;\n\n const valueNode = attrNode.children.find(\n (child: any) => child.type === \"html_attribute_value\"\n );\n const quotedValueNode = attrNode.children.find(\n (child: any) => child.type === \"html_quoted_attribute_value\"\n );\n\n let value: string | undefined;\n if (quotedValueNode) {\n // For quoted values, find the inner html_attribute_value\n const innerValueNode = quotedValueNode.children.find(\n (child: any) => child.type === \"html_attribute_value\"\n );\n value = innerValueNode ? innerValueNode.text : undefined;\n } else if (valueNode) {\n value = valueNode.text;\n }\n\n const attribute: HtmlAttributeNode = {\n type: \"html_attribute\",\n name: nameNode.text,\n };\n\n // Only include value property if there's actually a value\n if (value !== undefined) {\n attribute.value = value;\n }\n\n attributes.push(attribute);\n }\n\n const elementChildren: (\n | HtmlElementNode\n | ContentNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[] = [];\n\n // Process all children that are not start/end tags\n for (const child of node.children) {\n if (child.type === \"content\") {\n elementChildren.push({\n type: \"content\",\n content: child.text,\n });\n } else if (child.type === \"html_element\") {\n const nestedElement = convertHtmlElement(child);\n if (nestedElement) {\n elementChildren.push(nestedElement);\n }\n } else if (child.type === \"html_entity\") {\n const entityNode = convertHtmlEntity(child);\n if (entityNode) {\n elementChildren.push(entityNode);\n }\n }\n }\n\n const result: HtmlElementNode = {\n type: \"html_element\",\n name: tagName.text,\n children: elementChildren,\n };\n\n if (attributes.length > 0) {\n result.attributes = attributes;\n }\n\n if (isVoid) {\n result.void = true;\n }\n\n return result;\n }\n return null;\n }\n\n for (const child of tree.rootNode.children) {\n if (child.type === \"content\") {\n allNodes.push({\n type: \"content\",\n content: child.text,\n });\n } else if (child.type === \"html_element\") {\n const htmlElement = convertHtmlElement(child);\n if (htmlElement) {\n allNodes.push(htmlElement);\n }\n } else if (child.type === \"html_doctype\") {\n allNodes.push({\n type: \"doctype\",\n });\n } else if (child.type === \"html_entity\") {\n const entityNode = convertHtmlEntity(child);\n if (entityNode) {\n allNodes.push(entityNode);\n }\n } else {\n const converted = convertNode(child);\n if (converted) {\n rawNodes.push(converted);\n allNodes.push(converted);\n }\n }\n }\n\n // Second pass: build nested structure using a stack\n function buildNestedStructure(\n nodes: Array<\n | {\n type:\n | \"block\"\n | \"endblock\"\n | \"function\"\n | \"if\"\n | \"endif\"\n | \"content\"\n | \"html_element\"\n | \"doctype\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }\n | HtmlElementNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n >\n ): (\n | TwigStatementDirectiveNode\n | HtmlElementNode\n | ContentNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[] {\n const result: (\n | TwigStatementDirectiveNode\n | HtmlElementNode\n | ContentNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[] = [];\n const stack: TwigStatementDirectiveNode[] = [];\n\n for (const node of nodes) {\n if (node.type === \"block\") {\n const blockNode: TwigStatementDirectiveNode = {\n tag: {\n type: \"twig_tag\",\n name: \"block\",\n },\n type: \"twig_statement_directive\",\n variable: {\n type: \"twig_variable\",\n content: node.name!,\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(blockNode);\n }\n } else {\n // Add to root level\n result.push(blockNode);\n }\n\n // Push to stack for nesting\n stack.push(blockNode);\n } else if (node.type === \"endblock\") {\n // Pop from stack when we encounter an endblock\n stack.pop();\n } else if (node.type === \"if\") {\n const ifNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n condition: {\n type: \"twig_condition\",\n expression: {\n type: \"twig_expression\",\n content: node.expression!,\n },\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(ifNode);\n }\n } else {\n // Add to root level\n result.push(ifNode);\n }\n\n // Push to stack for nesting\n stack.push(ifNode);\n } else if (node.type === \"endif\") {\n // Pop from stack when we encounter an endif\n stack.pop();\n } else if (node.type === \"function\") {\n const functionNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n function: {\n type: \"twig_function\",\n name: node.functionName!,\n },\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(functionNode);\n }\n } else {\n // Add to root level\n result.push(functionNode);\n }\n } else if (node.type === \"content\") {\n const contentNode: ContentNode = {\n type: \"content\",\n content: node.content!,\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(contentNode);\n }\n } else {\n // Content at root level - this shouldn't happen in well-formed templates\n // but we'll handle it gracefully\n result.push({\n type: \"twig_statement_directive\",\n children: [contentNode],\n });\n }\n } else if (node.type === \"html_element\" && \"name\" in node) {\n // HTML elements are already processed and can be added directly\n const htmlNode = node as HtmlElementNode;\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(htmlNode);\n }\n } else {\n // Add to root level\n result.push(htmlNode);\n }\n } else if (node.type === \"doctype\") {\n const doctypeNode: HtmlDoctypeNode = {\n type: \"doctype\",\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(doctypeNode);\n }\n } else {\n // Add to root level\n result.push(doctypeNode);\n }\n } else if (node.type === \"html_named_entity\" && \"content\" in node) {\n const entityNode = node as HtmlNamedEntityNode;\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(entityNode);\n }\n } else {\n // Add to root level\n result.push(entityNode);\n }\n } else if (node.type === \"html_numeric_entity\" && \"content\" in node) {\n const entityNode = node as HtmlNumericEntityNode;\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(entityNode);\n }\n } else {\n // Add to root level\n result.push(entityNode);\n }\n }\n }\n\n return result;\n }\n\n const children = buildNestedStructure(allNodes);\n\n return {\n rootNode: {\n type: \"template\",\n children,\n },\n };\n}\n"]}
@@ -3,7 +3,7 @@ type Tree = {
3
3
  };
4
4
  type TemplateNode = {
5
5
  type: "template";
6
- children: TwigStatementDirectiveNode[];
6
+ children: (TwigStatementDirectiveNode | HtmlElementNode | ContentNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
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)[];
14
+ children?: (TwigStatementDirectiveNode | ContentNode | HtmlElementNode | HtmlDoctypeNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
15
15
  };
16
16
  type TwigConditionNode = {
17
17
  type: "twig_condition";
@@ -37,6 +37,29 @@ type TwigFunctionNode = {
37
37
  type: "twig_function";
38
38
  name: string;
39
39
  };
40
+ type HtmlAttributeNode = {
41
+ type: "html_attribute";
42
+ name: string;
43
+ value?: string;
44
+ };
45
+ type HtmlElementNode = {
46
+ type: "html_element";
47
+ name: string;
48
+ attributes?: HtmlAttributeNode[];
49
+ children: (HtmlElementNode | ContentNode | HtmlNamedEntityNode | HtmlNumericEntityNode)[];
50
+ void?: boolean;
51
+ };
52
+ type HtmlDoctypeNode = {
53
+ type: "doctype";
54
+ };
55
+ type HtmlNamedEntityNode = {
56
+ type: "html_named_entity";
57
+ content: string;
58
+ };
59
+ type HtmlNumericEntityNode = {
60
+ type: "html_numeric_entity";
61
+ content: string;
62
+ };
40
63
  export declare function parse(content: string): Tree;
41
64
  export {};
42
65
  //# 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,0BAA0B,EAAE,CAAC;CACxC,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,CAAC,0BAA0B,GAAG,WAAW,CAAC,EAAE,CAAC;CACzD,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;AAMF,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA6O3C"}
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,CAoe3C"}
package/dist/esm/index.js CHANGED
@@ -59,6 +59,106 @@ export function parse(content) {
59
59
  const rawNodes = [];
60
60
  // Also collect content nodes
61
61
  const allNodes = [];
62
+ function convertHtmlEntity(node) {
63
+ if (node.type === "html_entity") {
64
+ const entityText = node.text;
65
+ // Check if it's a numeric entity (starts with &#)
66
+ if (entityText.startsWith("&#")) {
67
+ return {
68
+ type: "html_numeric_entity",
69
+ content: entityText,
70
+ };
71
+ }
72
+ else if (entityText.startsWith("&")) {
73
+ return {
74
+ type: "html_named_entity",
75
+ content: entityText,
76
+ };
77
+ }
78
+ }
79
+ return null;
80
+ }
81
+ function convertHtmlElement(node) {
82
+ if (node.type === "html_element") {
83
+ // Check for self-closing tag first
84
+ const selfClosingTag = node.children.find((child) => child.type === "html_self_closing_tag");
85
+ // Find the start tag to get the element name
86
+ const startTag = node.children.find((child) => child.type === "html_start_tag");
87
+ // Use self-closing tag if available, otherwise start tag
88
+ const tagToUse = selfClosingTag || startTag;
89
+ if (!tagToUse)
90
+ return null;
91
+ const tagName = tagToUse.children.find((child) => child.type === "html_tag_name");
92
+ if (!tagName)
93
+ return null;
94
+ // Check if this is a void element (no end tag and not self-closing)
95
+ const hasEndTag = node.children.some((child) => child.type === "html_end_tag");
96
+ const isVoid = !hasEndTag;
97
+ // Parse attributes from the tag (either self-closing or start tag)
98
+ const attributes = [];
99
+ const attributeNodes = tagToUse.children.filter((child) => child.type === "html_attribute");
100
+ for (const attrNode of attributeNodes) {
101
+ const nameNode = attrNode.children.find((child) => child.type === "html_attribute_name");
102
+ if (!nameNode)
103
+ continue;
104
+ const valueNode = attrNode.children.find((child) => child.type === "html_attribute_value");
105
+ const quotedValueNode = attrNode.children.find((child) => child.type === "html_quoted_attribute_value");
106
+ let value;
107
+ if (quotedValueNode) {
108
+ // For quoted values, find the inner html_attribute_value
109
+ const innerValueNode = quotedValueNode.children.find((child) => child.type === "html_attribute_value");
110
+ value = innerValueNode ? innerValueNode.text : undefined;
111
+ }
112
+ else if (valueNode) {
113
+ value = valueNode.text;
114
+ }
115
+ const attribute = {
116
+ type: "html_attribute",
117
+ name: nameNode.text,
118
+ };
119
+ // Only include value property if there's actually a value
120
+ if (value !== undefined) {
121
+ attribute.value = value;
122
+ }
123
+ attributes.push(attribute);
124
+ }
125
+ const elementChildren = [];
126
+ // Process all children that are not start/end tags
127
+ for (const child of node.children) {
128
+ if (child.type === "content") {
129
+ elementChildren.push({
130
+ type: "content",
131
+ content: child.text,
132
+ });
133
+ }
134
+ else if (child.type === "html_element") {
135
+ const nestedElement = convertHtmlElement(child);
136
+ if (nestedElement) {
137
+ elementChildren.push(nestedElement);
138
+ }
139
+ }
140
+ else if (child.type === "html_entity") {
141
+ const entityNode = convertHtmlEntity(child);
142
+ if (entityNode) {
143
+ elementChildren.push(entityNode);
144
+ }
145
+ }
146
+ }
147
+ const result = {
148
+ type: "html_element",
149
+ name: tagName.text,
150
+ children: elementChildren,
151
+ };
152
+ if (attributes.length > 0) {
153
+ result.attributes = attributes;
154
+ }
155
+ if (isVoid) {
156
+ result.void = true;
157
+ }
158
+ return result;
159
+ }
160
+ return null;
161
+ }
62
162
  for (const child of tree.rootNode.children) {
63
163
  if (child.type === "content") {
64
164
  allNodes.push({
@@ -66,6 +166,23 @@ export function parse(content) {
66
166
  content: child.text,
67
167
  });
68
168
  }
169
+ else if (child.type === "html_element") {
170
+ const htmlElement = convertHtmlElement(child);
171
+ if (htmlElement) {
172
+ allNodes.push(htmlElement);
173
+ }
174
+ }
175
+ else if (child.type === "html_doctype") {
176
+ allNodes.push({
177
+ type: "doctype",
178
+ });
179
+ }
180
+ else if (child.type === "html_entity") {
181
+ const entityNode = convertHtmlEntity(child);
182
+ if (entityNode) {
183
+ allNodes.push(entityNode);
184
+ }
185
+ }
69
186
  else {
70
187
  const converted = convertNode(child);
71
188
  if (converted) {
@@ -181,6 +298,65 @@ export function parse(content) {
181
298
  });
182
299
  }
183
300
  }
301
+ else if (node.type === "html_element" && "name" in node) {
302
+ // HTML elements are already processed and can be added directly
303
+ const htmlNode = node;
304
+ if (stack.length > 0) {
305
+ // Add to the current parent's children
306
+ const parent = stack[stack.length - 1];
307
+ if (parent && parent.children) {
308
+ parent.children.push(htmlNode);
309
+ }
310
+ }
311
+ else {
312
+ // Add to root level
313
+ result.push(htmlNode);
314
+ }
315
+ }
316
+ else if (node.type === "doctype") {
317
+ const doctypeNode = {
318
+ type: "doctype",
319
+ };
320
+ if (stack.length > 0) {
321
+ // Add to the current parent's children
322
+ const parent = stack[stack.length - 1];
323
+ if (parent && parent.children) {
324
+ parent.children.push(doctypeNode);
325
+ }
326
+ }
327
+ else {
328
+ // Add to root level
329
+ result.push(doctypeNode);
330
+ }
331
+ }
332
+ else if (node.type === "html_named_entity" && "content" in node) {
333
+ const entityNode = node;
334
+ if (stack.length > 0) {
335
+ // Add to the current parent's children
336
+ const parent = stack[stack.length - 1];
337
+ if (parent && parent.children) {
338
+ parent.children.push(entityNode);
339
+ }
340
+ }
341
+ else {
342
+ // Add to root level
343
+ result.push(entityNode);
344
+ }
345
+ }
346
+ else if (node.type === "html_numeric_entity" && "content" in node) {
347
+ const entityNode = node;
348
+ if (stack.length > 0) {
349
+ // Add to the current parent's children
350
+ const parent = stack[stack.length - 1];
351
+ if (parent && parent.children) {
352
+ parent.children.push(entityNode);
353
+ }
354
+ }
355
+ else {
356
+ // Add to root level
357
+ result.push(entityNode);
358
+ }
359
+ }
184
360
  }
185
361
  return result;
186
362
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import Parser from \"tree-sitter\";\nimport ShopwareTwig from \"tree-sitter-shopware-twig\";\n\ntype Tree = {\n rootNode: TemplateNode;\n};\n\ntype TemplateNode = {\n type: \"template\";\n children: TwigStatementDirectiveNode[];\n};\n\ntype TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\";\n tag?: TwigTagNode;\n variable?: TwigVariableNode;\n function?: TwigFunctionNode;\n condition?: TwigConditionNode;\n children?: (TwigStatementDirectiveNode | ContentNode)[];\n};\n\ntype TwigConditionNode = {\n type: \"twig_condition\";\n expression: TwigExpressionNode;\n};\n\ntype TwigExpressionNode = {\n type: \"twig_expression\";\n content: string;\n};\n\ntype ContentNode = {\n type: \"content\";\n content: string;\n};\n\ntype TwigTagNode = {\n type: \"twig_tag\";\n name: string;\n};\n\ntype TwigVariableNode = {\n type: \"twig_variable\";\n content: string;\n};\n\ntype TwigFunctionNode = {\n type: \"twig_function\";\n name: string;\n};\n\nconst parser = new Parser();\n// @ts-expect-error\nparser.setLanguage(ShopwareTwig);\n\nexport function parse(content: string): Tree {\n const tree = parser.parse(content);\n\n function convertNode(node: any): {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n } | null {\n if (node.type === \"statement_directive\") {\n // Check for if_statement\n const ifStatement = node.children.find(\n (child: any) => child.type === \"if_statement\"\n );\n if (ifStatement) {\n const conditionalNode = ifStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = ifStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (conditionalNode && conditionalNode.text === \"if\" && variableNode) {\n return {\n type: \"if\",\n expression: variableNode.text,\n };\n }\n }\n\n // Check for tag_statement\n const tagStatement = node.children.find(\n (child: any) => child.type === \"tag_statement\"\n );\n const functionCall = node.children.find(\n (child: any) => child.type === \"function_call\"\n );\n\n if (tagStatement) {\n const tagNode = tagStatement.children.find(\n (child: any) => child.type === \"tag\"\n );\n const conditionalNode = tagStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = tagStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (tagNode && tagNode.text === \"block\" && variableNode) {\n return {\n type: \"block\",\n name: variableNode.text,\n };\n } else if (tagNode && tagNode.text === \"endblock\") {\n return {\n type: \"endblock\",\n };\n } else if (conditionalNode && conditionalNode.text === \"endif\") {\n return {\n type: \"endif\",\n };\n }\n } else if (functionCall) {\n const functionIdentifier = functionCall.children.find(\n (child: any) => child.type === \"function_identifier\"\n );\n\n if (functionIdentifier) {\n return {\n type: \"function\",\n functionName: functionIdentifier.text,\n };\n }\n }\n }\n return null;\n }\n\n // First pass: convert all nodes to intermediate format\n const rawNodes: {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n }[] = [];\n\n // Also collect content nodes\n const allNodes: Array<{\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\" | \"content\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }> = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === \"content\") {\n allNodes.push({\n type: \"content\",\n content: child.text,\n });\n } else {\n const converted = convertNode(child);\n if (converted) {\n rawNodes.push(converted);\n allNodes.push(converted);\n }\n }\n }\n\n // Second pass: build nested structure using a stack\n function buildNestedStructure(\n nodes: Array<{\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\" | \"content\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }>\n ): TwigStatementDirectiveNode[] {\n const result: TwigStatementDirectiveNode[] = [];\n const stack: TwigStatementDirectiveNode[] = [];\n\n for (const node of nodes) {\n if (node.type === \"block\") {\n const blockNode: TwigStatementDirectiveNode = {\n tag: {\n type: \"twig_tag\",\n name: \"block\",\n },\n type: \"twig_statement_directive\",\n variable: {\n type: \"twig_variable\",\n content: node.name!,\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(blockNode);\n }\n } else {\n // Add to root level\n result.push(blockNode);\n }\n\n // Push to stack for nesting\n stack.push(blockNode);\n } else if (node.type === \"endblock\") {\n // Pop from stack when we encounter an endblock\n stack.pop();\n } else if (node.type === \"if\") {\n const ifNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n condition: {\n type: \"twig_condition\",\n expression: {\n type: \"twig_expression\",\n content: node.expression!,\n },\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(ifNode);\n }\n } else {\n // Add to root level\n result.push(ifNode);\n }\n\n // Push to stack for nesting\n stack.push(ifNode);\n } else if (node.type === \"endif\") {\n // Pop from stack when we encounter an endif\n stack.pop();\n } else if (node.type === \"function\") {\n const functionNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n function: {\n type: \"twig_function\",\n name: node.functionName!,\n },\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(functionNode);\n }\n } else {\n // Add to root level\n result.push(functionNode);\n }\n } else if (node.type === \"content\") {\n const contentNode: ContentNode = {\n type: \"content\",\n content: node.content!,\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(contentNode);\n }\n } else {\n // Content at root level - this shouldn't happen in well-formed templates\n // but we'll handle it gracefully\n result.push({\n type: \"twig_statement_directive\",\n children: [contentNode],\n });\n }\n }\n }\n\n return result;\n }\n\n const children = buildNestedStructure(allNodes);\n\n return {\n rootNode: {\n type: \"template\",\n children,\n },\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import Parser from \"tree-sitter\";\nimport ShopwareTwig from \"tree-sitter-shopware-twig\";\n\ntype Tree = {\n rootNode: TemplateNode;\n};\n\ntype TemplateNode = {\n type: \"template\";\n children: (\n | TwigStatementDirectiveNode\n | HtmlElementNode\n | ContentNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[];\n};\n\ntype TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\";\n tag?: TwigTagNode;\n variable?: TwigVariableNode;\n function?: TwigFunctionNode;\n condition?: TwigConditionNode;\n children?: (\n | TwigStatementDirectiveNode\n | ContentNode\n | HtmlElementNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[];\n};\n\ntype TwigConditionNode = {\n type: \"twig_condition\";\n expression: TwigExpressionNode;\n};\n\ntype TwigExpressionNode = {\n type: \"twig_expression\";\n content: string;\n};\n\ntype ContentNode = {\n type: \"content\";\n content: string;\n};\n\ntype TwigTagNode = {\n type: \"twig_tag\";\n name: string;\n};\n\ntype TwigVariableNode = {\n type: \"twig_variable\";\n content: string;\n};\n\ntype TwigFunctionNode = {\n type: \"twig_function\";\n name: string;\n};\n\ntype HtmlAttributeNode = {\n type: \"html_attribute\";\n name: string;\n value?: string;\n};\n\ntype HtmlElementNode = {\n type: \"html_element\";\n name: string;\n attributes?: HtmlAttributeNode[];\n children: (\n | HtmlElementNode\n | ContentNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[];\n void?: boolean;\n};\n\ntype HtmlDoctypeNode = {\n type: \"doctype\";\n};\n\ntype HtmlNamedEntityNode = {\n type: \"html_named_entity\";\n content: string;\n};\n\ntype HtmlNumericEntityNode = {\n type: \"html_numeric_entity\";\n content: string;\n};\n\nconst parser = new Parser();\n// @ts-expect-error\nparser.setLanguage(ShopwareTwig);\n\nexport function parse(content: string): Tree {\n const tree = parser.parse(content);\n\n function convertNode(node: any): {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n } | null {\n if (node.type === \"statement_directive\") {\n // Check for if_statement\n const ifStatement = node.children.find(\n (child: any) => child.type === \"if_statement\"\n );\n if (ifStatement) {\n const conditionalNode = ifStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = ifStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (conditionalNode && conditionalNode.text === \"if\" && variableNode) {\n return {\n type: \"if\",\n expression: variableNode.text,\n };\n }\n }\n\n // Check for tag_statement\n const tagStatement = node.children.find(\n (child: any) => child.type === \"tag_statement\"\n );\n const functionCall = node.children.find(\n (child: any) => child.type === \"function_call\"\n );\n\n if (tagStatement) {\n const tagNode = tagStatement.children.find(\n (child: any) => child.type === \"tag\"\n );\n const conditionalNode = tagStatement.children.find(\n (child: any) => child.type === \"conditional\"\n );\n const variableNode = tagStatement.children.find(\n (child: any) => child.type === \"variable\"\n );\n\n if (tagNode && tagNode.text === \"block\" && variableNode) {\n return {\n type: \"block\",\n name: variableNode.text,\n };\n } else if (tagNode && tagNode.text === \"endblock\") {\n return {\n type: \"endblock\",\n };\n } else if (conditionalNode && conditionalNode.text === \"endif\") {\n return {\n type: \"endif\",\n };\n }\n } else if (functionCall) {\n const functionIdentifier = functionCall.children.find(\n (child: any) => child.type === \"function_identifier\"\n );\n\n if (functionIdentifier) {\n return {\n type: \"function\",\n functionName: functionIdentifier.text,\n };\n }\n }\n }\n return null;\n }\n\n // First pass: convert all nodes to intermediate format\n const rawNodes: {\n type: \"block\" | \"endblock\" | \"function\" | \"if\" | \"endif\";\n name?: string;\n functionName?: string;\n expression?: string;\n }[] = [];\n\n // Also collect content nodes\n const allNodes: Array<\n | {\n type:\n | \"block\"\n | \"endblock\"\n | \"function\"\n | \"if\"\n | \"endif\"\n | \"content\"\n | \"html_element\"\n | \"doctype\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }\n | HtmlElementNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n > = [];\n\n function convertHtmlEntity(\n node: any\n ): HtmlNamedEntityNode | HtmlNumericEntityNode | null {\n if (node.type === \"html_entity\") {\n const entityText = node.text;\n\n // Check if it's a numeric entity (starts with &#)\n if (entityText.startsWith(\"&#\")) {\n return {\n type: \"html_numeric_entity\",\n content: entityText,\n };\n } else if (entityText.startsWith(\"&\")) {\n return {\n type: \"html_named_entity\",\n content: entityText,\n };\n }\n }\n return null;\n }\n\n function convertHtmlElement(node: any): HtmlElementNode | null {\n if (node.type === \"html_element\") {\n // Check for self-closing tag first\n const selfClosingTag = node.children.find(\n (child: any) => child.type === \"html_self_closing_tag\"\n );\n\n // Find the start tag to get the element name\n const startTag = node.children.find(\n (child: any) => child.type === \"html_start_tag\"\n );\n\n // Use self-closing tag if available, otherwise start tag\n const tagToUse = selfClosingTag || startTag;\n if (!tagToUse) return null;\n\n const tagName = tagToUse.children.find(\n (child: any) => child.type === \"html_tag_name\"\n );\n if (!tagName) return null;\n\n // Check if this is a void element (no end tag and not self-closing)\n const hasEndTag = node.children.some(\n (child: any) => child.type === \"html_end_tag\"\n );\n const isVoid = !hasEndTag;\n\n // Parse attributes from the tag (either self-closing or start tag)\n const attributes: HtmlAttributeNode[] = [];\n const attributeNodes = tagToUse.children.filter(\n (child: any) => child.type === \"html_attribute\"\n );\n\n for (const attrNode of attributeNodes) {\n const nameNode = attrNode.children.find(\n (child: any) => child.type === \"html_attribute_name\"\n );\n if (!nameNode) continue;\n\n const valueNode = attrNode.children.find(\n (child: any) => child.type === \"html_attribute_value\"\n );\n const quotedValueNode = attrNode.children.find(\n (child: any) => child.type === \"html_quoted_attribute_value\"\n );\n\n let value: string | undefined;\n if (quotedValueNode) {\n // For quoted values, find the inner html_attribute_value\n const innerValueNode = quotedValueNode.children.find(\n (child: any) => child.type === \"html_attribute_value\"\n );\n value = innerValueNode ? innerValueNode.text : undefined;\n } else if (valueNode) {\n value = valueNode.text;\n }\n\n const attribute: HtmlAttributeNode = {\n type: \"html_attribute\",\n name: nameNode.text,\n };\n\n // Only include value property if there's actually a value\n if (value !== undefined) {\n attribute.value = value;\n }\n\n attributes.push(attribute);\n }\n\n const elementChildren: (\n | HtmlElementNode\n | ContentNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[] = [];\n\n // Process all children that are not start/end tags\n for (const child of node.children) {\n if (child.type === \"content\") {\n elementChildren.push({\n type: \"content\",\n content: child.text,\n });\n } else if (child.type === \"html_element\") {\n const nestedElement = convertHtmlElement(child);\n if (nestedElement) {\n elementChildren.push(nestedElement);\n }\n } else if (child.type === \"html_entity\") {\n const entityNode = convertHtmlEntity(child);\n if (entityNode) {\n elementChildren.push(entityNode);\n }\n }\n }\n\n const result: HtmlElementNode = {\n type: \"html_element\",\n name: tagName.text,\n children: elementChildren,\n };\n\n if (attributes.length > 0) {\n result.attributes = attributes;\n }\n\n if (isVoid) {\n result.void = true;\n }\n\n return result;\n }\n return null;\n }\n\n for (const child of tree.rootNode.children) {\n if (child.type === \"content\") {\n allNodes.push({\n type: \"content\",\n content: child.text,\n });\n } else if (child.type === \"html_element\") {\n const htmlElement = convertHtmlElement(child);\n if (htmlElement) {\n allNodes.push(htmlElement);\n }\n } else if (child.type === \"html_doctype\") {\n allNodes.push({\n type: \"doctype\",\n });\n } else if (child.type === \"html_entity\") {\n const entityNode = convertHtmlEntity(child);\n if (entityNode) {\n allNodes.push(entityNode);\n }\n } else {\n const converted = convertNode(child);\n if (converted) {\n rawNodes.push(converted);\n allNodes.push(converted);\n }\n }\n }\n\n // Second pass: build nested structure using a stack\n function buildNestedStructure(\n nodes: Array<\n | {\n type:\n | \"block\"\n | \"endblock\"\n | \"function\"\n | \"if\"\n | \"endif\"\n | \"content\"\n | \"html_element\"\n | \"doctype\";\n name?: string;\n functionName?: string;\n expression?: string;\n content?: string;\n }\n | HtmlElementNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n >\n ): (\n | TwigStatementDirectiveNode\n | HtmlElementNode\n | ContentNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[] {\n const result: (\n | TwigStatementDirectiveNode\n | HtmlElementNode\n | ContentNode\n | HtmlDoctypeNode\n | HtmlNamedEntityNode\n | HtmlNumericEntityNode\n )[] = [];\n const stack: TwigStatementDirectiveNode[] = [];\n\n for (const node of nodes) {\n if (node.type === \"block\") {\n const blockNode: TwigStatementDirectiveNode = {\n tag: {\n type: \"twig_tag\",\n name: \"block\",\n },\n type: \"twig_statement_directive\",\n variable: {\n type: \"twig_variable\",\n content: node.name!,\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(blockNode);\n }\n } else {\n // Add to root level\n result.push(blockNode);\n }\n\n // Push to stack for nesting\n stack.push(blockNode);\n } else if (node.type === \"endblock\") {\n // Pop from stack when we encounter an endblock\n stack.pop();\n } else if (node.type === \"if\") {\n const ifNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n condition: {\n type: \"twig_condition\",\n expression: {\n type: \"twig_expression\",\n content: node.expression!,\n },\n },\n children: [],\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(ifNode);\n }\n } else {\n // Add to root level\n result.push(ifNode);\n }\n\n // Push to stack for nesting\n stack.push(ifNode);\n } else if (node.type === \"endif\") {\n // Pop from stack when we encounter an endif\n stack.pop();\n } else if (node.type === \"function\") {\n const functionNode: TwigStatementDirectiveNode = {\n type: \"twig_statement_directive\",\n function: {\n type: \"twig_function\",\n name: node.functionName!,\n },\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(functionNode);\n }\n } else {\n // Add to root level\n result.push(functionNode);\n }\n } else if (node.type === \"content\") {\n const contentNode: ContentNode = {\n type: \"content\",\n content: node.content!,\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(contentNode);\n }\n } else {\n // Content at root level - this shouldn't happen in well-formed templates\n // but we'll handle it gracefully\n result.push({\n type: \"twig_statement_directive\",\n children: [contentNode],\n });\n }\n } else if (node.type === \"html_element\" && \"name\" in node) {\n // HTML elements are already processed and can be added directly\n const htmlNode = node as HtmlElementNode;\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(htmlNode);\n }\n } else {\n // Add to root level\n result.push(htmlNode);\n }\n } else if (node.type === \"doctype\") {\n const doctypeNode: HtmlDoctypeNode = {\n type: \"doctype\",\n };\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(doctypeNode);\n }\n } else {\n // Add to root level\n result.push(doctypeNode);\n }\n } else if (node.type === \"html_named_entity\" && \"content\" in node) {\n const entityNode = node as HtmlNamedEntityNode;\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(entityNode);\n }\n } else {\n // Add to root level\n result.push(entityNode);\n }\n } else if (node.type === \"html_numeric_entity\" && \"content\" in node) {\n const entityNode = node as HtmlNumericEntityNode;\n\n if (stack.length > 0) {\n // Add to the current parent's children\n const parent = stack[stack.length - 1];\n if (parent && parent.children) {\n parent.children.push(entityNode);\n }\n } else {\n // Add to root level\n result.push(entityNode);\n }\n }\n }\n\n return result;\n }\n\n const children = buildNestedStructure(allNodes);\n\n return {\n rootNode: {\n type: \"template\",\n children,\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopware-twig-parser",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "main": "./dist/commonjs/index.js",
5
5
  "files": [
6
6
  "dist"