From 70e7da8bfba934a94d2113eb9323f1a6e4572bee Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Sun, 5 Jul 2015 00:25:48 -0500 Subject: [PATCH] Make it easier to incorporate longer code blocks with py_codegen --- pytools/py_codegen.py | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/pytools/py_codegen.py b/pytools/py_codegen.py index 54a8d7d..5c90be9 100644 --- a/pytools/py_codegen.py +++ b/pytools/py_codegen.py @@ -44,12 +44,8 @@ class PythonCodeGenerator(object): self.level = 0 def extend(self, sub_generator): - self.code.extend(sub_generator.code) - - def extend_indent(self, sub_generator): - with Indentation(self): - for line in sub_generator.code: - self.write(line) + for line in sub_generator.code: + self.code.append(" "*(4*self.level) + line) def get(self): result = "\n".join(self.code) @@ -64,6 +60,9 @@ class PythonCodeGenerator(object): if not s.strip(): self.code.append("") else: + if "\n" in s: + s = remove_common_indentation(s) + for l in s.split("\n"): self.code.append(" "*(4*self.level) + l) @@ -92,3 +91,32 @@ class PythonFunctionGenerator(PythonCodeGenerator): func = result_dict[self.name] result_dict["_MODULE_SOURCE_CODE"] = source_text return func + + +# {{{ remove common indentation + +def remove_common_indentation(code, require_leading_newline=True): + if "\n" not in code: + return code + + if require_leading_newline and not code.startswith("\n"): + return code + + lines = code.split("\n") + while lines[0].strip() == "": + lines.pop(0) + while lines[-1].strip() == "": + lines.pop(-1) + + if lines: + base_indent = 0 + while lines[0][base_indent] in " \t": + base_indent += 1 + + for line in lines[1:]: + if line[:base_indent].strip(): + raise ValueError("inconsistent indentation") + + return "\n".join(line[base_indent:] for line in lines) + +# }}} -- GitLab