summaryrefslogtreecommitdiff
path: root/node_modules/nunjucks/src/transformer.js
diff options
context:
space:
mode:
authorShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
committerShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
commit7a52ddeba2a68388b544f529d2d92104420f77b0 (patch)
tree15ddd47457a2cb4a96060747437d36474e4f6b4e /node_modules/nunjucks/src/transformer.js
parent53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff)
Changed from static to 11ty!
Diffstat (limited to 'node_modules/nunjucks/src/transformer.js')
-rw-r--r--node_modules/nunjucks/src/transformer.js166
1 files changed, 166 insertions, 0 deletions
diff --git a/node_modules/nunjucks/src/transformer.js b/node_modules/nunjucks/src/transformer.js
new file mode 100644
index 0000000..b11e91c
--- /dev/null
+++ b/node_modules/nunjucks/src/transformer.js
@@ -0,0 +1,166 @@
+'use strict';
+
+var nodes = require('./nodes');
+var lib = require('./lib');
+var sym = 0;
+function gensym() {
+ return 'hole_' + sym++;
+}
+
+// copy-on-write version of map
+function mapCOW(arr, func) {
+ var res = null;
+ for (var i = 0; i < arr.length; i++) {
+ var item = func(arr[i]);
+ if (item !== arr[i]) {
+ if (!res) {
+ res = arr.slice();
+ }
+ res[i] = item;
+ }
+ }
+ return res || arr;
+}
+function walk(ast, func, depthFirst) {
+ if (!(ast instanceof nodes.Node)) {
+ return ast;
+ }
+ if (!depthFirst) {
+ var astT = func(ast);
+ if (astT && astT !== ast) {
+ return astT;
+ }
+ }
+ if (ast instanceof nodes.NodeList) {
+ var children = mapCOW(ast.children, function (node) {
+ return walk(node, func, depthFirst);
+ });
+ if (children !== ast.children) {
+ ast = new nodes[ast.typename](ast.lineno, ast.colno, children);
+ }
+ } else if (ast instanceof nodes.CallExtension) {
+ var args = walk(ast.args, func, depthFirst);
+ var contentArgs = mapCOW(ast.contentArgs, function (node) {
+ return walk(node, func, depthFirst);
+ });
+ if (args !== ast.args || contentArgs !== ast.contentArgs) {
+ ast = new nodes[ast.typename](ast.extName, ast.prop, args, contentArgs);
+ }
+ } else {
+ var props = ast.fields.map(function (field) {
+ return ast[field];
+ });
+ var propsT = mapCOW(props, function (prop) {
+ return walk(prop, func, depthFirst);
+ });
+ if (propsT !== props) {
+ ast = new nodes[ast.typename](ast.lineno, ast.colno);
+ propsT.forEach(function (prop, i) {
+ ast[ast.fields[i]] = prop;
+ });
+ }
+ }
+ return depthFirst ? func(ast) || ast : ast;
+}
+function depthWalk(ast, func) {
+ return walk(ast, func, true);
+}
+function _liftFilters(node, asyncFilters, prop) {
+ var children = [];
+ var walked = depthWalk(prop ? node[prop] : node, function (descNode) {
+ var symbol;
+ if (descNode instanceof nodes.Block) {
+ return descNode;
+ } else if (descNode instanceof nodes.Filter && lib.indexOf(asyncFilters, descNode.name.value) !== -1 || descNode instanceof nodes.CallExtensionAsync) {
+ symbol = new nodes.Symbol(descNode.lineno, descNode.colno, gensym());
+ children.push(new nodes.FilterAsync(descNode.lineno, descNode.colno, descNode.name, descNode.args, symbol));
+ }
+ return symbol;
+ });
+ if (prop) {
+ node[prop] = walked;
+ } else {
+ node = walked;
+ }
+ if (children.length) {
+ children.push(node);
+ return new nodes.NodeList(node.lineno, node.colno, children);
+ } else {
+ return node;
+ }
+}
+function liftFilters(ast, asyncFilters) {
+ return depthWalk(ast, function (node) {
+ if (node instanceof nodes.Output) {
+ return _liftFilters(node, asyncFilters);
+ } else if (node instanceof nodes.Set) {
+ return _liftFilters(node, asyncFilters, 'value');
+ } else if (node instanceof nodes.For) {
+ return _liftFilters(node, asyncFilters, 'arr');
+ } else if (node instanceof nodes.If) {
+ return _liftFilters(node, asyncFilters, 'cond');
+ } else if (node instanceof nodes.CallExtension) {
+ return _liftFilters(node, asyncFilters, 'args');
+ } else {
+ return undefined;
+ }
+ });
+}
+function liftSuper(ast) {
+ return walk(ast, function (blockNode) {
+ if (!(blockNode instanceof nodes.Block)) {
+ return;
+ }
+ var hasSuper = false;
+ var symbol = gensym();
+ blockNode.body = walk(blockNode.body, function (node) {
+ // eslint-disable-line consistent-return
+ if (node instanceof nodes.FunCall && node.name.value === 'super') {
+ hasSuper = true;
+ return new nodes.Symbol(node.lineno, node.colno, symbol);
+ }
+ });
+ if (hasSuper) {
+ blockNode.body.children.unshift(new nodes.Super(0, 0, blockNode.name, new nodes.Symbol(0, 0, symbol)));
+ }
+ });
+}
+function convertStatements(ast) {
+ return depthWalk(ast, function (node) {
+ if (!(node instanceof nodes.If) && !(node instanceof nodes.For)) {
+ return undefined;
+ }
+ var async = false;
+ walk(node, function (child) {
+ if (child instanceof nodes.FilterAsync || child instanceof nodes.IfAsync || child instanceof nodes.AsyncEach || child instanceof nodes.AsyncAll || child instanceof nodes.CallExtensionAsync) {
+ async = true;
+ // Stop iterating by returning the node
+ return child;
+ }
+ return undefined;
+ });
+ if (async) {
+ if (node instanceof nodes.If) {
+ return new nodes.IfAsync(node.lineno, node.colno, node.cond, node.body, node.else_);
+ } else if (node instanceof nodes.For && !(node instanceof nodes.AsyncAll)) {
+ return new nodes.AsyncEach(node.lineno, node.colno, node.arr, node.name, node.body, node.else_);
+ }
+ }
+ return undefined;
+ });
+}
+function cps(ast, asyncFilters) {
+ return convertStatements(liftSuper(liftFilters(ast, asyncFilters)));
+}
+function transform(ast, asyncFilters) {
+ return cps(ast, asyncFilters || []);
+}
+
+// var parser = require('./parser');
+// var src = 'hello {% foo %}{% endfoo %} end';
+// var ast = transform(parser.parse(src, [new FooExtension()]), ['bar']);
+// nodes.printNodes(ast);
+
+module.exports = {
+ transform: transform
+}; \ No newline at end of file