-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconvert_to_vim_snippets.py
108 lines (88 loc) · 3.92 KB
/
convert_to_vim_snippets.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
import json
from typing import Optional
import re
PATH_TO_JSON = "obsidian_snippets.json"
def load_json_file():
with open(PATH_TO_JSON) as json_file:
return json.load(json_file)
obsidian_snippet_variables: dict[str, str] = {
"${GREEK}": "alpha|beta|gamma|Gamma|delta|Delta|epsilon|varepsilon|zeta|eta|theta|vartheta|Theta|iota|kappa|lambda|Lambda|mu|nu|xi|omicron|pi|rho|varrho|sigma|Sigma|tau|upsilon|Upsilon|phi|varphi|Phi|chi|psi|omega|Omega",
"${SYMBOL}": "parallel|perp|partial|nabla|hbar|ell|infty|oplus|ominus|otimes|oslash|square|star|dagger|vee|wedge|subseteq|subset|supseteq|supset|emptyset|exists|nexists|forall|implies|impliedby|iff|setminus|neg|lor|land|bigcup|bigcap|cdot|times|simeq|approx",
"${MORE_SYMBOLS}": "leq|geq|neq|gg|ll|equiv|sim|propto|rightarrow|leftarrow|Rightarrow|Leftarrow|leftrightarrow|to|mapsto|cap|cup|in|sum|prod|exp|ln|log|det|dots|vdots|ddots|pm|mp|int|iint|iiint|oint"
}
class ObsidianSnippet:
trigger: str
replacement: str
options: str
priority: Optional[int]
description: Optional[str]
flags: Optional[str]
def __init__(self, trigger: str, replacement: str, options: str,
priority: Optional[int] = None, description: Optional[str] = None,
flags: Optional[str] = None):
self.trigger = trigger
self.replacement = replacement
self.options = options
self.priority = priority
self.description = description
self.flags = flags
def math_context(self):
math_chars: list[str] = ["m", "M", "n"]
return "context \"math()\"\n" if any(math_char in self.options for math_char in math_chars) else ""
def output_priority(self):
return f"priority {int(self.priority)}\n" if self.priority is not None else ""
def convert_options(self):
converted: str = ""
for c in self.options:
match c:
case 'c':
raise ValueError(f"option is {c}")
case 'A' | 'r' | 'w' | 'b':
converted += f"{c}"
case 'm' | 'M' |'n':
converted += "i"
# do nothing for 't' case
return converted
def is_regex(self):
return 'r' in self.options
def generate_replacement(self):
replacement: str = self.replacement
if self.is_regex():
replacement = replacement.replace("[[0]]", "`!p snip.rv = match.group(1)`")
replacement = replacement.replace("[[1]]", " `!p snip.rv = match.group(2)`")
return replacement
def generate_trigger(self):
trigger: str = self.trigger
if self.is_regex():
trigger = trigger.replace("\n", "\\n")
for snippet_var, replacement in obsidian_snippet_variables.items():
trigger = trigger.replace(snippet_var, replacement)
try:
re.compile(trigger)
except Exception as e:
print(self.__dict__)
raise ValueError(e)
return f"\"{trigger}\""
def generate_description(self):
if self.description is None:
return "\"\""
else:
return f"\"{self.description}\""
def generate_snippet(self):
output: str = f"{self.output_priority()}"
output += f"{self.math_context()}"
output += f"snippet {self.generate_trigger()} {self.generate_description()} {self.convert_options()}\n"
output += self.generate_replacement() + "\nendsnippet"
return output
if __name__ == "__main__":
math_context: str = """
# Include this code block at the top of a *.snippets file...
# ----------------------------- #
global !p
def math():
return vim.eval('vimtex#syntax#in_mathzone()') == '1'
endglobal
"""
snippets = "\n\n".join([ObsidianSnippet(**item).generate_snippet() for item in load_json_file()])
with open("math.snippets", 'w') as output_file:
print(math_context + "\n" + snippets, file=output_file)