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
|
#!/usr/bin/env python3
import numpy as np
import os
import subprocess
import sys
class SVGObject:
def __init__(self, attrlist):
self.id = attrlist[0]
self.x = float(attrlist[1])
self.y = float(attrlist[2])
self.w = float(attrlist[3])
self.h = float(attrlist[4])
self.x_ = self.x + self.w
self.y_ = self.y + self.h
def is_path(self):
return self.id.startswith("path")
def is_tspan(self):
return self.id.startswith("tspan")
def __repr__(self):
return "{}<x={}, y={}, w={}, h={}>".format(
self.id, self.x, self.y, self.w, self.h
)
def main(infile, *outfiles):
ret = subprocess.run(
["inkscape", "--query-all", infile], capture_output=True, check=True
)
objects = ret.stdout.decode("ascii").split("\n")
# remove last (empty) line
objects.pop()
# objects = [[ID, X, Y, W, H], ... ]
objects = list(map(lambda x: x.split(","), objects))
objects = list(map(lambda x: SVGObject(x), objects))
ys = list()
for o in objects:
if o.is_path() and o.h > 2 and o.h < 4 and o.w > 9:
ys.append(o.y)
ys = np.array(ys, dtype=np.int64)
if "double_decker_export" in os.environ:
# the first object is the "svg2" element describing the entire document
split = objects[0].h * 0.6
if os.environ["double_decker_export"] == "lower":
ys = ys[ys >= split]
else:
ys = ys[ys <= split]
bins = np.bincount(ys)
candidates = list(filter(lambda i: bins[i] > 2, range(len(bins))))
crop_y_min = np.min(candidates) - 1
crop_y_max = np.max(candidates) + 5
objects_to_delete = list()
x_positions = list()
for o in objects:
if (o.is_path() or o.is_tspan()) and (o.y < crop_y_min or o.y_ > crop_y_max):
objects_to_delete.append(o.id)
objects_to_delete = ",".join(objects_to_delete)
select_objects = f"--select={objects_to_delete}"
for outfile in outfiles:
if outfile.endswith(".png"):
subprocess.run(
[
"xvfb-run",
"-a",
"inkscape",
"--export-area-drawing",
select_objects,
"--verb=EditDelete",
"--batch-process",
"--export-dpi=600",
"-o",
outfile,
infile,
]
)
elif outfile.endswith(".svg"):
subprocess.run(
[
"xvfb-run",
"-a",
"inkscape",
"--export-area-drawing",
select_objects,
"--verb=EditDelete",
"--batch-process",
"-o",
outfile,
infile,
]
)
else:
raise RuntimeError(f"Unsupported export format: {outfile}")
if __name__ == "__main__":
main(*sys.argv[1:])
|