-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobsidian_to_jekyll.py
141 lines (116 loc) · 4.18 KB
/
obsidian_to_jekyll.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from ast import Bytes
import re
import frontmatter
from datetime import datetime, timezone
import dateutil.parser as dp
import calendar
from yaml.constructor import ConstructorError
from os import walk, path, rename, sep, mkdir
from shutil import copyfile, rmtree
from io import BytesIO
JEKYLL_POSTS_FOLDER = "_posts/"
JEKYLL_ASSET_FOLDER = "assets/img/notes/"
OBSIDIAN_ASSET_FOLDER = "my-vault/00-09 System/00 Assets"
def get_new_name(f, old_f):
post_format = lambda x : x.lower().replace(" ", "-")
acceptable_pattern = r"[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]\-[^\s]*\.md"
p = re.compile(acceptable_pattern)
valid_form = p.match(f)
new_f = f
if not valid_form:
post = frontmatter.load(old_f)
date = post.get("date", None)
if date is None:
uxt = path.getmtime(old_f)
date = datetime.fromtimestamp(uxt).strftime("%Y-%m-%d")
date = dp.parse(date).strftime("%Y-%m-%d")
ff = f"{date}-{post_format(f)}"
new_f = path.join(JEKYLL_POSTS_FOLDER, ff)
assert p.match(ff)
# rename(old_f, new_f)
return new_f
def copy_over_published_markdown(f, d):
old_f = path.join(d, f)
print(f"Copy Published Markdown::File: {old_f}")
try:
post = frontmatter.load(old_f)
publishable = post.get("share", False)
if publishable:
print(f"{f}:")
new_f = get_new_name(f, old_f)
print("\t[name]", new_f)
copyfile(old_f, new_f)
return new_f
except ConstructorError:
print("Error parsing:", old_f)
return None
def improve_metadata(f):
post = frontmatter.load(f)
post["author"] = "ianfhunter"
post["math"] = True
post["mermaid"] = True
# post["title"] =
# post["date"] =
# with open(f,"w") as w:
b = BytesIO()
frontmatter.dump(post, b)
with open(f, "wb") as w:
w.write(b.getbuffer())
def copy_over_referenced_images(f):
with open(f,"r") as r:
content = r.read()
# print(content)
markdown_pattern = r"\!\[\[([a-zA-Z0-9\_\s]+\.(png|gif|jpg))\]\]"
p = re.compile(markdown_pattern)
g = re.findall(p, content)
if len(g) > 0:
for img, ext in g:
print(f"\t[img]: {img}")
src_path = path.join(OBSIDIAN_ASSET_FOLDER, img)
dst_path = path.join(JEKYLL_ASSET_FOLDER, img)
if path.exists(src_path):
copyfile(src_path, dst_path)
# print("Before:", content)
content = re.sub(p, f"<img src='/assets/img/notes/{img}' />", content, 1)
with open(f, "w") as w:
w.write(content)
def fix_internal_links(f):
# Replace [[Internal]] and [[Internal|Text]]
# With
# [Text](AbsoluteInternal)
linkify = lambda x : "../"+ x.lower().replace(" ","-")
with open(f,"r") as r:
content = r.read()
markdown_pattern = r"\[\[([a-zA-Z0-9\_\s]+)\|?([a-zA-Z0-9\_\s]*)\]\]"
p = re.compile(markdown_pattern)
g = re.findall(p, content)
if len(g) > 0:
for reference, alt_text in g:
if alt_text == '':
att = reference
else:
att = alt_text
reference = linkify(reference)
content = re.sub(p, f"[{att}]({reference})", content, 1)
with open(f, "w") as w:
w.write(content)
def main():
# TODO: Copy from my-vault to _posts
# TODO: Copy images over also
# Clear out post folder
rmtree(JEKYLL_POSTS_FOLDER, ignore_errors=True)
rmtree(JEKYLL_ASSET_FOLDER, ignore_errors=True)
if not path.exists(JEKYLL_POSTS_FOLDER):
mkdir(JEKYLL_POSTS_FOLDER)
mkdir(JEKYLL_ASSET_FOLDER)
for (dirpath, dirnames, filenames) in walk("my-vault"):
for f in filenames:
if ".md" in f:
ff = copy_over_published_markdown(f, dirpath)
if ff is None:
continue
improve_metadata(ff)
copy_over_referenced_images(ff)
fix_internal_links(ff)
if __name__ == "__main__":
main()