]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
Combine common template data/outputs in AST
authorKevin <kevin@kevin-brown.com>
Sun, 10 May 2020 20:44:08 +0000 (16:44 -0400)
committerKevin <kevin@kevin-brown.com>
Sun, 10 May 2020 20:44:08 +0000 (16:44 -0400)
This makes it easier to compare the AST generated by the old Jinja
parser and the AST generated by the new one, since the new AST
separates out template data character by character currently.

new_parser.py

index 0d1aa79e43bc3553507713185fac2ccada38bfda..5e517387c8343175a2dd25118acd15784514903e 100644 (file)
@@ -5,9 +5,44 @@ def lineno_from_parseinfo(parseinfo):
     return parseinfo.line + 1\r
 \r
 def parse(ast):\r
+    def merge_output(blocks):\r
+        if len(blocks) < 2:\r
+            return blocks\r
+\r
+        for idx in range(len(blocks) - 1, 0, -1):\r
+            block = blocks[idx]\r
+            previous_block = blocks[idx - 1]\r
+\r
+            if isinstance(block, nodes.Output) and isinstance(previous_block, nodes.Output):\r
+                previous_block.nodes += block.nodes\r
+                del blocks[idx]\r
+\r
+        return blocks\r
+\r
+    def merge_template_data(blocks):\r
+        for block in blocks:\r
+            if isinstance(block, nodes.Output):\r
+                if len(block.nodes) < 2:\r
+                    continue\r
+\r
+                outputs = block.nodes\r
+\r
+                for idx in range(len(outputs) - 1, 0, -1):\r
+                    output = outputs[idx]\r
+                    previous_output = outputs[idx - 1]\r
+\r
+                    if isinstance(output, nodes.TemplateData) and isinstance(previous_output, nodes.TemplateData):\r
+                        previous_output.data += output.data\r
+                        del outputs[idx]\r
+\r
+        return blocks\r
+\r
+    def remove_none(blocks):\r
+        return [block for block in blocks if block is not None]\r
+\r
     if isinstance(ast, list):\r
-        nodes = (parse(item) for item in ast)\r
-        return [node for node in nodes if node is not None]\r
+        blocks = [parse(item) for item in ast]\r
+        return merge_template_data(merge_output(remove_none(blocks)))\r
 \r
     if isinstance(ast, str):\r
         return parse_output(ast)\r