shopware-twig-parser 0.1.0 → 0.2.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.
- package/dist/commonjs/index.d.ts +21 -3
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +119 -5
- package/dist/commonjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +21 -3
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +119 -5
- package/dist/esm/index.js.map +1 -1
- package/package.json +2 -2
package/dist/commonjs/index.d.ts
CHANGED
|
@@ -7,9 +7,23 @@ type TemplateNode = {
|
|
|
7
7
|
};
|
|
8
8
|
type TwigStatementDirectiveNode = {
|
|
9
9
|
type: "twig_statement_directive";
|
|
10
|
-
tag
|
|
11
|
-
variable
|
|
12
|
-
|
|
10
|
+
tag?: TwigTagNode;
|
|
11
|
+
variable?: TwigVariableNode;
|
|
12
|
+
function?: TwigFunctionNode;
|
|
13
|
+
condition?: TwigConditionNode;
|
|
14
|
+
children?: (TwigStatementDirectiveNode | ContentNode)[];
|
|
15
|
+
};
|
|
16
|
+
type TwigConditionNode = {
|
|
17
|
+
type: "twig_condition";
|
|
18
|
+
expression: TwigExpressionNode;
|
|
19
|
+
};
|
|
20
|
+
type TwigExpressionNode = {
|
|
21
|
+
type: "twig_expression";
|
|
22
|
+
content: string;
|
|
23
|
+
};
|
|
24
|
+
type ContentNode = {
|
|
25
|
+
type: "content";
|
|
26
|
+
content: string;
|
|
13
27
|
};
|
|
14
28
|
type TwigTagNode = {
|
|
15
29
|
type: "twig_tag";
|
|
@@ -19,6 +33,10 @@ type TwigVariableNode = {
|
|
|
19
33
|
type: "twig_variable";
|
|
20
34
|
content: string;
|
|
21
35
|
};
|
|
36
|
+
type TwigFunctionNode = {
|
|
37
|
+
type: "twig_function";
|
|
38
|
+
name: string;
|
|
39
|
+
};
|
|
22
40
|
export declare function parse(content: string): Tree;
|
|
23
41
|
export {};
|
|
24
42
|
//# 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,EAAE,WAAW,CAAC;
|
|
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"}
|
package/dist/commonjs/index.js
CHANGED
|
@@ -13,9 +13,24 @@ function parse(content) {
|
|
|
13
13
|
const tree = parser.parse(content);
|
|
14
14
|
function convertNode(node) {
|
|
15
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
|
|
16
29
|
const tagStatement = node.children.find((child) => child.type === "tag_statement");
|
|
30
|
+
const functionCall = node.children.find((child) => child.type === "function_call");
|
|
17
31
|
if (tagStatement) {
|
|
18
32
|
const tagNode = tagStatement.children.find((child) => child.type === "tag");
|
|
33
|
+
const conditionalNode = tagStatement.children.find((child) => child.type === "conditional");
|
|
19
34
|
const variableNode = tagStatement.children.find((child) => child.type === "variable");
|
|
20
35
|
if (tagNode && tagNode.text === "block" && variableNode) {
|
|
21
36
|
return {
|
|
@@ -28,16 +43,41 @@ function parse(content) {
|
|
|
28
43
|
type: "endblock",
|
|
29
44
|
};
|
|
30
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
|
+
}
|
|
31
60
|
}
|
|
32
61
|
}
|
|
33
62
|
return null;
|
|
34
63
|
}
|
|
35
64
|
// First pass: convert all nodes to intermediate format
|
|
36
65
|
const rawNodes = [];
|
|
66
|
+
// Also collect content nodes
|
|
67
|
+
const allNodes = [];
|
|
37
68
|
for (const child of tree.rootNode.children) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
69
|
+
if (child.type === "content") {
|
|
70
|
+
allNodes.push({
|
|
71
|
+
type: "content",
|
|
72
|
+
content: child.text,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const converted = convertNode(child);
|
|
77
|
+
if (converted) {
|
|
78
|
+
rawNodes.push(converted);
|
|
79
|
+
allNodes.push(converted);
|
|
80
|
+
}
|
|
41
81
|
}
|
|
42
82
|
}
|
|
43
83
|
// Second pass: build nested structure using a stack
|
|
@@ -60,7 +100,10 @@ function parse(content) {
|
|
|
60
100
|
};
|
|
61
101
|
if (stack.length > 0) {
|
|
62
102
|
// Add to the current parent's children
|
|
63
|
-
stack[stack.length - 1]
|
|
103
|
+
const parent = stack[stack.length - 1];
|
|
104
|
+
if (parent && parent.children) {
|
|
105
|
+
parent.children.push(blockNode);
|
|
106
|
+
}
|
|
64
107
|
}
|
|
65
108
|
else {
|
|
66
109
|
// Add to root level
|
|
@@ -73,10 +116,81 @@ function parse(content) {
|
|
|
73
116
|
// Pop from stack when we encounter an endblock
|
|
74
117
|
stack.pop();
|
|
75
118
|
}
|
|
119
|
+
else if (node.type === "if") {
|
|
120
|
+
const ifNode = {
|
|
121
|
+
type: "twig_statement_directive",
|
|
122
|
+
condition: {
|
|
123
|
+
type: "twig_condition",
|
|
124
|
+
expression: {
|
|
125
|
+
type: "twig_expression",
|
|
126
|
+
content: node.expression,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
children: [],
|
|
130
|
+
};
|
|
131
|
+
if (stack.length > 0) {
|
|
132
|
+
// Add to the current parent's children
|
|
133
|
+
const parent = stack[stack.length - 1];
|
|
134
|
+
if (parent && parent.children) {
|
|
135
|
+
parent.children.push(ifNode);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// Add to root level
|
|
140
|
+
result.push(ifNode);
|
|
141
|
+
}
|
|
142
|
+
// Push to stack for nesting
|
|
143
|
+
stack.push(ifNode);
|
|
144
|
+
}
|
|
145
|
+
else if (node.type === "endif") {
|
|
146
|
+
// Pop from stack when we encounter an endif
|
|
147
|
+
stack.pop();
|
|
148
|
+
}
|
|
149
|
+
else if (node.type === "function") {
|
|
150
|
+
const functionNode = {
|
|
151
|
+
type: "twig_statement_directive",
|
|
152
|
+
function: {
|
|
153
|
+
type: "twig_function",
|
|
154
|
+
name: node.functionName,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
if (stack.length > 0) {
|
|
158
|
+
// Add to the current parent's children
|
|
159
|
+
const parent = stack[stack.length - 1];
|
|
160
|
+
if (parent && parent.children) {
|
|
161
|
+
parent.children.push(functionNode);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Add to root level
|
|
166
|
+
result.push(functionNode);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (node.type === "content") {
|
|
170
|
+
const contentNode = {
|
|
171
|
+
type: "content",
|
|
172
|
+
content: node.content,
|
|
173
|
+
};
|
|
174
|
+
if (stack.length > 0) {
|
|
175
|
+
// Add to the current parent's children
|
|
176
|
+
const parent = stack[stack.length - 1];
|
|
177
|
+
if (parent && parent.children) {
|
|
178
|
+
parent.children.push(contentNode);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Content at root level - this shouldn't happen in well-formed templates
|
|
183
|
+
// but we'll handle it gracefully
|
|
184
|
+
result.push({
|
|
185
|
+
type: "twig_statement_directive",
|
|
186
|
+
children: [contentNode],
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
76
190
|
}
|
|
77
191
|
return result;
|
|
78
192
|
}
|
|
79
|
-
const children = buildNestedStructure(
|
|
193
|
+
const children = buildNestedStructure(allNodes);
|
|
80
194
|
return {
|
|
81
195
|
rootNode: {
|
|
82
196
|
type: "template",
|
|
@@ -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 children: TwigStatementDirectiveNode[];\n};\n\ntype TwigTagNode = {\n type: \"twig_tag\";\n name: string;\n};\n\ntype TwigVariableNode = {\n type: \"twig_variable\";\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(\n node: any\n ): { type: \"block\" | \"endblock\"; name?: string } | null {\n if (node.type === \"statement_directive\") {\n const tagStatement = node.children.find(\n (child: any) => child.type === \"tag_statement\"\n );\n if (tagStatement) {\n const tagNode = tagStatement.children.find(\n (child: any) => child.type === \"tag\"\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 }\n }\n }\n return null;\n }\n\n // First pass: convert all nodes to intermediate format\n const rawNodes: { type: \"block\" | \"endblock\"; name?: string }[] = [];\n for (const child of tree.rootNode.children) {\n const converted = convertNode(child);\n if (converted) {\n rawNodes.push(converted);\n }\n }\n\n // Second pass: build nested structure using a stack\n function buildNestedStructure(\n nodes: { type: \"block\" | \"endblock\"; name?: string }[]\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 stack[stack.length - 1]?.children.push(blockNode);\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 }\n }\n\n return result;\n }\n\n const children = buildNestedStructure(rawNodes);\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: 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"]}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -7,9 +7,23 @@ type TemplateNode = {
|
|
|
7
7
|
};
|
|
8
8
|
type TwigStatementDirectiveNode = {
|
|
9
9
|
type: "twig_statement_directive";
|
|
10
|
-
tag
|
|
11
|
-
variable
|
|
12
|
-
|
|
10
|
+
tag?: TwigTagNode;
|
|
11
|
+
variable?: TwigVariableNode;
|
|
12
|
+
function?: TwigFunctionNode;
|
|
13
|
+
condition?: TwigConditionNode;
|
|
14
|
+
children?: (TwigStatementDirectiveNode | ContentNode)[];
|
|
15
|
+
};
|
|
16
|
+
type TwigConditionNode = {
|
|
17
|
+
type: "twig_condition";
|
|
18
|
+
expression: TwigExpressionNode;
|
|
19
|
+
};
|
|
20
|
+
type TwigExpressionNode = {
|
|
21
|
+
type: "twig_expression";
|
|
22
|
+
content: string;
|
|
23
|
+
};
|
|
24
|
+
type ContentNode = {
|
|
25
|
+
type: "content";
|
|
26
|
+
content: string;
|
|
13
27
|
};
|
|
14
28
|
type TwigTagNode = {
|
|
15
29
|
type: "twig_tag";
|
|
@@ -19,6 +33,10 @@ type TwigVariableNode = {
|
|
|
19
33
|
type: "twig_variable";
|
|
20
34
|
content: string;
|
|
21
35
|
};
|
|
36
|
+
type TwigFunctionNode = {
|
|
37
|
+
type: "twig_function";
|
|
38
|
+
name: string;
|
|
39
|
+
};
|
|
22
40
|
export declare function parse(content: string): Tree;
|
|
23
41
|
export {};
|
|
24
42
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -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,EAAE,WAAW,CAAC;
|
|
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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -7,9 +7,24 @@ export function parse(content) {
|
|
|
7
7
|
const tree = parser.parse(content);
|
|
8
8
|
function convertNode(node) {
|
|
9
9
|
if (node.type === "statement_directive") {
|
|
10
|
+
// Check for if_statement
|
|
11
|
+
const ifStatement = node.children.find((child) => child.type === "if_statement");
|
|
12
|
+
if (ifStatement) {
|
|
13
|
+
const conditionalNode = ifStatement.children.find((child) => child.type === "conditional");
|
|
14
|
+
const variableNode = ifStatement.children.find((child) => child.type === "variable");
|
|
15
|
+
if (conditionalNode && conditionalNode.text === "if" && variableNode) {
|
|
16
|
+
return {
|
|
17
|
+
type: "if",
|
|
18
|
+
expression: variableNode.text,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Check for tag_statement
|
|
10
23
|
const tagStatement = node.children.find((child) => child.type === "tag_statement");
|
|
24
|
+
const functionCall = node.children.find((child) => child.type === "function_call");
|
|
11
25
|
if (tagStatement) {
|
|
12
26
|
const tagNode = tagStatement.children.find((child) => child.type === "tag");
|
|
27
|
+
const conditionalNode = tagStatement.children.find((child) => child.type === "conditional");
|
|
13
28
|
const variableNode = tagStatement.children.find((child) => child.type === "variable");
|
|
14
29
|
if (tagNode && tagNode.text === "block" && variableNode) {
|
|
15
30
|
return {
|
|
@@ -22,16 +37,41 @@ export function parse(content) {
|
|
|
22
37
|
type: "endblock",
|
|
23
38
|
};
|
|
24
39
|
}
|
|
40
|
+
else if (conditionalNode && conditionalNode.text === "endif") {
|
|
41
|
+
return {
|
|
42
|
+
type: "endif",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (functionCall) {
|
|
47
|
+
const functionIdentifier = functionCall.children.find((child) => child.type === "function_identifier");
|
|
48
|
+
if (functionIdentifier) {
|
|
49
|
+
return {
|
|
50
|
+
type: "function",
|
|
51
|
+
functionName: functionIdentifier.text,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
25
54
|
}
|
|
26
55
|
}
|
|
27
56
|
return null;
|
|
28
57
|
}
|
|
29
58
|
// First pass: convert all nodes to intermediate format
|
|
30
59
|
const rawNodes = [];
|
|
60
|
+
// Also collect content nodes
|
|
61
|
+
const allNodes = [];
|
|
31
62
|
for (const child of tree.rootNode.children) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
63
|
+
if (child.type === "content") {
|
|
64
|
+
allNodes.push({
|
|
65
|
+
type: "content",
|
|
66
|
+
content: child.text,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const converted = convertNode(child);
|
|
71
|
+
if (converted) {
|
|
72
|
+
rawNodes.push(converted);
|
|
73
|
+
allNodes.push(converted);
|
|
74
|
+
}
|
|
35
75
|
}
|
|
36
76
|
}
|
|
37
77
|
// Second pass: build nested structure using a stack
|
|
@@ -54,7 +94,10 @@ export function parse(content) {
|
|
|
54
94
|
};
|
|
55
95
|
if (stack.length > 0) {
|
|
56
96
|
// Add to the current parent's children
|
|
57
|
-
stack[stack.length - 1]
|
|
97
|
+
const parent = stack[stack.length - 1];
|
|
98
|
+
if (parent && parent.children) {
|
|
99
|
+
parent.children.push(blockNode);
|
|
100
|
+
}
|
|
58
101
|
}
|
|
59
102
|
else {
|
|
60
103
|
// Add to root level
|
|
@@ -67,10 +110,81 @@ export function parse(content) {
|
|
|
67
110
|
// Pop from stack when we encounter an endblock
|
|
68
111
|
stack.pop();
|
|
69
112
|
}
|
|
113
|
+
else if (node.type === "if") {
|
|
114
|
+
const ifNode = {
|
|
115
|
+
type: "twig_statement_directive",
|
|
116
|
+
condition: {
|
|
117
|
+
type: "twig_condition",
|
|
118
|
+
expression: {
|
|
119
|
+
type: "twig_expression",
|
|
120
|
+
content: node.expression,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
children: [],
|
|
124
|
+
};
|
|
125
|
+
if (stack.length > 0) {
|
|
126
|
+
// Add to the current parent's children
|
|
127
|
+
const parent = stack[stack.length - 1];
|
|
128
|
+
if (parent && parent.children) {
|
|
129
|
+
parent.children.push(ifNode);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// Add to root level
|
|
134
|
+
result.push(ifNode);
|
|
135
|
+
}
|
|
136
|
+
// Push to stack for nesting
|
|
137
|
+
stack.push(ifNode);
|
|
138
|
+
}
|
|
139
|
+
else if (node.type === "endif") {
|
|
140
|
+
// Pop from stack when we encounter an endif
|
|
141
|
+
stack.pop();
|
|
142
|
+
}
|
|
143
|
+
else if (node.type === "function") {
|
|
144
|
+
const functionNode = {
|
|
145
|
+
type: "twig_statement_directive",
|
|
146
|
+
function: {
|
|
147
|
+
type: "twig_function",
|
|
148
|
+
name: node.functionName,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
if (stack.length > 0) {
|
|
152
|
+
// Add to the current parent's children
|
|
153
|
+
const parent = stack[stack.length - 1];
|
|
154
|
+
if (parent && parent.children) {
|
|
155
|
+
parent.children.push(functionNode);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Add to root level
|
|
160
|
+
result.push(functionNode);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (node.type === "content") {
|
|
164
|
+
const contentNode = {
|
|
165
|
+
type: "content",
|
|
166
|
+
content: node.content,
|
|
167
|
+
};
|
|
168
|
+
if (stack.length > 0) {
|
|
169
|
+
// Add to the current parent's children
|
|
170
|
+
const parent = stack[stack.length - 1];
|
|
171
|
+
if (parent && parent.children) {
|
|
172
|
+
parent.children.push(contentNode);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
// Content at root level - this shouldn't happen in well-formed templates
|
|
177
|
+
// but we'll handle it gracefully
|
|
178
|
+
result.push({
|
|
179
|
+
type: "twig_statement_directive",
|
|
180
|
+
children: [contentNode],
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
70
184
|
}
|
|
71
185
|
return result;
|
|
72
186
|
}
|
|
73
|
-
const children = buildNestedStructure(
|
|
187
|
+
const children = buildNestedStructure(allNodes);
|
|
74
188
|
return {
|
|
75
189
|
rootNode: {
|
|
76
190
|
type: "template",
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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 children: TwigStatementDirectiveNode[];\n};\n\ntype TwigTagNode = {\n type: \"twig_tag\";\n name: string;\n};\n\ntype TwigVariableNode = {\n type: \"twig_variable\";\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(\n node: any\n ): { type: \"block\" | \"endblock\"; name?: string } | null {\n if (node.type === \"statement_directive\") {\n const tagStatement = node.children.find(\n (child: any) => child.type === \"tag_statement\"\n );\n if (tagStatement) {\n const tagNode = tagStatement.children.find(\n (child: any) => child.type === \"tag\"\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 }\n }\n }\n return null;\n }\n\n // First pass: convert all nodes to intermediate format\n const rawNodes: { type: \"block\" | \"endblock\"; name?: string }[] = [];\n for (const child of tree.rootNode.children) {\n const converted = convertNode(child);\n if (converted) {\n rawNodes.push(converted);\n }\n }\n\n // Second pass: build nested structure using a stack\n function buildNestedStructure(\n nodes: { type: \"block\" | \"endblock\"; name?: string }[]\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 stack[stack.length - 1]?.children.push(blockNode);\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 }\n }\n\n return result;\n }\n\n const children = buildNestedStructure(rawNodes);\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: 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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shopware-twig-parser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"main": "./dist/commonjs/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"tree-sitter": "^0.25.0",
|
|
21
|
-
"tree-sitter-shopware-twig": "^0.2.
|
|
21
|
+
"tree-sitter-shopware-twig": "^0.2.4"
|
|
22
22
|
},
|
|
23
23
|
"type": "module",
|
|
24
24
|
"tshy": {
|