-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmagic.ts
80 lines (70 loc) · 2.24 KB
/
magic.ts
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
import SVGPathCommander from "svg-path-commander";
import fs from "fs";
import optimize from "./src/components/IconEditor/optimize";
const toRelative = (line: string) => {
const d = line.replace(/ <path d="/, "").replace(/" \/>/, "");
const path = new SVGPathCommander(d, { round: 3 });
const [_, x, y] = path.segments[0];
path.reverse();
if (
x < path.segments[0][1] ||
(x === path.segments[0][1] && y < path.segments[0][2])
) {
path.reverse();
}
return path
.toRelative()
.toString()
.split(/(m[^a-z]*)/gi)
.slice(1) as [string, string];
};
const oldSvg = optimize(fs.readFileSync(process.argv[2], "utf8")) as string;
const newSvg = optimize(fs.readFileSync(process.argv[3], "utf8")) as string;
const newSvgLines = newSvg.split("\n");
const oldSvgLines = oldSvg.split("\n");
const onlyInNewSvgPaths = newSvgLines
.filter((line) => !oldSvgLines.includes(line))
.filter((line) => line.startsWith(" <path d="))
.map(toRelative);
const onlyInOldSvgPaths = oldSvgLines
.filter((line) => !newSvgLines.includes(line))
.filter((line) => line.startsWith(" <path d="))
.map(toRelative);
const diff = Object.fromEntries(
onlyInOldSvgPaths
.map((line, idx) => [
line[1],
`m${
parseFloat(onlyInNewSvgPaths[idx][0].split(/m/i)[1].split(" ")[0]) -
parseFloat(line[0].split(/m/i)[1].split(" ")[0])
} ${
parseFloat(onlyInNewSvgPaths[idx][0].split(" ")[1]) -
parseFloat(line[0].split(" ")[1])
} ` + onlyInNewSvgPaths[idx][1],
])
.filter(([_, b]) => b),
);
const magic = (input: string) =>
input
.split("\n")
.map((line) => {
if (!line.startsWith(" <path d=")) return line;
const [start, normalizedSegments] = toRelative(line);
if (!diff[normalizedSegments]) return line;
return (
' <path d="' +
new SVGPathCommander(start + diff[normalizedSegments], { round: 3 })
.toAbsolute()
.toString()
.replace(/^M[^M]*/, "") +
'" />'
);
})
.join("\n");
for (const file of process.argv.slice(4)) {
const input = fs.readFileSync(file, "utf8");
if (input !== magic(input)) {
console.log("Writing", file);
fs.writeFileSync(file, optimize(magic(optimize(input))));
}
}