svgmapviewer-tools-floors 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/LICENSE +15 -0
  2. package/inkscape/extensions/Attic/fix_guides.inx +17 -0
  3. package/inkscape/extensions/Attic/fix_guides.py +30 -0
  4. package/inkscape/extensions/Attic/fix_symbol_links.inx +17 -0
  5. package/inkscape/extensions/Attic/fix_symbol_links.py +71 -0
  6. package/inkscape/extensions/Attic/flatten_style.inx +17 -0
  7. package/inkscape/extensions/Attic/flatten_style.py +31 -0
  8. package/inkscape/extensions/Attic/load_markers.inx +17 -0
  9. package/inkscape/extensions/Attic/load_markers.py +117 -0
  10. package/inkscape/extensions/Attic/load_patterns.inx +17 -0
  11. package/inkscape/extensions/Attic/load_patterns.py +116 -0
  12. package/inkscape/extensions/Attic/load_symbols.inx +17 -0
  13. package/inkscape/extensions/Attic/load_symbols.py +164 -0
  14. package/inkscape/extensions/Attic/renumber_tree.inx +24 -0
  15. package/inkscape/extensions/Attic/renumber_tree.py +39 -0
  16. package/inkscape/extensions/Attic/repeat_path.inx +17 -0
  17. package/inkscape/extensions/Attic/repeat_path.py +58 -0
  18. package/inkscape/extensions/Attic/resolve_facility_links.inx +19 -0
  19. package/inkscape/extensions/Attic/resolve_facility_links.py +16 -0
  20. package/inkscape/extensions/Attic/sort_symbols.inx +17 -0
  21. package/inkscape/extensions/Attic/sort_symbols.py +48 -0
  22. package/inkscape/extensions/Attic/symbol_load.inx +17 -0
  23. package/inkscape/extensions/Attic/symbol_load.py +99 -0
  24. package/inkscape/extensions/Attic/tidy_tree.inx +22 -0
  25. package/inkscape/extensions/Attic/tidy_tree.py +178 -0
  26. package/inkscape/extensions/Attic/use_shop.inx +22 -0
  27. package/inkscape/extensions/Attic/use_shop.py +26 -0
  28. package/inkscape/extensions/README.md +34 -0
  29. package/inkscape/extensions/daijimaps/__init__.py +72 -0
  30. package/inkscape/extensions/daijimaps/address_tree.py +231 -0
  31. package/inkscape/extensions/daijimaps/common.py +49 -0
  32. package/inkscape/extensions/daijimaps/generate_addresses.py +41 -0
  33. package/inkscape/extensions/daijimaps/guards.py +47 -0
  34. package/inkscape/extensions/daijimaps/map_layer.py +47 -0
  35. package/inkscape/extensions/daijimaps/name.py +167 -0
  36. package/inkscape/extensions/daijimaps/renumber.py +38 -0
  37. package/inkscape/extensions/daijimaps/resolve_labels.py +65 -0
  38. package/inkscape/extensions/daijimaps/resolve_names.py +170 -0
  39. package/inkscape/extensions/daijimaps/save_addresses.py +274 -0
  40. package/inkscape/extensions/daijimaps/types.py +128 -0
  41. package/inkscape/extensions/daijimaps/visit_parents.py +37 -0
  42. package/inkscape/extensions/extract_labels.py +79 -0
  43. package/inkscape/extensions/fixup_floor_svg.py +28 -0
  44. package/inkscape/extensions/fixup_texts.inx +15 -0
  45. package/inkscape/extensions/fixup_texts.py +110 -0
  46. package/inkscape/extensions/fixup_tree.inx +15 -0
  47. package/inkscape/extensions/fixup_tree.py +17 -0
  48. package/inkscape/extensions/flatten_transform.inx +17 -0
  49. package/inkscape/extensions/flatten_transform.py +63 -0
  50. package/inkscape/extensions/import_labels.inx +20 -0
  51. package/inkscape/extensions/import_labels.py +52 -0
  52. package/inkscape/extensions/import_shops.inx +20 -0
  53. package/inkscape/extensions/import_shops.py +47 -0
  54. package/inkscape/extensions/install.sh +14 -0
  55. package/inkscape/extensions/load_shops.inx +20 -0
  56. package/inkscape/extensions/load_shops.py +86 -0
  57. package/inkscape/extensions/renumber_group.inx +15 -0
  58. package/inkscape/extensions/renumber_group.py +17 -0
  59. package/inkscape/extensions/resolve_labels.inx +20 -0
  60. package/inkscape/extensions/resolve_labels.py +142 -0
  61. package/inkscape/extensions/resolve_shops.inx +20 -0
  62. package/inkscape/extensions/resolve_shops.py +73 -0
  63. package/inkscape/extensions/unresolve_labels.inx +20 -0
  64. package/inkscape/extensions/unresolve_labels.py +53 -0
  65. package/inkscape/extensions/unresolve_shops.inx +20 -0
  66. package/inkscape/extensions/unresolve_shops.py +56 -0
  67. package/inkscape/templates/floors.svg +665 -0
  68. package/map-extract-floors.js +821 -0
  69. package/package.json +19 -0
  70. package/pyproject.toml +20 -0
  71. package/scripts/inkex-inkscape +14 -0
  72. package/scripts/inkex-python +14 -0
  73. package/scripts/inkex-setup +6 -0
  74. package/scripts/labels.sh +18 -0
  75. package/scripts/regen.py +77 -0
  76. package/scripts/regen.sh +24 -0
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ import re
5
+
6
+ import daijimaps
7
+
8
+
9
+ class RenumberTree(daijimaps.AddressTree):
10
+ def _is_anonymous(self, node):
11
+ # - no label
12
+ # - or label NOT starting with [A-Z]
13
+ if node.label is None:
14
+ return True
15
+ return re.match("^[A-Z]", node.label) is None
16
+
17
+ def _check_children(self, node):
18
+ # All children should be anonymous (renumber-able)
19
+ for child in list(node):
20
+ if child.label and self._ignoring(child):
21
+ return False
22
+ if not self._is_anonymous(child):
23
+ return False
24
+ return True
25
+
26
+ def _visitor_node_branch_renumber(self, node, parents):
27
+ renumbering = self._check_children(node)
28
+ if renumbering:
29
+ daijimaps.renumber_group(node)
30
+
31
+ def _visitor_node_branch(self, node, parents):
32
+ self._visitor_node_branch_renumber(node, parents)
33
+
34
+ def effect(self):
35
+ super().effect()
36
+
37
+
38
+ if __name__ == "__main__":
39
+ RenumberTree().run()
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
3
+ <name>Repeat path</name>
4
+ <id>daijimaps.repeat_path</id>
5
+ <label>Repeat path.</label>
6
+ <effect needs-live-preview="false">
7
+ <object-type>all</object-type>
8
+ <effects-menu>
9
+ <submenu name="Daiji Maps">
10
+ <submenu name="Path" />
11
+ </submenu>
12
+ </effects-menu>
13
+ </effect>
14
+ <script>
15
+ <command location="inx" interpreter="python">repeat_path.py</command>
16
+ </script>
17
+ </inkscape-extension>
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ import inkex
5
+
6
+
7
+ def repeat_path_path(p: inkex.Path):
8
+ xs = list(p.control_points)
9
+ if len(xs) != 4:
10
+ return None
11
+ o = xs[0]
12
+ v1 = xs[1] - o
13
+ v2 = xs[2] - o
14
+ v3 = xs[3] - o
15
+ # checks
16
+ if v1.dot(v2) != 0:
17
+ return None
18
+ if v2.cross(v3) != 0:
19
+ return None
20
+ d = -v1 + v2
21
+ c = inkex.Vector2d()
22
+ pp = inkex.Path()
23
+ pp.append(inkex.paths.Move(o.x, o.y))
24
+ while c.length < v3.length:
25
+ pp.append(inkex.paths.line(v1.x, v1.y))
26
+ pp.append(inkex.paths.move(d.x, d.y))
27
+ c = c + v2
28
+ pp.append(inkex.paths.line(v1.x, v1.y))
29
+ return pp
30
+
31
+
32
+ def repeat_path(node: inkex.PathElement):
33
+ p = node.get_path().to_absolute()
34
+ pp = repeat_path_path(p)
35
+ if pp is None:
36
+ # self.msg(f"n points: {len(xs)}")
37
+ # self.msg(f"# of points must be 4!")
38
+ return False
39
+ else:
40
+ node.set_path(pp)
41
+ return True
42
+
43
+
44
+ class RepeatPath(inkex.EffectExtension):
45
+ def _repeat_path(self, node):
46
+ if not isinstance(node, inkex.PathElement):
47
+ # self.msg(f"not a path element!")
48
+ return False
49
+ repeat_path(node)
50
+
51
+ def effect(self):
52
+ if self.svg.selection:
53
+ for node in self.svg.selection.values():
54
+ self._repeat_path(node)
55
+
56
+
57
+ if __name__ == "__main__":
58
+ RepeatPath().run()
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
3
+ <name>Resolve facility links</name>
4
+ <id>daijimaps.resolve_facility_links</id>
5
+ <label>Resolve facility links.</label>
6
+ <effect needs-live-preview="false">
7
+ <object-type>all</object-type>
8
+ <effects-menu>
9
+ <submenu name="Daiji Maps">
10
+ <submenu name="Addressess">
11
+ <submenu name="Resolve" />
12
+ </submenu>
13
+ </submenu>
14
+ </effects-menu>
15
+ </effect>
16
+ <script>
17
+ <command location="inx" interpreter="python">resolve_facility_links.py</command>
18
+ </script>
19
+ </inkscape-extension>
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ import daijimaps
5
+
6
+
7
+ class ResolveFacilityLinks(daijimaps.SaveAddresses):
8
+ def _post_layers(self):
9
+ self.msg("=== resolve facility links: start")
10
+ self._collect_links()
11
+ self._save_links()
12
+ self.msg("=== resolve facility links: end")
13
+
14
+
15
+ if __name__ == "__main__":
16
+ ResolveFacilityLinks().run()
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
3
+ <name>Sort Symbols</name>
4
+ <id>daijimaps.sort_symbols</id>
5
+ <label>Sort symbols.</label>
6
+ <effect needs-live-preview="false">
7
+ <object-type>all</object-type>
8
+ <effects-menu>
9
+ <submenu name="Daiji Maps">
10
+ <submenu name="Assets" />
11
+ </submenu>
12
+ </effects-menu>
13
+ </effect>
14
+ <script>
15
+ <command location="inx" interpreter="python">sort_symbols.py</command>
16
+ </script>
17
+ </inkscape-extension>
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ import inkex
5
+ import re
6
+
7
+
8
+ PER_ROW = 20
9
+
10
+
11
+ class SortSymbols(inkex.EffectExtension):
12
+ def _sort_symbols(self, node):
13
+ if not isinstance(node, inkex.Group):
14
+ return False
15
+ max_width = 0
16
+ max_height = 0
17
+ for child in list(node):
18
+ label = child.label
19
+ if not label:
20
+ return False
21
+ if not re.match("^[A-Z].*$", label):
22
+ return False
23
+ bb = child.shape_box()
24
+ if bb is None:
25
+ return False
26
+ size = bb.size
27
+ max_width = max(max_width, size.x)
28
+ max_height = max(max_height, size.y)
29
+ children = sorted(list(node), key=lambda e: e.label if e.label else "")
30
+ for child in children:
31
+ node.remove(child)
32
+ for i, child in enumerate(children):
33
+ x = i % PER_ROW
34
+ y = int(i / PER_ROW)
35
+ tx = x * max_width * 1.25
36
+ ty = y * max_height * 1.25
37
+ child.transform = inkex.Transform(f"translate({tx}, {ty})")
38
+ node.append(child)
39
+ return True
40
+
41
+ def effect(self):
42
+ if self.svg.selection:
43
+ for node in self.svg.selection.values():
44
+ self._sort_symbols(node)
45
+
46
+
47
+ if __name__ == "__main__":
48
+ SortSymbols().run()
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
3
+ <name>Symbol Load</name>
4
+ <id>daijimaps.symbol_load</id>
5
+ <label>Load a symbol into the defs section.</label>
6
+ <effect needs-live-preview="false">
7
+ <object-type>all</object-type>
8
+ <effects-menu>
9
+ <submenu name="Daiji Maps">
10
+ <submenu name="Symbol" />
11
+ </submenu>
12
+ </effects-menu>
13
+ </effect>
14
+ <script>
15
+ <command location="inx" interpreter="python">symbol_load.py</command>
16
+ </script>
17
+ </inkscape-extension>
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ import inkex
5
+
6
+
7
+ class SymbolLoad(inkex.EffectExtension):
8
+ _symbol_name = ""
9
+ _symbol_content = None
10
+ _symbol_node = None
11
+
12
+ def _replace_symbol(self):
13
+ content = self._symbol_content
14
+ node = self._symbol_node
15
+
16
+ if not (content is not None and node is not None):
17
+ self.msg("Something is wrong!")
18
+ return False
19
+
20
+ self.msg(f"Loading the new symbol {self._symbol_name}!")
21
+
22
+ content.delete()
23
+ node.remove_all()
24
+ # XXX why node.add(list) does not work?
25
+ for c in list(content):
26
+ self.msg(f"appending {c}...")
27
+ node.append(c)
28
+
29
+ return True
30
+
31
+ def _find_symbol_for_replace(self):
32
+ name = self._symbol_name
33
+
34
+ sym = self.svg.getElementById(f"#{name}")
35
+ if sym is None:
36
+ self.msg(f"Target <symbol> (#{name}) not found!")
37
+ return False
38
+
39
+ if sym.tag_name != "symbol":
40
+ self.msg("Not a <symbol> tag!")
41
+ return False
42
+
43
+ self._symbol_node = sym
44
+
45
+ return True
46
+
47
+ def _check_group_for_replace(self, node):
48
+ if not isinstance(node, inkex.Group):
49
+ self.msg("Group must be selected!")
50
+ return False
51
+
52
+ name = node.label
53
+ if name is None:
54
+ self.msg("Symbol name must be defined as label!")
55
+ return False
56
+
57
+ children = list(node)
58
+
59
+ if len(children) != 2:
60
+ self.msg("Group must exactly contain <use> and <g>!")
61
+ return False
62
+
63
+ orig = children[0]
64
+
65
+ if not isinstance(orig, inkex.Use):
66
+ self.msg("Group must exactly contain <use> and <g>!")
67
+ return False
68
+
69
+ if not orig.href:
70
+ self.msg("no href found")
71
+ return False
72
+
73
+ href = f"#{orig.href.get_id()}"
74
+
75
+ if href != f"#{name}":
76
+ self.msg(f"Group name ({name}) does not match <use> symbol name ({href})!")
77
+ return False
78
+
79
+ content = children[1]
80
+
81
+ if not isinstance(content, inkex.Group):
82
+ self.msg("The target is not a Group!")
83
+ return False
84
+
85
+ self._symbol_name = name
86
+ self._symbol_content = content
87
+
88
+ return True
89
+
90
+ def effect(self):
91
+ if self.svg.selection:
92
+ for node in self.svg.selection.values():
93
+ if self._check_group_for_replace(node):
94
+ if self._find_symbol_for_replace():
95
+ self._replace_symbol()
96
+
97
+
98
+ if __name__ == "__main__":
99
+ SymbolLoad().run()
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
3
+ <name>Tidy tree</name>
4
+ <id>daijimaps.tidy_tree</id>
5
+ <label>Tidy tree for Daiji Maps map SVG.</label>
6
+ <param name="tab" type="notebook">
7
+ <page name="Options" gui-text="Options">
8
+ <param name="floor" type="string" gui-text="Target floor (regular expression)">.</param>
9
+ </page>
10
+ </param>
11
+ <effect needs-live-preview="false">
12
+ <object-type>all</object-type>
13
+ <effects-menu>
14
+ <submenu name="Daiji Maps">
15
+ <submenu name="Tidy" />
16
+ </submenu>
17
+ </effects-menu>
18
+ </effect>
19
+ <script>
20
+ <command location="inx" interpreter="python">tidy_tree.py</command>
21
+ </script>
22
+ </inkscape-extension>
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ import inkex
5
+ import re
6
+ import daijimaps
7
+ import repeat_path
8
+
9
+
10
+ attrib_styles = inkex.all_properties.keys()
11
+
12
+ group_styles = {"display"}
13
+
14
+ invalid_styles = {
15
+ "line-height",
16
+ "text-align",
17
+ }
18
+
19
+
20
+ class TidyTree(daijimaps.AddressTree):
21
+ _find_layers_opts = {
22
+ # include '(Assets)'
23
+ "skip_ignoring": False
24
+ }
25
+
26
+ def _fixup_style(self, node):
27
+ if "display" in node.style and node.style["display"] == "inline":
28
+ self.msg(f"fixing display: {node.label}")
29
+ del node.style["display"]
30
+
31
+ if "opacity" in node.style and node.style["opacity"] == "1":
32
+ self.msg(f"fixing opacity: {node.label}")
33
+ del node.style["opacity"]
34
+
35
+ for k, v in node.style.items():
36
+ if k not in group_styles:
37
+ self.msg(f"fixing {k}: {node.label}")
38
+ del node.style[k]
39
+ if re.match("^-.*$", k):
40
+ # skip -inkscape-font-specification
41
+ pass
42
+ else:
43
+ node.set(k, v)
44
+
45
+ def _fixup_attrib(self, node):
46
+ # clear attribs irrelevant for <g/>
47
+ if isinstance(node, inkex.Group):
48
+ for a in node.attrib:
49
+ if a in attrib_styles:
50
+ self.msg(f"del {a} from node {node.label}")
51
+ del node.attrib[a]
52
+
53
+ for a in node.attrib:
54
+ if a in invalid_styles:
55
+ self.msg(f"del {a} from node {node.label}")
56
+ del node.attrib[a]
57
+
58
+ def _fixup_path(self, node):
59
+ # pass
60
+ # has_stroke = True
61
+ # has_stroke_width = False
62
+ has_marker_start = False
63
+ has_marker_end = False
64
+ if not isinstance(node, inkex.PathElement):
65
+ return
66
+ for a in node.attrib:
67
+ # if a == "stroke" and node.attrib["stroke"] == "none":
68
+ # has_stroke = False
69
+ # if a == "stroke-width":
70
+ # has_stroke_width = True
71
+ if a == "marker-start":
72
+ has_marker_start = True
73
+ if a == "marker-end":
74
+ has_marker_end = True
75
+ # for k, v in node.style.items():
76
+ # if k == "stroke" and node.style["stroke"] == "none":
77
+ # has_stroke = False
78
+ # if k == "stroke-width":
79
+ # has_stroke_width = True
80
+ # if has_stroke and not has_stroke_width:
81
+ # self.msg(f"fixing stroke-width for {node.label}")
82
+ # node.attrib["stroke-width"] = "1"
83
+ if has_marker_start:
84
+ if node.attrib["marker-start"] != "url(#Triangle)":
85
+ self.msg(f"fixing marker-start for {node.label}")
86
+ node.attrib["marker-start"] = "url(#Triangle)"
87
+ if has_marker_end:
88
+ if node.attrib["marker-end"] != "url(#Triangle)":
89
+ self.msg(f"fixing marker-end for {node.label}")
90
+ node.attrib["marker-end"] = "url(#Triangle)"
91
+ # expand repeat path
92
+ if repeat_path.repeat_path(node):
93
+ self.msg(f"expanding repeat path for {node.label}")
94
+
95
+ def _sort_children(self, node):
96
+ children = {}
97
+ for a in list(node):
98
+ if a.label:
99
+ node.remove(a)
100
+ # a.label looks like: "Sov. @ A4F-Shops-1-3"
101
+ if a.label not in children:
102
+ children[a.label] = []
103
+ children[a.label].append(a)
104
+ # assume alphabetical order
105
+ labels = sorted(children.keys(), key=lambda label: str.lower(label))
106
+ for label in labels:
107
+ for a in children[label]:
108
+ node.append(a)
109
+
110
+ def _fixup_facilities_use(self, kind, child):
111
+ if child.href.get("id") == f"X{kind.label}":
112
+ return 0
113
+ self.msg("fixing facilities (use)")
114
+ child.href = f"X{kind.label}"
115
+ return 1
116
+
117
+ def _fixup_facilities_center(self, kind, child):
118
+ c = None
119
+ if isinstance(child, inkex.Circle):
120
+ c = child.center
121
+ elif isinstance(child, inkex.Ellipse):
122
+ c = child.center
123
+ if c is None:
124
+ return -1
125
+ self.msg("fixing facilities")
126
+ x = inkex.Use()
127
+ x.label = child.label
128
+ x.href = f"X{kind.label}"
129
+ x.transform = f"translate({c.x},{c.y})"
130
+ kind.append(x)
131
+ kind.remove(child)
132
+ return 1
133
+
134
+ def _fixup_facilities(self, node):
135
+ if not isinstance(node, inkex.Group) or node.label != "Facilities":
136
+ return
137
+ for kind in list(node):
138
+ changed = False
139
+ for child in list(kind):
140
+ ok = None
141
+ if isinstance(child, inkex.Use):
142
+ ok = self._fixup_facilities_use(kind, child)
143
+ else:
144
+ ok = self._fixup_facilities_center(kind, child)
145
+ if ok > 0:
146
+ changed = True
147
+ elif ok < 0:
148
+ # XXX
149
+ return
150
+ if changed:
151
+ self._sort_children(kind)
152
+
153
+ def _fixup_marker(self, node):
154
+ if not isinstance(node, inkex.Marker):
155
+ return
156
+ xid = node.get("id")
157
+ if xid == "Triangle":
158
+ return
159
+ self.msg(f"removing marker: {node.label}:{xid}")
160
+ p = node.getparent()
161
+ if p:
162
+ p.remove(node)
163
+
164
+ def _process_addresses(self, node):
165
+ super()._process_addresses(node)
166
+ self.msg("=== fixup start")
167
+ for e in node.descendants():
168
+ self._fixup_facilities(e)
169
+ self._fixup_style(e)
170
+ # XXX group style attribs have purposes & are actually used
171
+ # self._fixup_attrib(e)
172
+ self._fixup_path(e)
173
+ self._fixup_marker(e)
174
+ self.msg("=== fixup done")
175
+
176
+
177
+ if __name__ == "__main__":
178
+ TidyTree().run()
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
3
+ <name>Set shop ID</name>
4
+ <id>daijimaps.use_shop</id>
5
+ <label>Set use's href to shop's IDs.</label>
6
+ <param name="tab" type="notebook">
7
+ <page name="Options" gui-text="Options">
8
+ <param name="href" type="string" gui-text="Shop symbol ID:">XShop1</param>
9
+ </page>
10
+ </param>
11
+ <effect needs-live-preview="false">
12
+ <object-type>all</object-type>
13
+ <effects-menu>
14
+ <submenu name="Daiji Maps">
15
+ <submenu name="Use" />
16
+ </submenu>
17
+ </effects-menu>
18
+ </effect>
19
+ <script>
20
+ <command location="inx" interpreter="python">use_shop.py</command>
21
+ </script>
22
+ </inkscape-extension>
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+
4
+ from argparse import ArgumentParser
5
+ import inkex
6
+
7
+
8
+ class UseShop(inkex.EffectExtension):
9
+ def _change_use_href(self, node, id_string):
10
+ if not isinstance(node, inkex.Use):
11
+ return
12
+ node.href = id_string
13
+
14
+ def add_arguments(self, pars: ArgumentParser) -> None:
15
+ pars.add_argument("--tab", type=str, dest="tab")
16
+ pars.add_argument("--href", type=str, default="XShop1")
17
+ return super().add_arguments(pars)
18
+
19
+ def effect(self):
20
+ if self.svg.selection:
21
+ for node in self.svg.selection.values():
22
+ self._change_use_href(node, self.options.href)
23
+
24
+
25
+ if __name__ == "__main__":
26
+ UseShop().run()
@@ -0,0 +1,34 @@
1
+ # Inkscape extensions for DaijiMaps
2
+
3
+ - renumber_group
4
+ - TODO renumber_tree
5
+ - TODO assign_addresses
6
+ - TODO unlabel_group, unlabel_tree
7
+
8
+ - TODO validation
9
+ - TODO fixup
10
+ - TODO classification
11
+ - define classes (e.g. shops, facilities, shop, address, scale, symbol, ...)
12
+ - use Classes (e.g. `node.classes.append('shop')`)
13
+
14
+ ## renumber_tree
15
+
16
+ - Skip pattern (`/^[A-Z].*$/`)
17
+ - Terminal condition (`node.get('transform')`)
18
+
19
+ ## assign_addresses
20
+
21
+ - e.g. `F1F-Shops-N-1-1`
22
+ - delimiter (`-`)
23
+ - Omit pattern (e.g. `Floor`)
24
+ - 1F/Floor/Shops/... => `1F-Shops-...`
25
+ - Skip pattern (e.g. `Background`)
26
+ - 1F/Background is skipped/ignored
27
+ - prefix, suffix
28
+
29
+ ## symbol_load
30
+
31
+ - <g label="Toilets_Inv">
32
+ - <use href="#Toilets_Inv">
33
+ - <g>
34
+ - ...