Hugo formatting

While Hugo can take Markdown files and use those for posts, they need to be in a specific layout. The most important is probably the front matter. The front matter contains the metadata for the post; date, title, tags etc. It can look like this (it’s the one from this post - still in “draft mode”):

title: "Writing the files"
date: 2023-10-23T07:05:24+02:00
author: "Emil Harder"
draft: false

There should be some minus signs, title date and author segment.

I’m not really that strong in handling strings. There might by far more elegant ways of achieving the formatting I’m after. But my goal is simply something that works. (Guess it’s the primary theme for this project..) But it’s possible to write multi line strings in Python, by using 3 quotations marks, like this:

string_to_print = (
    title: \"""" + subject + """\"
    date: """ + date_formatted + """
    author: \"Emil Harder\"
    + content

This causes the line breaks gets stored too. Adding the values returned from the mail fetching function into the mix, and the post is pretty much ready to be written to a file.

Adding data from mails

Because the return from the function that fetches mails, is a list; a for loop is used. From there it’s simple to store date, subject and body from the second dimension (sublist) in the list:

for i in m:
    date = i[0]
    subject = i[1]
    body = i[2]
    date = datetime.strptime(date, "%a, %d %b  %Y %H:%M:%S %z")
    date_formatted = datetime.strftime(date,"%Y-%m-%dT%H:%M:%S%z")
    content = "{{<poem>}}"+body.strip()+"{{</poem>}}\n"

Hugo uses a different format for the date than the one from imaplib. Instead of doing some elaborate string juggling, I converted the string from the mail, to a datetime object, and back again to a string. This way I could use the format parameter of the strftime function. Not elegant, but easy to get going.

Because I wanted the line breaks to behave different for these snippets (poems), I made the shortcode {{}}, which had to be added to the body. This seemed like the correct time to do it. And while at it, stripping the leading and trailing white spaces etc. And for some reason I added a last line break.

Write it down

The string is ready. Lets create the file!

file_date = datetime.strftime(date,"%d-%m-%Y %H-%M")
subject = re.sub('[^A-Za-z0-9]+', '', subject)
with open(post_path+"/"+file_date+subject+"/", "w") as text_file:
    print(string_to_print, file=text_file)

Because some file systems (or OS’s maybe) can’t handle colons, the date had to change format, yet again. It’s of cause not really necessary to use the date in the file name. I just think my future self would appreciate it, when trying to get a overview of all the old garbage on his web server. One last gotcha (that at least got me) was the use of special characters for the file name. Because the titles for the posts is in danish, they might contain æ, ø or å. As I use the titles for the posts as the file names too and Hugo uses the file names for the urls too, (and to my understanding does not catch any “illegal” characters there,) it has to be done here. It is done with the regular expression library re, and the sub command from that. It looks for everything that is not an alphanumerical value, and deletes it. It might make the file names a bit tricky to read, but again; it works.

Besides that, there is not really much worth writing about. File gets written as text file, and I remembered to close it: Job done!

Next (and last) post will be some final remarks about the project at a whole.