在Jinja2中包装长文本部分

时间:2019-03-08 15:24:13

标签: templates text jinja2 long-integer multiline

我在YAML文件中具有变量的定义,名称和相关注释,并且正在尝试使用Jinja2创建适当的目标文件;在这种情况下是专有的配置文件

...
- comment: >
      This is a comment which will almost certainly end up longer than standard eighty characters or at least on the occasion on which it does. 
  name: my_useful_variable
  value: /a/long/example/path/to/my/file.txt

我希望此文本显示如下:

# This is a comment which will almost certainly end up
# longer than standard eighty characters or at least on
# the occasion on which it does.
my_useful_variable = "/a/long/example/path/to/my/file.txt"

Jinja2是否有任何包装文本的方式,以使长注释行的长度受到限制并且可以分为多行?

到目前为止,我有:

# {{item.comment}}    
{{item.name}} = "{{item.value}}"

但这当然不涉及评论的长度。

解决方案

在下面@blhsing提供的答案之后,我想到了以下宏,该宏适用于基本变量和简单列表(即非字典或更复杂的分层数据结构:

{% macro set_params(param_list, ind=4, wid=80) -%}
{% for item in param_list %}
{% if item.comment is defined %}{{item.comment|wordwrap(wid - ind - 2)|replace('',  ' ' * ind +'# ', 1)|replace('\n', '\n' + ' ' * ind + '# ')}}
{% endif %}
{% if item.value is iterable and item.value is not string %}{{item.name|indent(ind, True)}} = [ {% for item_2 in item.value %}{{item_2}}{{ ", " if not loop.last else " " }}{% endfor %}{% else %}{{item.name|indent(ind, True)}} = {{item.value}}{% endif %}
{% endfor %}
{%- endmacro %}

要使用此功能,只需传递与顶部规格相似的项目列表以及缩进和页面宽度即可。

一些解释:

  • 第3行,如果定义了注释,则考虑到宽度和缩进,将其自动换行为正确的长度。第一个替换处理缩进第一行,第二个缩进后续行。所有前缀为“#”
  • 第5行,根据变量是简单变量还是可迭代变量,它以name = valuename = [ value1, value2, value3 ]的形式呈现

当然,它不是万无一失的,但可以满足我的基本要求。

1 个答案:

答案 0 :(得分:1)

您可以在给定的字符串前添加换行符,然后使用wordwrap过滤器先将文本包装成多行,然后使用replace过滤器将换行符替换为换行符加{{ 1}}:

'# '

以上假设您希望每行不超过80个字符。将{{ ('\n' ~ item.comment) | wordwrap(78) | replace('\n', '\n# ') }} 更改为所需的线宽减2,为78留出空间。