erbal 1.2.rc2 → 1.2.rc3
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.
- data/README.rdoc +38 -13
- data/ext/erbal/erbal.c +11 -7
- data/ext/erbal/parser.c +135 -97
- data/ext/erbal/parser.rl +1 -3
- data/lib/erbal/rails.rb +8 -16
- data/spec/erbal_spec.rb +27 -0
- data/tasks/gem.rake +1 -1
- metadata +4 -4
data/README.rdoc
CHANGED
|
@@ -15,10 +15,14 @@ Erbal is a lightweight ERB parser that uses the Ragel State Machine Compiler (ht
|
|
|
15
15
|
Erbal.new takes an optional 2nd argument which is a hash of options, available options are:
|
|
16
16
|
|
|
17
17
|
* <b>:buffer</b> - The name of the output buffer. Default is '@output_buffer'.
|
|
18
|
+
|
|
18
19
|
* <b>:buffer_initial_value</b> - The initial value of the output buffer. Default is a blank string.
|
|
19
|
-
|
|
20
|
+
|
|
20
21
|
* <b>:unsafe_concat_method</b> - The method to call on the buffer when concatenating a string which DOES need escaping, i.e <%= some_method %> will result in the use of unsafe_concat_method. Default is 'concat'.
|
|
21
|
-
|
|
22
|
+
|
|
23
|
+
* <b>:safe_concat_method</b> - The method to call on the buffer when concatenating a string which doesn't need escaping, i.e text outside of ERB tags (your raw HTML) uses the safe concatenation method. Default is 'concat'.
|
|
24
|
+
|
|
25
|
+
* <b>:safe_concat_keyword</b> - By default the '<%=' tag uses the unsafe_concat_method, with this option you can specify a keyword to signify that the safe_concat_method should be used instead. For example if safe_concat_method is set to 'raw' then <%= raw some_method %> will result in a concatenation using the safe_concat_method. Be mindful that even thought the 'raw' keyword looks like a method call, it isn't. Erbal expects that the key is followed by one or more spaces, so a tag like '<%= raw(some_method) %>' will not be recognised by Erbal. Whitespace before the keyword is optional, so '<%=raw' is valid. The keyword can either be one or more a-z characters, or a single of the following: ! @ $ * = ^ & +. For example, given :safe_concat_keyword => '!' then the following is valid: '<%=! some_method %>'. Default is blank, i.e no keyword is specified.
|
|
22
26
|
|
|
23
27
|
<b>NOTE: Erbal itself does NOT perform escaping, it is the responsibility of your unsafe_concat_method to escape the string passed to it.</b>
|
|
24
28
|
|
|
@@ -28,6 +32,27 @@ Create the file 'config/initializers/erbal.rb' containing:
|
|
|
28
32
|
|
|
29
33
|
require 'erbal/rails'
|
|
30
34
|
|
|
35
|
+
=== Rails 2.3 + rails_xss (https://github.com/rails/rails_xss)
|
|
36
|
+
|
|
37
|
+
If you're using the rails_xss plugin, use this in your initialiser instead:
|
|
38
|
+
|
|
39
|
+
require 'erbal'
|
|
40
|
+
|
|
41
|
+
class ErbalTemplateHandler < ActionView::TemplateHandler
|
|
42
|
+
include ActionView::TemplateHandlers::Compilable
|
|
43
|
+
def compile(template)
|
|
44
|
+
::Erbal.new("<% __in_erb_template=true %>#{template.source}",
|
|
45
|
+
{:buffer => '@output_buffer',
|
|
46
|
+
:buffer_initial_value => 'ActiveSupport::SafeBuffer.new',
|
|
47
|
+
:safe_concat_method => 'safe_concat',
|
|
48
|
+
:unsafe_concat_method => 'concat',
|
|
49
|
+
:safe_concat_keyword => 'raw'}
|
|
50
|
+
).parse
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
ActionView::Template.register_template_handler :erb, ErbalTemplateHandler
|
|
55
|
+
|
|
31
56
|
== Rails 3
|
|
32
57
|
|
|
33
58
|
I've not looked into yet.. patches are welcome! ;)
|
|
@@ -43,37 +68,37 @@ Erubis: 2.6.6
|
|
|
43
68
|
Erbal: 1.1
|
|
44
69
|
|
|
45
70
|
=> Parsing Benchmark
|
|
46
|
-
|
|
71
|
+
|
|
47
72
|
=> Erb
|
|
48
73
|
0.851 0.853 0.848 0.847 0.849 0.847
|
|
49
74
|
=> Average: 0.849
|
|
50
|
-
|
|
75
|
+
|
|
51
76
|
=> Erubis (using FastEruby engine)
|
|
52
77
|
0.442 0.442 0.444 0.442 0.441 0.442
|
|
53
78
|
=> Average: 0.442
|
|
54
|
-
|
|
79
|
+
|
|
55
80
|
=> Erubis (using default Eruby engine)
|
|
56
81
|
0.451 0.424 0.446 0.425 0.445 0.446
|
|
57
82
|
=> Average: 0.439
|
|
58
|
-
|
|
83
|
+
|
|
59
84
|
=> Erbal
|
|
60
85
|
0.036 0.039 0.066 0.038 0.067 0.039
|
|
61
86
|
=> Average: 0.047
|
|
62
|
-
|
|
87
|
+
|
|
63
88
|
=> eval() Benchmark
|
|
64
|
-
|
|
89
|
+
|
|
65
90
|
=> Erb
|
|
66
91
|
0.203 0.192 0.180 0.180 0.179 0.191
|
|
67
92
|
=> Average: 0.187
|
|
68
|
-
|
|
93
|
+
|
|
69
94
|
=> Erubis (using FastEruby engine)
|
|
70
95
|
0.129 0.127 0.128 0.128 0.114 0.128
|
|
71
96
|
=> Average: 0.125
|
|
72
|
-
|
|
97
|
+
|
|
73
98
|
=> Erubis (using default Eruby engine)
|
|
74
99
|
0.178 0.176 0.165 0.176 0.175 0.164
|
|
75
100
|
=> Average: 0.172
|
|
76
|
-
|
|
101
|
+
|
|
77
102
|
=> Erbal
|
|
78
103
|
0.111 0.125 0.124 0.110 0.133 0.124
|
|
79
104
|
=> Average: 0.121
|
|
@@ -89,6 +114,6 @@ Erbal: 1.1
|
|
|
89
114
|
|
|
90
115
|
Many thanks to Adrian Thurston for writing the Ragel State Machine Compiler (http://www.complang.org/ragel/)!
|
|
91
116
|
|
|
92
|
-
==
|
|
117
|
+
== Copyrigh
|
|
93
118
|
|
|
94
|
-
Copyright (c) 2010 Envato & Ian Leitch. See LICENSE for details.
|
|
119
|
+
Copyright (c) 2010-2011 Envato & Ian Leitch. See LICENSE for details.
|
data/ext/erbal/erbal.c
CHANGED
|
@@ -7,11 +7,21 @@ void rb_erbal_free(erbal_parser *parser) {
|
|
|
7
7
|
free(parser->state);
|
|
8
8
|
free(parser);
|
|
9
9
|
}
|
|
10
|
+
void rb_erbal_mark(erbal_parser *parser) {
|
|
11
|
+
rb_gc_mark_maybe(parser->str);
|
|
12
|
+
rb_gc_mark_maybe(parser->src);
|
|
13
|
+
rb_gc_mark_maybe(parser->buffer_name);
|
|
14
|
+
rb_gc_mark_maybe(parser->options);
|
|
15
|
+
rb_gc_mark_maybe(parser->safe_concat_method);
|
|
16
|
+
rb_gc_mark_maybe(parser->unsafe_concat_method);
|
|
17
|
+
rb_gc_mark_maybe(parser->keyword);
|
|
18
|
+
rb_gc_mark_maybe(parser->safe_concat_keyword);
|
|
19
|
+
}
|
|
10
20
|
|
|
11
21
|
VALUE rb_erbal_alloc(VALUE klass) {
|
|
12
22
|
erbal_parser *parser = ALLOC(erbal_parser);
|
|
13
23
|
parser->state = ALLOC(parser_state);
|
|
14
|
-
VALUE obj = Data_Wrap_Struct(klass,
|
|
24
|
+
VALUE obj = Data_Wrap_Struct(klass, rb_erbal_mark, rb_erbal_free, parser);
|
|
15
25
|
return obj;
|
|
16
26
|
}
|
|
17
27
|
|
|
@@ -24,10 +34,6 @@ void rb_erbal_setup_option(VALUE self, erbal_parser* parser, VALUE* parser_optio
|
|
|
24
34
|
} else {
|
|
25
35
|
*(parser_option) = rb_str_new2(default_value);
|
|
26
36
|
}
|
|
27
|
-
|
|
28
|
-
VALUE ivar = rb_str_new2("@");
|
|
29
|
-
ivar = rb_str_cat2(ivar, key);
|
|
30
|
-
rb_iv_set(self, RSTRING(ivar)->ptr, *(parser_option));
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
VALUE rb_erbal_initialize(int argc, VALUE *argv, VALUE self) {
|
|
@@ -48,8 +54,6 @@ VALUE rb_erbal_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
48
54
|
parser->options = options;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
rb_iv_set(self, "@options", parser->options);
|
|
52
|
-
|
|
53
57
|
if (rb_hash_aref(parser->options, ID2SYM(rb_intern("debug"))) == Qtrue) {
|
|
54
58
|
parser->debug = 1;
|
|
55
59
|
} else {
|
data/ext/erbal/parser.c
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
#line 12 "parser.c"
|
|
12
|
-
static const int erbal_parser_start =
|
|
13
|
-
static const int erbal_parser_first_final =
|
|
12
|
+
static const int erbal_parser_start = 4;
|
|
13
|
+
static const int erbal_parser_first_final = 4;
|
|
14
14
|
static const int erbal_parser_error = -1;
|
|
15
15
|
|
|
16
|
-
static const int erbal_parser_en_main =
|
|
16
|
+
static const int erbal_parser_en_main = 4;
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
#line 34 "parser.rl"
|
|
@@ -227,8 +227,6 @@ void erbal_parser_init(VALUE self, erbal_parser *parser) {
|
|
|
227
227
|
|
|
228
228
|
parser->src = rb_str_dup(parser->buffer_name);
|
|
229
229
|
|
|
230
|
-
rb_iv_set(self, "@src", parser->src);
|
|
231
|
-
|
|
232
230
|
VALUE buffer_init_val = rb_hash_aref(parser->options, ID2SYM(rb_intern("buffer_initial_value")));
|
|
233
231
|
|
|
234
232
|
if (!NIL_P(buffer_init_val)) {
|
|
@@ -241,7 +239,7 @@ void erbal_parser_init(VALUE self, erbal_parser *parser) {
|
|
|
241
239
|
}
|
|
242
240
|
|
|
243
241
|
|
|
244
|
-
#line
|
|
242
|
+
#line 243 "parser.c"
|
|
245
243
|
{
|
|
246
244
|
cs = erbal_parser_start;
|
|
247
245
|
ts = 0;
|
|
@@ -249,14 +247,14 @@ void erbal_parser_init(VALUE self, erbal_parser *parser) {
|
|
|
249
247
|
act = 0;
|
|
250
248
|
}
|
|
251
249
|
|
|
252
|
-
#line
|
|
250
|
+
#line 256 "parser.rl"
|
|
253
251
|
}
|
|
254
252
|
|
|
255
253
|
void erbal_parser_exec(erbal_parser *parser) {
|
|
256
254
|
p = RSTRING(parser->str)->ptr;
|
|
257
255
|
pe = p + strlen(p);
|
|
258
256
|
|
|
259
|
-
#line
|
|
257
|
+
#line 258 "parser.c"
|
|
260
258
|
{
|
|
261
259
|
if ( p == pe )
|
|
262
260
|
goto _test_eof;
|
|
@@ -265,83 +263,83 @@ void erbal_parser_exec(erbal_parser *parser) {
|
|
|
265
263
|
tr0:
|
|
266
264
|
#line 23 "parser.rl"
|
|
267
265
|
{{p = ((te))-1;}{ erbal_parser_non_tag(parser); }}
|
|
268
|
-
goto
|
|
266
|
+
goto st4;
|
|
269
267
|
tr1:
|
|
270
268
|
#line 21 "parser.rl"
|
|
271
269
|
{te = p+1;{ erbal_parser_tag_close_with_trim(parser); }}
|
|
272
|
-
goto
|
|
270
|
+
goto st4;
|
|
273
271
|
tr2:
|
|
274
272
|
#line 20 "parser.rl"
|
|
275
273
|
{{p = ((te))-1;}{ erbal_parser_tag_open_for_unsafe_concat(parser); }}
|
|
276
|
-
goto
|
|
277
|
-
|
|
274
|
+
goto st4;
|
|
275
|
+
tr8:
|
|
278
276
|
#line 23 "parser.rl"
|
|
279
277
|
{te = p+1;{ erbal_parser_non_tag(parser); }}
|
|
280
|
-
goto
|
|
281
|
-
|
|
278
|
+
goto st4;
|
|
279
|
+
tr12:
|
|
282
280
|
#line 23 "parser.rl"
|
|
283
281
|
{te = p;p--;{ erbal_parser_non_tag(parser); }}
|
|
284
|
-
goto
|
|
285
|
-
|
|
282
|
+
goto st4;
|
|
283
|
+
tr13:
|
|
286
284
|
#line 22 "parser.rl"
|
|
287
285
|
{te = p+1;{ erbal_parser_tag_close(parser); }}
|
|
288
|
-
goto
|
|
289
|
-
|
|
286
|
+
goto st4;
|
|
287
|
+
tr16:
|
|
290
288
|
#line 17 "parser.rl"
|
|
291
289
|
{te = p;p--;{ erbal_parser_tag_open(parser); }}
|
|
292
|
-
goto
|
|
293
|
-
|
|
290
|
+
goto st4;
|
|
291
|
+
tr17:
|
|
294
292
|
#line 19 "parser.rl"
|
|
295
293
|
{te = p+1;{ erbal_parser_tag_open_for_comment(parser); }}
|
|
296
|
-
goto
|
|
297
|
-
|
|
294
|
+
goto st4;
|
|
295
|
+
tr18:
|
|
298
296
|
#line 18 "parser.rl"
|
|
299
297
|
{te = p+1;{ erbal_parser_tag_open_with_dash(parser); }}
|
|
300
|
-
goto
|
|
301
|
-
|
|
298
|
+
goto st4;
|
|
299
|
+
tr20:
|
|
302
300
|
#line 20 "parser.rl"
|
|
303
301
|
{te = p;p--;{ erbal_parser_tag_open_for_unsafe_concat(parser); }}
|
|
304
|
-
goto
|
|
305
|
-
|
|
302
|
+
goto st4;
|
|
303
|
+
tr24:
|
|
306
304
|
#line 9 "parser.rl"
|
|
307
305
|
{ parser->keyword_trailing_whitespace = p; }
|
|
308
306
|
#line 29 "parser.rl"
|
|
309
307
|
{te = p;p--;{ erbal_parser_tag_open_choose_concat(parser); }}
|
|
310
|
-
goto
|
|
311
|
-
|
|
308
|
+
goto st4;
|
|
309
|
+
st4:
|
|
312
310
|
#line 1 "NONE"
|
|
313
311
|
{ts = 0;}
|
|
314
312
|
if ( ++p == pe )
|
|
315
|
-
goto
|
|
316
|
-
case
|
|
313
|
+
goto _test_eof4;
|
|
314
|
+
case 4:
|
|
317
315
|
#line 1 "NONE"
|
|
318
316
|
{ts = p;}
|
|
319
|
-
#line
|
|
317
|
+
#line 318 "parser.c"
|
|
320
318
|
switch( (*p) ) {
|
|
321
|
-
case 37: goto
|
|
322
|
-
case 45: goto
|
|
323
|
-
case 60: goto
|
|
319
|
+
case 37: goto st5;
|
|
320
|
+
case 45: goto tr10;
|
|
321
|
+
case 60: goto st7;
|
|
324
322
|
}
|
|
325
|
-
goto
|
|
326
|
-
|
|
323
|
+
goto tr8;
|
|
324
|
+
st5:
|
|
327
325
|
if ( ++p == pe )
|
|
328
|
-
goto
|
|
329
|
-
case
|
|
326
|
+
goto _test_eof5;
|
|
327
|
+
case 5:
|
|
330
328
|
if ( (*p) == 62 )
|
|
331
|
-
goto
|
|
332
|
-
goto
|
|
333
|
-
|
|
329
|
+
goto tr13;
|
|
330
|
+
goto tr12;
|
|
331
|
+
tr10:
|
|
334
332
|
#line 1 "NONE"
|
|
335
333
|
{te = p+1;}
|
|
336
|
-
goto
|
|
337
|
-
|
|
334
|
+
goto st6;
|
|
335
|
+
st6:
|
|
338
336
|
if ( ++p == pe )
|
|
339
|
-
goto
|
|
340
|
-
case
|
|
341
|
-
#line
|
|
337
|
+
goto _test_eof6;
|
|
338
|
+
case 6:
|
|
339
|
+
#line 340 "parser.c"
|
|
342
340
|
if ( (*p) == 37 )
|
|
343
341
|
goto st0;
|
|
344
|
-
goto
|
|
342
|
+
goto tr12;
|
|
345
343
|
st0:
|
|
346
344
|
if ( ++p == pe )
|
|
347
345
|
goto _test_eof0;
|
|
@@ -349,38 +347,48 @@ case 0:
|
|
|
349
347
|
if ( (*p) == 62 )
|
|
350
348
|
goto tr1;
|
|
351
349
|
goto tr0;
|
|
352
|
-
st6:
|
|
353
|
-
if ( ++p == pe )
|
|
354
|
-
goto _test_eof6;
|
|
355
|
-
case 6:
|
|
356
|
-
if ( (*p) == 37 )
|
|
357
|
-
goto st7;
|
|
358
|
-
goto tr11;
|
|
359
350
|
st7:
|
|
360
351
|
if ( ++p == pe )
|
|
361
352
|
goto _test_eof7;
|
|
362
353
|
case 7:
|
|
354
|
+
if ( (*p) == 37 )
|
|
355
|
+
goto st8;
|
|
356
|
+
goto tr12;
|
|
357
|
+
st8:
|
|
358
|
+
if ( ++p == pe )
|
|
359
|
+
goto _test_eof8;
|
|
360
|
+
case 8:
|
|
363
361
|
switch( (*p) ) {
|
|
364
|
-
case 35: goto
|
|
365
|
-
case 45: goto
|
|
366
|
-
case 61: goto
|
|
362
|
+
case 35: goto tr17;
|
|
363
|
+
case 45: goto tr18;
|
|
364
|
+
case 61: goto tr19;
|
|
367
365
|
}
|
|
368
|
-
goto
|
|
369
|
-
|
|
366
|
+
goto tr16;
|
|
367
|
+
tr19:
|
|
370
368
|
#line 1 "NONE"
|
|
371
369
|
{te = p+1;}
|
|
372
|
-
goto
|
|
373
|
-
|
|
370
|
+
goto st9;
|
|
371
|
+
st9:
|
|
374
372
|
if ( ++p == pe )
|
|
375
|
-
goto
|
|
376
|
-
case
|
|
377
|
-
#line
|
|
378
|
-
|
|
379
|
-
goto
|
|
380
|
-
|
|
381
|
-
goto
|
|
382
|
-
|
|
383
|
-
|
|
373
|
+
goto _test_eof9;
|
|
374
|
+
case 9:
|
|
375
|
+
#line 376 "parser.c"
|
|
376
|
+
switch( (*p) ) {
|
|
377
|
+
case 32: goto tr21;
|
|
378
|
+
case 33: goto tr22;
|
|
379
|
+
case 36: goto tr22;
|
|
380
|
+
case 38: goto tr22;
|
|
381
|
+
case 61: goto tr22;
|
|
382
|
+
case 64: goto tr22;
|
|
383
|
+
case 94: goto tr22;
|
|
384
|
+
}
|
|
385
|
+
if ( (*p) > 43 ) {
|
|
386
|
+
if ( 97 <= (*p) && (*p) <= 122 )
|
|
387
|
+
goto tr23;
|
|
388
|
+
} else if ( (*p) >= 42 )
|
|
389
|
+
goto tr22;
|
|
390
|
+
goto tr20;
|
|
391
|
+
tr21:
|
|
384
392
|
#line 8 "parser.rl"
|
|
385
393
|
{ parser->keyword_preceding_whitespace = p; }
|
|
386
394
|
goto st1;
|
|
@@ -388,17 +396,27 @@ st1:
|
|
|
388
396
|
if ( ++p == pe )
|
|
389
397
|
goto _test_eof1;
|
|
390
398
|
case 1:
|
|
391
|
-
#line
|
|
392
|
-
|
|
393
|
-
goto st1;
|
|
394
|
-
|
|
399
|
+
#line 400 "parser.c"
|
|
400
|
+
switch( (*p) ) {
|
|
401
|
+
case 32: goto st1;
|
|
402
|
+
case 33: goto tr4;
|
|
403
|
+
case 36: goto tr4;
|
|
404
|
+
case 38: goto tr4;
|
|
405
|
+
case 61: goto tr4;
|
|
406
|
+
case 64: goto tr4;
|
|
407
|
+
case 94: goto tr4;
|
|
408
|
+
}
|
|
409
|
+
if ( (*p) > 43 ) {
|
|
410
|
+
if ( 97 <= (*p) && (*p) <= 122 )
|
|
411
|
+
goto tr5;
|
|
412
|
+
} else if ( (*p) >= 42 )
|
|
395
413
|
goto tr4;
|
|
396
414
|
goto tr2;
|
|
397
415
|
tr4:
|
|
398
416
|
#line 7 "parser.rl"
|
|
399
417
|
{ parser->keyword_start = p; }
|
|
400
418
|
goto st2;
|
|
401
|
-
|
|
419
|
+
tr22:
|
|
402
420
|
#line 8 "parser.rl"
|
|
403
421
|
{ parser->keyword_preceding_whitespace = p; }
|
|
404
422
|
#line 7 "parser.rl"
|
|
@@ -408,57 +426,77 @@ st2:
|
|
|
408
426
|
if ( ++p == pe )
|
|
409
427
|
goto _test_eof2;
|
|
410
428
|
case 2:
|
|
411
|
-
#line
|
|
429
|
+
#line 430 "parser.c"
|
|
412
430
|
if ( (*p) == 32 )
|
|
413
|
-
goto
|
|
414
|
-
if ( 97 <= (*p) && (*p) <= 122 )
|
|
415
|
-
goto st2;
|
|
431
|
+
goto tr6;
|
|
416
432
|
goto tr2;
|
|
417
|
-
|
|
433
|
+
tr6:
|
|
418
434
|
#line 11 "parser.rl"
|
|
419
435
|
{
|
|
420
436
|
parser->keyword_end = p;
|
|
421
437
|
parser->keyword = rb_str_new(parser->keyword_start, (p - parser->keyword_start));
|
|
422
438
|
}
|
|
423
|
-
goto
|
|
424
|
-
|
|
439
|
+
goto st10;
|
|
440
|
+
st10:
|
|
425
441
|
if ( ++p == pe )
|
|
426
|
-
goto
|
|
427
|
-
case
|
|
428
|
-
#line
|
|
442
|
+
goto _test_eof10;
|
|
443
|
+
case 10:
|
|
444
|
+
#line 445 "parser.c"
|
|
445
|
+
if ( (*p) == 32 )
|
|
446
|
+
goto st10;
|
|
447
|
+
goto tr24;
|
|
448
|
+
tr5:
|
|
449
|
+
#line 7 "parser.rl"
|
|
450
|
+
{ parser->keyword_start = p; }
|
|
451
|
+
goto st3;
|
|
452
|
+
tr23:
|
|
453
|
+
#line 8 "parser.rl"
|
|
454
|
+
{ parser->keyword_preceding_whitespace = p; }
|
|
455
|
+
#line 7 "parser.rl"
|
|
456
|
+
{ parser->keyword_start = p; }
|
|
457
|
+
goto st3;
|
|
458
|
+
st3:
|
|
459
|
+
if ( ++p == pe )
|
|
460
|
+
goto _test_eof3;
|
|
461
|
+
case 3:
|
|
462
|
+
#line 463 "parser.c"
|
|
429
463
|
if ( (*p) == 32 )
|
|
430
|
-
goto
|
|
431
|
-
|
|
464
|
+
goto tr6;
|
|
465
|
+
if ( 97 <= (*p) && (*p) <= 122 )
|
|
466
|
+
goto st3;
|
|
467
|
+
goto tr2;
|
|
432
468
|
}
|
|
433
|
-
_test_eof3: cs = 3; goto _test_eof;
|
|
434
469
|
_test_eof4: cs = 4; goto _test_eof;
|
|
435
470
|
_test_eof5: cs = 5; goto _test_eof;
|
|
436
|
-
_test_eof0: cs = 0; goto _test_eof;
|
|
437
471
|
_test_eof6: cs = 6; goto _test_eof;
|
|
472
|
+
_test_eof0: cs = 0; goto _test_eof;
|
|
438
473
|
_test_eof7: cs = 7; goto _test_eof;
|
|
439
474
|
_test_eof8: cs = 8; goto _test_eof;
|
|
475
|
+
_test_eof9: cs = 9; goto _test_eof;
|
|
440
476
|
_test_eof1: cs = 1; goto _test_eof;
|
|
441
477
|
_test_eof2: cs = 2; goto _test_eof;
|
|
442
|
-
|
|
478
|
+
_test_eof10: cs = 10; goto _test_eof;
|
|
479
|
+
_test_eof3: cs = 3; goto _test_eof;
|
|
443
480
|
|
|
444
481
|
_test_eof: {}
|
|
445
482
|
if ( p == eof )
|
|
446
483
|
{
|
|
447
484
|
switch ( cs ) {
|
|
448
|
-
case
|
|
449
|
-
case
|
|
485
|
+
case 5: goto tr12;
|
|
486
|
+
case 6: goto tr12;
|
|
450
487
|
case 0: goto tr0;
|
|
451
|
-
case
|
|
452
|
-
case
|
|
453
|
-
case
|
|
488
|
+
case 7: goto tr12;
|
|
489
|
+
case 8: goto tr16;
|
|
490
|
+
case 9: goto tr20;
|
|
454
491
|
case 1: goto tr2;
|
|
455
492
|
case 2: goto tr2;
|
|
456
|
-
case
|
|
493
|
+
case 10: goto tr24;
|
|
494
|
+
case 3: goto tr2;
|
|
457
495
|
}
|
|
458
496
|
}
|
|
459
497
|
|
|
460
498
|
}
|
|
461
499
|
|
|
462
|
-
#line
|
|
500
|
+
#line 262 "parser.rl"
|
|
463
501
|
erbal_parser_finish(parser);
|
|
464
502
|
}
|
data/ext/erbal/parser.rl
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
'<%=' (
|
|
26
26
|
[ ]* >keyword_preceding_whitespace
|
|
27
|
-
[a-z]
|
|
27
|
+
([a-z]+|[!@$*=^&+]{1,1}) >keyword_start %keyword_end
|
|
28
28
|
[ ]+ %keyword_trailing_whitespace
|
|
29
29
|
) => { erbal_parser_tag_open_choose_concat(parser); };
|
|
30
30
|
*|;
|
|
@@ -241,8 +241,6 @@ void erbal_parser_init(VALUE self, erbal_parser *parser) {
|
|
|
241
241
|
|
|
242
242
|
parser->src = rb_str_dup(parser->buffer_name);
|
|
243
243
|
|
|
244
|
-
rb_iv_set(self, "@src", parser->src);
|
|
245
|
-
|
|
246
244
|
VALUE buffer_init_val = rb_hash_aref(parser->options, ID2SYM(rb_intern("buffer_initial_value")));
|
|
247
245
|
|
|
248
246
|
if (!NIL_P(buffer_init_val)) {
|
data/lib/erbal/rails.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
require 'action_pack'
|
|
1
2
|
require 'erbal'
|
|
2
3
|
|
|
3
4
|
class Erbal
|
|
4
5
|
module Rails
|
|
5
|
-
class
|
|
6
|
+
class Rails_2_3_TemplateHandler < ActionView::TemplateHandler
|
|
6
7
|
include ActionView::TemplateHandlers::Compilable
|
|
7
8
|
def compile(template)
|
|
8
|
-
::Erbal.new("<% __in_erb_template=true %>#{template.source}", {:buffer => '@output_buffer'
|
|
9
|
-
:safe_concat_method => 'safe_concat', :unsafe_concat_method => 'concat', :safe_concat_keyword => 'raw'}).parse
|
|
9
|
+
::Erbal.new("<% __in_erb_template=true %>#{template.source}", {:buffer => '@output_buffer'}).parse
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -14,12 +14,9 @@ class Erbal
|
|
|
14
14
|
raise "Sorry, this version of Erbal doesn't support Rails #{ActionPack::VERSION::MAJOR}.#{ActionPack::VERSION::MINOR}.#{ActionPack::VERSION::TINY}."
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def self.
|
|
18
|
-
ActionView::Template.register_template_handler :erb,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def self.register_template_handler_for_2_3_10
|
|
22
|
-
register_template_handler(Rails_2_3_10_TemplateHandler)
|
|
17
|
+
def self.register_template_handler_for_2_3
|
|
18
|
+
ActionView::Template.register_template_handler :erb, Rails_2_3_TemplateHandler
|
|
19
|
+
ActionView::Template.register_template_handler :rhtml, Rails_2_3_TemplateHandler
|
|
23
20
|
end
|
|
24
21
|
end
|
|
25
22
|
end
|
|
@@ -28,15 +25,10 @@ case ActionPack::VERSION::MAJOR
|
|
|
28
25
|
when 2
|
|
29
26
|
case ActionPack::VERSION::MINOR
|
|
30
27
|
when 3
|
|
31
|
-
|
|
32
|
-
when 10
|
|
33
|
-
Erbal::Rails.register_template_handler_for_2_3_10
|
|
34
|
-
else
|
|
35
|
-
Erbal::Rails.version_unsupported
|
|
36
|
-
end
|
|
28
|
+
Erbal::Rails.register_template_handler_for_2_3
|
|
37
29
|
else
|
|
38
30
|
Erbal::Rails.version_unsupported
|
|
39
31
|
end
|
|
40
32
|
else
|
|
41
33
|
Erbal::Rails.version_unsupported
|
|
42
|
-
end
|
|
34
|
+
end
|
data/spec/erbal_spec.rb
CHANGED
|
@@ -144,6 +144,25 @@ describe Erbal do
|
|
|
144
144
|
erbal_parse("1 + 1 is <%= raw 1 + 1 %>", :unsafe_concat_method => 'unsafe_concat', :safe_concat_keyword => nil).should == "@output_buffer = '';@output_buffer.concat(%Q`1 + 1 is `);@output_buffer.unsafe_concat(%Q`\#{ raw 1 + 1 }`);@output_buffer"
|
|
145
145
|
end
|
|
146
146
|
|
|
147
|
+
it "should allow a non a-z character as the safe_concat_keyword" do
|
|
148
|
+
erbal_parse("<%=! 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '!').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
149
|
+
erbal_parse("<%=@ 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '@').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
150
|
+
erbal_parse("<%=$ 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '$').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
151
|
+
erbal_parse("<%=* 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '*').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
152
|
+
erbal_parse("<%== 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '=').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
153
|
+
erbal_parse("<%=^ 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '^').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
154
|
+
erbal_parse("<%=& 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '&').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
155
|
+
erbal_parse("<%=+ 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => '+').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should not allow more than a single non a-z character as the safe_concat_keyword" do
|
|
159
|
+
erbal_parse("<%=!= 1 + 1 %>", :unsafe_concat_method => 'unsafe_concat', :safe_concat_keyword => '!=').should == "@output_buffer = '';@output_buffer.unsafe_concat(%Q`\#{!= 1 + 1 }`);@output_buffer"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "should not allow a mix of a-z and non a-z characters as the safe_concat_keyword" do
|
|
163
|
+
erbal_parse("<%=!raw 1 + 1 %>", :unsafe_concat_method => 'unsafe_concat', :safe_concat_keyword => '!raw').should == "@output_buffer = '';@output_buffer.unsafe_concat(%Q`\#{!raw 1 + 1 }`);@output_buffer"
|
|
164
|
+
end
|
|
165
|
+
|
|
147
166
|
it "should preserve the whitespace following the safe_concat_keyword" do
|
|
148
167
|
erbal_parse("<%= raw 1 + 1 %>", :safe_concat_method => 'safe_concat', :safe_concat_keyword => 'raw').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`\#{ 1 + 1 }`);@output_buffer"
|
|
149
168
|
end
|
|
@@ -160,6 +179,10 @@ describe Erbal do
|
|
|
160
179
|
erbal_parse("omglololo <%=blah 1 + 1 %>", :unsafe_concat_method => 'unsafe_concat').should == "@output_buffer = '';@output_buffer.concat(%Q`omglololo `);@output_buffer.unsafe_concat(%Q`\#{blah 1 + 1 }`);@output_buffer"
|
|
161
180
|
end
|
|
162
181
|
|
|
182
|
+
it "should not use the safe concat method if the it is used as a helper method call" do
|
|
183
|
+
erbal_parse("<%= raw(1 + 1) %>", :unsafe_concat_method => 'unsafe_concat', :safe_concat_keyword => 'raw').should == "@output_buffer = '';@output_buffer.unsafe_concat(%Q`\#{ raw(1 + 1) }`);@output_buffer"
|
|
184
|
+
end
|
|
185
|
+
|
|
163
186
|
it "should end the current safe concat and begin a new unsafe concat" do
|
|
164
187
|
erbal_parse("hello <%= \"world\" %>", :unsafe_concat_method => 'unsafe_concat', :safe_concat_method => 'safe_concat').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`hello `);@output_buffer.unsafe_concat(%Q`\#{ \"world\" }`);@output_buffer"
|
|
165
188
|
end
|
|
@@ -188,6 +211,10 @@ describe Erbal do
|
|
|
188
211
|
it "should use interpolation if we switch from an unsafe concat to a safe concat and then back again" do
|
|
189
212
|
erbal_parse("omg <%= \"hello\" %> world", :unsafe_concat_method => 'concat', :safe_concat_method => 'concat').should == "@output_buffer = '';@output_buffer.concat(%Q`omg \#{ \"hello\" } world`);@output_buffer"
|
|
190
213
|
end
|
|
214
|
+
|
|
215
|
+
it "should not use interpolation if the unsafe and safe concat methods are not the same" do
|
|
216
|
+
erbal_parse("omg <%= raw \"hello\" %> world", :unsafe_concat_method => 'concat', :safe_concat_method => 'safe_concat').should == "@output_buffer = '';@output_buffer.safe_concat(%Q`omg `);@output_buffer.concat(%Q`\#{ raw \"hello\" }`);@output_buffer.safe_concat(%Q` world`);@output_buffer"
|
|
217
|
+
end
|
|
191
218
|
end
|
|
192
219
|
end
|
|
193
220
|
end
|
data/tasks/gem.rake
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: erbal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 977940508
|
|
5
5
|
prerelease: true
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
8
|
- 2
|
|
9
|
-
-
|
|
10
|
-
version: 1.2.
|
|
9
|
+
- rc3
|
|
10
|
+
version: 1.2.rc3
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Ian Leitch
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2011-01-
|
|
18
|
+
date: 2011-01-08 00:00:00 +11:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies: []
|
|
21
21
|
|