【问题标题】:Parsing YAML out of a Markdown file从 Markdown 文件中解析 YAML
【发布时间】:2019-12-01 18:45:30
【问题描述】:

我正在处理一些我继承的遗留代码(即,其中许多设计决策不是我的)。

代码将一个目录组织成带有markdown文件的子目录,并将它们编译成一个大的markdown文件(使用Markdown-PP:https://github.com/jreese/markdown-pp)。然后它将此文件转换为 HTML(使用 pandoc:https://pandoc.org/),最后转换为 PDF(使用 wkhtmltopdf:https://wkhtmltopdf.org/)。

我遇到的问题是许多原始降价文件都有 YAML 元数据标头。当通过 Markdown-PP 拼接在一起时,大型降价最终会出现大量散布在各处的 YAML 元数据块。由于 pandoc 处理 YAML 的方式,大部分元数据在转换为 HTML 时会丢失(许多标头使用相同的键名,并且 pandoc 组合了单独的 YAML 标头并仅保留相应键的第一个值)。

我最初没有出现在 HTML 中的 YAML,但能够通过正确修改 pandoc 的 HTML 模板来改变它。但我只得到每个对应键的第一个值。尚不清楚 pandoc 中是否有解决此问题的方法,因此我转而尝试在 pandoc 步骤之前尝试将 YAML 处理为 HTML。我尝试使用 PyYAML (yaml.load_all()) 解析组合降价中的 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 块被读取和输出。

我希望能够从大型降价文件中解析 YAML,并在正确的位置将其替换为相应的 HTML。我只是不确定这些(或任何)软件包是否有能力这样做。可能我只需要手动将原始 Markdown 文件中的 YAML 更改为 HTML(时间密集,但如果我开始这样做,我可能已经完成了)。

【问题讨论】:

  • 为什么不将每个 Markdown 文件分别解析为 HTML,然后将多个 HTML 片段组合成一个大的 HTML 文档?
  • 将这些片段放在一起有多容易?现在,存在一个索引 Markdown 文件,它告诉 Markdown-pp 在将它们放在一起时要包含哪些其他 Markdown 文件(有关更多详细信息,请参阅github.com/jreese/markdown-pp自述文件)。这些文件按最终网页 (HTML) 和文档 (PDF) 的所需顺序排列。只要文件名保持不变,就可以将 !INCLUDE 语法和文件扩展名从 .md 更改为 .html?不过,如果出现任何问题,它可能需要一个新的 HTML 的“索引”文件,对吧?
  • 我对 Markdown-pp 不熟悉,但是如果您希望每个文件都应用 YAML frontmatter,那么您需要分别解析每个 Markdown 文件(在合并之前)。您使用什么解决方案来组合 HTML 由您决定。但是,每个 Markdown 文档都应该生成一个有效的 HTML 片段,该片段可以轻松地附加到其他文档中。无需担心创建无效的 HTML。我想你唯一关心的是定义顺序并从组合的 HTML 创建一个全局目录。最后一个有很多解决方案。
  • 顺序的定义和目录的创建是主要关注点。然而,这似乎是解决问题的最直接的方法。我能想到的唯一另一件事是解析所有 Markdown 文件中的 YAML,并将其更改为 HTML。我认为 Markdown-pp 和 pandoc 只会忽略 HTML,我希望 pandoc 将它留在正确的位置。除此之外,我不确定一个简单的解决方案。不过,感谢您的所有帮助!

标签: python html yaml markdown pyyaml


【解决方案1】:

这个库怎么样:https://github.com/eyeseast/python-frontmatter

它解析文件中的front-matter和Markdown,将Markdown部分放在结果对象的content属性中。

适用于包含front-matterless和front-matterless(有这样的词吗?)文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-16
    • 2014-11-05
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    相关资源
    最近更新 更多