hive_markup 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2b5de6cfd829708c16d638eaad678d63e5ba173d
4
+ data.tar.gz: b4dad87f58e68df2d1d30dbf06a8073d61b23665
5
+ SHA512:
6
+ metadata.gz: c65ff215346e34525b5c79fd902b1ddfccb443299eceecab9015c5f65aff2cdefb0799934af0d4835fabc3766cbfc86f71b9111854ae3b832aec94b8eb1d5dcc
7
+ data.tar.gz: 2511dc20b3e43a2c5028dbf9690ccf29d5804ece4173b0007262ed4fff619458b64eb58e0838b30ee0d97eb572e7af85b69ded8ce5a6af232209972f23bf3d56
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('hive_markup')
@@ -0,0 +1,719 @@
1
+ #define RSTRING_NOT_MODIFIED
2
+
3
+ #include <ruby/ruby.h>
4
+ #include <ruby/encoding.h>
5
+ #include <ctype.h>
6
+
7
+ #include "houdini.h"
8
+
9
+ #define MIN_BUF_SIZE 128
10
+ #define MAX_BUF_SIZE 2 * 1024 * 1024
11
+ #define buf_puts(buf, str) buf_append(buf, str, sizeof str - 1)
12
+
13
+ static VALUE rb_mHive;
14
+ static VALUE rb_cMarkup;
15
+
16
+ typedef struct {
17
+ uint8_t *data;
18
+ size_t size;
19
+ size_t total;
20
+ uint8_t fragile;
21
+ } buffer;
22
+
23
+ static size_t parse_text(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
24
+ static size_t parse_em(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
25
+ static size_t parse_maybequote(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
26
+ static size_t parse_quote(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
27
+ static size_t parse_quotelink(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
28
+ static size_t parse_linebreak(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
29
+ static size_t parse_codeblock(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
30
+ static size_t parse_aablock(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
31
+ static size_t parse_spoiler(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
32
+ static size_t parse_escape(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
33
+ static size_t parse_autolink(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
34
+
35
+ typedef size_t (*trigger_func)(const uint8_t *text, size_t start, size_t size, buffer *out_buf);
36
+
37
+ static char trigger_map[256];
38
+
39
+ enum trigger_keys {
40
+ HIVE_NULL = 0,
41
+ HIVE_EM,
42
+ HIVE_QUOTE,
43
+ HIVE_LINEBREAK,
44
+ HIVE_CODE,
45
+ HIVE_SPOILER,
46
+ HIVE_ESCAPE,
47
+ HIVE_AA,
48
+ HIVE_AUTOLINK
49
+ };
50
+
51
+ static trigger_func trigger_funcs[] = {
52
+ 0,
53
+ parse_em,
54
+ parse_maybequote,
55
+ parse_linebreak,
56
+ parse_codeblock,
57
+ parse_spoiler,
58
+ parse_escape,
59
+ parse_aablock,
60
+ parse_autolink
61
+ };
62
+
63
+ static void init_triggers() {
64
+ trigger_map['*'] = HIVE_EM;
65
+ trigger_map['>'] = HIVE_QUOTE;
66
+ trigger_map['\n'] = HIVE_LINEBREAK;
67
+ trigger_map['`'] = HIVE_CODE;
68
+ trigger_map['$'] = HIVE_SPOILER;
69
+ trigger_map['\\'] = HIVE_ESCAPE;
70
+ trigger_map['~'] = HIVE_AA;
71
+ trigger_map['/'] = HIVE_AUTOLINK;
72
+ }
73
+
74
+ static buffer * buf_new() {
75
+ buffer *buf;
76
+
77
+ buf = malloc(sizeof (buffer));
78
+
79
+ if (buf) {
80
+ buf->data = 0;
81
+ buf->size = 0;
82
+ buf->total = 0;
83
+ buf->fragile = 0;
84
+ }
85
+
86
+ return buf;
87
+ }
88
+
89
+ static int buf_expand(buffer *buf, size_t new_size) {
90
+ void *new_ptr;
91
+
92
+ new_size = MIN_BUF_SIZE + new_size + (new_size >> 1);
93
+
94
+ if (new_size > MAX_BUF_SIZE) {
95
+ return 0;
96
+ }
97
+
98
+ new_ptr = realloc(buf->data, new_size);
99
+
100
+ if (new_ptr) {
101
+ buf->data = new_ptr;
102
+ buf->total = new_size;
103
+ return 1;
104
+ }
105
+
106
+ return 0;
107
+ }
108
+
109
+ static void buf_append(buffer *buf, const void *str, size_t size) {
110
+ if (buf->size + size > buf->total && !buf_expand(buf, buf->size + size)) {
111
+ return;
112
+ }
113
+
114
+ memcpy(buf->data + buf->size, str, size);
115
+ buf->size += size;
116
+ }
117
+
118
+ static void buf_putc(buffer *buf, uint8_t c) {
119
+ if (buf->size >= buf->total && !buf_expand(buf, buf->size + 1)) {
120
+ return;
121
+ }
122
+
123
+ buf->data[buf->size] = c;
124
+ ++buf->size;
125
+ }
126
+
127
+ static void buf_free(buffer *buf) {
128
+ free(buf->data);
129
+ free(buf);
130
+ }
131
+
132
+ static inline int is_space(uint8_t c) {
133
+ return c == ' ' || c == '\n';
134
+ }
135
+
136
+ static inline int is_alnum(uint8_t c) {
137
+ return isalnum(c) && c < 0x7b;
138
+ }
139
+
140
+ static inline int is_alpha(uint8_t c) {
141
+ return isalpha(c) && c < 0x7b;
142
+ }
143
+
144
+ static inline int is_digit(uint8_t c) {
145
+ return c >= '0' && c <= '9';
146
+ }
147
+
148
+ static inline int is_xdigit(uint8_t c) {
149
+ return is_digit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
150
+ }
151
+
152
+ static void preprocess_text(const uint8_t *text, size_t size, buffer *out_buf) {
153
+ size_t end = 0;
154
+
155
+ while (end < size) {
156
+ size_t from = end;
157
+
158
+ while (end < size && text[end] > 31 && text[end] != 127) {
159
+ ++end;
160
+ }
161
+
162
+ if (end > from) {
163
+ buf_append(out_buf, text + from, end - from);
164
+ }
165
+
166
+ if (end >= size) {
167
+ break;
168
+ }
169
+
170
+ if (text[end] == '\n') {
171
+ buf_putc(out_buf, '\n');
172
+ }
173
+ else if (text[end] == '\t') {
174
+ buf_putc(out_buf, ' ');
175
+ buf_putc(out_buf, ' ');
176
+ }
177
+
178
+ ++end;
179
+ }
180
+ }
181
+
182
+ static void escape_html_char(uint8_t c, buffer *out_buf) {
183
+ uint8_t esc;
184
+
185
+ if ((esc = HTML_ESCAPE_TABLE[c]) != 0) {
186
+ buf_append(out_buf, HTML_ESCAPES[esc], HTML_ESCAPES_LEN[esc]);
187
+ }
188
+ else {
189
+ buf_putc(out_buf, c);
190
+ }
191
+ }
192
+
193
+ static size_t escape_html(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
194
+ uint8_t esc = 0;
195
+ size_t end = start;
196
+
197
+ while (end < size) {
198
+ size_t from = end;
199
+
200
+ while (end < size && (esc = HTML_ESCAPE_TABLE[text[end]]) == 0) {
201
+ ++end;
202
+ }
203
+
204
+ if (end > from) {
205
+ buf_append(out_buf, text + from, end - from);
206
+ }
207
+
208
+ if (end >= size) {
209
+ break;
210
+ }
211
+
212
+ buf_append(out_buf, HTML_ESCAPES[esc], HTML_ESCAPES_LEN[esc]);
213
+
214
+ ++end;
215
+ }
216
+
217
+ return end - start;
218
+ }
219
+
220
+ static size_t parse_aablock(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
221
+ if (out_buf->fragile) {
222
+ return 0;
223
+ }
224
+
225
+ if (start > 0 && text[start - 1] != '\n') {
226
+ return 0;
227
+ }
228
+
229
+ if (start + 2 >= size || text[start + 1] != '~' || text[start + 2] != '~') {
230
+ return 0;
231
+ }
232
+
233
+ size_t end = start + 3;
234
+
235
+ while (end < size && text[end] == '\n') {
236
+ ++end;
237
+ }
238
+
239
+ if (end >= size) {
240
+ return 0;
241
+ }
242
+
243
+ size_t i, block_start = end;
244
+
245
+ for (i = 0; end < size; ++end) {
246
+ if (text[end] != '~' || text[end - 1] == '\\') {
247
+ i = 0;
248
+ }
249
+ else {
250
+ ++i;
251
+ }
252
+ if (i == 3 && text[end - 3] == '\n' && (end + 1 >= size || text[end + 1] == '\n')) {
253
+ break;
254
+ }
255
+ }
256
+
257
+ if (i < 3) {
258
+ return 0;
259
+ }
260
+
261
+ size_t block_end = end - 2;
262
+
263
+ while (block_end > block_start && text[block_end - 1] == '\n') {
264
+ block_end--;
265
+ }
266
+
267
+ if (block_end <= block_start) {
268
+ return 0;
269
+ }
270
+
271
+ buf_puts(out_buf, "<div class=\"aa\">");
272
+
273
+ escape_html(text, block_start, block_end, out_buf);
274
+
275
+ buf_puts(out_buf, "</div>");
276
+
277
+ if (end + 1 < size) {
278
+ ++end;
279
+ }
280
+
281
+ return end - start + 1;
282
+ }
283
+
284
+ static size_t parse_codeblock(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
285
+ if (out_buf->fragile) {
286
+ return 0;
287
+ }
288
+
289
+ if (start > 0 && text[start - 1] != '\n') {
290
+ return 0;
291
+ }
292
+
293
+ if (start + 2 >= size || text[start + 1] != '`' || text[start + 2] != '`') {
294
+ return 0;
295
+ }
296
+
297
+ size_t end = start + 3;
298
+
299
+ while (end < size && text[end] == '\n') {
300
+ ++end;
301
+ }
302
+
303
+ if (end >= size) {
304
+ return 0;
305
+ }
306
+
307
+ size_t i, block_start = end;
308
+
309
+ for (i = 0; end < size; ++end) {
310
+ if (text[end] != '`' || text[end - 1] == '\\') {
311
+ i = 0;
312
+ }
313
+ else {
314
+ ++i;
315
+ }
316
+ if (i == 3 && text[end - 3] == '\n' && (end + 1 >= size || text[end + 1] == '\n')) {
317
+ break;
318
+ }
319
+ }
320
+
321
+ if (i < 3) {
322
+ return 0;
323
+ }
324
+
325
+ size_t block_end = end - 2;
326
+
327
+ while (block_end > block_start && text[block_end - 1] == '\n') {
328
+ block_end--;
329
+ }
330
+
331
+ if (block_end <= block_start) {
332
+ return 0;
333
+ }
334
+
335
+ buf_puts(out_buf, "<pre><code class=\"prettyprint\">");
336
+
337
+ escape_html(text, block_start, block_end, out_buf);
338
+
339
+ buf_puts(out_buf, "</code></pre>");
340
+
341
+ if (end + 1 < size) {
342
+ ++end;
343
+ }
344
+
345
+ return end - start + 1;
346
+ }
347
+
348
+ static size_t parse_spoiler(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
349
+ if (start > 0 && is_alnum(text[start - 1])) {
350
+ return 0;
351
+ }
352
+
353
+ size_t end = start + 1;
354
+
355
+ while (end < size && text[end] == '$') {
356
+ ++end;
357
+ }
358
+
359
+ if (end - start != 2) {
360
+ buf_append(out_buf, text + start, end - start); // $
361
+ return end - start;
362
+ }
363
+
364
+ while (end < size && text[end] == '\n') {
365
+ ++end;
366
+ }
367
+
368
+ if (end >= size) {
369
+ return 0;
370
+ }
371
+
372
+ size_t block_start = end;
373
+
374
+ while (end < size) {
375
+ if (text[end] == '$'
376
+ && end + 1 < size
377
+ && text[end + 1] == '$'
378
+ && (end + 1 >= size || !is_alnum(text[end + 1]))
379
+ ) {
380
+ break;
381
+ }
382
+ ++end;
383
+ }
384
+
385
+ if (end >= size) {
386
+ return 0;
387
+ }
388
+
389
+ size_t block_end = end;
390
+
391
+ while (block_end > block_start && text[block_end - 1] == '\n') {
392
+ block_end--;
393
+ }
394
+
395
+ if (block_end <= block_start) {
396
+ return 0;
397
+ }
398
+
399
+ out_buf->fragile = 1;
400
+
401
+ buf_puts(out_buf, "<span class=\"s\">");
402
+
403
+ parse_text(text, block_start, block_end, out_buf);
404
+
405
+ buf_puts(out_buf, "</span>");
406
+
407
+ out_buf->fragile = 0;
408
+
409
+ return end - start + 2;
410
+ }
411
+
412
+ static size_t parse_em(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
413
+ if (start > 0 && is_alnum(text[start - 1])) {
414
+ return 0;
415
+ }
416
+
417
+ size_t end = start + 1;
418
+
419
+ while (end < size && text[end] == '*') {
420
+ ++end;
421
+ }
422
+
423
+ if (end - start > 1) {
424
+ buf_append(out_buf, text + start, end - start); // *
425
+ return end - start;
426
+ }
427
+
428
+ if (end < size && is_space(text[end])) {
429
+ return 0;
430
+ }
431
+
432
+ while (end < size && text[end] != '\n') {
433
+ if (text[end] == '*' && !is_space(text[end - 1])
434
+ && (end + 1 >= size || !is_alnum(text[end + 1]))
435
+ && text[end - 1] != '\\') {
436
+ break;
437
+ }
438
+ ++end;
439
+ }
440
+
441
+ if (end >= size || text[end] == '\n') {
442
+ return 0;
443
+ }
444
+
445
+ if (is_space(text[end - 1])) {
446
+ return 0;
447
+ }
448
+
449
+ ++start;
450
+
451
+ buf_puts(out_buf, "<em>");
452
+
453
+ parse_text(text, start, end, out_buf);
454
+
455
+ buf_puts(out_buf, "</em>");
456
+
457
+ return end - start + 2;
458
+ }
459
+
460
+ static size_t parse_escape(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
461
+ if (start + 1 < size) {
462
+ uint8_t c = text[start + 1];
463
+ if (c == '*' || c == '`' || c == '$' || c == '~') {
464
+ escape_html_char(c, out_buf);
465
+ return 2;
466
+ }
467
+ }
468
+ return 0;
469
+ }
470
+
471
+ static size_t parse_autolink(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
472
+ static const char *autolink_scheme = "http";
473
+ static const char *punct = ":;!?,.'\"&";
474
+
475
+ if (start < 5 || start + 2 >= size || text[start - 1] != ':' || text[start + 1] != '/') {
476
+ return 0;
477
+ }
478
+
479
+ size_t block_start, scheme_len;
480
+
481
+ if (text[start - 2] != 's') {
482
+ scheme_len = 5;
483
+ }
484
+ else {
485
+ scheme_len = 6;
486
+ }
487
+
488
+ if (scheme_len > start) {
489
+ return 0;
490
+ }
491
+
492
+ block_start = start - scheme_len;
493
+
494
+ if (memcmp(&text[block_start], autolink_scheme, 4) != 0) {
495
+ return 0;
496
+ }
497
+
498
+ size_t block_end = start + 2;
499
+
500
+ while (block_end < size && !is_space(text[block_end])) {
501
+ ++block_end;
502
+ }
503
+
504
+ while (block_end > start) {
505
+ if (strchr(punct, text[block_end - 1]) == 0) {
506
+ break;
507
+ }
508
+ block_end--;
509
+ }
510
+
511
+ size_t i = block_end;
512
+
513
+ while (i > start && text[i - 1] == ')') {
514
+ i--;
515
+ }
516
+
517
+ if (i < block_end) {
518
+ block_end = i;
519
+ while (i > start) {
520
+ if (text[i] == '(') {
521
+ ++block_end;
522
+ break;
523
+ }
524
+ i--;
525
+ }
526
+ }
527
+
528
+ out_buf->size -= scheme_len;
529
+
530
+ buf_puts(out_buf, "<a href=\"");
531
+ escape_html(text, block_start, block_end, out_buf);
532
+ buf_puts(out_buf, "\">");
533
+ escape_html(text, block_start, block_end, out_buf);
534
+ buf_puts(out_buf, "</a>");
535
+
536
+ return block_end - start;
537
+ }
538
+
539
+ static size_t parse_linebreak(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
540
+ size_t count = 1;
541
+
542
+ buf_puts(out_buf, "<br>");
543
+
544
+ ++start;
545
+
546
+ while (start < size && text[start] == '\n') {
547
+ ++start;
548
+ ++count;
549
+ }
550
+
551
+ if (count > 1) {
552
+ buf_puts(out_buf, "<br>");
553
+ }
554
+
555
+ return count;
556
+ }
557
+
558
+ static size_t parse_maybequote(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
559
+ size_t count;
560
+
561
+ if (count = parse_quotelink(text, start, size, out_buf)) {
562
+ return count;
563
+ }
564
+
565
+ return parse_quote(text, start, size, out_buf);
566
+ }
567
+
568
+ static size_t parse_quotelink(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
569
+ if (start > 0 && is_alnum(text[start - 1])) {
570
+ return 0;
571
+ }
572
+
573
+ ++start;
574
+
575
+ if (start >= size || text[start] != '>') {
576
+ return 0;
577
+ }
578
+
579
+ ++start;
580
+
581
+ size_t end = start;
582
+ size_t count = end - start;
583
+
584
+ while (end < size && is_digit(text[end]) && count < 10) {
585
+ ++end;
586
+ ++count;
587
+ }
588
+
589
+ if (end == start || (end < size && is_alpha(text[end]))) {
590
+ return 0;
591
+ }
592
+
593
+ size_t i;
594
+ uint8_t num[count];
595
+
596
+ for (i = 0; i < count; ++i) {
597
+ num[i] = text[start + i];
598
+ }
599
+
600
+ buf_puts(out_buf, "<a class=\"ql\" href=\"#");
601
+ buf_append(out_buf, &num, count);
602
+ buf_puts(out_buf, "\">&gt;&gt;");
603
+ buf_append(out_buf, &num, count);
604
+ buf_puts(out_buf, "</a>");
605
+
606
+ return count + 2;
607
+ }
608
+
609
+ static size_t parse_quote(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
610
+ if (start > 0 && text[start - 1] != '\n') {
611
+ return 0;
612
+ }
613
+
614
+ size_t end = start;
615
+
616
+ while (end < size && text[end] != '\n' ) {
617
+ ++end;
618
+ }
619
+
620
+ size_t block_start = start + 1;
621
+
622
+ while (block_start + 2 < size && text[block_start + 2] == '>') {
623
+ ++block_start;
624
+ }
625
+
626
+ size_t count = block_start - start;
627
+
628
+ buf_puts(out_buf, "<span class=\"q\">&gt;");
629
+
630
+ while (count > 1) {
631
+ buf_puts(out_buf, "&gt;");
632
+ count--;
633
+ }
634
+
635
+ parse_text(text, block_start, end, out_buf);
636
+
637
+ buf_puts(out_buf, "</span>");
638
+
639
+ return end - start;
640
+ }
641
+
642
+ static size_t parse_text(const uint8_t *text, size_t start, size_t size, buffer *out_buf) {
643
+ uint8_t action = 0;
644
+ size_t from, count, end;
645
+
646
+ end = start;
647
+
648
+ while (end < size) {
649
+ from = end;
650
+
651
+ while (end < size && (action = trigger_map[text[end]]) == 0) {
652
+ ++end;
653
+ }
654
+
655
+ if (end > from) {
656
+ escape_html(text, from, end, out_buf);
657
+ }
658
+
659
+ if (end >= size) {
660
+ break;
661
+ }
662
+
663
+ if ((count = trigger_funcs[action](text, end, size, out_buf)) != 0) {
664
+ end += count;
665
+ }
666
+ else {
667
+ escape_html(text, end, end + 1, out_buf);
668
+ ++end;
669
+ }
670
+ }
671
+
672
+ return end - start;
673
+ }
674
+
675
+ static VALUE rb_hive_markup_render(VALUE self, VALUE text) {
676
+ Check_Type(text, T_STRING);
677
+
678
+ size_t size;
679
+ size = RSTRING_LEN(text);
680
+
681
+ buffer *pre_buf = buf_new();
682
+
683
+ if (!pre_buf) {
684
+ return Qnil;
685
+ }
686
+
687
+ buffer *out_buf = buf_new();
688
+
689
+ if (!out_buf) {
690
+ return Qnil;
691
+ }
692
+
693
+ buf_expand(pre_buf, size);
694
+ buf_expand(out_buf, size);
695
+
696
+ preprocess_text((const uint8_t *)StringValuePtr(text), size, pre_buf);
697
+
698
+ parse_text(pre_buf->data, 0, pre_buf->size, out_buf);
699
+
700
+ text = rb_enc_str_new(
701
+ (const char *)out_buf->data,
702
+ out_buf->size,
703
+ rb_enc_get(text)
704
+ );
705
+
706
+ buf_free(pre_buf);
707
+ buf_free(out_buf);
708
+
709
+ return text;
710
+ }
711
+
712
+ void Init_hive_markup() {
713
+ init_triggers();
714
+
715
+ rb_mHive = rb_define_module("Hive");
716
+ rb_cMarkup = rb_define_class_under(rb_mHive, "Markup", rb_cObject);
717
+
718
+ rb_define_singleton_method(rb_cMarkup, "render", rb_hive_markup_render, 1);
719
+ }
@@ -0,0 +1,70 @@
1
+ /*
2
+ * Copyright (c) 2012, Vicent Marti
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ * THE SOFTWARE.
21
+ */
22
+
23
+ #ifndef HOUDINI_H
24
+ #define HOUDINI_H
25
+
26
+ /**
27
+ * According to the OWASP rules:
28
+ *
29
+ * & --> &amp;
30
+ * < --> &lt;
31
+ * > --> &gt;
32
+ * " --> &quot;
33
+ * ' --> &#x27; &apos; is not recommended
34
+ * / --> &#x2F; forward slash is included as it helps end an HTML entity
35
+ *
36
+ */
37
+ const char HTML_ESCAPE_TABLE[] = {
38
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40
+ 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
41
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
42
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54
+ };
55
+
56
+ const char *HTML_ESCAPES[] = {
57
+ "",
58
+ "&quot;",
59
+ "&amp;",
60
+ "&#39;",
61
+ "&#47;",
62
+ "&lt;",
63
+ "&gt;"
64
+ };
65
+
66
+ const char HTML_ESCAPES_LEN[] = {
67
+ 0, 6, 5, 5, 5, 4, 4
68
+ };
69
+
70
+ #endif
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'hive_markup'
3
+ s.version = '0.0.1'
4
+ s.summary = 'Markup parser for HiveBBS'
5
+ s.author = 'Maxime Youdine'
6
+ s.license = 'MIT'
7
+ s.homepage = 'https://github.com/desuwa/hive_markup'
8
+ s.required_ruby_version = '>= 1.9.3'
9
+ s.files = %w[
10
+ hive_markup.gemspec
11
+ lib/hive_markup/hive_markup.rb
12
+ ext/hive_markup/extconf.rb
13
+ ext/hive_markup/houdini.h
14
+ ext/hive_markup/hive_markup.c
15
+ ]
16
+ s.extensions = ['ext/hive_markup/extconf.rb']
17
+ s.require_paths = ['lib']
18
+ end
@@ -0,0 +1 @@
1
+ require 'hive_markup.so'
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hive_markup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Maxime Youdine
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ executables: []
16
+ extensions:
17
+ - ext/hive_markup/extconf.rb
18
+ extra_rdoc_files: []
19
+ files:
20
+ - hive_markup.gemspec
21
+ - lib/hive_markup/hive_markup.rb
22
+ - ext/hive_markup/extconf.rb
23
+ - ext/hive_markup/houdini.h
24
+ - ext/hive_markup/hive_markup.c
25
+ homepage: https://github.com/desuwa/hive_markup
26
+ licenses:
27
+ - MIT
28
+ metadata: {}
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.9.3
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 2.0.14
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: Markup parser for HiveBBS
49
+ test_files: []