The Cracked Bassoon


Displaying the contents of external files in Jekyll

The website is written in Jekyll. I like to display code in my posts, but copy-pasting working code directly from my scripts into Markdown files never felt like an elegant method. For one thing, if I changed my script for whatever reason, I also needed to go back and edit the Markdown file, which was annoying.

So I came up with the following method. First off, when I write a new script for a blog post, I always store it within a directory called /assets/scripts inside the GitHub repository for this website. After the script and the related post are both finished, but before I commit and push the changes to the repo, I run a file called code2yaml.py (also within /assets/scripts). This script looks like:

"""code2yaml.py

Convert contents of `scripts` directory to YAML.

"""
import os
import black


def code2yaml():
    """Convert contents of `scripts` directory to YAML.

    """

    for i, f in enumerate(os.listdir(os.getcwd())):

        src = os.path.join(os.getcwd(), f)
        contents = open(src).read()
        kwargs = {"fast": True, "mode": black.FileMode()}
        _, ext = os.path.splitext(f)
        if ext == ".py":
            try:
                # for some reason I can't get "in-place" formatter to work, so I just
                # overwrite the file instead
                contents = black.format_file_contents(contents, **kwargs)
            except black.NothingChanged:
                pass
        open(src, "w").write(contents)
        contents = "  " + contents.replace("\n", "\n  ").rstrip() + "\n"
        contents = f"{f.replace('.', '__')}: |\n" + contents
        open("../../_data/code.yaml", "w" if i == 0 else "a").write(contents)


if __name__ == "__main__":
    code2yaml()

As the name suggests, code2yaml.py converts the contents of all files within /assets/scripts to a YAML data file called _data/code.yaml. As an added bonus, it also formats any Python scripts using black. When Jekyll builds the website, all YAML data within _data/ become accessible via Liquid tags, which can be wrapped inside a Markdown code block with the appropriate language selected for syntax highlighting, like so:

```python
{{ site.data.code.code2yaml__py }}
```

Now I can make changes to my scripts at any time, and those changes will appear on the related posts (so long as I don’t forget to run code2yaml.py!).


Version history


Comments