hamlit 2.9.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +45 -0
  4. data/CHANGELOG.md +666 -0
  5. data/Gemfile +28 -0
  6. data/LICENSE.txt +44 -0
  7. data/README.md +146 -0
  8. data/REFERENCE.md +266 -0
  9. data/Rakefile +117 -0
  10. data/benchmark/boolean_attribute.haml +6 -0
  11. data/benchmark/class_attribute.haml +5 -0
  12. data/benchmark/common_attribute.haml +3 -0
  13. data/benchmark/data_attribute.haml +4 -0
  14. data/benchmark/dynamic_attributes/boolean_attribute.haml +4 -0
  15. data/benchmark/dynamic_attributes/class_attribute.haml +4 -0
  16. data/benchmark/dynamic_attributes/common_attribute.haml +2 -0
  17. data/benchmark/dynamic_attributes/data_attribute.haml +2 -0
  18. data/benchmark/dynamic_attributes/id_attribute.haml +2 -0
  19. data/benchmark/dynamic_boolean_attribute.haml +4 -0
  20. data/benchmark/etc/attribute_builder.haml +5 -0
  21. data/benchmark/etc/real_sample.haml +888 -0
  22. data/benchmark/etc/real_sample.rb +11 -0
  23. data/benchmark/etc/static_analyzer.haml +1 -0
  24. data/benchmark/etc/string_interpolation.haml +2 -0
  25. data/benchmark/etc/tags.haml +3 -0
  26. data/benchmark/etc/tags_loop.haml +2 -0
  27. data/benchmark/ext/build_data.rb +17 -0
  28. data/benchmark/ext/build_id.rb +13 -0
  29. data/benchmark/id_attribute.haml +3 -0
  30. data/benchmark/plain.haml +4 -0
  31. data/benchmark/script.haml +4 -0
  32. data/benchmark/slim/LICENSE +21 -0
  33. data/benchmark/slim/context.rb +11 -0
  34. data/benchmark/slim/run-benchmarks.rb +94 -0
  35. data/benchmark/slim/view.erb +23 -0
  36. data/benchmark/slim/view.haml +18 -0
  37. data/benchmark/slim/view.slim +17 -0
  38. data/benchmark/utils/benchmark_ips_extension.rb +43 -0
  39. data/bin/bench +77 -0
  40. data/bin/console +11 -0
  41. data/bin/ruby +3 -0
  42. data/bin/setup +7 -0
  43. data/bin/stackprof +27 -0
  44. data/bin/test +24 -0
  45. data/exe/hamlit +6 -0
  46. data/ext/hamlit/extconf.rb +10 -0
  47. data/ext/hamlit/hamlit.c +553 -0
  48. data/ext/hamlit/hescape.c +108 -0
  49. data/ext/hamlit/hescape.h +20 -0
  50. data/hamlit.gemspec +45 -0
  51. data/lib/hamlit.rb +11 -0
  52. data/lib/hamlit/attribute_builder.rb +173 -0
  53. data/lib/hamlit/attribute_compiler.rb +123 -0
  54. data/lib/hamlit/attribute_parser.rb +110 -0
  55. data/lib/hamlit/cli.rb +130 -0
  56. data/lib/hamlit/compiler.rb +97 -0
  57. data/lib/hamlit/compiler/children_compiler.rb +112 -0
  58. data/lib/hamlit/compiler/comment_compiler.rb +36 -0
  59. data/lib/hamlit/compiler/doctype_compiler.rb +46 -0
  60. data/lib/hamlit/compiler/script_compiler.rb +101 -0
  61. data/lib/hamlit/compiler/silent_script_compiler.rb +24 -0
  62. data/lib/hamlit/compiler/tag_compiler.rb +74 -0
  63. data/lib/hamlit/engine.rb +37 -0
  64. data/lib/hamlit/error.rb +15 -0
  65. data/lib/hamlit/escapable.rb +13 -0
  66. data/lib/hamlit/filters.rb +75 -0
  67. data/lib/hamlit/filters/base.rb +12 -0
  68. data/lib/hamlit/filters/cdata.rb +20 -0
  69. data/lib/hamlit/filters/coffee.rb +17 -0
  70. data/lib/hamlit/filters/css.rb +33 -0
  71. data/lib/hamlit/filters/erb.rb +10 -0
  72. data/lib/hamlit/filters/escaped.rb +22 -0
  73. data/lib/hamlit/filters/javascript.rb +33 -0
  74. data/lib/hamlit/filters/less.rb +20 -0
  75. data/lib/hamlit/filters/markdown.rb +10 -0
  76. data/lib/hamlit/filters/plain.rb +29 -0
  77. data/lib/hamlit/filters/preserve.rb +22 -0
  78. data/lib/hamlit/filters/ruby.rb +10 -0
  79. data/lib/hamlit/filters/sass.rb +15 -0
  80. data/lib/hamlit/filters/scss.rb +15 -0
  81. data/lib/hamlit/filters/text_base.rb +25 -0
  82. data/lib/hamlit/filters/tilt_base.rb +49 -0
  83. data/lib/hamlit/force_escapable.rb +29 -0
  84. data/lib/hamlit/helpers.rb +15 -0
  85. data/lib/hamlit/html.rb +14 -0
  86. data/lib/hamlit/identity.rb +13 -0
  87. data/lib/hamlit/object_ref.rb +30 -0
  88. data/lib/hamlit/parser.rb +49 -0
  89. data/lib/hamlit/parser/MIT-LICENSE +20 -0
  90. data/lib/hamlit/parser/README.md +30 -0
  91. data/lib/hamlit/parser/haml_buffer.rb +348 -0
  92. data/lib/hamlit/parser/haml_compiler.rb +553 -0
  93. data/lib/hamlit/parser/haml_error.rb +61 -0
  94. data/lib/hamlit/parser/haml_helpers.rb +727 -0
  95. data/lib/hamlit/parser/haml_options.rb +286 -0
  96. data/lib/hamlit/parser/haml_parser.rb +800 -0
  97. data/lib/hamlit/parser/haml_util.rb +288 -0
  98. data/lib/hamlit/parser/haml_xss_mods.rb +109 -0
  99. data/lib/hamlit/rails_helpers.rb +51 -0
  100. data/lib/hamlit/rails_template.rb +58 -0
  101. data/lib/hamlit/railtie.rb +10 -0
  102. data/lib/hamlit/ruby_expression.rb +32 -0
  103. data/lib/hamlit/string_splitter.rb +88 -0
  104. data/lib/hamlit/template.rb +28 -0
  105. data/lib/hamlit/utils.rb +18 -0
  106. data/lib/hamlit/version.rb +4 -0
  107. metadata +360 -0
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+
3
+ VERSIONS=(
4
+ 2.1.10
5
+ 2.2.5
6
+ 2.3.1
7
+ )
8
+
9
+ set -e
10
+ trap 'echo "${VERSIONS[2]}" > .ruby-version' 0
11
+
12
+ function test_with() {
13
+ version=$1
14
+ rbenv local $version
15
+ if ! bundle check > /dev/null; then
16
+ bundle install
17
+ fi
18
+ ruby -v
19
+ bundle exec rake test
20
+ }
21
+
22
+ for version in ${VERSIONS[@]}; do
23
+ test_with $version
24
+ done
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'hamlit/cli'
5
+
6
+ Hamlit::CLI.start(ARGV)
@@ -0,0 +1,10 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << ' -Wall -Wextra'
4
+
5
+ $srcs = %w[
6
+ hamlit.c
7
+ hescape.c
8
+ ]
9
+
10
+ create_makefile('hamlit/hamlit')
@@ -0,0 +1,553 @@
1
+ #include <ruby.h>
2
+ #include <ruby/encoding.h>
3
+ #include "hescape.h"
4
+ #include "string.h"
5
+
6
+ VALUE mAttributeBuilder, mObjectRef;
7
+ static ID id_flatten, id_keys, id_parse, id_prepend, id_tr, id_uniq_bang;
8
+ static ID id_aria, id_data, id_equal, id_hyphen, id_space, id_underscore;
9
+ static ID id_boolean_attributes, id_xhtml;
10
+
11
+ static VALUE str_aria() { return rb_const_get(mAttributeBuilder, id_aria); }
12
+ static VALUE str_data() { return rb_const_get(mAttributeBuilder, id_data); }
13
+ static VALUE str_equal() { return rb_const_get(mAttributeBuilder, id_equal); }
14
+ static VALUE str_hyphen() { return rb_const_get(mAttributeBuilder, id_hyphen); }
15
+ static VALUE str_space() { return rb_const_get(mAttributeBuilder, id_space); }
16
+ static VALUE str_underscore() { return rb_const_get(mAttributeBuilder, id_underscore); }
17
+
18
+ static void
19
+ delete_falsey_values(VALUE values)
20
+ {
21
+ VALUE value;
22
+ long i;
23
+
24
+ for (i = RARRAY_LEN(values) - 1; 0 <= i; i--) {
25
+ value = rb_ary_entry(values, i);
26
+ if (!RTEST(value)) {
27
+ rb_ary_delete_at(values, i);
28
+ }
29
+ }
30
+ }
31
+
32
+ static int
33
+ str_eq(VALUE str, const char *cstr, long n)
34
+ {
35
+ return RSTRING_LEN(str) == n && memcmp(RSTRING_PTR(str), cstr, n) == 0;
36
+ }
37
+
38
+ static VALUE
39
+ to_s(VALUE value)
40
+ {
41
+ return rb_convert_type(value, T_STRING, "String", "to_s");
42
+ }
43
+
44
+ static VALUE
45
+ hyphenate(VALUE str)
46
+ {
47
+ long i;
48
+
49
+ if (OBJ_FROZEN(str)) str = rb_str_dup(str);
50
+
51
+ for (i = 0; i < RSTRING_LEN(str); i++) {
52
+ if (RSTRING_PTR(str)[i] == '_') {
53
+ rb_str_update(str, i, 1, str_hyphen());
54
+ }
55
+ }
56
+ return str;
57
+ }
58
+
59
+ static VALUE
60
+ escape_html(VALUE str)
61
+ {
62
+ char *buf;
63
+ unsigned int size;
64
+ Check_Type(str, T_STRING);
65
+
66
+ size = hesc_escape_html(&buf, RSTRING_PTR(str), RSTRING_LEN(str));
67
+ if (size > RSTRING_LEN(str)) {
68
+ str = rb_enc_str_new(buf, size, rb_utf8_encoding());
69
+ free((void *)buf);
70
+ }
71
+
72
+ return str;
73
+ }
74
+
75
+ static VALUE
76
+ escape_attribute(VALUE escape_attrs, VALUE str)
77
+ {
78
+ if (RTEST(escape_attrs)) {
79
+ return escape_html(str);
80
+ } else {
81
+ return str;
82
+ }
83
+ }
84
+
85
+ static VALUE
86
+ rb_escape_html(RB_UNUSED_VAR(VALUE self), VALUE value)
87
+ {
88
+ return escape_html(to_s(value));
89
+ }
90
+
91
+ static VALUE
92
+ hamlit_build_id(VALUE escape_attrs, VALUE values)
93
+ {
94
+ VALUE attr_value;
95
+
96
+ values = rb_funcall(values, id_flatten, 0);
97
+ delete_falsey_values(values);
98
+
99
+ attr_value = rb_ary_join(values, str_underscore());
100
+ return escape_attribute(escape_attrs, attr_value);
101
+ }
102
+
103
+ static VALUE
104
+ hamlit_build_single_class(VALUE escape_attrs, VALUE value)
105
+ {
106
+ switch (TYPE(value)) {
107
+ case T_STRING:
108
+ break;
109
+ case T_ARRAY:
110
+ value = rb_funcall(value, id_flatten, 0);
111
+ delete_falsey_values(value);
112
+ value = rb_ary_join(value, str_space());
113
+ break;
114
+ default:
115
+ if (RTEST(value)) {
116
+ value = to_s(value);
117
+ } else {
118
+ return rb_str_new_cstr("");
119
+ }
120
+ break;
121
+ }
122
+ return escape_attribute(escape_attrs, value);
123
+ }
124
+
125
+ static VALUE
126
+ hamlit_build_multi_class(VALUE escape_attrs, VALUE values)
127
+ {
128
+ long i, j;
129
+ VALUE value, buf;
130
+
131
+ buf = rb_ary_new2(RARRAY_LEN(values));
132
+
133
+ for (i = 0; i < RARRAY_LEN(values); i++) {
134
+ value = rb_ary_entry(values, i);
135
+ switch (TYPE(value)) {
136
+ case T_STRING:
137
+ rb_ary_concat(buf, rb_str_split(value, " "));
138
+ break;
139
+ case T_ARRAY:
140
+ value = rb_funcall(value, id_flatten, 0);
141
+ delete_falsey_values(value);
142
+ for (j = 0; j < RARRAY_LEN(value); j++) {
143
+ rb_ary_push(buf, to_s(rb_ary_entry(value, j)));
144
+ }
145
+ break;
146
+ default:
147
+ if (RTEST(value)) {
148
+ rb_ary_push(buf, to_s(value));
149
+ }
150
+ break;
151
+ }
152
+ }
153
+
154
+ rb_ary_sort_bang(buf);
155
+ rb_funcall(buf, id_uniq_bang, 0);
156
+
157
+ return escape_attribute(escape_attrs, rb_ary_join(buf, str_space()));
158
+ }
159
+
160
+ static VALUE
161
+ hamlit_build_class(VALUE escape_attrs, VALUE array)
162
+ {
163
+ if (RARRAY_LEN(array) == 1) {
164
+ return hamlit_build_single_class(escape_attrs, rb_ary_entry(array, 0));
165
+ } else {
166
+ return hamlit_build_multi_class(escape_attrs, array);
167
+ }
168
+ }
169
+
170
+ struct merge_data_attrs_var {
171
+ VALUE merged;
172
+ VALUE key_str;
173
+ };
174
+
175
+ static int
176
+ merge_data_attrs_i(VALUE key, VALUE value, VALUE ptr)
177
+ {
178
+ struct merge_data_attrs_var *arg = (struct merge_data_attrs_var *)ptr;
179
+ VALUE merged = arg->merged;
180
+ VALUE key_str = arg->key_str;
181
+
182
+ if (NIL_P(key)) {
183
+ rb_hash_aset(merged, key_str, value);
184
+ } else {
185
+ key = rb_str_concat(rb_str_concat(rb_str_dup(key_str), rb_str_new_cstr("-")), to_s(key));
186
+ rb_hash_aset(merged, key, value);
187
+ }
188
+ return ST_CONTINUE;
189
+ }
190
+
191
+ static VALUE
192
+ merge_data_attrs(VALUE values, VALUE key_str)
193
+ {
194
+ long i;
195
+ VALUE value, merged = rb_hash_new();
196
+
197
+ for (i = 0; i < RARRAY_LEN(values); i++) {
198
+ struct merge_data_attrs_var arg;
199
+ arg.merged = merged;
200
+ arg.key_str = key_str;
201
+
202
+ value = rb_ary_entry(values, i);
203
+ switch (TYPE(value)) {
204
+ case T_HASH:
205
+ rb_hash_foreach(value, merge_data_attrs_i, (VALUE)&arg);
206
+ break;
207
+ default:
208
+ rb_hash_aset(merged, key_str, value);
209
+ break;
210
+ }
211
+ }
212
+ return merged;
213
+ }
214
+
215
+ struct flatten_data_attrs_i2_arg {
216
+ VALUE flattened;
217
+ VALUE key;
218
+ };
219
+
220
+ static int
221
+ flatten_data_attrs_i2(VALUE k, VALUE v, VALUE ptr)
222
+ {
223
+ VALUE key;
224
+ struct flatten_data_attrs_i2_arg *arg = (struct flatten_data_attrs_i2_arg *)ptr;
225
+
226
+ if (!RTEST(v)) return ST_CONTINUE;
227
+
228
+ if (k == Qnil) {
229
+ rb_hash_aset(arg->flattened, arg->key, v);
230
+ } else {
231
+ key = rb_str_dup(arg->key);
232
+ rb_str_cat(key, "-", 1);
233
+ rb_str_concat(key, to_s(k));
234
+
235
+ rb_hash_aset(arg->flattened, key, v);
236
+ }
237
+ return ST_CONTINUE;
238
+ }
239
+
240
+ static VALUE flatten_data_attrs(VALUE attrs);
241
+
242
+ static int
243
+ flatten_data_attrs_i(VALUE key, VALUE value, VALUE flattened)
244
+ {
245
+ struct flatten_data_attrs_i2_arg arg;
246
+ key = hyphenate(to_s(key));
247
+
248
+ switch (TYPE(value)) {
249
+ case T_HASH:
250
+ value = flatten_data_attrs(value);
251
+ arg.key = key;
252
+ arg.flattened = flattened;
253
+ rb_hash_foreach(value, flatten_data_attrs_i2, (VALUE)(&arg));
254
+ break;
255
+ default:
256
+ if (RTEST(value)) rb_hash_aset(flattened, key, value);
257
+ break;
258
+ }
259
+ return ST_CONTINUE;
260
+ }
261
+
262
+ static VALUE
263
+ flatten_data_attrs(VALUE attrs)
264
+ {
265
+ VALUE flattened = rb_hash_new();
266
+ rb_hash_foreach(attrs, flatten_data_attrs_i, flattened);
267
+
268
+ return flattened;
269
+ }
270
+
271
+ static VALUE
272
+ hamlit_build_data(VALUE escape_attrs, VALUE quote, VALUE values, VALUE key_str)
273
+ {
274
+ long i;
275
+ VALUE attrs, buf, keys, key, value;
276
+
277
+ attrs = merge_data_attrs(values, key_str);
278
+ attrs = flatten_data_attrs(attrs);
279
+ keys = rb_ary_sort_bang(rb_funcall(attrs, id_keys, 0));
280
+ buf = rb_str_new("", 0);
281
+
282
+ for (i = 0; i < RARRAY_LEN(keys); i++) {
283
+ key = rb_ary_entry(keys, i);
284
+ value = rb_hash_aref(attrs, key);
285
+
286
+ switch (value) {
287
+ case Qtrue:
288
+ rb_str_concat(buf, str_space());
289
+ rb_str_concat(buf, key);
290
+ break;
291
+ case Qnil:
292
+ break; // noop
293
+ case Qfalse:
294
+ break; // noop
295
+ default:
296
+ rb_str_concat(buf, str_space());
297
+ rb_str_concat(buf, key);
298
+ rb_str_concat(buf, str_equal());
299
+ rb_str_concat(buf, quote);
300
+ rb_str_concat(buf, escape_attribute(escape_attrs, to_s(value)));
301
+ rb_str_concat(buf, quote);
302
+ break;
303
+ }
304
+ }
305
+
306
+ return buf;
307
+ }
308
+
309
+ static VALUE
310
+ parse_object_ref(VALUE object_ref)
311
+ {
312
+ return rb_funcall(mObjectRef, id_parse, 1, object_ref);
313
+ }
314
+
315
+ static int
316
+ merge_all_attrs_i(VALUE key, VALUE value, VALUE merged)
317
+ {
318
+ VALUE array;
319
+
320
+ key = to_s(key);
321
+ if (str_eq(key, "id", 2) || str_eq(key, "class", 5) || str_eq(key, "data", 4) || str_eq(key, "aria", 4)) {
322
+ array = rb_hash_aref(merged, key);
323
+ if (NIL_P(array)) {
324
+ array = rb_ary_new2(1);
325
+ rb_hash_aset(merged, key, array);
326
+ }
327
+ rb_ary_push(array, value);
328
+ } else {
329
+ rb_hash_aset(merged, key, value);
330
+ }
331
+ return ST_CONTINUE;
332
+ }
333
+
334
+ static VALUE
335
+ merge_all_attrs(VALUE hashes)
336
+ {
337
+ long i;
338
+ VALUE hash, merged = rb_hash_new();
339
+
340
+ for (i = 0; i < RARRAY_LEN(hashes); i++) {
341
+ hash = rb_ary_entry(hashes, i);
342
+ if (!RB_TYPE_P(hash, T_HASH)) {
343
+ rb_raise(rb_eArgError, "Non-hash object is given to attributes!");
344
+ }
345
+ rb_hash_foreach(hash, merge_all_attrs_i, merged);
346
+ }
347
+ return merged;
348
+ }
349
+
350
+ int
351
+ is_boolean_attribute(VALUE key)
352
+ {
353
+ VALUE boolean_attributes;
354
+ if (str_eq(rb_str_substr(key, 0, 5), "data-", 5)) return 1;
355
+ if (str_eq(rb_str_substr(key, 0, 5), "aria-", 5)) return 1;
356
+
357
+ boolean_attributes = rb_const_get(mAttributeBuilder, id_boolean_attributes);
358
+ return RTEST(rb_ary_includes(boolean_attributes, key));
359
+ }
360
+
361
+ void
362
+ hamlit_build_for_id(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
363
+ {
364
+ rb_str_cat(buf, " id=", 4);
365
+ rb_str_concat(buf, quote);
366
+ rb_str_concat(buf, hamlit_build_id(escape_attrs, values));
367
+ rb_str_concat(buf, quote);
368
+ }
369
+
370
+ void
371
+ hamlit_build_for_class(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
372
+ {
373
+ rb_str_cat(buf, " class=", 7);
374
+ rb_str_concat(buf, quote);
375
+ rb_str_concat(buf, hamlit_build_class(escape_attrs, values));
376
+ rb_str_concat(buf, quote);
377
+ }
378
+
379
+ void
380
+ hamlit_build_for_data(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
381
+ {
382
+ rb_str_concat(buf, hamlit_build_data(escape_attrs, quote, values, str_data()));
383
+ }
384
+
385
+ void
386
+ hamlit_build_for_aria(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
387
+ {
388
+ rb_str_concat(buf, hamlit_build_data(escape_attrs, quote, values, str_aria()));
389
+ }
390
+
391
+ void
392
+ hamlit_build_for_others(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE key, VALUE value)
393
+ {
394
+ rb_str_cat(buf, " ", 1);
395
+ rb_str_concat(buf, key);
396
+ rb_str_cat(buf, "=", 1);
397
+ rb_str_concat(buf, quote);
398
+ rb_str_concat(buf, escape_attribute(escape_attrs, to_s(value)));
399
+ rb_str_concat(buf, quote);
400
+ }
401
+
402
+ void
403
+ hamlit_build_for_boolean(VALUE escape_attrs, VALUE quote, VALUE format, VALUE buf, VALUE key, VALUE value)
404
+ {
405
+ switch (value) {
406
+ case Qtrue:
407
+ rb_str_cat(buf, " ", 1);
408
+ rb_str_concat(buf, key);
409
+ if ((TYPE(format) == T_SYMBOL || TYPE(format) == T_STRING) && rb_to_id(format) == id_xhtml) {
410
+ rb_str_cat(buf, "=", 1);
411
+ rb_str_concat(buf, quote);
412
+ rb_str_concat(buf, key);
413
+ rb_str_concat(buf, quote);
414
+ }
415
+ break;
416
+ case Qfalse:
417
+ break; // noop
418
+ case Qnil:
419
+ break; // noop
420
+ default:
421
+ hamlit_build_for_others(escape_attrs, quote, buf, key, value);
422
+ break;
423
+ }
424
+ }
425
+
426
+ static VALUE
427
+ hamlit_build(VALUE escape_attrs, VALUE quote, VALUE format, VALUE object_ref, VALUE hashes)
428
+ {
429
+ long i;
430
+ VALUE attrs, buf, key, keys, value;
431
+
432
+ if (!NIL_P(object_ref)) rb_ary_push(hashes, parse_object_ref(object_ref));
433
+ attrs = merge_all_attrs(hashes);
434
+ buf = rb_str_new("", 0);
435
+ keys = rb_ary_sort_bang(rb_funcall(attrs, id_keys, 0));
436
+
437
+ for (i = 0; i < RARRAY_LEN(keys); i++) {
438
+ key = rb_ary_entry(keys, i);
439
+ value = rb_hash_aref(attrs, key);
440
+ if (str_eq(key, "id", 2)) {
441
+ hamlit_build_for_id(escape_attrs, quote, buf, value);
442
+ } else if (str_eq(key, "class", 5)) {
443
+ hamlit_build_for_class(escape_attrs, quote, buf, value);
444
+ } else if (str_eq(key, "data", 4)) {
445
+ hamlit_build_for_data(escape_attrs, quote, buf, value);
446
+ } else if (str_eq(key, "aria", 4)) {
447
+ hamlit_build_for_aria(escape_attrs, quote, buf, value);
448
+ } else if (is_boolean_attribute(key)) {
449
+ hamlit_build_for_boolean(escape_attrs, quote, format, buf, key, value);
450
+ } else {
451
+ hamlit_build_for_others(escape_attrs, quote, buf, key, value);
452
+ }
453
+ }
454
+
455
+ return buf;
456
+ }
457
+
458
+ static VALUE
459
+ rb_hamlit_build_id(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
460
+ {
461
+ VALUE array;
462
+
463
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
464
+ rb_scan_args(argc - 1, argv + 1, "*", &array);
465
+
466
+ return hamlit_build_id(argv[0], array);
467
+ }
468
+
469
+ static VALUE
470
+ rb_hamlit_build_class(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
471
+ {
472
+ VALUE array;
473
+
474
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
475
+ rb_scan_args(argc - 1, argv + 1, "*", &array);
476
+
477
+ return hamlit_build_class(argv[0], array);
478
+ }
479
+
480
+ static VALUE
481
+ rb_hamlit_build_aria(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
482
+ {
483
+ VALUE array;
484
+
485
+ rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
486
+ rb_scan_args(argc - 2, argv + 2, "*", &array);
487
+
488
+ return hamlit_build_data(argv[0], argv[1], array, str_aria());
489
+ }
490
+
491
+ static VALUE
492
+ rb_hamlit_build_data(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
493
+ {
494
+ VALUE array;
495
+
496
+ rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
497
+ rb_scan_args(argc - 2, argv + 2, "*", &array);
498
+
499
+ return hamlit_build_data(argv[0], argv[1], array, str_data());
500
+ }
501
+
502
+ static VALUE
503
+ rb_hamlit_build(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
504
+ {
505
+ VALUE array;
506
+
507
+ rb_check_arity(argc, 4, UNLIMITED_ARGUMENTS);
508
+ rb_scan_args(argc - 4, argv + 4, "*", &array);
509
+
510
+ return hamlit_build(argv[0], argv[1], argv[2], argv[3], array);
511
+ }
512
+
513
+ void
514
+ Init_hamlit(void)
515
+ {
516
+ VALUE mHamlit, mUtils;
517
+
518
+ mHamlit = rb_define_module("Hamlit");
519
+ mObjectRef = rb_define_module_under(mHamlit, "ObjectRef");
520
+ mUtils = rb_define_module_under(mHamlit, "Utils");
521
+ mAttributeBuilder = rb_define_module_under(mHamlit, "AttributeBuilder");
522
+
523
+ rb_define_singleton_method(mUtils, "escape_html", rb_escape_html, 1);
524
+ rb_define_singleton_method(mAttributeBuilder, "build", rb_hamlit_build, -1);
525
+ rb_define_singleton_method(mAttributeBuilder, "build_id", rb_hamlit_build_id, -1);
526
+ rb_define_singleton_method(mAttributeBuilder, "build_class", rb_hamlit_build_class, -1);
527
+ rb_define_singleton_method(mAttributeBuilder, "build_aria", rb_hamlit_build_aria, -1);
528
+ rb_define_singleton_method(mAttributeBuilder, "build_data", rb_hamlit_build_data, -1);
529
+
530
+ id_flatten = rb_intern("flatten");
531
+ id_keys = rb_intern("keys");
532
+ id_parse = rb_intern("parse");
533
+ id_prepend = rb_intern("prepend");
534
+ id_tr = rb_intern("tr");
535
+ id_uniq_bang = rb_intern("uniq!");
536
+
537
+ id_aria = rb_intern("ARIA");
538
+ id_data = rb_intern("DATA");
539
+ id_equal = rb_intern("EQUAL");
540
+ id_hyphen = rb_intern("HYPHEN");
541
+ id_space = rb_intern("SPACE");
542
+ id_underscore = rb_intern("UNDERSCORE");
543
+
544
+ id_boolean_attributes = rb_intern("BOOLEAN_ATTRIBUTES");
545
+ id_xhtml = rb_intern("xhtml");
546
+
547
+ rb_const_set(mAttributeBuilder, id_aria, rb_obj_freeze(rb_str_new_cstr("aria")));
548
+ rb_const_set(mAttributeBuilder, id_data, rb_obj_freeze(rb_str_new_cstr("data")));
549
+ rb_const_set(mAttributeBuilder, id_equal, rb_obj_freeze(rb_str_new_cstr("=")));
550
+ rb_const_set(mAttributeBuilder, id_hyphen, rb_obj_freeze(rb_str_new_cstr("-")));
551
+ rb_const_set(mAttributeBuilder, id_space, rb_obj_freeze(rb_str_new_cstr(" ")));
552
+ rb_const_set(mAttributeBuilder, id_underscore, rb_obj_freeze(rb_str_new_cstr("_")));
553
+ }