eim_xml 0.0.4 → 1.0.0
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.
- checksums.yaml +7 -0
- data/LICENSE +339 -0
- data/lib/eim_xml/assertions.rb +14 -14
- data/lib/eim_xml/dsl.rb +104 -96
- data/lib/eim_xml/formatter/element_wrapper.rb +8 -6
- data/lib/eim_xml/formatter.rb +105 -106
- data/lib/eim_xml/matcher.rb +23 -20
- data/lib/eim_xml/parser.rb +68 -70
- data/lib/eim_xml/xhtml/dsl.rb +16 -14
- data/lib/eim_xml/xhtml.rb +156 -152
- data/lib/eim_xml.rb +202 -202
- metadata +31 -61
- data/Rakefile +0 -26
- data/Rakefile.utirake +0 -374
- data/spec/assertions_test.rb +0 -30
- data/spec/dsl_spec.rb +0 -217
- data/spec/eim_xml_spec.rb +0 -441
- data/spec/formatter_spec.rb +0 -260
- data/spec/parser_spec.rb +0 -102
- data/spec/xhtml_spec.rb +0 -524
data/lib/eim_xml/formatter.rb
CHANGED
@@ -1,123 +1,122 @@
|
|
1
|
-
require
|
1
|
+
require 'eim_xml'
|
2
2
|
|
3
3
|
module EimXML
|
4
|
-
|
5
|
-
|
4
|
+
class Formatter
|
5
|
+
attr_reader :out
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
def self.write(element, opt = {})
|
8
|
+
opt = { out: '' }.merge(opt)
|
9
|
+
new(opt).write(element)
|
10
|
+
opt[:out]
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
def initialize(opt)
|
14
|
+
@out = opt[:out]
|
15
|
+
@preservers = opt[:preservers]
|
16
|
+
@preserve_space = false
|
17
|
+
@indent_string = ' '
|
18
|
+
@indent_depth = 0
|
19
|
+
@option = opt.dup.tap { |h| %i[out preservers].each { |k| h.delete(k) } }
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
22
|
+
def write(src)
|
23
|
+
case src
|
24
|
+
when ElementWrapper
|
25
|
+
write_wrapper(src)
|
26
|
+
when Comment
|
27
|
+
write_comment(src)
|
28
|
+
when Element
|
29
|
+
write_element(src)
|
30
|
+
when PCString
|
31
|
+
write_pcstring(src)
|
32
|
+
else
|
33
|
+
write_string(src.to_s)
|
34
|
+
end
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
def indent(&proc)
|
38
|
+
@indent_depth += 1
|
39
|
+
proc.call
|
40
|
+
ensure
|
41
|
+
@indent_depth -= 1
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
def preserve_space_element?(elm)
|
45
|
+
@preservers&.any? do |e|
|
46
|
+
case e
|
47
|
+
when Symbol
|
48
|
+
e == elm.name
|
49
|
+
when Class
|
50
|
+
elm.is_a?(e)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
def write_indent
|
56
|
+
out << (@indent_string * @indent_depth) unless @preserve_space
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
def write_newline
|
60
|
+
out << "\n" unless @preserve_space
|
61
|
+
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
def write_comment(commend)
|
64
|
+
write_indent
|
65
|
+
commend.write_to(out)
|
66
|
+
write_newline
|
67
|
+
end
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
69
|
+
def write_contents_of(elm)
|
70
|
+
flag = @preserve_space
|
71
|
+
@preserve_space = true if preserve_space_element?(elm)
|
72
|
+
write_newline
|
73
|
+
indent do
|
74
|
+
elm.contents.each do |c|
|
75
|
+
write(c)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
write_indent
|
79
|
+
ensure
|
80
|
+
@preserve_space = flag
|
81
|
+
end
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
83
|
+
def write_element(elm)
|
84
|
+
write_indent
|
85
|
+
out << '<'
|
86
|
+
elm.name_and_attributes(out)
|
87
|
+
case elm.contents.size
|
88
|
+
when 0
|
89
|
+
out << ' />'
|
90
|
+
else
|
91
|
+
out << '>'
|
92
|
+
write_contents_of(elm)
|
93
|
+
out << "</#{elm.name}>"
|
94
|
+
end
|
95
|
+
write_newline
|
96
|
+
end
|
98
97
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
98
|
+
def write_pcstring(pcs)
|
99
|
+
pcs.encoded_string.each_line do |l|
|
100
|
+
write_indent
|
101
|
+
out << l
|
102
|
+
end
|
103
|
+
write_newline
|
104
|
+
end
|
106
105
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
106
|
+
def write_string(str)
|
107
|
+
PCString.encode(str).each_line do |l|
|
108
|
+
write_indent
|
109
|
+
out << l
|
110
|
+
end
|
111
|
+
write_newline
|
112
|
+
end
|
114
113
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
114
|
+
def write_wrapper(wrapper)
|
115
|
+
wrapper.each(@option) do |i|
|
116
|
+
write(i)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
121
120
|
end
|
122
121
|
|
123
|
-
require
|
122
|
+
require 'eim_xml/formatter/element_wrapper'
|
data/lib/eim_xml/matcher.rb
CHANGED
@@ -1,25 +1,28 @@
|
|
1
|
-
require
|
2
|
-
module EimXML::Matchers
|
3
|
-
class HaveContent
|
4
|
-
def initialize(expected)
|
5
|
-
@expected = expected
|
6
|
-
end
|
1
|
+
require 'eim_xml'
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
module EimXML
|
4
|
+
module Matchers
|
5
|
+
class HaveContent
|
6
|
+
def initialize(expected)
|
7
|
+
@expected = expected
|
8
|
+
end
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def matches?(target)
|
11
|
+
@target = target
|
12
|
+
@target.has?(@expected)
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
15
|
+
def failure_message
|
16
|
+
"expected #{@target.inspect} must have #{@expected}, but not."
|
17
|
+
end
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
def negative_failure_message
|
20
|
+
"expected #{@target.inspect} must not have #{@expected}, but has."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def have(expected)
|
25
|
+
HaveContent.new(expected)
|
26
|
+
end
|
27
|
+
end
|
25
28
|
end
|
data/lib/eim_xml/parser.rb
CHANGED
@@ -4,84 +4,82 @@
|
|
4
4
|
# You can redistribute it and/or modify it under GPL2.
|
5
5
|
#
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require 'eim_xml'
|
8
|
+
require 'strscan'
|
9
9
|
|
10
10
|
module EimXML
|
11
|
-
|
12
|
-
|
11
|
+
class ParseError < StandardError
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
module RE
|
17
|
-
EMPTY_ELEMENT = /<([^>]*?)\/>/
|
18
|
-
START_TAG = /<([^>]*?([^\/>]\s*))>/
|
19
|
-
END_TAG = /<\/(\S+?)\s*>/
|
20
|
-
ATTRIBUTE = /\s+([^=\s]+)\s*=\s*('(.*?)'|"(.*?)")/m
|
21
|
-
STRING = /[^<]+/
|
22
|
-
end
|
14
|
+
class Parser
|
15
|
+
attr_reader :scanner
|
23
16
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
17
|
+
module RE
|
18
|
+
EMPTY_ELEMENT = %r{<([^>]*?)/>}
|
19
|
+
START_TAG = %r{<([^>]*?([^/>]\s*))>}
|
20
|
+
END_TAG = %r{</(\S+?)\s*>}
|
21
|
+
ATTRIBUTE = /\s+([^=\s]+)\s*=\s*('(.*?)'|"(.*?)")/m
|
22
|
+
STRING = /[^<]+/
|
23
|
+
end
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
else
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
end
|
25
|
+
PARSING_MAP = {
|
26
|
+
'amp' => '&',
|
27
|
+
'quot' => '"',
|
28
|
+
'apos' => "'",
|
29
|
+
'lt' => '<',
|
30
|
+
'gt' => '>'
|
31
|
+
}
|
40
32
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
e
|
46
|
-
end
|
47
|
-
protected :parse_tag
|
33
|
+
def initialize(src)
|
34
|
+
@scanner = StringScanner.new(src)
|
35
|
+
@scanner.scan(/\s*<\?.*?\?>\s*/)
|
36
|
+
end
|
48
37
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
38
|
+
def parse
|
39
|
+
if @scanner.scan(RE::EMPTY_ELEMENT)
|
40
|
+
parse_empty_element
|
41
|
+
elsif @scanner.scan(RE::START_TAG)
|
42
|
+
parse_start_tag
|
43
|
+
elsif @scanner.scan(RE::STRING)
|
44
|
+
parse_string
|
45
|
+
end
|
46
|
+
end
|
53
47
|
|
54
|
-
|
55
|
-
|
48
|
+
def parse_tag
|
49
|
+
s = StringScanner.new(@scanner[1])
|
50
|
+
e = Element.new(s.scan(/\S+/))
|
51
|
+
e[s[1]] = s[3] || s[4] while s.scan(RE::ATTRIBUTE)
|
52
|
+
e
|
53
|
+
end
|
54
|
+
protected :parse_tag
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
raise ParseError.new("End tag mismatched.") unless @scanner[1].to_sym==e.name
|
63
|
-
e
|
64
|
-
end
|
65
|
-
protected :parse_start_tag
|
56
|
+
def parse_empty_element
|
57
|
+
parse_tag
|
58
|
+
end
|
59
|
+
protected :parse_empty_element
|
66
60
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
61
|
+
def parse_start_tag
|
62
|
+
e = parse_tag
|
63
|
+
|
64
|
+
until @scanner.scan(RE::END_TAG)
|
65
|
+
c = parse
|
66
|
+
raise ParseError, 'Syntax error.' unless c
|
67
|
+
|
68
|
+
e << c
|
69
|
+
end
|
70
|
+
raise ParseError, 'End tag mismatched.' unless @scanner[1].to_sym == e.name
|
71
|
+
|
72
|
+
e
|
73
|
+
end
|
74
|
+
protected :parse_start_tag
|
75
|
+
|
76
|
+
def parse_string
|
77
|
+
s = @scanner[0]
|
78
|
+
s = s.gsub(/&(amp|quot|apos|lt|gt);/) do
|
79
|
+
PARSING_MAP[Regexp.last_match(1)]
|
80
|
+
end
|
81
|
+
PCString.new(s)
|
82
|
+
end
|
83
|
+
protected :parse_string
|
84
|
+
end
|
87
85
|
end
|
data/lib/eim_xml/xhtml/dsl.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'eim_xml/dsl'
|
2
|
+
require 'eim_xml/xhtml'
|
3
3
|
|
4
|
-
module EimXML
|
5
|
-
|
6
|
-
|
4
|
+
module EimXML
|
5
|
+
module XHTML
|
6
|
+
class DSL < EimXML::BaseDSL
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
class OpenDSL < EimXML::OpenDSL
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
constants.each do |c|
|
13
|
+
v = const_get(c)
|
14
|
+
if v.is_a?(Class) && /_$/ !~ v.name
|
15
|
+
DSL.register v
|
16
|
+
OpenDSL.register v
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
18
20
|
end
|