A first attempt at converting frontmatter

This commit is contained in:
Martin Frost 2025-07-31 19:27:17 +02:00
commit d3bdf8a4ca
2 changed files with 90 additions and 0 deletions

15
README.md Normal file
View file

@ -0,0 +1,15 @@
# Convert nikola frontmatter to zola
Nikola uses HTML comments for frontmatter.
Zola does not.
## Requirements
A somewhat modern Python 3 installation.
## Usage
```
./nikola_to_zola.py path/to/nikola/page.md > desired/destination/zola/page.md
```

75
nikola_to_zola.py Executable file
View file

@ -0,0 +1,75 @@
#!/usr/bin/env python3
import argparse
import datetime
import zoneinfo
SWEDEN = zoneinfo.ZoneInfo("Europe/Stockholm")
parser = argparse.ArgumentParser(
prog="nikola_to_zola.py",
description="Convert Nikola frontmatter to Zola",
)
parser.add_argument("filename")
args = parser.parse_args()
def parse_frontmatter_line(line: str) -> tuple[str, str]:
"""Parse one line from Nikola frontmatter
Returns a tuple with (key, value).
Parses dates into ISO8601 format.
"""
frontmatter = tuple(line.strip()[3:].split(": ", 1))
key = frontmatter[0]
if len(frontmatter) < 2:
val = ""
else:
val = frontmatter[1]
# Parse dateformat used in our frontmatter
if key == 'date':
try:
time_format = "%Y-%m-%d %H:%M:%S %Z"
val = datetime.datetime.strptime(val, time_format)
except ValueError:
time_format2 = "%Y-%m-%d %H:%M %Z"
val = datetime.datetime.strptime(val, time_format2)
val = val.astimezone(SWEDEN).isoformat()
return key, val
def read_file():
frontmatter = {}
text = []
with open(args.filename, 'r') as file:
reading_frontmatter = True
for line in file:
if line == "<!--\n":
continue
if line.startswith("-->"):
reading_frontmatter = False
continue
# Strip out teaser comments
if line.startswith("<!-- TEASER"):
continue
if reading_frontmatter and line.startswith(".. "):
fkey, fval = parse_frontmatter_line(line)
frontmatter[fkey] = fval
else:
text.append(line)
print("+++")
for key, val in frontmatter.items():
print(f'{key} = "{val}"')
print("+++")
print("".join(text).strip())
if __name__ == '__main__':
read_file()