在 markdown 文件中编辑 YAML Frontmatter
Edit YAML Frontmatter in markdown file
ruby 中是否有某种方法可以像 Jekyll 和 Middleman 中使用的那样编辑 markdown 文件顶部的 YAML Frontmatter?
类似于:
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.
似乎唯一的选择是解析整个文件,然后重写整个文件,只更改所需的部分,但我希望有更好的东西。
我不知道还有什么更好的,但实现起来非常简单:
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(), Regexp.last_match.post_match
data = update_data(data)
YAML.dump(data, $stdout)
$stdout.puts("---", content)
end
以上内容从 $stdin
读取并写入 $stdout
(实际操作见 on Ideone), but in practice you'd probably want to read from a file and write to a Tempfile, and upon success replace the original file with the Tempfile (using, say, FileUtils
)。
如果你想知道,我偷了 YAML_FRONT_MATTER_REGEXP
straight from Jekyll and adapted its frontmatter handling code。
是的,你可以做得更好,你只需要从源代码中阅读 YAML 文档
并在其末尾停止读取 (---
),然后处理 YAML,将其写入新文件(数据的实际长度可能会发生变化,因此您不太可能就地重写它),然后读取输入文件的其余部分,并将其写出。
我看到的最大问题是,您的 ruby YAML 解析器会在往返过程中删除所有注释、标签名称和可能使 YAML 人类可读的其他内容。
Middleman 的一位开发人员实际上在 Twitter 上联系并提供了一个 Middleman 特定的,但仍然非常慷慨和有帮助的回应。它在实践中与其他答案类似(截至撰写本文时),但它使用了一些中间人功能。他们的回复(经过编辑以使其在这种情况下有意义)如下。
如果您制作脚本或扩展程序,您可以要求 middleman-core/util/data
提供 ::Middleman::Util::Data.parse
这将需要一个文件名和一个中间人 "source file" 和一个分隔符列表(前面使用的 ---
)和 return 2 个值:前面的数据对象matter 和文件其余部分的字符串内容。
然后您可以修改此 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}
})
抱歉,数据解析的东西有点奇怪(需要特殊的文件描述符和配置值),这些东西通常不在核心之外使用。
最近我遇到了同样的问题,作为替代,您可以使用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
ruby 中是否有某种方法可以像 Jekyll 和 Middleman 中使用的那样编辑 markdown 文件顶部的 YAML Frontmatter?
类似于:
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.
似乎唯一的选择是解析整个文件,然后重写整个文件,只更改所需的部分,但我希望有更好的东西。
我不知道还有什么更好的,但实现起来非常简单:
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(), Regexp.last_match.post_match
data = update_data(data)
YAML.dump(data, $stdout)
$stdout.puts("---", content)
end
以上内容从 $stdin
读取并写入 $stdout
(实际操作见 on Ideone), but in practice you'd probably want to read from a file and write to a Tempfile, and upon success replace the original file with the Tempfile (using, say, FileUtils
)。
如果你想知道,我偷了 YAML_FRONT_MATTER_REGEXP
straight from Jekyll and adapted its frontmatter handling code。
是的,你可以做得更好,你只需要从源代码中阅读 YAML 文档
并在其末尾停止读取 (---
),然后处理 YAML,将其写入新文件(数据的实际长度可能会发生变化,因此您不太可能就地重写它),然后读取输入文件的其余部分,并将其写出。
我看到的最大问题是,您的 ruby YAML 解析器会在往返过程中删除所有注释、标签名称和可能使 YAML 人类可读的其他内容。
Middleman 的一位开发人员实际上在 Twitter 上联系并提供了一个 Middleman 特定的,但仍然非常慷慨和有帮助的回应。它在实践中与其他答案类似(截至撰写本文时),但它使用了一些中间人功能。他们的回复(经过编辑以使其在这种情况下有意义)如下。
如果您制作脚本或扩展程序,您可以要求 middleman-core/util/data
提供 ::Middleman::Util::Data.parse
这将需要一个文件名和一个中间人 "source file" 和一个分隔符列表(前面使用的 ---
)和 return 2 个值:前面的数据对象matter 和文件其余部分的字符串内容。
然后您可以修改此 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}
})
抱歉,数据解析的东西有点奇怪(需要特殊的文件描述符和配置值),这些东西通常不在核心之外使用。
最近我遇到了同样的问题,作为替代,您可以使用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