在同一文档上分隔YAML和纯文本

时间:2016-06-17 13:20:27

标签: yaml blogs plaintext pyyaml

在使用django构建博客时,我意识到将文章的文本和所有相关信息(标题,作者等等)以人类可读的文件格式存储在一起是非常实用的,然后使用简单的脚本在数据库上收取这些文件。

现在说,YAML因其可读性和易用性引起了我的注意,YAML语法的唯一缺点是缩进:

---
title: Title of the article
author: Somebody
# Other stuffs here ...
text:| 
    This is the text of the article. I can write whatever I want
    but I need to be careful with the indentation...and this is a
    bit boring.
---

我认为这不是最佳解决方案(特别是如果文件将由临时用户编写)。像这样的格式可能会更好

---
title: Title of the article
author: Somebody
# Other stuffs here ...
---
Here there is the text of the article, it is not valid YAML but
just plain text. Here I could put **Markdown** or <html>...or whatever
I want...

有什么解决方案吗?最好使用python。 其他文件格式的建议也是受欢迎的!

2 个答案:

答案 0 :(得分:0)

我发现Front Matter完全符合我的要求。 还有a python package

答案 1 :(得分:0)

不幸的是,这是不可能的,人们认为可以使用|作为单独文档中的单个标量:

import ruamel.yaml

yaml_str = """\
title: Title of the article
author: Somebody
---
|
Here there is the text of the article, it is not valid YAML but
just plain text. Here I could put **Markdown** or <html>...or whatever
I want...
"""

for d in ruamel.yaml.load_all(yaml_str):
    print(d)
    print('-----')

但不是因为|block indentation indicator。尽管在顶级,0(零)的缩进很容易起作用,但ruamel.yaml(和PyYAML)不允许这样做。

然而,自己很容易解析这个问题,这比使用YAML 1.2的前端物品包更具优势,因为使用PyYAML的前置制造者,因此不限于使用YAML 1.1。另请注意,我使用文档标记...更合适的结尾来将YAML与降价分开:

import ruamel.yaml

combined_str = """\
title: Title of the article
author: Somebody
...
Here there is the text of the article, it is not valid YAML but
just plain text. Here I could put **Markdown** or <html>...or whatever
I want...
"""

with open('test.yaml', 'w') as fp:
    fp.write(combined_str)


data = None
lines = []
yaml_str = ""
with open('test.yaml') as fp:
    for line in fp:
        if data is not None:
            lines.append(line)
            continue
        if line == '...\n':
            data = ruamel.yaml.round_trip_load(yaml_str)
            continue
        yaml_str += line

print(data['author'])
print(lines[2])

给出:

Somebody
I want...

round_trip_load允许转储并保留评论,锚名称等。)