Было бы проще, если бы Джинджа предоставила возможность. Похоже, что над этим была проделана некоторая работа, но проблема в настоящее время закрыта (20 ноября 2019), а запрос на включение еще не был объединен. Это может быть связано с тем, что с отступами довольно быстро возникают сложности (подумайте, например, о табуляциях и пробелах).
Ниже приведено простое решение, которое я нашел эффективным для создания кода Python. Он хорошо справляется с файлами, в которых для отступов используются пробелы, и может подойти для вашего варианта использования.
auto_indent()
определяет уровень отступа переменной в основном шаблоне, а затем применяет этот отступ к фрагменту текста.
import os
import itertools
import jinja2
def indent_lines(text_lines: list, indent: int):
return [' ' * indent + line for line in text_lines]
def matching_line(s, substring):
lineno = s[:s.index(substring)].count('\n')
return s.splitlines()[lineno]
def is_space(c):
return c == ' '
def indentation(line: str) -> int:
initial_spaces = ''.join(itertools.takewhile(is_space, line))
return len(initial_spaces)
def auto_indent(template: str, placeholder: str, content_to_indent: str):
placeholder_line = matching_line(template, '{{ ' + placeholder + ' }}')
indent_width = indentation(placeholder_line)
lines = content_to_indent.splitlines()
first_line = [lines[0]] # first line uses placeholder indent-- no added indent
rest = indent_lines(lines[1:], indent_width)
return os.linesep.join(first_line + rest)
Пример:
action_class = """\
class Actions:
def __init__(self):
pass
def prequel(self):
pass
{{ methods }}
def sequel(self):
pass
"""
inserted_methods = """\
def create_branch():
pass
def merge_branch():
pass
"""
if __name__ == '__main__':
indented_methods = auto_indent(action_class, 'methods', inserted_methods)
print(jinja2.Template(action_class).render(methods=indented_methods))
Пример вывода:
>>> python indent.py
class Actions:
def __init__(self):
pass
def prequel(self):
pass
def create_branch():
pass
def merge_branch():
pass
def sequel(self):
pass
person
Nick
schedule
20.09.2019