forked from perkinsben/obs_tools
-
Notifications
You must be signed in to change notification settings - Fork 8
/
obs-batch-linkr.py
104 lines (89 loc) · 3.46 KB
/
obs-batch-linkr.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
import yaml
import sys
import os
import re
page_titles = []
page_aliases = {}
obsidian_home = ''
def link_title(title, txt):
updated_txt = txt
# find instances of the title where it's not surrounded by [] or other letters
m = re.search('(?<!([\[\w\|]))' + re.escape(title.lower()) + '(?!([\]\w]))', txt.lower(), 1) # get 1 match at a time
if (m):
# get the original text to link
txt_to_link = txt[m.start():m.end()]
#print(txt_to_link)
# handle aliases
if (title in page_aliases): title = page_aliases[title]
# handle the display text if it doesn't match the page title
if (txt_to_link != title): title = title + '|' + txt_to_link
# create the link and update our text
updated_txt = txt[:m.start()] + '[[' + title + ']]' + txt[m.end():]
#print(updated_txt)
return updated_txt
# validate obsidian vault location
if (len(sys.argv) > 1):
obsidian_home = sys.argv[1]
if not os.path.isdir(obsidian_home):
print('folder specified is not valid')
exit()
else:
print("usage - python obs-link.py [path to obsidian vault]")
exit()
# get text from clipboard
clip_txt = pyperclip.paste()
print('--- clipboard text ---')
print(clip_txt)
print('----------------------')
# make a copy of it and lowercase it for search purposes
clip_low = clip_txt.lower()
# get a directory listing of obsidian *.md files
# use it to build our list of titles
for root, dirs, files in os.walk(obsidian_home):
for file in files:
if file.endswith('.md'):
page_title = re.sub(r'\.md$', '', file)
print(page_title)
page_titles.append(page_title)
# we'll also check for an aliases file and load that
# we pivot (invert) the dict for lookup purposes
aliases_file = obsidian_home + "/aliases.yml"
if os.path.isfile(aliases_file):
with open(aliases_file, 'r') as stream:
try:
aliases = yaml.full_load(stream)
for title in aliases:
#print(title)
for alias in aliases[title]:
page_aliases[alias] = title
#print(page_aliases)
except yaml.YAMLError as exc:
print(exc)
exit()
# append our aliases to the list of titles
for alias in page_aliases:
page_titles.append(alias)
# sort from longest to shortest page titles so that we don't
# identify scenarios where a page title is a subset of another
page_titles = sorted(page_titles, key=lambda x: len(x), reverse=True)
print('----------------------')
## iterate through our page titles
for page_title in page_titles:
# if we have a case-insenitive title match...
if page_title.lower() in clip_low:
print('found %s in text' % page_title)
# track whether we still have unlinked references to process
unlinked_refs_remain = True
# keep attempting to match titles until we're done
while unlinked_refs_remain:
updated_txt = link_title(page_title, clip_txt)
# we can tell whether we're finished by testing whether
# the linking process changed the updated text length
if len(updated_txt) == len(clip_txt):
unlinked_refs_remain = False
else:
clip_txt = updated_txt
# lowercase our updated text for the next round of search
clip_low = clip_txt.lower()
print('----------------------')
print('Your vault is interlinked')