@@ -16,14 +16,6 @@ import xmltree
1616from streams import newStringStream
1717from strtabs import hasKey
1818
19-
20- let
21- attribute = r " [a-zA-Z][a-zA-Z0-9_\-]* "
22- classes = r " {\.[a-zA-Z0-9_][a-zA-Z0-9_\-]*} "
23- attributes = r " {\[ " & attribute & r " \s*([\*\^\$\~]?\=\s*[\'"" ]?(\s*\ident\s*)+[\'"" ]?)?\]} "
24- pselectors = peg (r " \s*{\ident}?({'#'\ident})? ( " & classes & " )* " & attributes & " *" )
25- pattributes = peg (r " {\[{ " & attribute & r " }\s*({[\*\^\$\~]?}\=\s*[\'"" ]?{(\s*\ident\s*)+}[\'"" ]?)?\]} " )
26-
2719type
2820 Attribute = object
2921 name: string
3628 id: string
3729 classes: seq [string ]
3830 attributes: seq [Attribute ]
31+ pSelectors: Peg
32+ pAttributes: Peg
3933
4034 QueryContext = object
4135 root: seq [XmlNode ]
4236
4337proc newSelector (tag, id = " " , classes: seq [string ] = @ [], attributes: seq [Attribute ] = @ []): Selector =
38+ let
39+ attributeSelector = r " [a-zA-Z][a-zA-Z0-9_\-]* "
40+ classesSelector = r " {\.[a-zA-Z0-9_][a-zA-Z0-9_\-]*} "
41+ attributesSelector = r " {\[ " & attributeSelector & r " \s*([\*\^\$\~]?\=\s*[\'"" ]?(\s*\ident\s*)+[\'"" ]?)?\]} "
42+
4443 result .combinator = ' '
4544 result .tag = tag
4645 result .id = id
4746 result .classes = classes
4847 result .attributes = attributes
4948
49+ result .pSelectors = peg (r " \s*{\ident}?({'#'\ident})? ( " & classesSelector & " )* " & attributesSelector & " *" )
50+ result .pAttributes = peg (r " {\[{ " & attributeSelector & r " }\s*({[\*\^\$\~]?}\=\s*[\'"" ]?{(\s*\ident\s*)+}[\'"" ]?)?\]} " )
51+
5052proc initContext (root: seq [XmlNode ]): QueryContext =
5153 result .root = root
5254
@@ -166,13 +168,13 @@ proc searchCombined(parents: var seq[XmlNode], selectors: seq[Selector]) =
166168
167169 parents = found
168170
169- proc parseSelector (token: string ): Selector =
171+ proc parseSelector (token: string ): Selector {. gcsafe .} =
170172 result = newSelector ()
171173 # Universal selector
172174 if token == " *" :
173175 result .tag = " *"
174176 # Type selector
175- elif token =~ pselectors :
177+ elif token =~ result .pSelectors :
176178 for i in 0 .. matches.len- 1 :
177179 if matches[i].len == 0 :
178180 continue
@@ -184,16 +186,16 @@ proc parseSelector(token: string): Selector =
184186 result .id = matches[i]
185187 of '.' :
186188 matches[i].delete (0 , 0 )
187- result .classes.add (matches[i])
189+ result .classes.add (move matches[i])
188190 of '[' :
189- if matches[i] =~ pattributes :
191+ if matches[i] =~ result .pAttributes :
190192 result .attributes.add (newAttribute (matches[1 ], matches[2 ], matches[3 ]))
191193 else :
192194 result .tag = matches[i]
193195 else :
194196 discard
195197
196- proc select * (q: QueryContext , s: string = " " ): seq [XmlNode ] =
198+ proc select * (q: QueryContext , s: string = " " ): seq [XmlNode ] {. gcsafe .} =
197199 # # Return list of nodes matched by CSS selector
198200 result = q.root
199201
0 commit comments