trenni 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a3542181e14f5fed337b838c2ade044b487f9f65
4
- data.tar.gz: b440daa0411f50da581a02c77f163a74a007a1b4
3
+ metadata.gz: 17e4c37bf42689b8147fa6a2bd1c1ec0e639ba4e
4
+ data.tar.gz: 1329a84371a078a28fc2ffc51fd700491cf8d71b
5
5
  SHA512:
6
- metadata.gz: ee9347b54904e93f91d2153bbee549895763e16a1de8f0ed2d45e1fd54461a49fdb96d678c5de330fbf75a1b4417bff5bbddc865f6fc0734acd4e383d25c204c
7
- data.tar.gz: 67a322f46cde72f4e629f56c8988a3db6b82d75c146e2e6ce92ecb5cdba3e0c54b16651ca6934871377d8daef459d6275cdad67c03dbcbf89318a2d04d5baaa7
6
+ metadata.gz: '0088146935eaa008d901c8c1675bfcce76770114e45d1359891dd1cf6d56a91313e781db70707efae6061bc8f3b82749815bc2deed5af1e4498e94c735998900'
7
+ data.tar.gz: 3291577a7d8ad37f4d48217c9e43e033414f6dc64e769cff239f088420dfb80610bc2490c2f3b72ed1555efdd152dce624d3a33c97e6049148ce82d0145d6aff
data/.rspec CHANGED
@@ -2,3 +2,4 @@
2
2
  --format documentation
3
3
  --backtrace
4
4
  --warnings
5
+ --require spec_helper
data/.travis.yml CHANGED
@@ -6,6 +6,7 @@ rvm:
6
6
  - 2.1.8
7
7
  - 2.2.4
8
8
  - 2.3.0
9
+ - 2.4.0
9
10
  - ruby-head
10
11
  - rbx-2
11
12
  env:
data/Gemfile CHANGED
@@ -5,16 +5,19 @@ gemspec
5
5
 
6
6
  group :development do
7
7
  gem 'pry'
8
- gem 'ruby-prof', platforms: [:mri]
9
-
10
- gem "benchmark-ips"
11
8
 
12
9
  gem "rake-compiler"
13
10
 
14
- # For comparisons:
15
- gem "nokogiri"
11
+ gem "ruby-beautify"
16
12
  end
17
13
 
18
14
  group :test do
19
- gem 'coveralls', platforms: [:mri]
15
+ gem 'ruby-prof', platforms: [:mri]
16
+ gem "benchmark-ips"
17
+
18
+ gem 'simplecov'
19
+ gem 'coveralls', require: false
20
+
21
+ # For comparisons:
22
+ gem "nokogiri"
20
23
  end
data/README.md CHANGED
@@ -18,6 +18,8 @@ In addition, I wanted a simple markup parser and builder for HTML style markup.
18
18
 
19
19
  The 2nd release of Trenni in 2016 saw an overhaul of the internal parsers. I used [Ragel](http://www.colm.net/open-source/ragel/) to implement efficient event-based markup and template parsers, which can be compiled to both C and Ruby. This provides a native code path where possible giving speed-ups between 10x - 20x. In addition, the formal grammar is more robust.
20
20
 
21
+ The 3rd release of Trenni in 2017 was primarily focused on performance, by moving more of the critical parsing, escaping and tag generation functions to C. In practical usage, this gave about a 40-50% improvement in performance overall.
22
+
21
23
  ## Is it fast?
22
24
 
23
25
  It's faster than Nokogiri for parsing markup:
@@ -70,66 +72,70 @@ The markup parser parses a loose super-set of HTML in a way that's useful for co
70
72
 
71
73
  To invoke the markup parser:
72
74
 
73
- require 'trenni'
75
+ ```ruby
76
+ require 'trenni'
77
+
78
+ buffer = Trenni::Buffer(string)
79
+
80
+ # Custom entities, or could use Trenni::Entities::HTML5
81
+ entities = {'amp' => '&', 'lt', => '<', 'gt' => '>', 'quot' => '"'}
82
+
83
+ # Modify this class to accumulate events or pass them on somewhere else.
84
+ class Delegate
85
+ # Called when encountering an open tag: `<` name
86
+ def open_tag_begin(name, offset)
87
+ end
74
88
 
75
- buffer = Trenni::Buffer(string)
89
+ # Called when encountering an attribute after open_tag_begin
90
+ def attribute(key, value)
91
+ end
76
92
 
77
- # Custom entities, or could use Trenni::Entities::HTML5
78
- entities = {'amp' => '&', 'lt', => '<', 'gt' => '>', 'quot' => '"'}
93
+ # Called when encountering the end of the opening tag.
94
+ def open_tag_end(self_closing)
95
+ end
79
96
 
80
- # Modify this class to accumulate events or pass them on somewhere else.
81
- class Delegate
82
- # Called when encountering an open tag: `<` name
83
- def open_tag_begin(name, offset)
84
- end
85
-
86
- # Called when encountering an attribute after open_tag_begin
87
- def attribute(key, value)
88
- end
89
-
90
- # Called when encountering the end of the opening tag.
91
- def open_tag_end(self_closing)
92
- end
93
-
94
- # Called when encountering the closing tag: '</' name '>'
95
- def close_tag(name, offset)
96
- end
97
-
98
- # Called with the full doctype: '<!DOCTYPE html>'
99
- def doctype(string)
100
- end
101
-
102
- # Called with the full comment: '<!-- comment -->'
103
- def comment(string)
104
- end
105
-
106
- # Called with the parsed instruction: '<?' identifier space+ body '?>'
107
- def instruction(string)
108
- end
109
-
110
- # Called with a cdata block: '<![CDATA[text]]>'
111
- def cdata(string)
112
- end
113
-
114
- # Called with any arbitrary pcdata text (e.g. between tags).
115
- def text(string)
116
- end
97
+ # Called when encountering the closing tag: '</' name '>'
98
+ def close_tag(name, offset)
99
+ end
100
+
101
+ # Called with the full doctype: '<!DOCTYPE html>'
102
+ def doctype(string)
103
+ end
104
+
105
+ # Called with the full comment: '<!-- comment -->'
106
+ def comment(string)
107
+ end
108
+
109
+ # Called with the parsed instruction: '<?' identifier space+ body '?>'
110
+ def instruction(string)
117
111
  end
118
112
 
119
- # Do the actual work:
120
- Trenni::Parsers.parse_markup(buffer, Delegate.new, entities)
113
+ # Called with a cdata block: '<![CDATA[text]]>'
114
+ def cdata(string)
115
+ end
116
+
117
+ # Called with any arbitrary pcdata text (e.g. between tags).
118
+ def text(string)
119
+ end
120
+ end
121
+
122
+ # Do the actual work:
123
+ Trenni::Parsers.parse_markup(buffer, Delegate.new, entities)
124
+ ```
121
125
 
122
126
  ### Templates
123
127
 
124
128
  Trenni templates work essentially the same way as all other templating systems:
125
129
 
126
- buffer = Trenni::Buffer('<?r self.each do |item| ?>#{item}<?r end ?>')
127
- template = Trenni::Template.new(buffer)
128
-
129
- items = 1..4
130
-
131
- template.to_string(items) # => "1234"
130
+ ```ruby
131
+ buffer = Trenni::Buffer('<?r self.each do |item| ?>#{item}<?r end ?>')
132
+ template = Trenni::Template.new(buffer)
132
133
 
134
+ items = 1..4
135
+
136
+ template.to_string(items) # => "1234"
137
+ ```
138
+
133
139
  The code above demonstrate the only two constructs, `<?r expression ?>` and `#{output}`.
134
140
 
135
141
  Trenni doesn't support using `binding` for evaluation, as this is a slow code path. It uses `instance_exec`
@@ -138,18 +144,17 @@ Trenni doesn't support using `binding` for evaluation, as this is a slow code pa
138
144
 
139
145
  Trenni can help construct XML/HTML using a simple DSL:
140
146
 
141
- Trenni::Builder.fragment do |builder|
142
- builder.inline 'p' do
143
- builder.tag 'strong' do
144
- builder.text 'Hello'
145
- end
146
- builder.text ' World'
147
- end
148
- builder.tag 'script', type: 'text/html' do
149
- builder.text 'console.log("Hello World")'
147
+ ```ruby
148
+ Trenni::Builder.fragment do |builder|
149
+ builder.inline 'p' do
150
+ builder.tag 'strong' do
151
+ builder.text 'Hello'
150
152
  end
153
+ builder.text ' World'
151
154
  end
152
- # => "<p><strong>Hello</strong> World</p>\n<script type=\"text/html\">\n\tconsole.log(\"Hello World\")\n</script>"
155
+ end.to_s
156
+ # => "<p><strong>Hello</strong> World</p>"
157
+ ```
153
158
 
154
159
  ### Integration
155
160
 
@@ -179,7 +184,7 @@ To test the native C parsers:
179
184
 
180
185
  Released under the MIT license.
181
186
 
182
- Copyright, 2012, 2016, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
187
+ Copyright, 2017, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
183
188
 
184
189
  Permission is hereby granted, free of charge, to any person obtaining a copy
185
190
  of this software and associated documentation files (the "Software"), to deal
@@ -197,4 +202,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
197
202
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198
203
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
199
204
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
200
- THE SOFTWARE.
205
+ THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,13 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
- RSpec::Core::RakeTask.new(:spec) do |task|
5
- begin
6
- require('simplecov/version')
7
- task.rspec_opts = %w{--require simplecov} if ENV['COVERAGE']
8
- rescue LoadError
9
- end
10
- end
4
+ RSpec::Core::RakeTask.new(:spec)
11
5
 
12
6
  task :default => :spec
13
7
 
@@ -59,6 +53,8 @@ task :generate_fallback_parsers do
59
53
  Dir.glob("*.rl").each do |parser_path|
60
54
  sh("ragel", "-I", PARSERS_DIRECTORY, "-R", parser_path, "-F1")
61
55
  end
56
+
57
+ sh("ruby-beautify", "--tabs", "--overwrite", *Dir.glob("*.rb"))
62
58
  end
63
59
  end
64
60
 
@@ -0,0 +1,150 @@
1
+
2
+ #include "escape.h"
3
+ #include <assert.h>
4
+
5
+ inline static int Trenni_Markup_is_markup(VALUE value) {
6
+ if (RB_IMMEDIATE_P(value))
7
+ return 0;
8
+
9
+ // This is a short-cut:
10
+ if (rb_class_of(value) == rb_Trenni_MarkupString) {
11
+ return 1;
12
+ }
13
+
14
+ return rb_funcall(value, id_is_a, 1, rb_Trenni_Markup) == Qtrue;
15
+ }
16
+
17
+ VALUE Trenni_MarkupString_raw(VALUE self, VALUE string) {
18
+ string = rb_str_dup(string);
19
+
20
+ rb_obj_reveal(string, rb_Trenni_MarkupString);
21
+
22
+ return string;
23
+ }
24
+
25
+ // => [["<", 60, "3c"], [">", 62, "3e"], ["\"", 34, "22"], ["&", 38, "26"]]
26
+ // static const uint32_t MASK = 0x3e3e3e3e;
27
+ //
28
+ // static const uint32_t MASK_LT = 0x3c3c3c3c;
29
+ // static const uint32_t MASK_GT = 0x3e3e3e3e;
30
+ // static const uint32_t MASK_QUOT = 0x22222222;
31
+ // static const uint32_t MASK_AMP = 0x26262626;
32
+
33
+ static inline const char * Trenni_Markup_index_symbol(const char * begin, const char * end) {
34
+ const char * p = begin;
35
+
36
+ while (p < end) {
37
+ // if ((end - p) >= 4) {
38
+ // // Do the next 4 characters contain anything we are interested in?
39
+ // if ((*(const uint32_t *)p) & MASK_LT) {
40
+ // p += 4;
41
+ //
42
+ // continue;
43
+ // }
44
+ // }
45
+
46
+ switch (*p) {
47
+ case '<':
48
+ case '>':
49
+ case '"':
50
+ case '&':
51
+ return p;
52
+ }
53
+
54
+ p += 1;
55
+ }
56
+
57
+ return end;
58
+ }
59
+
60
+ static inline void Trenni_Markup_append_entity(const char * p, VALUE buffer) {
61
+ // What symbol are we looking at?
62
+ switch (*p) {
63
+ case '<':
64
+ rb_str_cat_cstr(buffer, "&lt;");
65
+ break;
66
+ case '>':
67
+ rb_str_cat_cstr(buffer, "&gt;");
68
+ break;
69
+ case '"':
70
+ rb_str_cat_cstr(buffer, "&quot;");
71
+ break;
72
+ case '&':
73
+ rb_str_cat_cstr(buffer, "&amp;");
74
+ break;
75
+ }
76
+ }
77
+
78
+ static inline VALUE Trenni_Markup_append_buffer(VALUE buffer, const char * s, const char * p, const char * end) {
79
+ while (1) {
80
+ // Append the non-symbol part:
81
+ rb_str_buf_cat(buffer, s, p - s);
82
+
83
+ // We escape early if there were no changes to be made:
84
+ if (p == end) return buffer;
85
+
86
+ Trenni_Markup_append_entity(p, buffer);
87
+
88
+ s = p + 1;
89
+ p = Trenni_Markup_index_symbol(s, end);
90
+ }
91
+ }
92
+
93
+ // Escape and append a string to the output buffer.
94
+ VALUE Trenni_Markup_append_string(VALUE buffer, VALUE string) {
95
+ const char * begin = RSTRING_PTR(string);
96
+ const char * end = begin + RSTRING_LEN(string);
97
+
98
+ const char * s = begin;
99
+
100
+ // There are two outcomes, either p is at end, or p points to a symbol:
101
+ const char * p = Trenni_Markup_index_symbol(s, end);
102
+
103
+ return Trenni_Markup_append_buffer(buffer, s, p, end);
104
+ }
105
+
106
+ VALUE Trenni_Markup_append(VALUE self, VALUE buffer, VALUE value) {
107
+ if (value == Qnil) return Qnil;
108
+
109
+ if (Trenni_Markup_is_markup(value)) {
110
+ rb_str_append(buffer, value);
111
+ } else {
112
+ if (rb_type(value) != T_STRING) {
113
+ value = rb_funcall(value, id_to_s, 0);
114
+ }
115
+
116
+ Trenni_Markup_append_string(buffer, value);
117
+ }
118
+
119
+ return buffer;
120
+ }
121
+
122
+ // Convert markup special characters to entities. May return the original string if no changes were made.
123
+ VALUE Trenni_Markup_escape_string(VALUE self, VALUE string) {
124
+ const char * begin = RSTRING_PTR(string);
125
+ const char * end = begin + RSTRING_LEN(string);
126
+
127
+ const char * s = begin;
128
+
129
+ // There are two outcomes, either p is at end, or p points to a symbol:
130
+ const char * p = Trenni_Markup_index_symbol(s, end);
131
+
132
+ // We escape early if there were no changes to be made:
133
+ if (p == end) return string;
134
+
135
+ return Trenni_Markup_append_buffer(Trenni_buffer_for(string), s, p, end);
136
+ }
137
+
138
+ void Init_trenni_escape() {
139
+ rb_Trenni_MarkupString = rb_define_class_under(rb_Trenni, "MarkupString", rb_cString);
140
+ rb_include_module(rb_Trenni_MarkupString, rb_Trenni_Markup);
141
+
142
+ rb_undef_method(rb_class_of(rb_Trenni_Markup), "escape_string");
143
+ rb_define_singleton_method(rb_Trenni_Markup, "escape_string", Trenni_Markup_escape_string, 1);
144
+
145
+ rb_undef_method(rb_class_of(rb_Trenni_Markup), "append");
146
+ rb_define_singleton_method(rb_Trenni_Markup, "append", Trenni_Markup_append, 2);
147
+
148
+ rb_undef_method(rb_class_of(rb_Trenni_Markup), "raw");
149
+ rb_define_singleton_method(rb_Trenni_Markup, "raw", Trenni_MarkupString_raw, 1);
150
+ }
@@ -0,0 +1,15 @@
1
+
2
+ #pragma once
3
+
4
+ #include "trenni.h"
5
+
6
+ void Init_trenni_escape();
7
+
8
+ // Given a string, replace it's class with Trenni::MarkupString so that it would be output as is.
9
+ VALUE Trenni_MarkupString_raw(VALUE self, VALUE string);
10
+
11
+ // Append any value to the output buffer efficiently, escaping entities as needed.
12
+ VALUE Trenni_Markup_append(VALUE self, VALUE buffer, VALUE value);
13
+
14
+ // Escape any entities in the given string. If no entities were found, might return the original string.
15
+ VALUE Trenni_Markup_escape_string(VALUE self, VALUE string);
@@ -3,6 +3,11 @@ require 'mkmf'
3
3
 
4
4
  $CFLAGS << " -O3 -std=c99"
5
5
 
6
+ # Needed by Ruby 2.1
7
+ have_func("rb_sym2str")
8
+ have_func("rb_str_cat_cstr")
9
+ have_func("rb_str_reserve")
10
+
6
11
  gem_name = File.basename(__dir__)
7
12
  extension_name = 'trenni'
8
13
 
data/ext/trenni/markup.c CHANGED
@@ -3,10 +3,8 @@
3
3
 
4
4
  #include "markup.h"
5
5
 
6
- #include <ruby/encoding.h>
7
6
 
8
-
9
- #line 10 "markup.c"
7
+ #line 8 "markup.c"
10
8
  static const int Trenni_markup_parser_start = 48;
11
9
  static const int Trenni_markup_parser_first_final = 48;
12
10
  static const int Trenni_markup_parser_error = 0;
@@ -15,7 +13,7 @@ static const int Trenni_markup_parser_en_parse_entity = 42;
15
13
  static const int Trenni_markup_parser_en_main = 48;
16
14
 
17
15
 
18
- #line 190 "markup.rl"
16
+ #line 195 "markup.rl"
19
17
 
20
18
 
21
19
  VALUE Trenni_Native_parse_markup(VALUE self, VALUE buffer, VALUE delegate, VALUE entities) {
@@ -25,26 +23,26 @@ VALUE Trenni_Native_parse_markup(VALUE self, VALUE buffer, VALUE delegate, VALUE
25
23
 
26
24
  VALUE pcdata = Qnil;
27
25
 
28
- VALUE empty_string = rb_obj_freeze(rb_enc_str_new("", 0, encoding));
26
+ VALUE empty_string = rb_obj_freeze(rb_enc_str_new(0, 0, encoding));
29
27
 
30
28
  const char *s, *p, *pe, *eof;
31
29
  unsigned long cs, top = 0, stack[2] = {0};
32
30
  unsigned long codepoint = 0;
33
31
 
34
32
  Token identifier = {0}, cdata = {0}, characters = {0}, entity = {0}, doctype = {0}, comment = {0}, instruction = {0};
35
- unsigned self_closing = 0, has_value = 0;
33
+ unsigned self_closing = 0, has_value = 0, has_entities = 0;
36
34
 
37
35
  s = p = RSTRING_PTR(string);
38
36
  eof = pe = p + RSTRING_LEN(string);
39
37
 
40
38
 
41
- #line 42 "markup.c"
39
+ #line 40 "markup.c"
42
40
  {
43
41
  cs = Trenni_markup_parser_start;
44
42
  top = 0;
45
43
  }
46
44
 
47
- #line 48 "markup.c"
45
+ #line 46 "markup.c"
48
46
  {
49
47
  if ( p == pe )
50
48
  goto _test_eof;
@@ -128,130 +126,137 @@ case 48:
128
126
  }
129
127
  goto tr87;
130
128
  tr93:
131
- #line 32 "markup.rl"
129
+ #line 31 "markup.rl"
132
130
  {
133
131
  characters.begin = p;
134
132
  }
135
133
  goto st49;
136
134
  tr87:
137
- #line 25 "markup.rl"
135
+ #line 24 "markup.rl"
138
136
  {
139
137
  }
140
- #line 18 "markup.rl"
138
+ #line 16 "markup.rl"
141
139
  {
142
140
  pcdata = Qnil;
141
+ has_entities = 0;
143
142
  }
144
- #line 32 "markup.rl"
143
+ #line 31 "markup.rl"
145
144
  {
146
145
  characters.begin = p;
147
146
  }
148
147
  goto st49;
149
148
  tr96:
150
- #line 158 "markup.rl"
149
+ #line 163 "markup.rl"
151
150
  {
152
151
  rb_funcall(delegate, id_open_tag_end, 1, self_closing == 1 ? Qtrue : Qfalse);
153
152
  }
154
- #line 25 "markup.rl"
153
+ #line 24 "markup.rl"
155
154
  {
156
155
  }
157
- #line 18 "markup.rl"
156
+ #line 16 "markup.rl"
158
157
  {
159
158
  pcdata = Qnil;
159
+ has_entities = 0;
160
160
  }
161
- #line 32 "markup.rl"
161
+ #line 31 "markup.rl"
162
162
  {
163
163
  characters.begin = p;
164
164
  }
165
165
  goto st49;
166
166
  tr99:
167
- #line 92 "markup.rl"
167
+ #line 97 "markup.rl"
168
168
  {
169
169
  comment.end = p;
170
170
 
171
171
  rb_funcall(delegate, id_comment, 1, Trenni_token(comment, encoding));
172
172
  }
173
- #line 25 "markup.rl"
173
+ #line 24 "markup.rl"
174
174
  {
175
175
  }
176
- #line 18 "markup.rl"
176
+ #line 16 "markup.rl"
177
177
  {
178
178
  pcdata = Qnil;
179
+ has_entities = 0;
179
180
  }
180
- #line 32 "markup.rl"
181
+ #line 31 "markup.rl"
181
182
  {
182
183
  characters.begin = p;
183
184
  }
184
185
  goto st49;
185
186
  tr102:
186
- #line 78 "markup.rl"
187
+ #line 83 "markup.rl"
187
188
  {
188
189
  doctype.end = p;
189
190
 
190
191
  rb_funcall(delegate, id_doctype, 1, Trenni_token(doctype, encoding));
191
192
  }
192
- #line 25 "markup.rl"
193
+ #line 24 "markup.rl"
193
194
  {
194
195
  }
195
- #line 18 "markup.rl"
196
+ #line 16 "markup.rl"
196
197
  {
197
198
  pcdata = Qnil;
199
+ has_entities = 0;
198
200
  }
199
- #line 32 "markup.rl"
201
+ #line 31 "markup.rl"
200
202
  {
201
203
  characters.begin = p;
202
204
  }
203
205
  goto st49;
204
206
  tr105:
205
- #line 177 "markup.rl"
207
+ #line 182 "markup.rl"
206
208
  {
207
209
  cdata.end = p;
208
210
 
209
211
  rb_funcall(delegate, id_cdata, 1, Trenni_token(cdata, encoding));
210
212
  }
211
- #line 25 "markup.rl"
213
+ #line 24 "markup.rl"
212
214
  {
213
215
  }
214
- #line 18 "markup.rl"
216
+ #line 16 "markup.rl"
215
217
  {
216
218
  pcdata = Qnil;
219
+ has_entities = 0;
217
220
  }
218
- #line 32 "markup.rl"
221
+ #line 31 "markup.rl"
219
222
  {
220
223
  characters.begin = p;
221
224
  }
222
225
  goto st49;
223
226
  tr108:
224
- #line 165 "markup.rl"
227
+ #line 170 "markup.rl"
225
228
  {
226
229
  rb_funcall(delegate, id_close_tag, 2, Trenni_token(identifier, encoding), ULONG2NUM(identifier.begin-s));
227
230
  }
228
- #line 25 "markup.rl"
231
+ #line 24 "markup.rl"
229
232
  {
230
233
  }
231
- #line 18 "markup.rl"
234
+ #line 16 "markup.rl"
232
235
  {
233
236
  pcdata = Qnil;
237
+ has_entities = 0;
234
238
  }
235
- #line 32 "markup.rl"
239
+ #line 31 "markup.rl"
236
240
  {
237
241
  characters.begin = p;
238
242
  }
239
243
  goto st49;
240
244
  tr111:
241
- #line 112 "markup.rl"
245
+ #line 117 "markup.rl"
242
246
  {
243
247
  instruction.end = p;
244
248
 
245
249
  rb_funcall(delegate, id_instruction, 1, Trenni_token(instruction, encoding));
246
250
  }
247
- #line 25 "markup.rl"
251
+ #line 24 "markup.rl"
248
252
  {
249
253
  }
250
- #line 18 "markup.rl"
254
+ #line 16 "markup.rl"
251
255
  {
252
256
  pcdata = Qnil;
257
+ has_entities = 0;
253
258
  }
254
- #line 32 "markup.rl"
259
+ #line 31 "markup.rl"
255
260
  {
256
261
  characters.begin = p;
257
262
  }
@@ -260,409 +265,416 @@ st49:
260
265
  if ( ++p == pe )
261
266
  goto _test_eof49;
262
267
  case 49:
263
- #line 264 "markup.c"
268
+ #line 269 "markup.c"
264
269
  switch( (*p) ) {
265
270
  case 38: goto tr91;
266
271
  case 60: goto tr92;
267
272
  }
268
273
  goto st49;
269
274
  tr91:
270
- #line 36 "markup.rl"
275
+ #line 35 "markup.rl"
271
276
  {
272
277
  characters.end = p;
273
278
 
274
279
  Trenni_append_token(&pcdata, encoding, characters);
275
280
  }
276
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
281
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
277
282
  {{stack[top++] = 50; goto st42;}}
278
283
  goto st50;
279
284
  tr94:
280
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
285
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
281
286
  {{stack[top++] = 50; goto st42;}}
282
287
  goto st50;
283
288
  tr88:
284
- #line 25 "markup.rl"
289
+ #line 24 "markup.rl"
285
290
  {
286
291
  }
287
- #line 18 "markup.rl"
292
+ #line 16 "markup.rl"
288
293
  {
289
294
  pcdata = Qnil;
295
+ has_entities = 0;
290
296
  }
291
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
297
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
292
298
  {{stack[top++] = 50; goto st42;}}
293
299
  goto st50;
294
300
  tr97:
295
- #line 158 "markup.rl"
301
+ #line 163 "markup.rl"
296
302
  {
297
303
  rb_funcall(delegate, id_open_tag_end, 1, self_closing == 1 ? Qtrue : Qfalse);
298
304
  }
299
- #line 25 "markup.rl"
305
+ #line 24 "markup.rl"
300
306
  {
301
307
  }
302
- #line 18 "markup.rl"
308
+ #line 16 "markup.rl"
303
309
  {
304
310
  pcdata = Qnil;
311
+ has_entities = 0;
305
312
  }
306
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
313
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
307
314
  {{stack[top++] = 50; goto st42;}}
308
315
  goto st50;
309
316
  tr100:
310
- #line 92 "markup.rl"
317
+ #line 97 "markup.rl"
311
318
  {
312
319
  comment.end = p;
313
320
 
314
321
  rb_funcall(delegate, id_comment, 1, Trenni_token(comment, encoding));
315
322
  }
316
- #line 25 "markup.rl"
323
+ #line 24 "markup.rl"
317
324
  {
318
325
  }
319
- #line 18 "markup.rl"
326
+ #line 16 "markup.rl"
320
327
  {
321
328
  pcdata = Qnil;
329
+ has_entities = 0;
322
330
  }
323
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
331
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
324
332
  {{stack[top++] = 50; goto st42;}}
325
333
  goto st50;
326
334
  tr103:
327
- #line 78 "markup.rl"
335
+ #line 83 "markup.rl"
328
336
  {
329
337
  doctype.end = p;
330
338
 
331
339
  rb_funcall(delegate, id_doctype, 1, Trenni_token(doctype, encoding));
332
340
  }
333
- #line 25 "markup.rl"
341
+ #line 24 "markup.rl"
334
342
  {
335
343
  }
336
- #line 18 "markup.rl"
344
+ #line 16 "markup.rl"
337
345
  {
338
346
  pcdata = Qnil;
347
+ has_entities = 0;
339
348
  }
340
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
349
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
341
350
  {{stack[top++] = 50; goto st42;}}
342
351
  goto st50;
343
352
  tr106:
344
- #line 177 "markup.rl"
353
+ #line 182 "markup.rl"
345
354
  {
346
355
  cdata.end = p;
347
356
 
348
357
  rb_funcall(delegate, id_cdata, 1, Trenni_token(cdata, encoding));
349
358
  }
350
- #line 25 "markup.rl"
359
+ #line 24 "markup.rl"
351
360
  {
352
361
  }
353
- #line 18 "markup.rl"
362
+ #line 16 "markup.rl"
354
363
  {
355
364
  pcdata = Qnil;
365
+ has_entities = 0;
356
366
  }
357
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
367
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
358
368
  {{stack[top++] = 50; goto st42;}}
359
369
  goto st50;
360
370
  tr109:
361
- #line 165 "markup.rl"
371
+ #line 170 "markup.rl"
362
372
  {
363
373
  rb_funcall(delegate, id_close_tag, 2, Trenni_token(identifier, encoding), ULONG2NUM(identifier.begin-s));
364
374
  }
365
- #line 25 "markup.rl"
375
+ #line 24 "markup.rl"
366
376
  {
367
377
  }
368
- #line 18 "markup.rl"
378
+ #line 16 "markup.rl"
369
379
  {
370
380
  pcdata = Qnil;
381
+ has_entities = 0;
371
382
  }
372
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
383
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
373
384
  {{stack[top++] = 50; goto st42;}}
374
385
  goto st50;
375
386
  tr112:
376
- #line 112 "markup.rl"
387
+ #line 117 "markup.rl"
377
388
  {
378
389
  instruction.end = p;
379
390
 
380
391
  rb_funcall(delegate, id_instruction, 1, Trenni_token(instruction, encoding));
381
392
  }
382
- #line 25 "markup.rl"
393
+ #line 24 "markup.rl"
383
394
  {
384
395
  }
385
- #line 18 "markup.rl"
396
+ #line 16 "markup.rl"
386
397
  {
387
398
  pcdata = Qnil;
399
+ has_entities = 0;
388
400
  }
389
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
401
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
390
402
  {{stack[top++] = 50; goto st42;}}
391
403
  goto st50;
392
404
  st50:
393
405
  if ( ++p == pe )
394
406
  goto _test_eof50;
395
407
  case 50:
396
- #line 397 "markup.c"
408
+ #line 409 "markup.c"
397
409
  switch( (*p) ) {
398
410
  case 38: goto tr94;
399
411
  case 60: goto tr95;
400
412
  }
401
413
  goto tr93;
402
414
  tr89:
403
- #line 129 "markup.rl"
415
+ #line 134 "markup.rl"
404
416
  {
405
417
  }
406
- #line 162 "markup.rl"
418
+ #line 167 "markup.rl"
407
419
  {
408
420
  }
409
- #line 102 "markup.rl"
421
+ #line 107 "markup.rl"
410
422
  {
411
423
  instruction.begin = p;
412
424
  }
413
- #line 88 "markup.rl"
425
+ #line 93 "markup.rl"
414
426
  {
415
427
  comment.begin = p;
416
428
  }
417
- #line 74 "markup.rl"
429
+ #line 79 "markup.rl"
418
430
  {
419
431
  doctype.begin = p;
420
432
  }
421
- #line 173 "markup.rl"
433
+ #line 178 "markup.rl"
422
434
  {
423
435
  cdata.begin = p;
424
436
  }
425
437
  goto st1;
426
438
  tr92:
427
- #line 36 "markup.rl"
439
+ #line 35 "markup.rl"
428
440
  {
429
441
  characters.end = p;
430
442
 
431
443
  Trenni_append_token(&pcdata, encoding, characters);
432
444
  }
433
- #line 22 "markup.rl"
445
+ #line 21 "markup.rl"
434
446
  {
435
447
  }
436
- #line 28 "markup.rl"
448
+ #line 27 "markup.rl"
437
449
  {
438
- rb_funcall(delegate, id_text, 1, pcdata);
450
+ rb_funcall(delegate, id_text, 1, Trenni_markup_safe(pcdata, has_entities));
439
451
  }
440
- #line 129 "markup.rl"
452
+ #line 134 "markup.rl"
441
453
  {
442
454
  }
443
- #line 162 "markup.rl"
455
+ #line 167 "markup.rl"
444
456
  {
445
457
  }
446
- #line 102 "markup.rl"
458
+ #line 107 "markup.rl"
447
459
  {
448
460
  instruction.begin = p;
449
461
  }
450
- #line 88 "markup.rl"
462
+ #line 93 "markup.rl"
451
463
  {
452
464
  comment.begin = p;
453
465
  }
454
- #line 74 "markup.rl"
466
+ #line 79 "markup.rl"
455
467
  {
456
468
  doctype.begin = p;
457
469
  }
458
- #line 173 "markup.rl"
470
+ #line 178 "markup.rl"
459
471
  {
460
472
  cdata.begin = p;
461
473
  }
462
474
  goto st1;
463
475
  tr95:
464
- #line 22 "markup.rl"
476
+ #line 21 "markup.rl"
465
477
  {
466
478
  }
467
- #line 28 "markup.rl"
479
+ #line 27 "markup.rl"
468
480
  {
469
- rb_funcall(delegate, id_text, 1, pcdata);
481
+ rb_funcall(delegate, id_text, 1, Trenni_markup_safe(pcdata, has_entities));
470
482
  }
471
- #line 129 "markup.rl"
483
+ #line 134 "markup.rl"
472
484
  {
473
485
  }
474
- #line 162 "markup.rl"
486
+ #line 167 "markup.rl"
475
487
  {
476
488
  }
477
- #line 102 "markup.rl"
489
+ #line 107 "markup.rl"
478
490
  {
479
491
  instruction.begin = p;
480
492
  }
481
- #line 88 "markup.rl"
493
+ #line 93 "markup.rl"
482
494
  {
483
495
  comment.begin = p;
484
496
  }
485
- #line 74 "markup.rl"
497
+ #line 79 "markup.rl"
486
498
  {
487
499
  doctype.begin = p;
488
500
  }
489
- #line 173 "markup.rl"
501
+ #line 178 "markup.rl"
490
502
  {
491
503
  cdata.begin = p;
492
504
  }
493
505
  goto st1;
494
506
  tr98:
495
- #line 158 "markup.rl"
507
+ #line 163 "markup.rl"
496
508
  {
497
509
  rb_funcall(delegate, id_open_tag_end, 1, self_closing == 1 ? Qtrue : Qfalse);
498
510
  }
499
- #line 129 "markup.rl"
511
+ #line 134 "markup.rl"
500
512
  {
501
513
  }
502
- #line 162 "markup.rl"
514
+ #line 167 "markup.rl"
503
515
  {
504
516
  }
505
- #line 102 "markup.rl"
517
+ #line 107 "markup.rl"
506
518
  {
507
519
  instruction.begin = p;
508
520
  }
509
- #line 88 "markup.rl"
521
+ #line 93 "markup.rl"
510
522
  {
511
523
  comment.begin = p;
512
524
  }
513
- #line 74 "markup.rl"
525
+ #line 79 "markup.rl"
514
526
  {
515
527
  doctype.begin = p;
516
528
  }
517
- #line 173 "markup.rl"
529
+ #line 178 "markup.rl"
518
530
  {
519
531
  cdata.begin = p;
520
532
  }
521
533
  goto st1;
522
534
  tr101:
523
- #line 92 "markup.rl"
535
+ #line 97 "markup.rl"
524
536
  {
525
537
  comment.end = p;
526
538
 
527
539
  rb_funcall(delegate, id_comment, 1, Trenni_token(comment, encoding));
528
540
  }
529
- #line 129 "markup.rl"
541
+ #line 134 "markup.rl"
530
542
  {
531
543
  }
532
- #line 162 "markup.rl"
544
+ #line 167 "markup.rl"
533
545
  {
534
546
  }
535
- #line 102 "markup.rl"
547
+ #line 107 "markup.rl"
536
548
  {
537
549
  instruction.begin = p;
538
550
  }
539
- #line 88 "markup.rl"
551
+ #line 93 "markup.rl"
540
552
  {
541
553
  comment.begin = p;
542
554
  }
543
- #line 74 "markup.rl"
555
+ #line 79 "markup.rl"
544
556
  {
545
557
  doctype.begin = p;
546
558
  }
547
- #line 173 "markup.rl"
559
+ #line 178 "markup.rl"
548
560
  {
549
561
  cdata.begin = p;
550
562
  }
551
563
  goto st1;
552
564
  tr104:
553
- #line 78 "markup.rl"
565
+ #line 83 "markup.rl"
554
566
  {
555
567
  doctype.end = p;
556
568
 
557
569
  rb_funcall(delegate, id_doctype, 1, Trenni_token(doctype, encoding));
558
570
  }
559
- #line 129 "markup.rl"
571
+ #line 134 "markup.rl"
560
572
  {
561
573
  }
562
- #line 162 "markup.rl"
574
+ #line 167 "markup.rl"
563
575
  {
564
576
  }
565
- #line 102 "markup.rl"
577
+ #line 107 "markup.rl"
566
578
  {
567
579
  instruction.begin = p;
568
580
  }
569
- #line 88 "markup.rl"
581
+ #line 93 "markup.rl"
570
582
  {
571
583
  comment.begin = p;
572
584
  }
573
- #line 74 "markup.rl"
585
+ #line 79 "markup.rl"
574
586
  {
575
587
  doctype.begin = p;
576
588
  }
577
- #line 173 "markup.rl"
589
+ #line 178 "markup.rl"
578
590
  {
579
591
  cdata.begin = p;
580
592
  }
581
593
  goto st1;
582
594
  tr107:
583
- #line 177 "markup.rl"
595
+ #line 182 "markup.rl"
584
596
  {
585
597
  cdata.end = p;
586
598
 
587
599
  rb_funcall(delegate, id_cdata, 1, Trenni_token(cdata, encoding));
588
600
  }
589
- #line 129 "markup.rl"
601
+ #line 134 "markup.rl"
590
602
  {
591
603
  }
592
- #line 162 "markup.rl"
604
+ #line 167 "markup.rl"
593
605
  {
594
606
  }
595
- #line 102 "markup.rl"
607
+ #line 107 "markup.rl"
596
608
  {
597
609
  instruction.begin = p;
598
610
  }
599
- #line 88 "markup.rl"
611
+ #line 93 "markup.rl"
600
612
  {
601
613
  comment.begin = p;
602
614
  }
603
- #line 74 "markup.rl"
615
+ #line 79 "markup.rl"
604
616
  {
605
617
  doctype.begin = p;
606
618
  }
607
- #line 173 "markup.rl"
619
+ #line 178 "markup.rl"
608
620
  {
609
621
  cdata.begin = p;
610
622
  }
611
623
  goto st1;
612
624
  tr110:
613
- #line 165 "markup.rl"
625
+ #line 170 "markup.rl"
614
626
  {
615
627
  rb_funcall(delegate, id_close_tag, 2, Trenni_token(identifier, encoding), ULONG2NUM(identifier.begin-s));
616
628
  }
617
- #line 129 "markup.rl"
629
+ #line 134 "markup.rl"
618
630
  {
619
631
  }
620
- #line 162 "markup.rl"
632
+ #line 167 "markup.rl"
621
633
  {
622
634
  }
623
- #line 102 "markup.rl"
635
+ #line 107 "markup.rl"
624
636
  {
625
637
  instruction.begin = p;
626
638
  }
627
- #line 88 "markup.rl"
639
+ #line 93 "markup.rl"
628
640
  {
629
641
  comment.begin = p;
630
642
  }
631
- #line 74 "markup.rl"
643
+ #line 79 "markup.rl"
632
644
  {
633
645
  doctype.begin = p;
634
646
  }
635
- #line 173 "markup.rl"
647
+ #line 178 "markup.rl"
636
648
  {
637
649
  cdata.begin = p;
638
650
  }
639
651
  goto st1;
640
652
  tr113:
641
- #line 112 "markup.rl"
653
+ #line 117 "markup.rl"
642
654
  {
643
655
  instruction.end = p;
644
656
 
645
657
  rb_funcall(delegate, id_instruction, 1, Trenni_token(instruction, encoding));
646
658
  }
647
- #line 129 "markup.rl"
659
+ #line 134 "markup.rl"
648
660
  {
649
661
  }
650
- #line 162 "markup.rl"
662
+ #line 167 "markup.rl"
651
663
  {
652
664
  }
653
- #line 102 "markup.rl"
665
+ #line 107 "markup.rl"
654
666
  {
655
667
  instruction.begin = p;
656
668
  }
657
- #line 88 "markup.rl"
669
+ #line 93 "markup.rl"
658
670
  {
659
671
  comment.begin = p;
660
672
  }
661
- #line 74 "markup.rl"
673
+ #line 79 "markup.rl"
662
674
  {
663
675
  doctype.begin = p;
664
676
  }
665
- #line 173 "markup.rl"
677
+ #line 178 "markup.rl"
666
678
  {
667
679
  cdata.begin = p;
668
680
  }
@@ -671,7 +683,7 @@ st1:
671
683
  if ( ++p == pe )
672
684
  goto _test_eof1;
673
685
  case 1:
674
- #line 675 "markup.c"
686
+ #line 687 "markup.c"
675
687
  switch( (*p) ) {
676
688
  case 33: goto st15;
677
689
  case 47: goto st36;
@@ -691,7 +703,7 @@ case 1:
691
703
  goto tr1;
692
704
  goto tr0;
693
705
  tr0:
694
- #line 10 "markup.rl"
706
+ #line 8 "markup.rl"
695
707
  {
696
708
  identifier.begin = p;
697
709
  }
@@ -700,7 +712,7 @@ st2:
700
712
  if ( ++p == pe )
701
713
  goto _test_eof2;
702
714
  case 2:
703
- #line 704 "markup.c"
715
+ #line 716 "markup.c"
704
716
  switch( (*p) ) {
705
717
  case 32: goto tr6;
706
718
  case 47: goto tr7;
@@ -726,33 +738,33 @@ case 2:
726
738
  goto tr1;
727
739
  goto st2;
728
740
  tr1:
729
- #line 169 "markup.rl"
741
+ #line 174 "markup.rl"
730
742
  {
731
743
  Trenni_raise_error("could not parse tag", buffer, p-s);
732
744
  }
733
745
  goto st0;
734
746
  tr69:
735
- #line 118 "markup.rl"
747
+ #line 123 "markup.rl"
736
748
  {
737
749
  Trenni_raise_error("could not parse instruction", buffer, p-s);
738
750
  }
739
751
  goto st0;
740
752
  tr75:
741
- #line 42 "markup.rl"
753
+ #line 41 "markup.rl"
742
754
  {
743
755
  Trenni_raise_error("could not parse entity", buffer, p-s);
744
756
  }
745
757
  goto st0;
746
- #line 747 "markup.c"
758
+ #line 759 "markup.c"
747
759
  st0:
748
760
  cs = 0;
749
761
  goto _out;
750
762
  tr6:
751
- #line 14 "markup.rl"
763
+ #line 12 "markup.rl"
752
764
  {
753
765
  identifier.end = p;
754
766
  }
755
- #line 122 "markup.rl"
767
+ #line 127 "markup.rl"
756
768
  {
757
769
  // Reset self-closing state - we don't know yet.
758
770
  self_closing = 0;
@@ -761,14 +773,14 @@ tr6:
761
773
  }
762
774
  goto st3;
763
775
  tr14:
764
- #line 14 "markup.rl"
776
+ #line 12 "markup.rl"
765
777
  {
766
778
  identifier.end = p;
767
779
  }
768
- #line 148 "markup.rl"
780
+ #line 153 "markup.rl"
769
781
  {
770
782
  if (has_value == 1) {
771
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
783
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
772
784
  } else if (has_value == 2) {
773
785
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
774
786
  } else {
@@ -777,14 +789,14 @@ tr14:
777
789
  }
778
790
  goto st3;
779
791
  tr26:
780
- #line 140 "markup.rl"
792
+ #line 145 "markup.rl"
781
793
  {
782
794
  has_value = 1;
783
795
  }
784
- #line 148 "markup.rl"
796
+ #line 153 "markup.rl"
785
797
  {
786
798
  if (has_value == 1) {
787
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
799
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
788
800
  } else if (has_value == 2) {
789
801
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
790
802
  } else {
@@ -793,14 +805,14 @@ tr26:
793
805
  }
794
806
  goto st3;
795
807
  tr32:
796
- #line 144 "markup.rl"
808
+ #line 149 "markup.rl"
797
809
  {
798
810
  has_value = 2;
799
811
  }
800
- #line 148 "markup.rl"
812
+ #line 153 "markup.rl"
801
813
  {
802
814
  if (has_value == 1) {
803
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
815
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
804
816
  } else if (has_value == 2) {
805
817
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
806
818
  } else {
@@ -812,7 +824,7 @@ st3:
812
824
  if ( ++p == pe )
813
825
  goto _test_eof3;
814
826
  case 3:
815
- #line 816 "markup.c"
827
+ #line 828 "markup.c"
816
828
  switch( (*p) ) {
817
829
  case 32: goto st3;
818
830
  case 47: goto tr11;
@@ -838,11 +850,11 @@ case 3:
838
850
  goto tr1;
839
851
  goto tr9;
840
852
  tr9:
841
- #line 136 "markup.rl"
853
+ #line 141 "markup.rl"
842
854
  {
843
855
  has_value = 0;
844
856
  }
845
- #line 10 "markup.rl"
857
+ #line 8 "markup.rl"
846
858
  {
847
859
  identifier.begin = p;
848
860
  }
@@ -851,7 +863,7 @@ st4:
851
863
  if ( ++p == pe )
852
864
  goto _test_eof4;
853
865
  case 4:
854
- #line 855 "markup.c"
866
+ #line 867 "markup.c"
855
867
  switch( (*p) ) {
856
868
  case 32: goto tr14;
857
869
  case 47: goto tr15;
@@ -878,84 +890,84 @@ case 4:
878
890
  goto tr1;
879
891
  goto st4;
880
892
  tr7:
881
- #line 14 "markup.rl"
893
+ #line 12 "markup.rl"
882
894
  {
883
895
  identifier.end = p;
884
896
  }
885
- #line 122 "markup.rl"
897
+ #line 127 "markup.rl"
886
898
  {
887
899
  // Reset self-closing state - we don't know yet.
888
900
  self_closing = 0;
889
901
 
890
902
  rb_funcall(delegate, id_open_tag_begin, 2, Trenni_token(identifier, encoding), ULONG2NUM(identifier.begin-s));
891
903
  }
892
- #line 132 "markup.rl"
904
+ #line 137 "markup.rl"
893
905
  {
894
906
  self_closing = 1;
895
907
  }
896
908
  goto st5;
897
909
  tr11:
898
- #line 132 "markup.rl"
910
+ #line 137 "markup.rl"
899
911
  {
900
912
  self_closing = 1;
901
913
  }
902
914
  goto st5;
903
915
  tr15:
904
- #line 14 "markup.rl"
916
+ #line 12 "markup.rl"
905
917
  {
906
918
  identifier.end = p;
907
919
  }
908
- #line 148 "markup.rl"
920
+ #line 153 "markup.rl"
909
921
  {
910
922
  if (has_value == 1) {
911
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
923
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
912
924
  } else if (has_value == 2) {
913
925
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
914
926
  } else {
915
927
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Qtrue);
916
928
  }
917
929
  }
918
- #line 132 "markup.rl"
930
+ #line 137 "markup.rl"
919
931
  {
920
932
  self_closing = 1;
921
933
  }
922
934
  goto st5;
923
935
  tr27:
924
- #line 140 "markup.rl"
936
+ #line 145 "markup.rl"
925
937
  {
926
938
  has_value = 1;
927
939
  }
928
- #line 148 "markup.rl"
940
+ #line 153 "markup.rl"
929
941
  {
930
942
  if (has_value == 1) {
931
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
943
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
932
944
  } else if (has_value == 2) {
933
945
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
934
946
  } else {
935
947
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Qtrue);
936
948
  }
937
949
  }
938
- #line 132 "markup.rl"
950
+ #line 137 "markup.rl"
939
951
  {
940
952
  self_closing = 1;
941
953
  }
942
954
  goto st5;
943
955
  tr33:
944
- #line 144 "markup.rl"
956
+ #line 149 "markup.rl"
945
957
  {
946
958
  has_value = 2;
947
959
  }
948
- #line 148 "markup.rl"
960
+ #line 153 "markup.rl"
949
961
  {
950
962
  if (has_value == 1) {
951
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
963
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
952
964
  } else if (has_value == 2) {
953
965
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
954
966
  } else {
955
967
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Qtrue);
956
968
  }
957
969
  }
958
- #line 132 "markup.rl"
970
+ #line 137 "markup.rl"
959
971
  {
960
972
  self_closing = 1;
961
973
  }
@@ -964,16 +976,16 @@ st5:
964
976
  if ( ++p == pe )
965
977
  goto _test_eof5;
966
978
  case 5:
967
- #line 968 "markup.c"
979
+ #line 980 "markup.c"
968
980
  if ( (*p) == 62 )
969
981
  goto st51;
970
982
  goto tr1;
971
983
  tr8:
972
- #line 14 "markup.rl"
984
+ #line 12 "markup.rl"
973
985
  {
974
986
  identifier.end = p;
975
987
  }
976
- #line 122 "markup.rl"
988
+ #line 127 "markup.rl"
977
989
  {
978
990
  // Reset self-closing state - we don't know yet.
979
991
  self_closing = 0;
@@ -982,14 +994,14 @@ tr8:
982
994
  }
983
995
  goto st51;
984
996
  tr17:
985
- #line 14 "markup.rl"
997
+ #line 12 "markup.rl"
986
998
  {
987
999
  identifier.end = p;
988
1000
  }
989
- #line 148 "markup.rl"
1001
+ #line 153 "markup.rl"
990
1002
  {
991
1003
  if (has_value == 1) {
992
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
1004
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
993
1005
  } else if (has_value == 2) {
994
1006
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
995
1007
  } else {
@@ -998,14 +1010,14 @@ tr17:
998
1010
  }
999
1011
  goto st51;
1000
1012
  tr28:
1001
- #line 140 "markup.rl"
1013
+ #line 145 "markup.rl"
1002
1014
  {
1003
1015
  has_value = 1;
1004
1016
  }
1005
- #line 148 "markup.rl"
1017
+ #line 153 "markup.rl"
1006
1018
  {
1007
1019
  if (has_value == 1) {
1008
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
1020
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
1009
1021
  } else if (has_value == 2) {
1010
1022
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
1011
1023
  } else {
@@ -1014,14 +1026,14 @@ tr28:
1014
1026
  }
1015
1027
  goto st51;
1016
1028
  tr34:
1017
- #line 144 "markup.rl"
1029
+ #line 149 "markup.rl"
1018
1030
  {
1019
1031
  has_value = 2;
1020
1032
  }
1021
- #line 148 "markup.rl"
1033
+ #line 153 "markup.rl"
1022
1034
  {
1023
1035
  if (has_value == 1) {
1024
- rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), pcdata);
1036
+ rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), Trenni_markup_safe(pcdata, has_entities));
1025
1037
  } else if (has_value == 2) {
1026
1038
  rb_funcall(delegate, id_attribute, 2, Trenni_token(identifier, encoding), empty_string);
1027
1039
  } else {
@@ -1033,14 +1045,14 @@ st51:
1033
1045
  if ( ++p == pe )
1034
1046
  goto _test_eof51;
1035
1047
  case 51:
1036
- #line 1037 "markup.c"
1048
+ #line 1049 "markup.c"
1037
1049
  switch( (*p) ) {
1038
1050
  case 38: goto tr97;
1039
1051
  case 60: goto tr98;
1040
1052
  }
1041
1053
  goto tr96;
1042
1054
  tr16:
1043
- #line 14 "markup.rl"
1055
+ #line 12 "markup.rl"
1044
1056
  {
1045
1057
  identifier.end = p;
1046
1058
  }
@@ -1049,7 +1061,7 @@ st6:
1049
1061
  if ( ++p == pe )
1050
1062
  goto _test_eof6;
1051
1063
  case 6:
1052
- #line 1053 "markup.c"
1064
+ #line 1065 "markup.c"
1053
1065
  switch( (*p) ) {
1054
1066
  case 34: goto st7;
1055
1067
  case 39: goto st12;
@@ -1066,17 +1078,18 @@ case 7:
1066
1078
  }
1067
1079
  goto tr20;
1068
1080
  tr20:
1069
- #line 18 "markup.rl"
1081
+ #line 16 "markup.rl"
1070
1082
  {
1071
1083
  pcdata = Qnil;
1084
+ has_entities = 0;
1072
1085
  }
1073
- #line 32 "markup.rl"
1086
+ #line 31 "markup.rl"
1074
1087
  {
1075
1088
  characters.begin = p;
1076
1089
  }
1077
1090
  goto st8;
1078
1091
  tr29:
1079
- #line 32 "markup.rl"
1092
+ #line 31 "markup.rl"
1080
1093
  {
1081
1094
  characters.begin = p;
1082
1095
  }
@@ -1085,7 +1098,7 @@ st8:
1085
1098
  if ( ++p == pe )
1086
1099
  goto _test_eof8;
1087
1100
  case 8:
1088
- #line 1089 "markup.c"
1101
+ #line 1102 "markup.c"
1089
1102
  switch( (*p) ) {
1090
1103
  case 34: goto tr24;
1091
1104
  case 38: goto tr25;
@@ -1093,18 +1106,18 @@ case 8:
1093
1106
  }
1094
1107
  goto st8;
1095
1108
  tr24:
1096
- #line 36 "markup.rl"
1109
+ #line 35 "markup.rl"
1097
1110
  {
1098
1111
  characters.end = p;
1099
1112
 
1100
1113
  Trenni_append_token(&pcdata, encoding, characters);
1101
1114
  }
1102
- #line 22 "markup.rl"
1115
+ #line 21 "markup.rl"
1103
1116
  {
1104
1117
  }
1105
1118
  goto st9;
1106
1119
  tr30:
1107
- #line 22 "markup.rl"
1120
+ #line 21 "markup.rl"
1108
1121
  {
1109
1122
  }
1110
1123
  goto st9;
@@ -1112,7 +1125,7 @@ st9:
1112
1125
  if ( ++p == pe )
1113
1126
  goto _test_eof9;
1114
1127
  case 9:
1115
- #line 1116 "markup.c"
1128
+ #line 1129 "markup.c"
1116
1129
  switch( (*p) ) {
1117
1130
  case 32: goto tr26;
1118
1131
  case 47: goto tr27;
@@ -1122,32 +1135,33 @@ case 9:
1122
1135
  goto tr26;
1123
1136
  goto tr1;
1124
1137
  tr22:
1125
- #line 18 "markup.rl"
1138
+ #line 16 "markup.rl"
1126
1139
  {
1127
1140
  pcdata = Qnil;
1141
+ has_entities = 0;
1128
1142
  }
1129
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1143
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1130
1144
  {{stack[top++] = 10; goto st42;}}
1131
1145
  goto st10;
1132
1146
  tr25:
1133
- #line 36 "markup.rl"
1147
+ #line 35 "markup.rl"
1134
1148
  {
1135
1149
  characters.end = p;
1136
1150
 
1137
1151
  Trenni_append_token(&pcdata, encoding, characters);
1138
1152
  }
1139
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1153
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1140
1154
  {{stack[top++] = 10; goto st42;}}
1141
1155
  goto st10;
1142
1156
  tr31:
1143
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1157
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1144
1158
  {{stack[top++] = 10; goto st42;}}
1145
1159
  goto st10;
1146
1160
  st10:
1147
1161
  if ( ++p == pe )
1148
1162
  goto _test_eof10;
1149
1163
  case 10:
1150
- #line 1151 "markup.c"
1164
+ #line 1165 "markup.c"
1151
1165
  switch( (*p) ) {
1152
1166
  case 34: goto tr30;
1153
1167
  case 38: goto tr31;
@@ -1177,17 +1191,18 @@ case 12:
1177
1191
  }
1178
1192
  goto tr35;
1179
1193
  tr35:
1180
- #line 18 "markup.rl"
1194
+ #line 16 "markup.rl"
1181
1195
  {
1182
1196
  pcdata = Qnil;
1197
+ has_entities = 0;
1183
1198
  }
1184
- #line 32 "markup.rl"
1199
+ #line 31 "markup.rl"
1185
1200
  {
1186
1201
  characters.begin = p;
1187
1202
  }
1188
1203
  goto st13;
1189
1204
  tr39:
1190
- #line 32 "markup.rl"
1205
+ #line 31 "markup.rl"
1191
1206
  {
1192
1207
  characters.begin = p;
1193
1208
  }
@@ -1196,7 +1211,7 @@ st13:
1196
1211
  if ( ++p == pe )
1197
1212
  goto _test_eof13;
1198
1213
  case 13:
1199
- #line 1200 "markup.c"
1214
+ #line 1215 "markup.c"
1200
1215
  switch( (*p) ) {
1201
1216
  case 38: goto tr38;
1202
1217
  case 39: goto tr24;
@@ -1204,32 +1219,33 @@ case 13:
1204
1219
  }
1205
1220
  goto st13;
1206
1221
  tr36:
1207
- #line 18 "markup.rl"
1222
+ #line 16 "markup.rl"
1208
1223
  {
1209
1224
  pcdata = Qnil;
1225
+ has_entities = 0;
1210
1226
  }
1211
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1227
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1212
1228
  {{stack[top++] = 14; goto st42;}}
1213
1229
  goto st14;
1214
1230
  tr38:
1215
- #line 36 "markup.rl"
1231
+ #line 35 "markup.rl"
1216
1232
  {
1217
1233
  characters.end = p;
1218
1234
 
1219
1235
  Trenni_append_token(&pcdata, encoding, characters);
1220
1236
  }
1221
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1237
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1222
1238
  {{stack[top++] = 14; goto st42;}}
1223
1239
  goto st14;
1224
1240
  tr40:
1225
- #line 10 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1241
+ #line 10 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1226
1242
  {{stack[top++] = 14; goto st42;}}
1227
1243
  goto st14;
1228
1244
  st14:
1229
1245
  if ( ++p == pe )
1230
1246
  goto _test_eof14;
1231
1247
  case 14:
1232
- #line 1233 "markup.c"
1248
+ #line 1249 "markup.c"
1233
1249
  switch( (*p) ) {
1234
1250
  case 38: goto tr40;
1235
1251
  case 39: goto tr30;
@@ -1438,7 +1454,7 @@ case 36:
1438
1454
  goto tr1;
1439
1455
  goto tr65;
1440
1456
  tr65:
1441
- #line 10 "markup.rl"
1457
+ #line 8 "markup.rl"
1442
1458
  {
1443
1459
  identifier.begin = p;
1444
1460
  }
@@ -1447,7 +1463,7 @@ st37:
1447
1463
  if ( ++p == pe )
1448
1464
  goto _test_eof37;
1449
1465
  case 37:
1450
- #line 1451 "markup.c"
1466
+ #line 1467 "markup.c"
1451
1467
  switch( (*p) ) {
1452
1468
  case 47: goto tr1;
1453
1469
  case 62: goto tr67;
@@ -1466,7 +1482,7 @@ case 37:
1466
1482
  goto tr1;
1467
1483
  goto st37;
1468
1484
  tr67:
1469
- #line 14 "markup.rl"
1485
+ #line 12 "markup.rl"
1470
1486
  {
1471
1487
  identifier.end = p;
1472
1488
  }
@@ -1475,7 +1491,7 @@ st55:
1475
1491
  if ( ++p == pe )
1476
1492
  goto _test_eof55;
1477
1493
  case 55:
1478
- #line 1479 "markup.c"
1494
+ #line 1495 "markup.c"
1479
1495
  switch( (*p) ) {
1480
1496
  case 38: goto tr109;
1481
1497
  case 60: goto tr110;
@@ -1502,7 +1518,7 @@ case 38:
1502
1518
  goto tr69;
1503
1519
  goto tr68;
1504
1520
  tr68:
1505
- #line 10 "markup.rl"
1521
+ #line 8 "markup.rl"
1506
1522
  {
1507
1523
  identifier.begin = p;
1508
1524
  }
@@ -1511,7 +1527,7 @@ st39:
1511
1527
  if ( ++p == pe )
1512
1528
  goto _test_eof39;
1513
1529
  case 39:
1514
- #line 1515 "markup.c"
1530
+ #line 1531 "markup.c"
1515
1531
  switch( (*p) ) {
1516
1532
  case 32: goto tr71;
1517
1533
  case 47: goto tr69;
@@ -1536,11 +1552,11 @@ case 39:
1536
1552
  goto tr69;
1537
1553
  goto st39;
1538
1554
  tr71:
1539
- #line 14 "markup.rl"
1555
+ #line 12 "markup.rl"
1540
1556
  {
1541
1557
  identifier.end = p;
1542
1558
  }
1543
- #line 106 "markup.rl"
1559
+ #line 111 "markup.rl"
1544
1560
  {
1545
1561
  }
1546
1562
  goto st40;
@@ -1548,12 +1564,12 @@ st40:
1548
1564
  if ( ++p == pe )
1549
1565
  goto _test_eof40;
1550
1566
  case 40:
1551
- #line 1552 "markup.c"
1567
+ #line 1568 "markup.c"
1552
1568
  if ( (*p) == 63 )
1553
1569
  goto tr73;
1554
1570
  goto st40;
1555
1571
  tr73:
1556
- #line 109 "markup.rl"
1572
+ #line 114 "markup.rl"
1557
1573
  {
1558
1574
  }
1559
1575
  goto st41;
@@ -1561,7 +1577,7 @@ st41:
1561
1577
  if ( ++p == pe )
1562
1578
  goto _test_eof41;
1563
1579
  case 41:
1564
- #line 1565 "markup.c"
1580
+ #line 1581 "markup.c"
1565
1581
  switch( (*p) ) {
1566
1582
  case 62: goto st56;
1567
1583
  case 63: goto tr73;
@@ -1601,7 +1617,7 @@ case 43:
1601
1617
  goto tr78;
1602
1618
  goto tr75;
1603
1619
  tr78:
1604
- #line 46 "markup.rl"
1620
+ #line 45 "markup.rl"
1605
1621
  {
1606
1622
  entity.begin = p;
1607
1623
  }
@@ -1610,53 +1626,59 @@ st44:
1610
1626
  if ( ++p == pe )
1611
1627
  goto _test_eof44;
1612
1628
  case 44:
1613
- #line 1614 "markup.c"
1629
+ #line 1630 "markup.c"
1614
1630
  if ( (*p) == 59 )
1615
1631
  goto tr81;
1616
1632
  if ( 48 <= (*p) && (*p) <= 57 )
1617
1633
  goto st44;
1618
1634
  goto tr75;
1619
1635
  tr81:
1620
- #line 66 "markup.rl"
1636
+ #line 69 "markup.rl"
1621
1637
  {
1622
1638
  entity.end = p;
1623
1639
 
1640
+ has_entities = 1;
1641
+
1624
1642
  codepoint = strtoul(entity.begin, (char **)&entity.end, 10);
1625
1643
 
1626
1644
  Trenni_append_codepoint(&pcdata, encoding, codepoint);
1627
1645
  }
1628
- #line 8 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1646
+ #line 8 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1629
1647
  {{cs = stack[--top];goto _again;}}
1630
1648
  goto st57;
1631
1649
  tr84:
1632
- #line 58 "markup.rl"
1650
+ #line 59 "markup.rl"
1633
1651
  {
1634
1652
  entity.end = p;
1635
1653
 
1654
+ has_entities = 1;
1655
+
1636
1656
  codepoint = strtoul(entity.begin, (char **)&entity.end, 16);
1637
1657
 
1638
1658
  Trenni_append_codepoint(&pcdata, encoding, codepoint);
1639
1659
  }
1640
- #line 8 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1660
+ #line 8 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1641
1661
  {{cs = stack[--top];goto _again;}}
1642
1662
  goto st57;
1643
1663
  tr86:
1644
- #line 50 "markup.rl"
1664
+ #line 49 "markup.rl"
1645
1665
  {
1646
1666
  entity.end = p;
1647
1667
 
1648
- Trenni_append_string(&pcdata, encoding,
1668
+ has_entities = 1;
1669
+
1670
+ Trenni_append(&pcdata, encoding,
1649
1671
  rb_funcall(entities, id_key_get, 1, Trenni_token(entity, encoding))
1650
1672
  );
1651
1673
  }
1652
- #line 8 "/Users/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1674
+ #line 8 "/home/samuel/Documents/Programming/ioquatix/trenni/parsers/trenni/entities.rl"
1653
1675
  {{cs = stack[--top];goto _again;}}
1654
1676
  goto st57;
1655
1677
  st57:
1656
1678
  if ( ++p == pe )
1657
1679
  goto _test_eof57;
1658
1680
  case 57:
1659
- #line 1660 "markup.c"
1681
+ #line 1682 "markup.c"
1660
1682
  goto st0;
1661
1683
  st45:
1662
1684
  if ( ++p == pe )
@@ -1672,7 +1694,7 @@ case 45:
1672
1694
  goto tr82;
1673
1695
  goto tr75;
1674
1696
  tr82:
1675
- #line 46 "markup.rl"
1697
+ #line 45 "markup.rl"
1676
1698
  {
1677
1699
  entity.begin = p;
1678
1700
  }
@@ -1681,7 +1703,7 @@ st46:
1681
1703
  if ( ++p == pe )
1682
1704
  goto _test_eof46;
1683
1705
  case 46:
1684
- #line 1685 "markup.c"
1706
+ #line 1707 "markup.c"
1685
1707
  if ( (*p) == 59 )
1686
1708
  goto tr84;
1687
1709
  if ( (*p) < 65 ) {
@@ -1694,7 +1716,7 @@ case 46:
1694
1716
  goto st46;
1695
1717
  goto tr75;
1696
1718
  tr77:
1697
- #line 46 "markup.rl"
1719
+ #line 45 "markup.rl"
1698
1720
  {
1699
1721
  entity.begin = p;
1700
1722
  }
@@ -1703,7 +1725,7 @@ st47:
1703
1725
  if ( ++p == pe )
1704
1726
  goto _test_eof47;
1705
1727
  case 47:
1706
- #line 1707 "markup.c"
1728
+ #line 1729 "markup.c"
1707
1729
  if ( (*p) == 59 )
1708
1730
  goto tr86;
1709
1731
  if ( (*p) < 65 ) {
@@ -1784,13 +1806,13 @@ case 47:
1784
1806
  case 45:
1785
1807
  case 46:
1786
1808
  case 47:
1787
- #line 42 "markup.rl"
1809
+ #line 41 "markup.rl"
1788
1810
  {
1789
1811
  Trenni_raise_error("could not parse entity", buffer, p-s);
1790
1812
  }
1791
1813
  break;
1792
1814
  case 53:
1793
- #line 78 "markup.rl"
1815
+ #line 83 "markup.rl"
1794
1816
  {
1795
1817
  doctype.end = p;
1796
1818
 
@@ -1798,13 +1820,13 @@ case 47:
1798
1820
  }
1799
1821
  break;
1800
1822
  case 26:
1801
- #line 84 "markup.rl"
1823
+ #line 89 "markup.rl"
1802
1824
  {
1803
1825
  Trenni_raise_error("could not parse doctype", buffer, p-s);
1804
1826
  }
1805
1827
  break;
1806
1828
  case 52:
1807
- #line 92 "markup.rl"
1829
+ #line 97 "markup.rl"
1808
1830
  {
1809
1831
  comment.end = p;
1810
1832
 
@@ -1814,13 +1836,13 @@ case 47:
1814
1836
  case 17:
1815
1837
  case 18:
1816
1838
  case 19:
1817
- #line 98 "markup.rl"
1839
+ #line 103 "markup.rl"
1818
1840
  {
1819
1841
  Trenni_raise_error("could not parse comment", buffer, p-s);
1820
1842
  }
1821
1843
  break;
1822
1844
  case 56:
1823
- #line 112 "markup.rl"
1845
+ #line 117 "markup.rl"
1824
1846
  {
1825
1847
  instruction.end = p;
1826
1848
 
@@ -1831,19 +1853,19 @@ case 47:
1831
1853
  case 39:
1832
1854
  case 40:
1833
1855
  case 41:
1834
- #line 118 "markup.rl"
1856
+ #line 123 "markup.rl"
1835
1857
  {
1836
1858
  Trenni_raise_error("could not parse instruction", buffer, p-s);
1837
1859
  }
1838
1860
  break;
1839
1861
  case 51:
1840
- #line 158 "markup.rl"
1862
+ #line 163 "markup.rl"
1841
1863
  {
1842
1864
  rb_funcall(delegate, id_open_tag_end, 1, self_closing == 1 ? Qtrue : Qfalse);
1843
1865
  }
1844
1866
  break;
1845
1867
  case 55:
1846
- #line 165 "markup.rl"
1868
+ #line 170 "markup.rl"
1847
1869
  {
1848
1870
  rb_funcall(delegate, id_close_tag, 2, Trenni_token(identifier, encoding), ULONG2NUM(identifier.begin-s));
1849
1871
  }
@@ -1864,13 +1886,13 @@ case 47:
1864
1886
  case 14:
1865
1887
  case 36:
1866
1888
  case 37:
1867
- #line 169 "markup.rl"
1889
+ #line 174 "markup.rl"
1868
1890
  {
1869
1891
  Trenni_raise_error("could not parse tag", buffer, p-s);
1870
1892
  }
1871
1893
  break;
1872
1894
  case 54:
1873
- #line 177 "markup.rl"
1895
+ #line 182 "markup.rl"
1874
1896
  {
1875
1897
  cdata.end = p;
1876
1898
 
@@ -1880,43 +1902,43 @@ case 47:
1880
1902
  case 33:
1881
1903
  case 34:
1882
1904
  case 35:
1883
- #line 183 "markup.rl"
1905
+ #line 188 "markup.rl"
1884
1906
  {
1885
1907
  Trenni_raise_error("could not parse cdata", buffer, p-s);
1886
1908
  }
1887
1909
  break;
1888
1910
  case 50:
1889
- #line 22 "markup.rl"
1911
+ #line 21 "markup.rl"
1890
1912
  {
1891
1913
  }
1892
- #line 28 "markup.rl"
1914
+ #line 27 "markup.rl"
1893
1915
  {
1894
- rb_funcall(delegate, id_text, 1, pcdata);
1916
+ rb_funcall(delegate, id_text, 1, Trenni_markup_safe(pcdata, has_entities));
1895
1917
  }
1896
1918
  break;
1897
1919
  case 49:
1898
- #line 36 "markup.rl"
1920
+ #line 35 "markup.rl"
1899
1921
  {
1900
1922
  characters.end = p;
1901
1923
 
1902
1924
  Trenni_append_token(&pcdata, encoding, characters);
1903
1925
  }
1904
- #line 22 "markup.rl"
1926
+ #line 21 "markup.rl"
1905
1927
  {
1906
1928
  }
1907
- #line 28 "markup.rl"
1929
+ #line 27 "markup.rl"
1908
1930
  {
1909
- rb_funcall(delegate, id_text, 1, pcdata);
1931
+ rb_funcall(delegate, id_text, 1, Trenni_markup_safe(pcdata, has_entities));
1910
1932
  }
1911
1933
  break;
1912
- #line 1913 "markup.c"
1934
+ #line 1935 "markup.c"
1913
1935
  }
1914
1936
  }
1915
1937
 
1916
1938
  _out: {}
1917
1939
  }
1918
1940
 
1919
- #line 214 "markup.rl"
1941
+ #line 219 "markup.rl"
1920
1942
 
1921
1943
 
1922
1944
  if (p != eof) {