forked from JoshVarga/svgparser
/
find.go
146 lines (132 loc) · 2.95 KB
/
find.go
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package svgparser
import (
"regexp"
)
// FindID finds the first child with the specified ID.
func (e *Element) FindID(id string) *Element {
for _, child := range e.Children {
if childID, ok := child.Attributes["id"]; ok && childID == id {
return child
}
if element := child.FindID(id); element != nil {
return element
}
}
return nil
}
// FindUUID finds the first child with the specified UUID.
func (e *Element) FindUUID(uuid string) *Element {
for _, child := range e.Children {
if child.UUID == uuid {
return child
}
if element := child.FindUUID(uuid); element != nil {
return element
}
}
return nil
}
// FindAll finds all children with the given name.
func (e *Element) FindAll(name string) []*Element {
var elements []*Element
for _, child := range e.Children {
if child.Name == name {
elements = append(elements, child)
}
elements = append(elements, child.FindAll(name)...)
}
return elements
}
// SelectByUUIDs filter all children with the given ids.
func (e *Element) SelectByUUIDs(uuids []string) *Element {
c := &Element{}
for _, uuid := range uuids {
if e.UUID == uuid {
*c = *e
c.Children = []*Element{}
break
}
}
c.Children = e.selectChildrenByUUIDs(uuids)
return c
}
func (e *Element) selectChildrenByUUIDs(uuids []string) []*Element {
var elements []*Element
for _, child := range e.Children {
for _, uuid := range uuids {
if child.UUID == uuid {
c := &Element{}
*c = *child
c.Children = []*Element{}
c.Children = child.selectChildrenByUUIDs(uuids)
elements = append(elements, c)
}
}
}
return elements
}
// FindAllLinkedIDs finds related linked ID recursively
func FindAllLinkedIDs(r *Element, id string) []string {
ids := []string{}
f := r.FindID(id)
if f == nil {
return ids
}
c := f
for c.Children != nil {
for _, h := range c.Children {
for _, id := range h.FindLinkedIDs() {
ids = append(ids, id)
}
c = h
}
}
ids = append(ids, f.FindLinkedIDs()...)
for _, fid := range ids {
if fid == id {
continue
}
ids = append(ids, FindAllLinkedIDs(r, fid)...)
}
return ids
}
// FindAllLinkedUUIDs finds related linked ID recursively
func FindAllLinkedUUIDs(r *Element, uuid string) []string {
ids := []string{}
f := r.FindUUID(uuid)
if f == nil {
return ids
}
id := f.Attributes["id"]
c := f
for c.Children != nil {
for _, h := range c.Children {
for _, id := range h.FindLinkedIDs() {
ids = append(ids, id)
}
c = h
}
}
ids = append(ids, f.FindLinkedIDs()...)
for _, fid := range ids {
if fid == id {
continue
}
ids = append(ids, FindAllLinkedIDs(r, fid)...)
}
return ids
}
// FindLinkedIDs finds related linked ID
func (e *Element) FindLinkedIDs() []string {
ids := []string{}
if id, found := e.Attributes["id"]; found {
ids = append(ids, id)
}
r := regexp.MustCompile("#(\\w+)")
for _, v := range e.Attributes {
if m := r.FindStringSubmatch(v); len(m) > 0 {
ids = append(ids, m[1])
}
}
return ids
}