【问题标题】:Edit YAML Frontmatter in markdown file在 markdown 文件中编辑 YAML Frontmatter
【发布时间】:2016-08-25 05:35:24
【问题描述】:

在 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.

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

【问题讨论】:

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


    【解决方案1】:

    最近我遇到了同样的问题,作为替代方案,您可以使用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】:

      是的,您可以做得更好,您只需从源代码中读取 YAML 文档 并在其末尾停止读取(---),然后处理 YAML,将其写入新文件(数据的实际长度可能会改变,因此您不太可能将其重写到位),然后读取输入文件的其余部分,并将其写出来。

      我看到的最大问题是,您的 ruby​​ YAML 解析器将在往返过程中丢弃所有 cmets、标签名称和其他可能使 YAML 人类可读的东西。

      【讨论】:

        【解决方案3】:

        我不知道有什么更好的方法,但实现起来很简单:

        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

        【讨论】:

          【解决方案4】:

          Middleman 的一位开发人员实际上在 Twitter 上联系了 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}
          })
          

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

          【讨论】:

            猜你喜欢
            • 2015-03-29
            • 1970-01-01
            • 2021-08-30
            • 1970-01-01
            • 1970-01-01
            • 2018-12-19
            • 2023-03-16
            • 2015-06-13
            相关资源
            最近更新 更多