我正在处理一些遗留代码,这些设计决策并非由我做出。
该代码需要处理一个有许多子目录的目录,其中包含Markdown文件,并将它们编译成一个大的Markdown文件(使用Markdown-PP:https://github.com/jreese/markdown-pp)。然后它将此文件转换为HTML(使用pandoc: https://pandoc.org/),最终再将其转换为PDF(使用wkhtmltopdf:https://wkhtmltopdf.org/)。
问题在于原始Markdown文件中有很多YAML元数据头部分。当Markdown-PP将它们连结在一起时,生成的大型Markdown文件中就会有许多YAML元数据块。由于pandoc处理YAML的方式(许多头使用相同的键名,pandoc会合并这些单独的YAML头部,只保留对应键的第一个值),因此在将其转换为HTML时,大部分元数据都会丢失。
起初我从未在HTML中看到过任何YAML,但通过正确修改pandoc的HTML模板,我成功改变了这一点。但是每个对应键仅获取第一个值。我不确定pandoc是否有解决这个问题的方法,因此我尝试在pandoc之前尝试将YAML处理成HTML。我尝试使用PyYAML(yaml.load_all())在合并后的Markdown中解析YAML,但只能看到第一个YAML块。
以下是一个YAML块的示例:
---
author: foo
size_minimum: 100
time_req_minutes: 120
# and so on
---
问题在于最终文档中的20多个模块都有这些关联元数据。
为了尝试解析YAML,我使用了从这篇文章中借鉴的代码:Is it possible to use PyYAML to read a text file written with a "YAML front matter" block inside?,并进行了一些修改。
import yaml
import sys
def get_yaml(f):
pointer = f.tell()
if f.readline() != '---\n':
f.seek(pointer)
return ''
readline = iter(f.readline, '')
readline = iter(readline.__next__, '---\n') #underscores needed for Python3?
return ''.join(readline)
# Remove sys.argv, not sure what it was doing
with open(filepath, encoding='UTF-8') as f:
config = list(yaml.load_all(get_yaml(f), Loader=yaml.SafeLoader)) # Load all to get all the YAML documents, Loader option required for most recent PyYAML, and list because it was originally returning a generator object
text = f.read()
print("TEXT from", f)
#print(text)
print("CONFIG from", f)
print(config)
但即使如此,这只会导致第一个YAML块被读取和输出。
我想要能够解析大型Markdown文件中的YAML,并在正确位置用相应的HTML替换它。 我只是不确定这些(或任何)软件包是否具有此功能。 可能我只需要在原始Markdown文件中手动将YAML更改为HTML(耗时,但如果我一开始就这样做,我可能已经完成了)。