1
+ # -----------------------------------------------------------------------------# position_after
2
+ function position_after (needle:: Vector{UInt8} , haystack:: Vector{UInt8} , i)
3
+ x = findnext (needle, haystack, i)
4
+ isnothing (x) ? nothing : x[end ] + 1
5
+ end
6
+
7
+ position_after (needle:: String , haystack:: Vector{UInt8} , i) = position_after (Vector {UInt8} (needle), haystack, i)
8
+
9
+
10
+
11
+
1
12
# -----------------------------------------------------------------------------# DeclaredElement
2
13
struct DeclaredElement
3
14
name:: String
11
22
Base. show (io:: IO , o:: DeclaredElement ) = print (io, " <!ELEMENT " , o. name, " " , o. content, " >" )
12
23
13
24
function get_declared_elements (data:: Vector{UInt8} )
14
- i = findnext ( Vector {UInt8} ( " <!ELEMENT" ) , data, 1 )[ end ]
25
+ i = position_after ( " <!ELEMENT" , data, 1 )
15
26
out = DeclaredElement[]
16
27
while ! isnothing (i)
17
28
name, i = get_name (data, i + 1 )
@@ -23,8 +34,7 @@ function get_declared_elements(data::Vector{UInt8})
23
34
content, i = get_name (data, i)
24
35
end
25
36
push! (out, DeclaredElement (name, content))
26
- fn = findnext (Vector {UInt8} (" <!ELEMENT" ), data, i)
27
- i = isnothing (fn) ? nothing : fn[end ]
37
+ i = position_after (" <!ELEMENT" , data, i)
28
38
end
29
39
return out
30
40
end
@@ -38,19 +48,56 @@ struct DeclaredAttribute
38
48
end
39
49
Base. show (io:: IO , o:: DeclaredAttribute ) = print (io, " <!ATTLIST " , o. element_name, " " , o. attribute_name, " " , o. attribute_type, " " , o. attribute_value, " >" )
40
50
51
+
41
52
function get_declared_attributes (data)
42
- []
53
+ i = position_after (" <!ATTLIST" , data, 1 )
54
+ out = DeclaredAttribute[]
55
+ while ! isnothing (i)
56
+ element_name, i = get_name (data, i)
57
+ attribute_name, i = get_name (data, i)
58
+ i = findnext (! isspace, data, i)
59
+ attribute_type = if data[i] == UInt (' (' )
60
+ j = findnext (== (UInt8 (' )' )), data, i)
61
+ String (data[i: j])
62
+ i = j + 1
63
+ else
64
+ nm, i = get_name (data, i)
65
+ nm
66
+ end
67
+ i = findnext (! isspace, data, i)
68
+ is_hash = data[i] == UInt8 (' #' )
69
+ val, i = get_name (data, i)
70
+ attribute_value = is_hash ? ' #' * val : val
71
+ push! (out, DeclaredAttribute (element_name, attribute_name, attribute_type, attribute_value))
72
+ i = position_after (" <!ATTLIST" , data, i)
73
+ end
74
+ return out
43
75
end
44
76
45
77
# -----------------------------------------------------------------------------# DeclaredEntity
46
78
struct DeclaredEntity
47
79
name:: String
80
+ external:: Bool
48
81
value:: String
49
82
end
50
- Base. show (io:: IO , o:: DeclaredEntity ) = print (io, " <!ENTITY " , o. name, " " , o. value, " >" )
83
+ function Base. show (io:: IO , o:: DeclaredEntity )
84
+ print (io, " <!ENTITY " , o. name, " " , o. external ? " SYSTEM" : " " , repr (o. value), " >" )
85
+ end
51
86
52
87
function get_declared_entities (data)
53
- []
88
+ i = position_after (" <!ENTITY" , data, 1 )
89
+ out = DeclaredEntity[]
90
+ while ! isnothing (i)
91
+ name, i = get_name (data, i)
92
+ value, i = get_name (data, i)
93
+ external = value == " SYSTEM"
94
+ if external
95
+ value, i = get_name (data, i)
96
+ end
97
+ push! (out, DeclaredEntity (name, external, value))
98
+ i = position_after (" <!ENTITY" , data, i)
99
+ end
100
+ return out
54
101
end
55
102
56
103
# -----------------------------------------------------------------------------# DTDBody
@@ -62,19 +109,19 @@ struct DTDBody
62
109
end
63
110
64
111
function Base. show (io:: IO , o:: DTDBody )
65
- println (io, " DTDBody(root=\" " , o. root)
66
- println (io, " • DeclaredElements" )
67
- foreach (x -> println (io, " " , x), o. elements)
68
- println (io, " • DeclaredAttributes" )
69
- println (io, " • DeclaredEntities" )
112
+ printstyled (io, " DTDBody(root=\" " , o. root, " \" )\n " , color= :light_cyan )
113
+ printstyled (io, " DeclaredElements (" , length (o. elements), " )\n " , color= :light_green )
114
+ foreach (x -> println (io, " " , x), o. elements)
115
+ printstyled (io, " DeclaredAttributes (" , length (o. attributes), " )\n " , color= :light_green )
116
+ foreach (x -> println (io, " " , x), o. attributes)
117
+ printstyled (io, " DeclaredEntities (" , length (o. entities), " )\n " , color= :light_green )
118
+ foreach (x -> println (io, " " , x), o. entities)
70
119
end
71
120
72
121
73
122
74
123
function DTDBody (data:: Vector{UInt8} )
75
- start = " <!DOCTYPE"
76
- data[1 : length (start)] == Vector {UInt8} (start) || error (" DTD must start with `<!DOCTYPE`." )
77
- i = length (start) + 1
124
+ i = position_after (" <!DOCTYPE" , data, 1 )
78
125
root, i = get_name (data, i)
79
126
80
127
i = findnext (== (UInt8 (' [' )), data, i)
0 commit comments