berns 4.1.2 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{README.org → README.md} +98 -90
- data/ext/berns/berns.c +589 -583
- data/ext/berns/strxcat.c +20 -0
- data/ext/berns/strxcat.h +11 -0
- data/ext/berns/strxcpy.c +50 -0
- data/ext/berns/strxcpy.h +32 -0
- data/ext/berns/strxempty.c +9 -0
- data/ext/berns/strxempty.h +9 -0
- data/ext/berns/strxfree.c +6 -0
- data/ext/berns/strxfree.h +9 -0
- data/ext/berns/strxnew.c +8 -0
- data/ext/berns/strxnew.h +11 -0
- data/ext/berns/strxresize.c +6 -0
- data/ext/berns/strxresize.h +10 -0
- data/lib/berns/berns.bundle +0 -0
- data/lib/berns/version.rb +1 -1
- metadata +17 -5
data/ext/berns/berns.c
CHANGED
@@ -1,5 +1,13 @@
|
|
1
|
-
#include
|
1
|
+
#include <stdbool.h>
|
2
|
+
|
2
3
|
#include "hescape.h"
|
4
|
+
#include "ruby.h"
|
5
|
+
#include "strxcat.h"
|
6
|
+
#include "strxcpy.h"
|
7
|
+
#include "strxempty.h"
|
8
|
+
#include "strxfree.h"
|
9
|
+
#include "strxnew.h"
|
10
|
+
#include "strxresize.h"
|
3
11
|
|
4
12
|
static const char *attr_close = "\"";
|
5
13
|
static const size_t attr_clen = 1;
|
@@ -28,576 +36,574 @@ static const size_t sllen = 1;
|
|
28
36
|
* content.
|
29
37
|
*/
|
30
38
|
#define CONTENT_FROM_BLOCK \
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
VALUE content; \
|
40
|
+
\
|
41
|
+
if (rb_block_given_p()) { \
|
42
|
+
content = rb_yield(Qnil); \
|
43
|
+
\
|
44
|
+
if (TYPE(content) == T_NIL || TYPE(content) == T_FALSE) { \
|
45
|
+
content = rb_utf8_str_new_cstr(""); \
|
46
|
+
} else if (TYPE(content) != T_STRING) { \
|
47
|
+
content = rb_funcall(content, rb_intern("to_s"), 0); \
|
48
|
+
} \
|
49
|
+
} else { \
|
50
|
+
content = rb_utf8_str_new_cstr(""); \
|
51
|
+
}
|
44
52
|
|
45
53
|
/*
|
46
54
|
* Macro to define a "dynamic" function that generates a void element.
|
47
55
|
*/
|
48
56
|
#define VOID_ELEMENT(element_name) \
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
static VALUE external_##element_name##_element(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self)) { \
|
58
|
+
rb_check_arity(argc, 0, 1); \
|
59
|
+
\
|
60
|
+
const char *tag = #element_name; \
|
61
|
+
char *string; \
|
62
|
+
\
|
63
|
+
if (argc == 1) { \
|
64
|
+
string = void_element_with_attributes(tag, strlen(tag), argv[0]); \
|
65
|
+
} else { \
|
66
|
+
string = void_element_without_attributes(tag, strlen(tag)); \
|
67
|
+
} \
|
68
|
+
VALUE rstring = rb_utf8_str_new_cstr(string); \
|
69
|
+
strxfree(string); \
|
70
|
+
\
|
71
|
+
return rstring; \
|
72
|
+
}
|
59
73
|
|
60
74
|
/*
|
61
75
|
* Macro to define a "dynamic" function that generates a standard element.
|
62
76
|
*/
|
63
77
|
#define STANDARD_ELEMENT(element_name) \
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
if (end) {
|
82
|
-
end--;
|
83
|
-
}
|
84
|
-
|
85
|
-
while (*source && destination < end) {
|
86
|
-
*destination++ = *source++;
|
87
|
-
}
|
88
|
-
|
89
|
-
if (destination) {
|
90
|
-
*destination = '\0';
|
91
|
-
}
|
92
|
-
|
93
|
-
return destination;
|
94
|
-
}
|
78
|
+
static VALUE external_##element_name##_element(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self)) { \
|
79
|
+
rb_check_arity(argc, 0, 1); \
|
80
|
+
\
|
81
|
+
CONTENT_FROM_BLOCK \
|
82
|
+
const char *tag = #element_name; \
|
83
|
+
char *string; \
|
84
|
+
\
|
85
|
+
if (argc == 1) { \
|
86
|
+
string = element_with_attributes(tag, strlen(tag), RSTRING_PTR(content), RSTRING_LEN(content), argv[0]); \
|
87
|
+
} else { \
|
88
|
+
string = element_without_attributes(tag, strlen(tag), RSTRING_PTR(content), RSTRING_LEN(content)); \
|
89
|
+
} \
|
90
|
+
VALUE rstring = rb_utf8_str_new_cstr(string); \
|
91
|
+
strxfree(string); \
|
92
|
+
\
|
93
|
+
return rstring; \
|
94
|
+
}
|
95
95
|
|
96
96
|
/*
|
97
97
|
* The external API for Berns.sanitize
|
98
98
|
*
|
99
|
-
*
|
99
|
+
* string should be a string or nil, anything else will raise an error.
|
100
100
|
*
|
101
101
|
*/
|
102
102
|
static VALUE external_sanitize(RB_UNUSED_VAR(VALUE self), VALUE string) {
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
103
|
+
if (TYPE(string) == T_NIL) {
|
104
|
+
return Qnil;
|
105
|
+
}
|
106
|
+
|
107
|
+
StringValue(string);
|
108
|
+
|
109
|
+
size_t slen = RSTRING_LEN(string);
|
110
|
+
char *str = RSTRING_PTR(string);
|
111
|
+
|
112
|
+
char dest[slen + 1];
|
113
|
+
|
114
|
+
bool entity = false;
|
115
|
+
bool modified = false;
|
116
|
+
bool open = false;
|
117
|
+
unsigned int index = 0;
|
118
|
+
|
119
|
+
for (unsigned int i = 0; i < slen; i++) {
|
120
|
+
switch(str[i]) {
|
121
|
+
case '<':
|
122
|
+
open = true;
|
123
|
+
modified = true;
|
124
|
+
break;
|
125
|
+
case '>':
|
126
|
+
open = false;
|
127
|
+
break;
|
128
|
+
case '&':
|
129
|
+
entity = true;
|
130
|
+
modified = true;
|
131
|
+
break;
|
132
|
+
case ';':
|
133
|
+
entity = false;
|
134
|
+
break;
|
135
|
+
default:
|
136
|
+
if (!open && !entity) {
|
137
|
+
dest[index++] = str[i];
|
138
|
+
}
|
139
|
+
|
140
|
+
break;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
dest[index] = '\0';
|
145
|
+
|
146
|
+
/*
|
147
|
+
* If the string was never modified, return the original string, otherwise
|
148
|
+
* create a new string from our destination buffer.
|
149
|
+
*/
|
150
|
+
if (modified) {
|
151
|
+
return rb_utf8_str_new_cstr(dest);
|
152
|
+
} else {
|
153
|
+
return string;
|
154
|
+
}
|
146
155
|
}
|
147
156
|
|
148
157
|
/*
|
149
158
|
* The external API for Berns.escape_html.
|
150
159
|
*
|
151
|
-
*
|
160
|
+
* Anything other than a string will raise an error.
|
152
161
|
*
|
153
162
|
*/
|
154
163
|
static VALUE external_escape_html(RB_UNUSED_VAR(VALUE self), VALUE string) {
|
155
|
-
|
164
|
+
StringValue(string);
|
156
165
|
|
157
|
-
|
158
|
-
|
159
|
-
|
166
|
+
uint8_t *dest = NULL;
|
167
|
+
size_t slen = RSTRING_LEN(string);
|
168
|
+
size_t esclen = hesc_escape_html(&dest, RSTRING_PTR(string), slen);
|
160
169
|
|
161
|
-
|
170
|
+
VALUE rstring;
|
162
171
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
172
|
+
if (esclen > slen) {
|
173
|
+
rstring = rb_utf8_str_new_cstr(dest);
|
174
|
+
free(dest);
|
175
|
+
} else {
|
176
|
+
rstring = string;
|
177
|
+
}
|
169
178
|
|
170
|
-
|
179
|
+
return rstring;
|
171
180
|
}
|
172
181
|
|
173
182
|
/*
|
174
183
|
* Return a freeable piece of memory with a copy of the attribute passed in it.
|
175
184
|
* Why does this exist? So we can free the memory created by this without having
|
176
|
-
* branch further in other places.
|
185
|
+
* to branch further in other places.
|
177
186
|
*/
|
178
|
-
static char * empty_value_to_attribute(const char *attr, const size_t attrlen) {
|
179
|
-
|
180
|
-
|
181
|
-
char *end = dest + total_size;
|
187
|
+
static inline char * empty_value_to_attribute(const char *attr, const size_t attrlen) {
|
188
|
+
size_t total_size = attrlen + 1;
|
189
|
+
char *dest = strxnew(total_size);
|
182
190
|
|
183
|
-
|
191
|
+
strxcat(dest, total_size, attr);
|
184
192
|
|
185
|
-
|
193
|
+
return dest;
|
186
194
|
}
|
187
195
|
|
188
196
|
/*
|
189
|
-
* Takes a string attribute name and value pair and converts them into a string
|
190
|
-
*
|
191
|
-
|
192
|
-
*/
|
197
|
+
* Takes a string attribute name and value pair and converts them into a string
|
198
|
+
* ready to use in HTML
|
199
|
+
*/
|
193
200
|
static char * string_value_to_attribute(const char *attr, const size_t attrlen, const char *value, const size_t vallen) {
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
if (esclen > vallen) {
|
217
|
-
free(edest);
|
218
|
-
}
|
219
|
-
|
220
|
-
return dest;
|
221
|
-
}
|
201
|
+
if (vallen == 0) {
|
202
|
+
size_t total_size = attrlen + 1;
|
203
|
+
char *dest = strxnew(total_size);
|
204
|
+
|
205
|
+
strxcat(dest, total_size, attr);
|
206
|
+
|
207
|
+
return dest;
|
208
|
+
} else {
|
209
|
+
uint8_t *edest = NULL;
|
210
|
+
size_t esclen = hesc_escape_html(&edest, value, vallen);
|
211
|
+
|
212
|
+
size_t total_size = attrlen + attr_eqlen + esclen + attr_clen + 1;
|
213
|
+
char *dest = strxnew(total_size);
|
214
|
+
|
215
|
+
strxcat(dest, total_size, attr, attr_equals, edest, attr_close);
|
216
|
+
|
217
|
+
if (esclen > vallen) {
|
218
|
+
free(edest);
|
219
|
+
}
|
220
|
+
|
221
|
+
return dest;
|
222
|
+
}
|
222
223
|
}
|
223
224
|
|
224
225
|
static char * hash_value_to_attribute(const char *attr, const size_t attrlen, VALUE value) {
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
free(combined);
|
358
|
-
}
|
359
|
-
|
360
|
-
/*
|
361
|
-
* Reallocate destination to final size. This is generally a reduction in the
|
362
|
-
* allocated memory since we chunk allocations in 256 byte multiples.
|
363
|
-
*/
|
364
|
-
char *rightsizeddest = realloc(destination, occupied + 1);
|
226
|
+
Check_Type(value, T_HASH);
|
227
|
+
|
228
|
+
if (RHASH_SIZE(value) == 0) {
|
229
|
+
return strxempty();
|
230
|
+
}
|
231
|
+
|
232
|
+
VALUE subkey;
|
233
|
+
VALUE subvalue;
|
234
|
+
|
235
|
+
const VALUE keys = rb_funcall(value, rb_intern("keys"), 0);
|
236
|
+
const VALUE length = RARRAY_LEN(keys);
|
237
|
+
|
238
|
+
size_t allocated = 256;
|
239
|
+
size_t occupied = 0;
|
240
|
+
|
241
|
+
char *destination = strxnew(allocated);
|
242
|
+
char *position = destination;
|
243
|
+
|
244
|
+
for (unsigned int i = 0; i < length; i++) {
|
245
|
+
subkey = rb_ary_entry(keys, i);
|
246
|
+
subvalue = rb_hash_aref(value, subkey);
|
247
|
+
|
248
|
+
switch(TYPE(subkey)) {
|
249
|
+
case T_STRING:
|
250
|
+
break;
|
251
|
+
case T_NIL:
|
252
|
+
subkey = rb_utf8_str_new_cstr("");
|
253
|
+
break;
|
254
|
+
case T_SYMBOL:
|
255
|
+
subkey = rb_sym2str(subkey);
|
256
|
+
break;
|
257
|
+
default:
|
258
|
+
strxfree(destination);
|
259
|
+
rb_raise(rb_eTypeError, "Berns.to_attribute value keys must be Strings, Symbols, or nil.");
|
260
|
+
break;
|
261
|
+
}
|
262
|
+
|
263
|
+
size_t subattr_len = attrlen;
|
264
|
+
size_t subkey_len = RSTRING_LEN(subkey);
|
265
|
+
|
266
|
+
if (attrlen > 0 && subkey_len > 0) {
|
267
|
+
subattr_len += dlen;
|
268
|
+
}
|
269
|
+
|
270
|
+
if (subkey_len > 0) {
|
271
|
+
subattr_len += subkey_len;
|
272
|
+
}
|
273
|
+
|
274
|
+
char subattr[subattr_len + 1];
|
275
|
+
char *ptr = subattr;
|
276
|
+
char *subend = subattr + subattr_len + 1;
|
277
|
+
|
278
|
+
if (attrlen > 0) {
|
279
|
+
ptr = strxcat(ptr, attrlen + 1, attr);
|
280
|
+
}
|
281
|
+
|
282
|
+
if (attrlen > 0 && subkey_len > 0) {
|
283
|
+
ptr = strxcat(ptr, dlen + 1, dash);
|
284
|
+
}
|
285
|
+
|
286
|
+
strxcat(ptr, subkey_len + 1, RSTRING_PTR(subkey));
|
287
|
+
|
288
|
+
char *combined;
|
289
|
+
|
290
|
+
switch(TYPE(subvalue)) {
|
291
|
+
case T_FALSE:
|
292
|
+
combined = strxempty();
|
293
|
+
break;
|
294
|
+
|
295
|
+
case T_NIL:
|
296
|
+
/* Fall through. */
|
297
|
+
case T_TRUE:
|
298
|
+
combined = empty_value_to_attribute(subattr, subattr_len);
|
299
|
+
break;
|
300
|
+
|
301
|
+
case T_STRING:
|
302
|
+
combined = string_value_to_attribute(subattr, subattr_len, RSTRING_PTR(subvalue), RSTRING_LEN(subvalue));
|
303
|
+
break;
|
304
|
+
|
305
|
+
case T_SYMBOL:
|
306
|
+
subvalue = rb_sym2str(subvalue);
|
307
|
+
combined = string_value_to_attribute(subattr, subattr_len, RSTRING_PTR(subvalue), RSTRING_LEN(subvalue));
|
308
|
+
break;
|
309
|
+
|
310
|
+
case T_HASH:
|
311
|
+
combined = hash_value_to_attribute(subattr, subattr_len, subvalue);
|
312
|
+
break;
|
313
|
+
|
314
|
+
default:
|
315
|
+
subvalue = rb_funcall(subvalue, rb_intern("to_s"), 0);
|
316
|
+
combined = string_value_to_attribute(subattr, subattr_len, RSTRING_PTR(subvalue), RSTRING_LEN(subvalue));
|
317
|
+
break;
|
318
|
+
}
|
319
|
+
|
320
|
+
size_t combined_len = strlen(combined);
|
321
|
+
size_t size_to_append = combined_len + 1;
|
322
|
+
|
323
|
+
if (i > 0) {
|
324
|
+
size_to_append += splen;
|
325
|
+
}
|
326
|
+
|
327
|
+
if ((size_to_append + occupied) > allocated) {
|
328
|
+
/* To avoid an abundance of reallocations, this is a multiple of 256. */
|
329
|
+
double multiple = (double) (size_to_append + occupied) / 256;
|
330
|
+
size_t new_size_to_allocate = (unsigned int) ceil(multiple) * 256;
|
331
|
+
|
332
|
+
char *tmp = strxresize(destination, new_size_to_allocate);
|
333
|
+
|
334
|
+
allocated = new_size_to_allocate;
|
335
|
+
destination = tmp;
|
336
|
+
position = destination + occupied;
|
337
|
+
}
|
338
|
+
|
339
|
+
if (i > 0) {
|
340
|
+
position = strxcat(position, splen + 1, space);
|
341
|
+
occupied += splen;
|
342
|
+
}
|
343
|
+
|
344
|
+
position = strxcat(position, combined_len + 1, combined);
|
345
|
+
occupied += combined_len;
|
346
|
+
|
347
|
+
strxfree(combined);
|
348
|
+
}
|
349
|
+
|
350
|
+
/*
|
351
|
+
* Reallocate destination to final size. This is generally a reduction in the
|
352
|
+
* allocated memory since we chunk allocations in 256 byte multiples.
|
353
|
+
*/
|
354
|
+
char *rightsizeddest = strxresize(destination, occupied + 1);
|
355
|
+
|
356
|
+
rightsizeddest[occupied] = '\0';
|
365
357
|
|
366
|
-
|
367
|
-
free(destination);
|
368
|
-
rb_raise(rb_eNoMemError, "Berns could not allocate sufficient memory.");
|
369
|
-
}
|
370
|
-
|
371
|
-
rightsizeddest[occupied] = '\0';
|
372
|
-
|
373
|
-
return rightsizeddest;
|
358
|
+
return rightsizeddest;
|
374
359
|
}
|
375
360
|
|
376
361
|
/*
|
377
362
|
* Convert an attribute name and value into a string.
|
378
363
|
*/
|
379
364
|
static char * to_attribute(VALUE attr, VALUE value) {
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
365
|
+
switch(TYPE(attr)) {
|
366
|
+
case T_SYMBOL:
|
367
|
+
attr = rb_sym2str(attr);
|
368
|
+
break;
|
369
|
+
default:
|
370
|
+
break;
|
371
|
+
}
|
372
|
+
|
373
|
+
StringValue(attr);
|
374
|
+
|
375
|
+
char *val = NULL;
|
376
|
+
VALUE str;
|
377
|
+
|
378
|
+
switch(TYPE(value)) {
|
379
|
+
case T_NIL:
|
380
|
+
/* Fall through. */
|
381
|
+
case T_TRUE:
|
382
|
+
val = empty_value_to_attribute(RSTRING_PTR(attr), RSTRING_LEN(attr));
|
383
|
+
break;
|
384
|
+
case T_FALSE:
|
385
|
+
val = strxempty();
|
386
|
+
break;
|
387
|
+
case T_HASH:
|
388
|
+
val = hash_value_to_attribute(RSTRING_PTR(attr), RSTRING_LEN(attr), value);
|
389
|
+
break;
|
390
|
+
case T_STRING:
|
391
|
+
val = string_value_to_attribute(RSTRING_PTR(attr), RSTRING_LEN(attr), RSTRING_PTR(value), RSTRING_LEN(value));
|
392
|
+
break;
|
393
|
+
case T_SYMBOL:
|
394
|
+
str = rb_sym2str(value);
|
395
|
+
val = string_value_to_attribute(RSTRING_PTR(attr), RSTRING_LEN(attr), RSTRING_PTR(str), RSTRING_LEN(str));
|
396
|
+
break;
|
397
|
+
default:
|
398
|
+
str = rb_funcall(value, rb_intern("to_s"), 0);
|
399
|
+
val = string_value_to_attribute(RSTRING_PTR(attr), RSTRING_LEN(attr), RSTRING_PTR(str), RSTRING_LEN(str));
|
400
|
+
break;
|
401
|
+
}
|
402
|
+
|
403
|
+
return val;
|
419
404
|
}
|
420
405
|
|
421
406
|
/*
|
422
407
|
* The external API for Berns.to_attribute.
|
423
408
|
*
|
424
|
-
*
|
425
|
-
*
|
409
|
+
* attr should be either a symbol or string, otherwise an error is raised. value
|
410
|
+
* can be anything to responds to #to_s
|
426
411
|
*
|
427
412
|
*/
|
428
413
|
static VALUE external_to_attribute(RB_UNUSED_VAR(VALUE self), VALUE attr, VALUE value) {
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
break;
|
433
|
-
default:
|
434
|
-
break;
|
435
|
-
}
|
414
|
+
if (TYPE(attr) == T_SYMBOL) {
|
415
|
+
attr = rb_sym2str(attr);
|
416
|
+
}
|
436
417
|
|
437
|
-
|
418
|
+
StringValue(attr);
|
438
419
|
|
439
|
-
|
440
|
-
|
441
|
-
|
420
|
+
char *val = to_attribute(attr, value);
|
421
|
+
VALUE rstring = rb_utf8_str_new_cstr(val);
|
422
|
+
strxfree(val);
|
442
423
|
|
443
|
-
|
424
|
+
return rstring;
|
444
425
|
}
|
445
426
|
|
446
427
|
/*
|
447
428
|
* The external API for Berns.to_attributes.
|
448
429
|
*
|
449
|
-
*
|
430
|
+
* attributes should be a hash, otherwise an error is raised.
|
450
431
|
*
|
451
432
|
*/
|
452
433
|
static VALUE external_to_attributes(RB_UNUSED_VAR(VALUE self), VALUE attributes) {
|
453
|
-
|
454
|
-
|
455
|
-
if (RHASH_SIZE(attributes) == 0) {
|
456
|
-
return rb_utf8_str_new_cstr("");
|
457
|
-
}
|
434
|
+
Check_Type(attributes, T_HASH);
|
458
435
|
|
459
|
-
|
460
|
-
|
436
|
+
if (RHASH_SIZE(attributes) == 0) {
|
437
|
+
return rb_utf8_str_new_cstr("");
|
438
|
+
}
|
461
439
|
|
462
|
-
|
463
|
-
|
440
|
+
char *attrs = hash_value_to_attribute("", 0, attributes);
|
441
|
+
VALUE rstring = rb_utf8_str_new_cstr(attrs);
|
442
|
+
strxfree(attrs);
|
464
443
|
|
465
|
-
|
444
|
+
return rstring;
|
466
445
|
}
|
467
446
|
|
468
447
|
/*
|
469
|
-
* Create a void element i.e. one without children/content.
|
448
|
+
* Create a void element i.e. one without children/content but with attributes.
|
470
449
|
*/
|
471
|
-
static char *
|
472
|
-
|
473
|
-
char *attrs = hash_value_to_attribute(empty, 0, attributes);
|
474
|
-
size_t alen = strlen(attrs);
|
450
|
+
static char * void_element_with_attributes(const char *tag, size_t tlen, VALUE attributes) {
|
451
|
+
char *attrs = hash_value_to_attribute("", 0, attributes);
|
475
452
|
|
476
|
-
|
453
|
+
size_t alen = strlen(attrs);
|
454
|
+
size_t total = tag_olen + tlen + tag_clen + 1;
|
477
455
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
456
|
+
/* If we have some attributes, add a space and the attributes' length. */
|
457
|
+
if (alen > 0) {
|
458
|
+
total += splen + alen;
|
459
|
+
}
|
482
460
|
|
483
|
-
|
484
|
-
|
485
|
-
char *end = dest + total;
|
461
|
+
char *dest = strxnew(total);
|
462
|
+
char *ptr = strxcat(dest, tag_olen + tlen + 1, tag_open, tag);
|
486
463
|
|
487
|
-
|
488
|
-
|
464
|
+
if (alen > 0) {
|
465
|
+
ptr = strxcat(ptr, splen + alen + 1, space, attrs);
|
466
|
+
}
|
489
467
|
|
490
|
-
|
491
|
-
|
492
|
-
ptr = stecpy(ptr, attrs, end);
|
493
|
-
}
|
468
|
+
strxcat(ptr, tag_clen + 1, tag_close);
|
469
|
+
strxfree(attrs);
|
494
470
|
|
495
|
-
|
471
|
+
return dest;
|
472
|
+
}
|
496
473
|
|
497
|
-
|
474
|
+
/*
|
475
|
+
* Create a void element i.e. one without children/content or attributes.
|
476
|
+
*/
|
477
|
+
static char * void_element_without_attributes(const char *tag, size_t tlen) {
|
478
|
+
size_t total = tag_olen + tlen + tag_clen + 1;
|
479
|
+
|
480
|
+
char *dest = strxnew(total);
|
481
|
+
strxcat(dest, total, tag_open, tag, tag_close);
|
498
482
|
|
499
|
-
|
483
|
+
return dest;
|
500
484
|
}
|
501
485
|
|
502
486
|
/*
|
503
487
|
* The external API for Berns.void.
|
504
488
|
*
|
505
|
-
*
|
506
|
-
*
|
489
|
+
* The first argument should be a string or symbol, otherwise an error is
|
490
|
+
* raised. The second argument must be a hash if present.
|
507
491
|
*
|
508
492
|
*/
|
509
493
|
static VALUE external_void_element(int argc, VALUE *arguments, RB_UNUSED_VAR(VALUE self)) {
|
510
|
-
|
494
|
+
rb_check_arity(argc, 1, 2);
|
495
|
+
|
496
|
+
VALUE tag = arguments[0];
|
497
|
+
VALUE attributes = arguments[1];
|
511
498
|
|
512
|
-
|
513
|
-
|
499
|
+
if (TYPE(tag) == T_SYMBOL) {
|
500
|
+
tag = rb_sym2str(tag);
|
501
|
+
}
|
514
502
|
|
515
|
-
|
516
|
-
tag = rb_sym2str(tag);
|
517
|
-
}
|
503
|
+
StringValue(tag);
|
518
504
|
|
519
|
-
|
505
|
+
char *string;
|
520
506
|
|
521
|
-
|
522
|
-
|
507
|
+
if (argc == 2) {
|
508
|
+
string = void_element_with_attributes(RSTRING_PTR(tag), RSTRING_LEN(tag), attributes);
|
509
|
+
} else {
|
510
|
+
string = void_element_without_attributes(RSTRING_PTR(tag), RSTRING_LEN(tag));
|
511
|
+
}
|
523
512
|
|
524
|
-
|
513
|
+
VALUE rstring = rb_utf8_str_new_cstr(string);
|
514
|
+
strxfree(string);
|
525
515
|
|
526
|
-
|
516
|
+
return rstring;
|
527
517
|
}
|
528
518
|
|
529
|
-
static char *
|
530
|
-
|
531
|
-
|
532
|
-
size_t alen = strlen(attrs);
|
519
|
+
static char * element_with_attributes(const char *tag, size_t tlen, char *content, size_t conlen, VALUE attributes) {
|
520
|
+
char *attrs = hash_value_to_attribute("", 0, attributes);
|
521
|
+
size_t alen = strlen(attrs);
|
533
522
|
|
534
|
-
|
523
|
+
size_t total = tag_olen + tlen + tag_clen + tag_olen + sllen + tlen + tag_clen + 1;
|
535
524
|
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
525
|
+
/* If we have some attributes, add a space and the attributes' length. */
|
526
|
+
if (alen > 0) {
|
527
|
+
total += splen + alen;
|
528
|
+
}
|
540
529
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
530
|
+
/* If we have some content, add the content length to our total. */
|
531
|
+
if (conlen > 0) {
|
532
|
+
total += conlen;
|
533
|
+
}
|
545
534
|
|
546
|
-
|
547
|
-
|
548
|
-
char *end = dest + total;
|
535
|
+
char *dest = strxnew(total);
|
536
|
+
char *ptr = strxcat(dest, tag_olen + tlen + 1, tag_open, tag);
|
549
537
|
|
550
|
-
|
551
|
-
|
538
|
+
if (alen > 0) {
|
539
|
+
ptr = strxcat(ptr, splen + alen + 1, space, attrs);
|
540
|
+
}
|
552
541
|
|
553
|
-
|
554
|
-
ptr = stecpy(ptr, space, end);
|
555
|
-
ptr = stecpy(ptr, attrs, end);
|
556
|
-
}
|
542
|
+
ptr = strxcat(ptr, tag_clen + 1, tag_close);
|
557
543
|
|
558
|
-
|
544
|
+
if (conlen > 0) {
|
545
|
+
ptr = strxcat(ptr, conlen + 1, content);
|
546
|
+
}
|
559
547
|
|
560
|
-
|
561
|
-
|
562
|
-
}
|
548
|
+
ptr = strxcat(ptr, tag_olen + sllen + tlen + tag_clen + 1, tag_open, slash, tag, tag_close);
|
549
|
+
strxfree(attrs);
|
563
550
|
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
551
|
+
return dest;
|
552
|
+
}
|
553
|
+
|
554
|
+
static char * element_without_attributes(const char *tag, size_t tlen, char *content, size_t conlen) {
|
555
|
+
size_t total = tag_olen + tlen + tag_clen + tag_olen + sllen + tlen + tag_clen + 1;
|
556
|
+
|
557
|
+
/* If we have some content, add the content length to our total. */
|
558
|
+
if (conlen > 0) {
|
559
|
+
total += conlen;
|
560
|
+
}
|
561
|
+
|
562
|
+
char *dest = strxnew(total);
|
563
|
+
char *ptr = strxcat(dest, tag_olen + tlen + tag_clen + 1, tag_open, tag, tag_close);
|
568
564
|
|
569
|
-
|
565
|
+
if (conlen > 0) {
|
566
|
+
ptr = strxcat(ptr, conlen + 1, content);
|
567
|
+
}
|
570
568
|
|
571
|
-
|
569
|
+
strxcat(ptr, tag_olen + sllen + tlen + tag_clen + 1, tag_open, slash, tag, tag_close);
|
570
|
+
|
571
|
+
return dest;
|
572
572
|
}
|
573
573
|
|
574
574
|
/*
|
575
575
|
* The external API for Berns.element.
|
576
576
|
*
|
577
|
-
*
|
578
|
-
*
|
579
|
-
*
|
577
|
+
* The first argument should be a string or symbol, otherwise an error is
|
578
|
+
* raised. The second argument must be a hash if present. An optional block can
|
579
|
+
* be given which will used as the contents of the element.
|
580
580
|
*
|
581
581
|
*/
|
582
582
|
static VALUE external_element(int argc, VALUE *arguments, RB_UNUSED_VAR(VALUE self)) {
|
583
|
-
|
583
|
+
rb_check_arity(argc, 1, 2);
|
584
|
+
|
585
|
+
VALUE tag = arguments[0];
|
586
|
+
|
587
|
+
if (TYPE(tag) == T_SYMBOL) {
|
588
|
+
tag = rb_sym2str(tag);
|
589
|
+
}
|
584
590
|
|
585
|
-
|
586
|
-
VALUE attributes = arguments[1];
|
591
|
+
StringValue(tag);
|
587
592
|
|
588
|
-
|
589
|
-
tag = rb_sym2str(tag);
|
590
|
-
}
|
593
|
+
CONTENT_FROM_BLOCK
|
591
594
|
|
592
|
-
|
595
|
+
char *string;
|
593
596
|
|
594
|
-
|
597
|
+
if (argc == 2) {
|
598
|
+
string = element_with_attributes(RSTRING_PTR(tag), RSTRING_LEN(tag), RSTRING_PTR(content), RSTRING_LEN(content), arguments[1]);
|
599
|
+
} else {
|
600
|
+
string = element_without_attributes(RSTRING_PTR(tag), RSTRING_LEN(tag), RSTRING_PTR(content), RSTRING_LEN(content));
|
601
|
+
}
|
595
602
|
|
596
|
-
|
597
|
-
|
598
|
-
free(string);
|
603
|
+
VALUE rstring = rb_utf8_str_new_cstr(string);
|
604
|
+
strxfree(string);
|
599
605
|
|
600
|
-
|
606
|
+
return rstring;
|
601
607
|
}
|
602
608
|
|
603
609
|
VOID_ELEMENT(area)
|
@@ -712,142 +718,142 @@ STANDARD_ELEMENT(var)
|
|
712
718
|
STANDARD_ELEMENT(video)
|
713
719
|
|
714
720
|
void Init_berns() {
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
721
|
+
VALUE Berns = rb_define_module("Berns");
|
722
|
+
|
723
|
+
rb_define_singleton_method(Berns, "element", external_element, -1);
|
724
|
+
rb_define_singleton_method(Berns, "escape_html", external_escape_html, 1);
|
725
|
+
rb_define_singleton_method(Berns, "sanitize", external_sanitize, 1);
|
726
|
+
rb_define_singleton_method(Berns, "to_attribute", external_to_attribute, 2);
|
727
|
+
rb_define_singleton_method(Berns, "to_attributes", external_to_attributes, 1);
|
728
|
+
rb_define_singleton_method(Berns, "void", external_void_element, -1);
|
729
|
+
|
730
|
+
/*
|
731
|
+
* List of void elements - http://xahlee.info/js/html5_non-closing_tag.html
|
732
|
+
*
|
733
|
+
* area base br col embed hr img input link menuitem meta param source track
|
734
|
+
* wbr
|
735
|
+
*
|
736
|
+
*/
|
737
|
+
rb_define_singleton_method(Berns, "area", external_area_element, -1);
|
738
|
+
rb_define_singleton_method(Berns, "base", external_base_element, -1);
|
739
|
+
rb_define_singleton_method(Berns, "br", external_br_element, -1);
|
740
|
+
rb_define_singleton_method(Berns, "col", external_col_element, -1);
|
741
|
+
rb_define_singleton_method(Berns, "embed", external_embed_element, -1);
|
742
|
+
rb_define_singleton_method(Berns, "hr", external_hr_element, -1);
|
743
|
+
rb_define_singleton_method(Berns, "img", external_img_element, -1);
|
744
|
+
rb_define_singleton_method(Berns, "input", external_input_element, -1);
|
745
|
+
rb_define_singleton_method(Berns, "link", external_link_element, -1);
|
746
|
+
rb_define_singleton_method(Berns, "menuitem", external_menuitem_element, -1);
|
747
|
+
rb_define_singleton_method(Berns, "meta", external_meta_element, -1);
|
748
|
+
rb_define_singleton_method(Berns, "param", external_param_element, -1);
|
749
|
+
rb_define_singleton_method(Berns, "source", external_source_element, -1);
|
750
|
+
rb_define_singleton_method(Berns, "track", external_track_element, -1);
|
751
|
+
rb_define_singleton_method(Berns, "wbr", external_wbr_element, -1);
|
752
|
+
|
753
|
+
/*
|
754
|
+
* List of standard HTML5 elements - https://www.w3schools.com/TAgs/default.asp
|
755
|
+
*
|
756
|
+
* a abbr address article aside audio b bdi bdo blockquote body button canvas
|
757
|
+
* caption cite code colgroup datalist dd del details dfn dialog div dl dt em
|
758
|
+
* fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header html i
|
759
|
+
* iframe ins kbd label legend li main map mark menu meter nav noscript object
|
760
|
+
* ol optgroup option output p picture pre progress q rp rt ruby s samp script
|
761
|
+
* section select small span strong style sub summary table tbody td template
|
762
|
+
* textarea tfoot th thead time title tr u ul var video
|
763
|
+
*
|
764
|
+
*/
|
765
|
+
rb_define_singleton_method(Berns, "a", external_a_element, -1);
|
766
|
+
rb_define_singleton_method(Berns, "abbr", external_abbr_element, -1);
|
767
|
+
rb_define_singleton_method(Berns, "address", external_address_element, -1);
|
768
|
+
rb_define_singleton_method(Berns, "article", external_article_element, -1);
|
769
|
+
rb_define_singleton_method(Berns, "aside", external_aside_element, -1);
|
770
|
+
rb_define_singleton_method(Berns, "audio", external_audio_element, -1);
|
771
|
+
rb_define_singleton_method(Berns, "b", external_b_element, -1);
|
772
|
+
rb_define_singleton_method(Berns, "bdi", external_bdi_element, -1);
|
773
|
+
rb_define_singleton_method(Berns, "bdo", external_bdo_element, -1);
|
774
|
+
rb_define_singleton_method(Berns, "blockquote", external_blockquote_element, -1);
|
775
|
+
rb_define_singleton_method(Berns, "body", external_body_element, -1);
|
776
|
+
rb_define_singleton_method(Berns, "button", external_button_element, -1);
|
777
|
+
rb_define_singleton_method(Berns, "canvas", external_canvas_element, -1);
|
778
|
+
rb_define_singleton_method(Berns, "caption", external_caption_element, -1);
|
779
|
+
rb_define_singleton_method(Berns, "cite", external_cite_element, -1);
|
780
|
+
rb_define_singleton_method(Berns, "code", external_code_element, -1);
|
781
|
+
rb_define_singleton_method(Berns, "colgroup", external_colgroup_element, -1);
|
782
|
+
rb_define_singleton_method(Berns, "datalist", external_datalist_element, -1);
|
783
|
+
rb_define_singleton_method(Berns, "dd", external_dd_element, -1);
|
784
|
+
rb_define_singleton_method(Berns, "del", external_del_element, -1);
|
785
|
+
rb_define_singleton_method(Berns, "details", external_details_element, -1);
|
786
|
+
rb_define_singleton_method(Berns, "dfn", external_dfn_element, -1);
|
787
|
+
rb_define_singleton_method(Berns, "dialog", external_dialog_element, -1);
|
788
|
+
rb_define_singleton_method(Berns, "div", external_div_element, -1);
|
789
|
+
rb_define_singleton_method(Berns, "dl", external_dl_element, -1);
|
790
|
+
rb_define_singleton_method(Berns, "dt", external_dt_element, -1);
|
791
|
+
rb_define_singleton_method(Berns, "em", external_em_element, -1);
|
792
|
+
rb_define_singleton_method(Berns, "fieldset", external_fieldset_element, -1);
|
793
|
+
rb_define_singleton_method(Berns, "figcaption", external_figcaption_element, -1);
|
794
|
+
rb_define_singleton_method(Berns, "figure", external_figure_element, -1);
|
795
|
+
rb_define_singleton_method(Berns, "footer", external_footer_element, -1);
|
796
|
+
rb_define_singleton_method(Berns, "form", external_form_element, -1);
|
797
|
+
rb_define_singleton_method(Berns, "h1", external_h1_element, -1);
|
798
|
+
rb_define_singleton_method(Berns, "h2", external_h2_element, -1);
|
799
|
+
rb_define_singleton_method(Berns, "h3", external_h3_element, -1);
|
800
|
+
rb_define_singleton_method(Berns, "h4", external_h4_element, -1);
|
801
|
+
rb_define_singleton_method(Berns, "h5", external_h5_element, -1);
|
802
|
+
rb_define_singleton_method(Berns, "h6", external_h6_element, -1);
|
803
|
+
rb_define_singleton_method(Berns, "head", external_head_element, -1);
|
804
|
+
rb_define_singleton_method(Berns, "header", external_header_element, -1);
|
805
|
+
rb_define_singleton_method(Berns, "html", external_html_element, -1);
|
806
|
+
rb_define_singleton_method(Berns, "i", external_i_element, -1);
|
807
|
+
rb_define_singleton_method(Berns, "iframe", external_iframe_element, -1);
|
808
|
+
rb_define_singleton_method(Berns, "ins", external_ins_element, -1);
|
809
|
+
rb_define_singleton_method(Berns, "kbd", external_kbd_element, -1);
|
810
|
+
rb_define_singleton_method(Berns, "label", external_label_element, -1);
|
811
|
+
rb_define_singleton_method(Berns, "legend", external_legend_element, -1);
|
812
|
+
rb_define_singleton_method(Berns, "li", external_li_element, -1);
|
813
|
+
rb_define_singleton_method(Berns, "main", external_main_element, -1);
|
814
|
+
rb_define_singleton_method(Berns, "map", external_map_element, -1);
|
815
|
+
rb_define_singleton_method(Berns, "mark", external_mark_element, -1);
|
816
|
+
rb_define_singleton_method(Berns, "menu", external_menu_element, -1);
|
817
|
+
rb_define_singleton_method(Berns, "meter", external_meter_element, -1);
|
818
|
+
rb_define_singleton_method(Berns, "nav", external_nav_element, -1);
|
819
|
+
rb_define_singleton_method(Berns, "noscript", external_noscript_element, -1);
|
820
|
+
rb_define_singleton_method(Berns, "object", external_object_element, -1);
|
821
|
+
rb_define_singleton_method(Berns, "ol", external_ol_element, -1);
|
822
|
+
rb_define_singleton_method(Berns, "optgroup", external_optgroup_element, -1);
|
823
|
+
rb_define_singleton_method(Berns, "option", external_option_element, -1);
|
824
|
+
rb_define_singleton_method(Berns, "output", external_output_element, -1);
|
825
|
+
rb_define_singleton_method(Berns, "p", external_p_element, -1);
|
826
|
+
rb_define_singleton_method(Berns, "picture", external_picture_element, -1);
|
827
|
+
rb_define_singleton_method(Berns, "pre", external_pre_element, -1);
|
828
|
+
rb_define_singleton_method(Berns, "progress", external_progress_element, -1);
|
829
|
+
rb_define_singleton_method(Berns, "q", external_q_element, -1);
|
830
|
+
rb_define_singleton_method(Berns, "rp", external_rp_element, -1);
|
831
|
+
rb_define_singleton_method(Berns, "rt", external_rt_element, -1);
|
832
|
+
rb_define_singleton_method(Berns, "ruby", external_ruby_element, -1);
|
833
|
+
rb_define_singleton_method(Berns, "s", external_s_element, -1);
|
834
|
+
rb_define_singleton_method(Berns, "samp", external_samp_element, -1);
|
835
|
+
rb_define_singleton_method(Berns, "script", external_script_element, -1);
|
836
|
+
rb_define_singleton_method(Berns, "section", external_section_element, -1);
|
837
|
+
rb_define_singleton_method(Berns, "select", external_select_element, -1);
|
838
|
+
rb_define_singleton_method(Berns, "small", external_small_element, -1);
|
839
|
+
rb_define_singleton_method(Berns, "span", external_span_element, -1);
|
840
|
+
rb_define_singleton_method(Berns, "strong", external_strong_element, -1);
|
841
|
+
rb_define_singleton_method(Berns, "style", external_style_element, -1);
|
842
|
+
rb_define_singleton_method(Berns, "sub", external_sub_element, -1);
|
843
|
+
rb_define_singleton_method(Berns, "summary", external_summary_element, -1);
|
844
|
+
rb_define_singleton_method(Berns, "table", external_table_element, -1);
|
845
|
+
rb_define_singleton_method(Berns, "tbody", external_tbody_element, -1);
|
846
|
+
rb_define_singleton_method(Berns, "td", external_td_element, -1);
|
847
|
+
rb_define_singleton_method(Berns, "template", external_template_element, -1);
|
848
|
+
rb_define_singleton_method(Berns, "textarea", external_textarea_element, -1);
|
849
|
+
rb_define_singleton_method(Berns, "tfoot", external_tfoot_element, -1);
|
850
|
+
rb_define_singleton_method(Berns, "th", external_th_element, -1);
|
851
|
+
rb_define_singleton_method(Berns, "thead", external_thead_element, -1);
|
852
|
+
rb_define_singleton_method(Berns, "time", external_time_element, -1);
|
853
|
+
rb_define_singleton_method(Berns, "title", external_title_element, -1);
|
854
|
+
rb_define_singleton_method(Berns, "tr", external_tr_element, -1);
|
855
|
+
rb_define_singleton_method(Berns, "u", external_u_element, -1);
|
856
|
+
rb_define_singleton_method(Berns, "ul", external_ul_element, -1);
|
857
|
+
rb_define_singleton_method(Berns, "var", external_var_element, -1);
|
858
|
+
rb_define_singleton_method(Berns, "video", external_video_element, -1);
|
853
859
|
}
|