2016-04-29 87 views
4

有没有办法在ruby中编辑标记文件顶部的YAML Frontmatter,就像在Jekyll和Middleman中使用的那样?在降价文件中编辑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. 

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

回答

0

Middleman的一位开发者实际上已经在推特上提供了一个中间人特定的,但仍然非常慷慨和有益的回应。它在实践上与其他答案类似(截至写作时),但它使用了一些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} 
}) 

对不起,该数据分析的东西是有点怪异(需要特殊的文件描述符和配置值),这东西通常不在核心之外使用。

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_REGEXPstraight from Jekyll并改编其frontmatter handling code

2

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

我看到的最大问题是,您的ruby YAML解析器将在往返过程中删除所有注释,标签名称以及可能使YAML具有人类可读性的其他内容。

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