@@ -1,135 +0,0 @@
1−#!/usr/bin/env python3
2−
3−import os
4−import sys
5−from pathlib import Path
6−from typing import List, Tuple
7−
8−
9−# inspired by weights.sh
10−
11−# NOTE: This script does not prevent you from shooting yourself in the foot.
12−# If you manually set a bogus value for insert_anchor_links it will not fix it for you
13−"""
14−1. get a list of all .md files
15−2. for each md file
16− a. get front matter
17− b. get value of key `insert_anchor_links`, default to none if not present
18− c. output a tuple of (setting, file)
19−3. accumulate all anchor setting values for all md files
20−4. write tuple to 'anchors' file, prompt to edit, open in preferred editor
21−5. once prompt is answered, read back file
22−6. read edited 'anchors' file, overwrite new setting for each file
23−"""
24−
25−ANCHOR_KEY = "insert_anchor_links = "
26−ANCHOR_FILE = "anchors"
27−
28−def nth_occurrence(arr, target_value, wanted_idx):
29− return [idx for idx, val in enumerate(arr) if val == target_value][wanted_idx - 1]
30−
31−def validate_entry(setting: str, file: str):
32− if not setting in ["left", "right", "none"]:
33− sys.exit(f"Invalid setting '{setting}' provided for file '{file}'")
34−
35−
36−def find_all_mds() -> List[str]:
37− # the `insert_anchor_links` is only applicable on `_index.md` files (i.e. sections)
38− return [str(p) for p in Path('./').rglob('**/.md')]
39−
40−def setting_from_frontmatter(lines: List[str]) -> str:
41− # 'insert_anchor_links = "none"' -> 'none'
42− for line in lines:
43− if line.startswith(ANCHOR_KEY):
44− # 1. 'insert_anchor_links = "none"\n'
45− # 2. ['insert_anchor_links = ' '"none"\n'][1] => '"none"\n'
46− # 3. "none\n"
47− # 4. "none"
48− return line \
49− .split(ANCHOR_KEY)[1] \
50− .replace('\"', '') \
51− .replace('\n', '')
52−
53− return "none" # default setting if key not present
54−
55−def anchors_from_frontmatter(md_files: List[str]) -> List[Tuple[str, str]]:
56− # returns tuple(setting, file)
57− anchor_settings = []
58−
59− for md_file in md_files:
60− with open(md_file, "r") as f:
61− lines = f.readlines()
62− setting = setting_from_frontmatter(lines)
63− anchor_settings.append((setting, md_file))
64−
65− return anchor_settings
66−
67−def write_anchor_file(anchor_settings: List[Tuple[str, str]]):
68− with open(ANCHOR_FILE, "w+") as f:
69− for setting, file in anchor_settings:
70− f.write(f"{setting} {file}\n")
71−
72−
73−def prompt_editor():
74− editor = os.getenv('EDITOR', 'nano')
75− os.system(f"{editor} {ANCHOR_FILE}")
76− input("Edit the anchor settings and press enter...")
77−
78−def read_anchor_file() -> List[Tuple[str, str]]:
79− anchor_settings = []
80−
81− with open(ANCHOR_FILE, "r") as f:
82− for line in f:
83− line = line.replace('\n', '')
84− setting, file = line.split(' ')
85− anchor_settings.append((setting, file))
86−
87− return anchor_settings
88−
89−
90−def write_entry(setting: str, file: str):
91− validate_entry(setting, file)
92−
93−
94− # not optimized
95− with open(file, "r+") as f:
96− lines = f.readlines()
97− # lines = list(filter(bool, text.split('\n'))) # split text by lines,
98− fm_end = nth_occurrence(lines, "+++\n", 2) # get index of end of front matter (signaled by second '+++')
99−
100− # remove existing setting if it exists
101− for line in lines[:fm_end]:
102− if line.startswith(ANCHOR_KEY):
103− lines.remove(line)
104− fm_end -= 1 # correct the index for the removal
105−
106− if setting != "none":
107− # by default, there is no need to specify "none"
108− lines.insert(fm_end, ANCHOR_KEY + f'"{setting}"' + '\n') # insert the setting right before the end of front matter
109− f.seek(0) # go to beginning of file
110− f.writelines(lines) # overwrite with new contents
111− f.truncate() # idk why but necessary for bug-free behviour (otherwise it adds excess newlines and stuff)
112−
113−
114−
115−def anchors_to_frontmatter(anchor_settings: List[Tuple[str, str]]):
116− for setting, file in anchor_settings:
117− write_entry(setting, file)
118−
119−def cleanup():
120− os.remove("anchors")
121−
122−
123−def main():
124− files = find_all_mds()
125− print(f'found {len(files)} .md files')
126− write_anchor_file(anchors_from_frontmatter(files))
127− prompt_editor()
128− anchors_to_frontmatter(read_anchor_file())
129− cleanup()
130− print('done')
131−
132−
133−if __name__ == '__main__':
134− main()
135−