Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Correctly wrap JSON front-matter in markdown files
#!/usr/bin/env python
#
# Script to wrap JSON front-matter in markdown files with `---` delimiters.
#
# This allows Prettier to be used on the markdown file (and it won't try and format the JSON front
# matter).
#
# I needed this to convert old Hugo markdown files that had JSON front-matter.
import os
import sys
import json
import tempfile
def fix_files(filepaths):
for filepath in filepaths:
fix_file(filepath)
def fix_file(filepath):
with open(filepath, "r") as f:
# Only process files where the first line is a brace opening a JSON object.
line = f.readline().strip()
if line != "{":
return
# Split the file contents into the front-matter object and the markdown content.
front_matter, md_content = split_file(f)
# Combine the content into a new file with the front-matter properly delimited.
temp_fd, temp_filepath = tempfile.mkstemp()
with os.fdopen(temp_fd, 'w') as g:
g.write("---\n")
g.write(json.dumps(front_matter, indent=4))
g.write("\n---\n\n")
g.write(md_content)
# Copy the converted file into place.
os.rename(temp_filepath, filepath)
def split_file(f):
"""
Split a file into front-matter and markdown.
"""
front_matter = None
f.seek(0)
json_lines = []
md_lines = []
for line in f.readlines():
stripped_line = line.strip()
if front_matter is None:
json_lines.append(line)
else:
md_lines.append(line)
if stripped_line == "}" and front_matter is None:
json_str = "\n".join(json_lines)
front_matter = json.loads(json_str)
md_content = "".join(md_lines)
return front_matter, md_content
fix_files(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment