Skip to content

Instantly share code, notes, and snippets.

@KarlClinckspoor
Last active January 27, 2023 00:58
Show Gist options
  • Save KarlClinckspoor/4ec995fd506ec6483b8e02d8afc388fc to your computer and use it in GitHub Desktop.
Save KarlClinckspoor/4ec995fd506ec6483b8e02d8afc388fc to your computer and use it in GitHub Desktop.
Conversion tool to make Zettlr markdown files be visible in Graph Mode in Obsidian
# encoding=utf8
#
# The purpose of this script is to convert the internal links used by Zettlr into
# links recognized by Obsidian. I know Obsidian has a built-in converter, but it
# didn't work for my files, perhaps because of my custom ID format.
#
# Problem description
#
# Zettlr uses links in the form of [[ID]], and it then searches the files available
# to match this ID, and it often is in the filename. Obsidian is different, as it uses
# the method [[Filename]] to link files( which is, in my opinion, a bad idea because
# it locks in filenames, but whatever).
#
# Method
# 1. Build a dictionary of the IDs you have and their respective filenames. It assumes
# all Zettlr files have the format "ID Name.md".
# 2. Go through all of these files, and find the links by ID using a regex. If found,
# and the file is also known, replace the ID with ID + filename, without ".md".
# 3. Save the converted files into another directory, "./converted", so you can inspect
# them before commiting.
#
# Disclaimer
# This script is inelegant and rough. It worked for me, and I might update it if I want to.
# Backup your files first, and always! I am not responsible for anything.
#
# Instructions
# 1. Alter the tag/ID pattern to match the one you have.
# 2. Copy this script to the folder where your notes are located
# 3. Run the script with "python conversion.py"
# 4. Open the new directory with Obsidian and check out the graph window to see if the conversion
# went smoothly.
# Change here the regular expression of your files. The default is \d{14}.
zettlr_ID_regex = r"(\d{4})_(\d{2})_(\d{2})_(\d{2})-(\d{2})-(\d{2})"
import re
import glob
import os
files = glob.glob("*md")
id_pattern = re.compile(zettlr_ID_regex)
id_pattern_link = re.compile(r"\[\[" + zettlr_ID_regex + r"\]\]")
# Create ID-filename correlation
ids_to_filenames = {id_pattern.search(file).group(0): file[:-3] for file in files}
for file in files:
with open(file, "r", encoding="utf8") as original_file:
content = original_file.read()
# Finds all the [[ids]] to loop through
ids_in_file = id_pattern_link.finditer(content)
for id_match in ids_in_file:
try:
# Extracts [[ids]] and ids, to make replacing easier
internal_link = id_match.group(0)
internal_link_id = internal_link[2:-2]
# Replaces the original text, should be fine
content = content.replace(
internal_link, f"[[{ids_to_filenames[internal_link_id]}]]"
)
except KeyError:
print("Did not find key", internal_link_id, "referenced in file", file)
continue
# Makes sure the folder exists
if not os.path.isdir("./conversions"):
os.mkdir("./conversions")
# Saves the files in the new folder
with open(f"./conversions/{file}", "w", encoding="utf8") as destination_file:
destination_file.write(content)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment