@@ -124,7 +124,41 @@ struct RowNode
124
124
attributes:: Union{OrderedDict{String, String}, Nothing}
125
125
value:: Union{String, Nothing}
126
126
end
127
- Base. show (io:: IO , o:: RowNode ) = _show_node (io, o)
127
+ function Base. show (io:: IO , o:: RowNode )
128
+ printstyled (io, lpad (" $(o. depth) " , 2 o. depth), ' :' , o. nodetype, ' ' ; color= :light_green )
129
+ if o. nodetype === TEXT_NODE
130
+ printstyled (io, repr (o. value), color= :light_black )
131
+ elseif o. nodetype === ELEMENT_NODE
132
+ printstyled (io, ' <' , o. tag, color= :light_cyan )
133
+ _print_attrs (io, o)
134
+ printstyled (io, ' >' , color= :light_cyan )
135
+ elseif o. nodetype === DTD_NODE
136
+ printstyled (io, " <!DOCTYPE" , o. tag, color= :light_cyan )
137
+ printstyled (io, o. value, color= :light_black )
138
+ printstyled (io, ' >' , color= :light_cyan )
139
+ elseif o. nodetype === DECLARATION_NODE
140
+ printstyled (io, " <?xml" , color= :light_cyan )
141
+ _print_attrs (io, o)
142
+ printstyled (io, ' >' , color= :light_cyan )
143
+ elseif o. nodetype === COMMENT_NODE
144
+ printstyled (io, " <!--" , color= :light_cyan )
145
+ printstyled (io, o. value, color= :light_black )
146
+ printstyled (io, " -->" , color= :light_cyan )
147
+ elseif o. nodetype === CDATA_NODE
148
+ printstyled (io, " <![CDATA[" , color= :light_cyan )
149
+ printstyled (io, o. value, color= :light_black )
150
+ printstyled (io, " ]]>" , color= :light_cyan )
151
+ elseif o. nodetype === DOCUMENT_NODE
152
+ printstyled (io, " Document" , color= :light_cyan )
153
+ elseif o. nodetype === UNKNOWN_NODE
154
+ printstyled (io, " Unknown" , color= :light_cyan )
155
+ else
156
+ error (" Unreachable reached" )
157
+ end
158
+ end
159
+ function _print_attrs (io:: IO , o)
160
+ ! isnothing (o. attributes) && printstyled (io, [" $k =\" $v \" " for (k,v) in o. attributes]. .. ; color= :light_black )
161
+ end
128
162
129
163
130
164
Base. IteratorSize (:: Type{Rows} ) = Base. SizeUnknown ()
@@ -171,43 +205,33 @@ function Base.iterate(o::Rows, state = (1,1))
171
205
return out => state
172
206
end
173
207
174
-
175
- function get_name (data, i)
176
- i = findnext (x -> isletter (Char (x)) || x === UInt8 (' _' ), data, i)
177
- j = findnext (data, i) do x
178
- c = Char (x)
179
- ! (isletter (c) || isdigit (c) || c ∈ " ._-:" )
180
- end
181
- name = String (data[i: j- 1 ])
182
- return name, j
183
- end
184
-
185
208
# -----------------------------------------------------------------------------# get_attributes
186
209
function get_attributes (data)
187
210
out = OrderedDict {String, String} ()
188
211
i = 1
189
- while true
212
+ while ! isnothing (i)
190
213
# get key
191
- i = _name_start (data, i)
192
- isnothing (i) && break
193
- j = _name_stop (data, i)
194
- key = String (data[i: j])
214
+ key, i = get_name (data, i)
195
215
# get quotechar the value is wrapped in (either ' or ")
196
216
i = findnext (x -> Char (x) === ' "' || Char (x) === ' '' , data, i)
197
217
quotechar = data[i]
198
218
j = findnext (== (quotechar), data, i + 1 )
199
219
# get value and set it
200
220
value = String (data[i+ 1 : j- 1 ])
201
221
out[key] = value
202
- i = j + 1
222
+ i = _name_start (data, j + 1 )
203
223
end
204
224
return out
205
225
end
206
226
207
227
# -----------------------------------------------------------------------------# get_name
208
- _name_start (data, i) = findnext (x -> Char (x) === ' "' || Char (x) === ' '' , data, i)
228
+ # find the start/stop of a name given a starting position `i`
229
+ _name_start (data, i) = findnext (x -> isletter (Char (x)) || Char (x) === ' _' , data, i)
209
230
is_name_char (x) = (c = Char (x); isletter (c) || isdigit (c) || c ∈ " ._-:" )
210
- _name_stop (data, i) = (j = findnext (! is_name_char, data, i); isnothing (j) ? nothing : i - 1 )
231
+ function _name_stop (data, i)
232
+ i = findnext (! is_name_char, data, i)
233
+ isnothing (i) ? nothing : i
234
+ end
211
235
212
236
# start at position i, return name and position after name
213
237
function get_name (data, i)
@@ -247,6 +271,7 @@ function Node(o::Node; kw...)
247
271
Node (; nodetype= o. nodetype, tag= o. tag, attributes= o. attributes, content= o. content, children= o. children, depth= o. depth, kw... )
248
272
end
249
273
274
+ # -----------------------------------------------------------------------------# printing
250
275
function _show_node (io, o)
251
276
printstyled (io, lpad (" $(o. depth) " , 2 o. depth), ' :' , o. nodetype, ' ' ; color= :light_green )
252
277
if o. nodetype === TEXT_NODE
@@ -286,7 +311,7 @@ function _print_attrs(io::IO, o)
286
311
! isnothing (o. attributes) && printstyled (io, [" $k =\" $v \" " for (k,v) in o. attributes]. .. ; color= :light_black )
287
312
end
288
313
function _print_n_children (io:: IO , o)
289
- ! isnothing (o. children) && printstyled (io, " (" , length (o. children), " children)" , color= :light_black )
314
+ hasfield ( typeof (o), :children ) && ! isnothing (o. children) && printstyled (io, " (" , length (o. children), " children)" , color= :light_black )
290
315
end
291
316
292
317
Base. getindex (o:: Node , i:: Integer ) = o. children[i]
0 commit comments