在markdown文件

时间:2016-04-29 23:08:41

标签: ruby yaml jekyll middleman yaml-front-matter

在ruby中是否有某种方法可以在markdown文件的顶部编辑YAML Frontmatter,就像Jekyll和Middleman中使用的那样?

类似的东西:

def update_yaml
  #magic that changes A: 1 to A: 2 in Frontmatter block
end

然后我的降价文件将从

改变
---
A: 1
---
# Title
Words. More words. This is the words part of the file.

---
A: 2
---
# Title
Words. More words. This is the words part of the file.

似乎唯一的选择是解析整个文件,然后只更改所需的部分重写整个文件,但我希望有更好的东西。

4 个答案:

答案 0 :(得分:2)

是的,你可以做得更好,你只需要从源头阅读YAML文件 然后停止读取它(---)然后你处理你的YAML,把它写到一个新文件(数据的实际长度可能会改变,所以你不太可能重写它),然后读取输入文件的其余部分,并将其写出来。

我看到的最大问题是你的ruby YAML解析器会在往返过程中删除所有注释,标记名称以及使YAML人类可读的其他东西。

答案 1 :(得分:2)

最近我遇到了同样的问题,作为替代方案,您可以使用python-frontmatter。它很容易使用。以下是更改yaml变量值的代码:

    import frontmatter
    import io
    with io.open('File.md', 'r') as f:
        post = frontmatter.load(f)
        post['A'] = 2

        # Save the file.
        newfile = io.open(fname, 'w', encoding='utf8')
        frontmatter.dump(post, newfile)
        newfile.close()

有关更多示例,请访问this page

答案 2 :(得分:1)

我不知道更好的事情,但实施起来非常简单:

require "yaml"

YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m

def update_data(data)
  data.merge("A" => 2)
end

if $stdin.read =~ YAML_FRONT_MATTER_REGEXP
  data, content = YAML.load($1), Regexp.last_match.post_match
  data = update_data(data)
  YAML.dump(data, $stdout)
  $stdout.puts("---", content)
end

上述内容来自$stdin并写入$stdout(请参阅行动on Ideone),但在实践中,您可能希望read from a file并撰写到Tempfile,并在成功时用Tempfile替换原始文件(例如,使用FileUtils)。

如果您想知道,我偷了YAML_FRONT_MATTER_REGEXP straight from Jekyll并修改了frontmatter handling code

答案 3 :(得分:0)

其中一位来自米德尔曼的开发人员实际上已经在推特上联系并提供了一个具体的,但仍然非常慷慨和乐于助人的回应。它在实践中与其他答案(截至编写时)相似,但它使用了一些Middleman功能。他们的回答(在此背景下编辑有意义)如下。

如果您制作脚本或扩展程序,则可以middleman-core/util/data提供::Middleman::Util::Data.parse

这将采用文件名和中间人"源文件"和一个分隔符列表(前面使用的---)并返回2个值:前面的数据对象和文件其余部分的字符串内容。

然后,您可以修改此ruby对象并编写该文件。

所以,阅读看起来像:

require "middleman-core/util/data”

resource = app.sitemap.resources.find_resource_by_destination_path(“whatever.html”)

frontmatter, content = ::Middleman::Util::Data.parse(resource.file_descriptor, app.config[:frontmatter_delims])

写作:

# change frontmatter

::File.write(resource.source_file, %Q{
---
#{frontmatter.to_yaml}
---

#{content}
})

抱歉,数据解析的东西有点奇怪(需要特殊的文件描述符和配置值),这些东西通常不在核心之外使用。