-
Notifications
You must be signed in to change notification settings - Fork 4
/
th2enumeratestations.py
executable file
·105 lines (74 loc) · 2.81 KB
/
th2enumeratestations.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
#!/usr/bin/env python
'''
Copyright (C) 2008 Thomas Holder, http://sf.net/users/speleo3/
Distributed under the terms of the GNU General Public License v2 or later
Enumerate therion station names
'''
from typing import Tuple
import inkex
import re
from th2setprops import Th2SetProps
therion_laststationname = inkex.addNS('laststationname', 'therion')
BS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n: int, b=len(BS)) -> str: # noqa: B008
return "0" if not n else to_base(n // b, b).lstrip("0") + BS[n % b]
class StationName:
def __init__(self, name: str):
name = name.strip()
m = re.match(r'([0-9a-zA-Z]+)($|@.*)', name)
if m is None:
raise ValueError("can't increment station name '{}'".format(name))
stationName = m.group(1)
self.post = m.group(2)
self.pre, incrementingPart = SeparateStationNameParts(stationName)
if incrementingPart.isdigit():
self.base = 10
self.convertToLower = False
else:
self.base = 36
self.convertToLower = incrementingPart.islower()
self.number = int(incrementingPart, self.base)
def __str__(self) -> str:
incrementingPart = to_base(self.number, self.base)
if self.convertToLower:
incrementingPart = incrementingPart.lower()
return self.pre + incrementingPart + self.post
def __iter__(self):
return self
def __next__(self) -> str:
s = str(self)
self.number += 1
return s
next = __next__
def SeparateStationNameParts(s: str) -> Tuple[str, str]:
part1, part2 = '', ''
# Check if the string is entirely alphabetic or numeric
if s.isalpha() or s.isdigit():
return '', s
# Start from the end of the string and look for the transition point
for i in range(len(s) - 1, 0, -1):
if (s[i].isdigit() and s[i - 1].isalpha()) or (s[i].isalpha() and s[i - 1].isdigit()):
part1 = s[:i]
part2 = s[i:]
break
return part1, part2
class Th2EnumerateStations(Th2SetProps):
def __init__(self):
Th2SetProps.__init__(self)
self.arg_parser.add_argument(
"--stationname", type=str, dest="stationname")
def update_options(self, options: dict):
options['name'] = next(self.stationnames)
def effect(self):
root = self.document.getroot()
stationname = self.options.stationname
if not stationname:
stationname = root.get(therion_laststationname)
if not stationname:
raise ValueError("empty station name")
self.stationnames = StationName(stationname)
Th2SetProps.effect(self)
root.set(therion_laststationname, str(self.stationnames))
if __name__ == '__main__':
e = Th2EnumerateStations()
e.run()