-
Notifications
You must be signed in to change notification settings - Fork 8
/
__main__.py
124 lines (116 loc) · 3.95 KB
/
__main__.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
import os
import argparse
from terminalsize import get_terminal_size
print('Loading dictionary...')
from bijective_map import uk_us, undo
UK = 'uk'
US = 'us'
def parseArgs() -> argparse.Namespace:
parser = argparse.ArgumentParser(description='"Translate" text from American to British English and back')
parser.add_argument(
'--to', type = str,
choices=[UK, US], required=True,
help='select target language',
)
parser.add_argument(
'input_filename', type=str,
)
parser.add_argument(
'output_filename', type=str,
nargs='?', default=None,
)
args = parser.parse_args()
if args.output_filename is None:
base, ext = os.path.splitext(args.input_filename)
args.output_filename = (
base + '_' + args.to + ext
)
return args
def main():
args = parseArgs()
if os.path.isfile(args.output_filename):
print(f'Ok to overwrite "{args.output_filename}"? y/n')
if input('>').lower() != 'y':
print('User aborted.')
return
print('Note: wide characters (e.g. Chinese) breaks character alignment.')
print('Rules of undo:')
for uk, us in undo:
source, target = selectDirection(uk, us, args.to, reverse=True)
print(' '*3, source, '\t-> ', target)
print()
print( '|------------ × ------------|')
if args.to == UK:
print('| Beginning Britishisation |')
else:
print('| Beginning Americanization |')
print( '|------------ × ------------|')
print()
with open(args.input_filename, 'r', encoding='utf-8') as inF:
for line_no, line in enumerate(inF):
undone = tryUndo(line)
if undone != line:
print(f'Error: undo rule can operate on original string. Line {line_no}: ')
print(line)
raise ValueError
with open(args.input_filename, 'r', encoding='utf-8') as inF:
with open(
args.output_filename, 'w', newline='\n',
encoding='utf-8',
) as outF:
for line_no, line in enumerate(inF):
for uk, us in uk_us:
for source, target in iterCapitalize(*selectDirection(
uk, us, args.to,
)):
line = processLine(
line_no, line, source, target,
)
outF.write(line)
print('Done.')
def selectDirection(uk, us, to, reverse = False):
if (to == UK) ^ reverse:
return us, uk
else:
return uk, us
def iterCapitalize(source, target):
return (
(source, target),
(source.capitalize(), target.capitalize()),
)
def tryUndo(line):
for source, target in undo:
for s, t in iterCapitalize(source, target):
line = line.replace(s, t)
return line
INDENT = 4
def processLine(line_no, line, source, target):
try:
start = line.index(source)
except ValueError:
return line
replaced = line.replace(source, target, 1)
undone = tryUndo(replaced)
if undone != line:
width = get_terminal_size()[0] - 1 - INDENT
print('-' * width)
print('line', line_no, ':')
assert replaced == undone
mid = width // 2
offset = max(0, start - mid)
sub_line = line[offset : offset + width]
print(' ' * INDENT, sub_line.rstrip(), sep='')
display_padding = ' ' * (INDENT + start - offset)
print(display_padding, '^' * len(source), sep='')
print(display_padding, target, sep='')
print('Replace? y/n >', end='', flush=True)
if input().lower() == 'y':
return undone[:start + 1] + processLine(
line_no, undone[start + 1:], source, target,
)
else:
print('User decided not to replace.')
return line[:start + 1] + processLine(
line_no, line[start + 1:], source, target,
)
main()