Last active
September 12, 2025 14:40
-
-
Save aliva/7a79ab8adcbc2f26349ad16775ed70ef to your computer and use it in GitHub Desktop.
Create markdown files based on your ticktick notes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Create markdown files based on your ticktick notes | |
You need to export your data from ticktick and use as input: | |
* Export from: Setting -> Account -> Generate Backup | |
Usage: | |
> python main.py -f ticktick.csv -d output_dir/ [--flatten] | |
""" | |
from argparse import ArgumentParser, FileType | |
from csv import DictReader | |
from io import StringIO | |
from pathlib import Path | |
import os | |
FIRST_LINE = 6 | |
parser = ArgumentParser() | |
parser.add_argument( | |
"--file", | |
"-f", | |
type=FileType("r"), | |
required=True, | |
help="Path to exported file", | |
) | |
parser.add_argument( | |
"--dest", | |
"-d", | |
type=Path, | |
required=True, | |
help="Destination directory", | |
) | |
parser.add_argument( | |
"--flatten", | |
action="store_true", | |
help="Create a flatten output" | |
) | |
args = parser.parse_args() | |
dest_path = args.dest.absolute() | |
os.makedirs(dest_path, exist_ok=True) | |
# Remove first few metadata lines | |
data = args.file.readlines() | |
data = "".join(data[FIRST_LINE:]) | |
# For multi line tasks or notes | |
csv_stream = StringIO(data) | |
# process data and write | |
rows = DictReader(csv_stream) | |
for row in rows: | |
if row["Kind"] == "NOTE": | |
task_title = row["Title"] | |
task_list = row["List Name"] | |
task_content = row["Content"] | |
if args.flatten: | |
list_dir = dest_path | |
task_title = f"{task_list} - {task_title}" | |
else: | |
list_dir = os.path.join(dest_path, task_list) | |
os.makedirs(list_dir, exist_ok=True) | |
md_file_path = os.path.join(list_dir, f"{task_title}.md") | |
counter = 0 | |
while os.path.exists(md_file_path): | |
md_file_path = os.path.join(list_dir, f"{task_title} - {counter:03}.md") | |
counter += 1 | |
with open(md_file_path, "w") as md_file: | |
md_file.write(task_content) | |
Here is an update to fix the nested folders along with the "Folder Name" also being used and a --hashtags option to append hashtags at end of file. Example importing into Obsidian
Thanks for sharing! :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is an update to fix the nested folders along with the "Folder Name" also being used and a --hashtags option to append hashtags at end of file. Example importing into Obsidian