trenni 1.7.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +7 -3
- data/Gemfile +4 -0
- data/README.md +72 -10
- data/Rakefile +85 -0
- data/benchmark/call_vs_yield.rb +51 -0
- data/benchmark/interpolation_vs_concat.rb +29 -0
- data/benchmark/io_vs_string.rb +14 -4
- data/entities.json +2233 -0
- data/ext/trenni/extconf.rb +13 -0
- data/ext/trenni/markup.c +1981 -0
- data/ext/trenni/markup.h +6 -0
- data/ext/trenni/markup.rl +223 -0
- data/ext/trenni/template.c +1113 -0
- data/ext/trenni/template.h +6 -0
- data/ext/trenni/template.rl +77 -0
- data/ext/trenni/trenni.c +64 -0
- data/ext/trenni/trenni.h +28 -0
- data/lib/trenni.rb +1 -0
- data/lib/trenni/buffer.rb +13 -2
- data/lib/trenni/builder.rb +54 -47
- data/lib/trenni/entities.rb +2154 -0
- data/lib/trenni/entities.trenni +34 -0
- data/lib/trenni/fallback/markup.rb +1648 -0
- data/lib/trenni/fallback/markup.rl +236 -0
- data/lib/trenni/fallback/template.rb +843 -0
- data/lib/trenni/fallback/template.rl +97 -0
- data/lib/trenni/markup.rb +76 -0
- data/lib/trenni/native.rb +28 -0
- data/lib/trenni/parse_delegate.rb +34 -0
- data/lib/trenni/{scanner.rb → parse_error.rb} +9 -54
- data/lib/trenni/parsers.rb +12 -0
- data/lib/trenni/substitutions.rb +45 -0
- data/lib/trenni/template.rb +52 -135
- data/lib/trenni/version.rb +1 -1
- data/parsers/trenni/entities.rl +11 -0
- data/parsers/trenni/markup.rl +43 -0
- data/parsers/trenni/template.rl +60 -0
- data/spec/trenni/builder_spec.rb +37 -62
- data/spec/trenni/corpus/large.rb +4605 -0
- data/spec/trenni/corpus/large.xhtml +726 -0
- data/spec/trenni/markup_parser_spec.rb +233 -0
- data/spec/trenni/markup_spec.rb +48 -0
- data/spec/trenni/parsers_performance_spec.rb +44 -0
- data/spec/trenni/template_error_spec.rb +36 -0
- data/spec/trenni/template_performance_spec.rb +102 -0
- data/spec/trenni/template_spec.rb +90 -64
- data/spec/trenni/template_spec/basic.trenni +1 -0
- data/spec/trenni/template_spec/capture.trenni +2 -2
- data/spec/trenni/template_spec/error.trenni +4 -0
- data/trenni.gemspec +9 -6
- metadata +57 -15
- data/lib/trenni/parser.rb +0 -153
- data/spec/trenni/parser_spec.rb +0 -144
@@ -20,78 +20,104 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
# THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'trenni'
|
23
|
+
require 'trenni/template'
|
24
|
+
require 'trenni/parsers'
|
24
25
|
require 'benchmark'
|
25
26
|
|
26
|
-
|
27
|
+
RSpec.describe Trenni::Template do
|
28
|
+
let(:template_path) {File.expand_path('corpus/large.xhtml', __dir__)}
|
29
|
+
let(:template) {Trenni::Template.load_file template_path}
|
30
|
+
let(:output) {template.to_string}
|
31
|
+
|
32
|
+
it "should parse xhtml template and produce identical output" do
|
33
|
+
expect{output}.to_not raise_error
|
34
|
+
expect(output).to be == File.read(template_path)
|
35
|
+
end
|
36
|
+
end
|
27
37
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
it "should be able to fetch output buffer" do
|
39
|
-
expect(buffer_template.to_string).to be == 'test'
|
40
|
-
end
|
41
|
-
|
42
|
-
let(:nested_template) {Trenni::Template.load_file File.expand_path('template_spec/nested.trenni', __dir__)}
|
38
|
+
RSpec.describe Trenni::Template do
|
39
|
+
let(:capture_template) {Trenni::Template.load_file File.expand_path('template_spec/capture.trenni', __dir__)}
|
40
|
+
|
41
|
+
it "should be able to capture output" do
|
42
|
+
expect(capture_template.to_string).to be == '"TEST TEST TEST\n"'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "compiled template should match line numbers" do
|
46
|
+
code_lines = capture_template.send(:code).lines
|
43
47
|
|
44
|
-
|
45
|
-
|
46
|
-
|
48
|
+
expect(code_lines.count).to be == 4
|
49
|
+
expect(code_lines[3]).to include("inspect")
|
50
|
+
end
|
51
|
+
|
52
|
+
let(:buffer_template) {Trenni::Template.load_file File.expand_path('template_spec/buffer.trenni', __dir__)}
|
53
|
+
|
54
|
+
it "should be able to fetch output buffer" do
|
55
|
+
expect(buffer_template.to_string).to be == 'test'
|
56
|
+
end
|
57
|
+
|
58
|
+
let(:nested_template) {Trenni::Template.load_file File.expand_path('template_spec/nested.trenni', __dir__)}
|
59
|
+
|
60
|
+
it "should be able to handle nested interpolations" do
|
61
|
+
expect(nested_template.to_string).to be == "Hello world!"
|
62
|
+
end
|
63
|
+
|
64
|
+
let(:items) {1..4}
|
65
|
+
|
66
|
+
it "should process list of items" do
|
67
|
+
buffer = Trenni::Buffer.new('<?r items.each do |item| ?>#{item}<?r end ?>')
|
68
|
+
template = Trenni::Template.new(buffer)
|
47
69
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
expect(template.to_string(binding)).to be == "1234"
|
55
|
-
end
|
70
|
+
expect(template.to_string(self)).to be == "1234"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have correct indentation" do
|
74
|
+
buffer = Trenni::Buffer.new("\t<?r items.each do |item| ?>\n\t\#{item}\n\t<?r end ?>\n")
|
75
|
+
template = Trenni::Template.new(buffer)
|
56
76
|
|
57
|
-
|
77
|
+
expect(template.to_string(self)).to be == "\t1\n\t2\n\t3\n\t4\n"
|
78
|
+
end
|
79
|
+
|
80
|
+
let(:escaped_template) {Trenni::Template.load_file File.expand_path('template_spec/escaped.trenni', __dir__)}
|
81
|
+
|
82
|
+
it "should have the same number of lines as input" do
|
83
|
+
expect(escaped_template.send(:code).lines.count).to be == 2
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should process escaped characters" do
|
87
|
+
expect(escaped_template.to_string).to be ==
|
88
|
+
"This\\nisn't one line.\n" +
|
89
|
+
"\\tIndentation is the best."
|
90
|
+
end
|
91
|
+
end
|
58
92
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
object_time = Benchmark.realtime{n.times{large_template.to_string(self)}}
|
65
|
-
binding_time = Benchmark.realtime{n.times{large_template.to_string(binding)}}
|
66
|
-
|
67
|
-
#result = RubyProf.stop
|
68
|
-
|
69
|
-
# Print a flat profile to text
|
70
|
-
#printer = RubyProf::FlatPrinter.new(result)
|
71
|
-
#printer.print(STDOUT)
|
72
|
-
|
73
|
-
expect(object_time).to be < binding_time
|
74
|
-
end
|
93
|
+
RSpec.shared_examples "template parser" do
|
94
|
+
let(:delegate) {Trenni::ParseDelegate.new}
|
95
|
+
|
96
|
+
it "should fail to parse incomplete expression" do
|
97
|
+
buffer = Trenni::Buffer.new('<img src="#{poi_product.photo.thumbnail_url" />')
|
75
98
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
expect(escaped_template.to_string).to be ==
|
84
|
-
"This\\nisn't one line.\n" +
|
85
|
-
"\\tIndentation is the best."
|
86
|
-
end
|
99
|
+
expect{
|
100
|
+
subject.parse_template(buffer, delegate)
|
101
|
+
}.to raise_error(Trenni::ParseError)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should fail to parse incomplete instruction" do
|
105
|
+
buffer = Trenni::Buffer.new('<?r foo')
|
87
106
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
expect{broken_template.to_proc}.to raise_error(Trenni::ParseError) do |error|
|
93
|
-
expect(error.to_s).to include("<string>[1]: Could not find end of interpolation!")
|
94
|
-
end
|
95
|
-
end
|
107
|
+
expect{
|
108
|
+
subject.parse_template(buffer, delegate)
|
109
|
+
}.to raise_error(Trenni::ParseError)
|
96
110
|
end
|
97
111
|
end
|
112
|
+
|
113
|
+
if defined? Trenni::Fallback
|
114
|
+
RSpec.describe Trenni::Fallback do
|
115
|
+
it_behaves_like "template parser"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
if defined? Trenni::Native
|
120
|
+
RSpec.describe Trenni::Native do
|
121
|
+
it_behaves_like "template parser"
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
#{text}
|
data/trenni.gemspec
CHANGED
@@ -9,12 +9,11 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Samuel Williams"]
|
10
10
|
spec.email = ["samuel.williams@oriontransfer.co.nz"]
|
11
11
|
spec.description = <<-EOF
|
12
|
-
Trenni is a templating system
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
Trenni is a templating system built on top of SGML/XML. It uses efficient
|
13
|
+
native parsers where possible and compiles templates into efficient Ruby.
|
14
|
+
|
16
15
|
In addition, Trenni includes an SGML/XML builder to assist with the generation
|
17
|
-
of pleasantly formatted markup.
|
16
|
+
of pleasantly formatted markup which is compatible with the included parsers.
|
18
17
|
EOF
|
19
18
|
spec.summary = %q{A fast native templating system that compiles directly to Ruby code.}
|
20
19
|
spec.homepage = "https://github.com/ioquatix/trenni"
|
@@ -24,7 +23,11 @@ Gem::Specification.new do |spec|
|
|
24
23
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
24
|
spec.require_paths = ["lib"]
|
26
25
|
|
26
|
+
spec.required_ruby_version = '~> 2.1'
|
27
|
+
|
28
|
+
spec.extensions = %w[ext/trenni/extconf.rb]
|
29
|
+
|
27
30
|
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
-
spec.add_development_dependency "rspec", "~> 3.4
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.4"
|
29
32
|
spec.add_development_dependency "rake"
|
30
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trenni
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.4
|
33
|
+
version: '3.4'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.4
|
40
|
+
version: '3.4'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,14 +52,15 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description: "\tTrenni is a templating system
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
description: "\tTrenni is a templating system built on top of SGML/XML. It uses efficient\n\tnative
|
56
|
+
parsers where possible and compiles templates into efficient Ruby.\n\t\n\tIn addition,
|
57
|
+
Trenni includes an SGML/XML builder to assist with the generation\n\tof pleasantly
|
58
|
+
formatted markup which is compatible with the included parsers.\n"
|
59
59
|
email:
|
60
60
|
- samuel.williams@oriontransfer.co.nz
|
61
61
|
executables: []
|
62
|
-
extensions:
|
62
|
+
extensions:
|
63
|
+
- ext/trenni/extconf.rb
|
63
64
|
extra_rdoc_files: []
|
64
65
|
files:
|
65
66
|
- ".gitignore"
|
@@ -69,21 +70,54 @@ files:
|
|
69
70
|
- Gemfile
|
70
71
|
- README.md
|
71
72
|
- Rakefile
|
73
|
+
- benchmark/call_vs_yield.rb
|
74
|
+
- benchmark/interpolation_vs_concat.rb
|
72
75
|
- benchmark/io_vs_string.rb
|
76
|
+
- entities.json
|
77
|
+
- ext/trenni/extconf.rb
|
78
|
+
- ext/trenni/markup.c
|
79
|
+
- ext/trenni/markup.h
|
80
|
+
- ext/trenni/markup.rl
|
81
|
+
- ext/trenni/template.c
|
82
|
+
- ext/trenni/template.h
|
83
|
+
- ext/trenni/template.rl
|
84
|
+
- ext/trenni/trenni.c
|
85
|
+
- ext/trenni/trenni.h
|
73
86
|
- lib/trenni.rb
|
74
87
|
- lib/trenni/buffer.rb
|
75
88
|
- lib/trenni/builder.rb
|
76
|
-
- lib/trenni/
|
77
|
-
- lib/trenni/
|
89
|
+
- lib/trenni/entities.rb
|
90
|
+
- lib/trenni/entities.trenni
|
91
|
+
- lib/trenni/fallback/markup.rb
|
92
|
+
- lib/trenni/fallback/markup.rl
|
93
|
+
- lib/trenni/fallback/template.rb
|
94
|
+
- lib/trenni/fallback/template.rl
|
95
|
+
- lib/trenni/markup.rb
|
96
|
+
- lib/trenni/native.rb
|
97
|
+
- lib/trenni/parse_delegate.rb
|
98
|
+
- lib/trenni/parse_error.rb
|
99
|
+
- lib/trenni/parsers.rb
|
78
100
|
- lib/trenni/strings.rb
|
101
|
+
- lib/trenni/substitutions.rb
|
79
102
|
- lib/trenni/template.rb
|
80
103
|
- lib/trenni/version.rb
|
104
|
+
- parsers/trenni/entities.rl
|
105
|
+
- parsers/trenni/markup.rl
|
106
|
+
- parsers/trenni/template.rl
|
81
107
|
- spec/trenni/builder_spec.rb
|
82
|
-
- spec/trenni/
|
108
|
+
- spec/trenni/corpus/large.rb
|
109
|
+
- spec/trenni/corpus/large.xhtml
|
110
|
+
- spec/trenni/markup_parser_spec.rb
|
111
|
+
- spec/trenni/markup_spec.rb
|
112
|
+
- spec/trenni/parsers_performance_spec.rb
|
83
113
|
- spec/trenni/strings_spec.rb
|
114
|
+
- spec/trenni/template_error_spec.rb
|
115
|
+
- spec/trenni/template_performance_spec.rb
|
84
116
|
- spec/trenni/template_spec.rb
|
117
|
+
- spec/trenni/template_spec/basic.trenni
|
85
118
|
- spec/trenni/template_spec/buffer.trenni
|
86
119
|
- spec/trenni/template_spec/capture.trenni
|
120
|
+
- spec/trenni/template_spec/error.trenni
|
87
121
|
- spec/trenni/template_spec/escaped.trenni
|
88
122
|
- spec/trenni/template_spec/large.trenni
|
89
123
|
- spec/trenni/template_spec/nested.trenni
|
@@ -97,9 +131,9 @@ require_paths:
|
|
97
131
|
- lib
|
98
132
|
required_ruby_version: !ruby/object:Gem::Requirement
|
99
133
|
requirements:
|
100
|
-
- - "
|
134
|
+
- - "~>"
|
101
135
|
- !ruby/object:Gem::Version
|
102
|
-
version: '
|
136
|
+
version: '2.1'
|
103
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
138
|
requirements:
|
105
139
|
- - ">="
|
@@ -113,11 +147,19 @@ specification_version: 4
|
|
113
147
|
summary: A fast native templating system that compiles directly to Ruby code.
|
114
148
|
test_files:
|
115
149
|
- spec/trenni/builder_spec.rb
|
116
|
-
- spec/trenni/
|
150
|
+
- spec/trenni/corpus/large.rb
|
151
|
+
- spec/trenni/corpus/large.xhtml
|
152
|
+
- spec/trenni/markup_parser_spec.rb
|
153
|
+
- spec/trenni/markup_spec.rb
|
154
|
+
- spec/trenni/parsers_performance_spec.rb
|
117
155
|
- spec/trenni/strings_spec.rb
|
156
|
+
- spec/trenni/template_error_spec.rb
|
157
|
+
- spec/trenni/template_performance_spec.rb
|
118
158
|
- spec/trenni/template_spec.rb
|
159
|
+
- spec/trenni/template_spec/basic.trenni
|
119
160
|
- spec/trenni/template_spec/buffer.trenni
|
120
161
|
- spec/trenni/template_spec/capture.trenni
|
162
|
+
- spec/trenni/template_spec/error.trenni
|
121
163
|
- spec/trenni/template_spec/escaped.trenni
|
122
164
|
- spec/trenni/template_spec/large.trenni
|
123
165
|
- spec/trenni/template_spec/nested.trenni
|
data/lib/trenni/parser.rb
DELETED
@@ -1,153 +0,0 @@
|
|
1
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require_relative 'scanner'
|
22
|
-
|
23
|
-
module Trenni
|
24
|
-
# This parser processes general markup into a sequence of events which are passed to a delegate.
|
25
|
-
class Parser < StringScanner
|
26
|
-
OPENED_TAG = :opened
|
27
|
-
CLOSED_TAG = :closed
|
28
|
-
|
29
|
-
def initialize(buffer, delegate)
|
30
|
-
super(buffer)
|
31
|
-
|
32
|
-
@delegate = delegate
|
33
|
-
|
34
|
-
# The delegate must respond to:
|
35
|
-
# .begin_parse(self)
|
36
|
-
# .text(escaped_data)
|
37
|
-
# .cdata(unescaped_data)
|
38
|
-
# .attribute(name, value_or_true)
|
39
|
-
# .begin_tag(name, :opened or :closed)
|
40
|
-
# .end_tag(begin_tag_type, :opened or :closed)
|
41
|
-
# .doctype(doctype_attributes)
|
42
|
-
# .comment(comment_text)
|
43
|
-
# .instruction(instruction_text)
|
44
|
-
end
|
45
|
-
|
46
|
-
def parse!
|
47
|
-
@delegate.begin_parse(self)
|
48
|
-
|
49
|
-
until eos?
|
50
|
-
start_pos = self.pos
|
51
|
-
|
52
|
-
scan_text
|
53
|
-
scan_tag
|
54
|
-
|
55
|
-
raise_if_stuck(start_pos)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
protected
|
60
|
-
|
61
|
-
def scan_text
|
62
|
-
# Match any character data except the open tag character.
|
63
|
-
if self.scan(/[^<]+/m)
|
64
|
-
@delegate.text(self.matched)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def scan_tag
|
69
|
-
if self.scan(/</)
|
70
|
-
if self.scan(/\//)
|
71
|
-
scan_tag_normal(CLOSED_TAG)
|
72
|
-
elsif self.scan(/!\[CDATA\[/)
|
73
|
-
scan_tag_cdata
|
74
|
-
elsif self.scan(/!--/)
|
75
|
-
scan_tag_comment
|
76
|
-
elsif self.scan(/!DOCTYPE/)
|
77
|
-
scan_doctype
|
78
|
-
elsif self.scan(/\?/)
|
79
|
-
scan_tag_instruction
|
80
|
-
else
|
81
|
-
scan_tag_normal
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def scan_attributes
|
87
|
-
# Parse an attribute in the form of key="value" or key.
|
88
|
-
while self.scan(/\s*([^\s=\/>]+)/um)
|
89
|
-
name = self[1].freeze
|
90
|
-
if self.scan(/=((['"])(.*?)\2)/um)
|
91
|
-
value = self[3].freeze
|
92
|
-
@delegate.attribute(name, value)
|
93
|
-
else
|
94
|
-
@delegate.attribute(name, true)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def scan_tag_normal(begin_tag_type = OPENED_TAG)
|
100
|
-
if self.scan(/[^\s\/>]+/)
|
101
|
-
@delegate.begin_tag(self.matched.freeze, begin_tag_type)
|
102
|
-
|
103
|
-
self.scan(/\s*/)
|
104
|
-
self.scan_attributes
|
105
|
-
self.scan(/\s*/)
|
106
|
-
|
107
|
-
if self.scan(/\/>/)
|
108
|
-
if begin_tag_type == CLOSED_TAG
|
109
|
-
parse_error!("Tag cannot be closed at both ends!")
|
110
|
-
else
|
111
|
-
@delegate.finish_tag(begin_tag_type, CLOSED_TAG)
|
112
|
-
end
|
113
|
-
elsif self.scan(/>/)
|
114
|
-
@delegate.finish_tag(begin_tag_type, OPENED_TAG)
|
115
|
-
else
|
116
|
-
parse_error!("Invalid characters in tag!")
|
117
|
-
end
|
118
|
-
else
|
119
|
-
parse_error!("Invalid tag!")
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def scan_doctype
|
124
|
-
if self.scan_until(/(.*?)>/)
|
125
|
-
@delegate.doctype(self[1].strip.freeze)
|
126
|
-
else
|
127
|
-
parse_error!("DOCTYPE is not closed!")
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def scan_tag_cdata
|
132
|
-
if self.scan_until(/(.*?)\]\]>/m)
|
133
|
-
@delegate.cdata(self[1].freeze)
|
134
|
-
else
|
135
|
-
parse_error!("CDATA segment is not closed!")
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def scan_tag_comment
|
140
|
-
if self.scan_until(/(.*?)-->/m)
|
141
|
-
@delegate.comment(self[1].freeze)
|
142
|
-
else
|
143
|
-
parse_error!("Comment is not closed!")
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def scan_tag_instruction
|
148
|
-
if self.scan_until(/(.*)\?>/)
|
149
|
-
@delegate.instruction(self[1].freeze)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|