-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadd_cloze
executable file
·103 lines (81 loc) · 2.93 KB
/
add_cloze
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
#!/usr/bin/env python3
"""
Add Anki cloze deletions of increasing size to a text.
"""
import argparse
import logging
logging.basicConfig(level=logging.INFO)
CHUNK_MULTIPLIER = 2
INITIAL_CHUNK_SIZE = 2
def read_lines_from_file(filename):
with open(filename, "r") as file:
lines = [l.strip() for l in file]
while not lines[-1]:
lines.pop()
return lines
def start_cloze(line, cloze_index):
return "{{c" + str(cloze_index) + "::" + line
def finish_cloze(line):
return line + "}}"
def encloze(line, cloze_index):
return finish_cloze(start_cloze(line, cloze_index))
def create_nested_cloze_chunks(lines):
"""
Partially overlapping cloze deletions are not supported, so bigger chunks
must contain smaller chunks. Guaranteed if bigger chunk sizes are
multiples of smaller chunk sizes.
See
"There is no support for partial overlaps" in
https://docs.ankiweb.net/editing.html?highlight=cloze#cloze-deletion.
"""
cloze_index = 1
added_chunks = set()
# Distinguishing case chunk_size == 1 to skip empty lines. We assume
# there's at most one consecutive empty line.
for i in range(len(lines)):
if not lines[i]:
continue
lines[i] = encloze(lines[i], cloze_index)
added_chunks.add((i, i))
cloze_index += 1
chunk_size = 2
while chunk_size < len(lines):
for start in range(0, len(lines), chunk_size):
end = min(start + chunk_size, len(lines)) - 1
if (start, end) in added_chunks:
logging.debug(f"{start}, {end} already in.")
continue
logging.debug(f"{start}, {end}, {cloze_index} added.")
logging.debug(f"Begin: {lines[start]}")
logging.debug(f"End: {lines[end]}")
added_chunks.add((start, end))
lines[start] = start_cloze(lines[start], cloze_index)
lines[end] = finish_cloze(lines[end])
cloze_index += 1
chunk_size *= CHUNK_MULTIPLIER
def write_lines_to_file(filename, lines, overwrite=False):
cloze_file = "cloze_" + filename
mode = "w" if overwrite else "x"
try:
with open(cloze_file, mode) as file:
file.write("\n".join(lines))
except FileExistsError as e:
logging.error("File already exists: %s", e)
def add_cloze_deletion(filename, overwrite):
lines = read_lines_from_file(filename)
create_nested_cloze_chunks(lines)
write_lines_to_file(filename, lines, overwrite)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Add cloze deletion tags to chunks of text in a file."
)
parser.add_argument("filename", help="Input filename.")
parser.add_argument(
"-f",
"--force",
action="store_true",
default=False,
help="Overwrite existing file.",
)
args = parser.parse_args()
add_cloze_deletion(args.filename, overwrite=args.force)