rubyyamljekyllmiddlemanyaml-front-matter

Edit YAML Frontmatter in markdown file


Is there some way in ruby to edit the YAML Frontmatter at the top of a markdown file, like those used in Jekyll and Middleman?

Something like:

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

Then my markdown file which would change from

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

to

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

It seems like the only option is parsing the entire file, then rewriting the entire file with only the desired part changed but I'm hoping there is something better.


Solution

  • One of the devs from Middleman actually reached out on Twitter and provided a Middleman specific, but still really generous and helpful response. It's similar in practice to the other answers (as of time of writing) but it uses some Middleman functionality. Their response (edited to make sense in this context) is below.


    If you make a script or extension you can require middleman-core/util/data which provides ::Middleman::Util::Data.parse

    This will take a filename and a Middleman "source file" and a list of delimiters (the --- used in front matter) and return 2 values: a data object of the front matter and the string content of the rest of the file.

    You can then modify this ruby object and write the file.

    So, reading would look like:

    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])
    

    And writing:

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

    Sorry, the data parsing stuff is a little weird (requiring a special file descriptor and config value), this stuff isn’t usually used outside of the core.