在 Jinja2 中包装长文本部分
Wrapping long text sections in Jinja2
我在 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行,根据变量是simple还是iterable,渲染成
name = value
或name = [ value1, value2, value3 ]
的形式
当然不是万无一失的,但是满足我的基本要求
您可以在给定的字符串前加上换行符,然后使用 wordwrap
过滤器将文本先包装成多行,并使用 replace
过滤器将换行符替换为换行符加'# '
:
{{ ('\n' ~ item.comment) | wordwrap(78) | replace('\n', '\n# ') }}
以上假定您希望每行不超过 80 个字符。将 78
更改为您想要的线宽减去 2,以便为 '# '
.
留出空间
我在 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行,根据变量是simple还是iterable,渲染成
name = value
或name = [ value1, value2, value3 ]
的形式
当然不是万无一失的,但是满足我的基本要求
您可以在给定的字符串前加上换行符,然后使用 wordwrap
过滤器将文本先包装成多行,并使用 replace
过滤器将换行符替换为换行符加'# '
:
{{ ('\n' ~ item.comment) | wordwrap(78) | replace('\n', '\n# ') }}
以上假定您希望每行不超过 80 个字符。将 78
更改为您想要的线宽减去 2,以便为 '# '
.