redcarpet 1.17.2 → 2.0.0b
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- data/README.markdown +232 -37
- data/Rakefile +13 -15
- data/bin/redcarpet +1 -1
- data/ext/redcarpet/autolink.c +5 -5
- data/ext/redcarpet/autolink.h +7 -4
- data/ext/redcarpet/html.c +83 -71
- data/ext/redcarpet/html.h +14 -5
- data/ext/redcarpet/html_smartypants.c +35 -11
- data/ext/redcarpet/markdown.c +153 -85
- data/ext/redcarpet/markdown.h +6 -10
- data/ext/redcarpet/rc_markdown.c +108 -0
- data/ext/redcarpet/rc_render.c +469 -0
- data/lib/redcarpet.rb +68 -106
- data/redcarpet.gemspec +8 -11
- data/test/redcarpet_test.rb +206 -122
- metadata +17 -18
- data/ext/redcarpet/redcarpet.c +0 -161
- data/lib/markdown.rb +0 -1
- data/test/benchmark.rb +0 -56
- data/test/benchmark.txt +0 -306
- data/test/markdown_test.rb +0 -186
data/ext/redcarpet/html.h
CHANGED
@@ -34,20 +34,29 @@ typedef enum {
|
|
34
34
|
HTML_USE_XHTML = (1 << 11),
|
35
35
|
} render_mode;
|
36
36
|
|
37
|
+
typedef enum {
|
38
|
+
HTML_TAG_NONE = 0,
|
39
|
+
HTML_TAG_OPEN,
|
40
|
+
HTML_TAG_CLOSE,
|
41
|
+
} html_tag;
|
42
|
+
|
37
43
|
void
|
38
|
-
|
44
|
+
sdhtml_escape(struct buf *ob, const char *src, size_t size);
|
45
|
+
|
46
|
+
int
|
47
|
+
sdhtml_tag(const char *tag_data, size_t tag_size, const char *tagname);
|
39
48
|
|
40
49
|
extern void
|
41
|
-
|
50
|
+
sdhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags, void *extra);
|
42
51
|
|
43
52
|
extern void
|
44
|
-
|
53
|
+
sdhtml_toc_renderer(struct mkd_renderer *renderer, void *extra);
|
45
54
|
|
46
55
|
extern void
|
47
|
-
|
56
|
+
sdhtml_free_renderer(struct mkd_renderer *renderer);
|
48
57
|
|
49
58
|
extern void
|
50
|
-
|
59
|
+
sdhtml_smartypants(struct buf *ob, struct buf *text);
|
51
60
|
|
52
61
|
#endif
|
53
62
|
|
@@ -161,16 +161,14 @@ smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, char previ
|
|
161
161
|
static size_t
|
162
162
|
smartypants_cb__dash(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)
|
163
163
|
{
|
164
|
-
if (size >= 2) {
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
}
|
164
|
+
if (size >= 3 && text[1] == '-' && text[2] == '-') {
|
165
|
+
BUFPUTSL(ob, "—");
|
166
|
+
return 2;
|
167
|
+
}
|
169
168
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
}
|
169
|
+
if (size >= 2 && text[1] == '-') {
|
170
|
+
BUFPUTSL(ob, "–");
|
171
|
+
return 1;
|
174
172
|
}
|
175
173
|
|
176
174
|
bufputc(ob, text[0]);
|
@@ -264,11 +262,37 @@ smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, char previ
|
|
264
262
|
static size_t
|
265
263
|
smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)
|
266
264
|
{
|
267
|
-
|
265
|
+
static const char *skip_tags[] = {"pre", "code", "kbd", "script"};
|
266
|
+
static const size_t skip_tags_count = 4;
|
267
|
+
|
268
|
+
size_t tag, i = 0;
|
268
269
|
|
269
270
|
while (i < size && text[i] != '>')
|
270
271
|
i++;
|
271
272
|
|
273
|
+
for (tag = 0; tag < skip_tags_count; ++tag) {
|
274
|
+
if (sdhtml_tag(text, size, skip_tags[tag]) == HTML_TAG_OPEN)
|
275
|
+
break;
|
276
|
+
}
|
277
|
+
|
278
|
+
if (tag < skip_tags_count) {
|
279
|
+
for (;;) {
|
280
|
+
while (i < size && text[i] != '<')
|
281
|
+
i++;
|
282
|
+
|
283
|
+
if (i == size)
|
284
|
+
break;
|
285
|
+
|
286
|
+
if (sdhtml_tag(text + i, size - i, skip_tags[tag]) == HTML_TAG_CLOSE)
|
287
|
+
break;
|
288
|
+
|
289
|
+
i++;
|
290
|
+
}
|
291
|
+
|
292
|
+
while (i < size && text[i] != '>')
|
293
|
+
i++;
|
294
|
+
}
|
295
|
+
|
272
296
|
bufput(ob, text, i + 1);
|
273
297
|
return i;
|
274
298
|
}
|
@@ -304,7 +328,7 @@ static struct {
|
|
304
328
|
#endif
|
305
329
|
|
306
330
|
void
|
307
|
-
|
331
|
+
sdhtml_smartypants(struct buf *ob, struct buf *text)
|
308
332
|
{
|
309
333
|
size_t i;
|
310
334
|
struct smartypants_data smrt = {0, 0};
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -60,6 +60,7 @@ static size_t char_autolink_url(struct buf *ob, struct render *rndr, char *data,
|
|
60
60
|
static size_t char_autolink_email(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
61
61
|
static size_t char_autolink_www(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
62
62
|
static size_t char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
63
|
+
static size_t char_superscript(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
63
64
|
|
64
65
|
enum markdown_char_t {
|
65
66
|
MD_CHAR_NONE = 0,
|
@@ -72,7 +73,8 @@ enum markdown_char_t {
|
|
72
73
|
MD_CHAR_ENTITITY,
|
73
74
|
MD_CHAR_AUTOLINK_URL,
|
74
75
|
MD_CHAR_AUTOLINK_EMAIL,
|
75
|
-
MD_CHAR_AUTOLINK_WWW
|
76
|
+
MD_CHAR_AUTOLINK_WWW,
|
77
|
+
MD_CHAR_SUPERSCRIPT,
|
76
78
|
};
|
77
79
|
|
78
80
|
static char_trigger markdown_char_ptrs[] = {
|
@@ -87,6 +89,7 @@ static char_trigger markdown_char_ptrs[] = {
|
|
87
89
|
&char_autolink_url,
|
88
90
|
&char_autolink_email,
|
89
91
|
&char_autolink_www,
|
92
|
+
&char_superscript,
|
90
93
|
};
|
91
94
|
|
92
95
|
/* render • structure containing one particular render */
|
@@ -145,13 +148,14 @@ static struct html_tag block_tags[] = {
|
|
145
148
|
{ "h6", 2 },
|
146
149
|
{ "ol", 2 },
|
147
150
|
{ "ul", 2 },
|
148
|
-
|
151
|
+
{ "del", 3 }, /* 10 */
|
149
152
|
{ "div", 3 },
|
150
|
-
|
153
|
+
{ "ins", 3 }, /* 12 */
|
151
154
|
{ "pre", 3 },
|
152
155
|
{ "form", 4 },
|
153
156
|
{ "math", 4 },
|
154
157
|
{ "table", 5 },
|
158
|
+
{ "figure", 6 },
|
155
159
|
{ "iframe", 6 },
|
156
160
|
{ "script", 6 },
|
157
161
|
{ "fieldset", 8 },
|
@@ -224,7 +228,7 @@ find_block_tag(char *data, size_t size)
|
|
224
228
|
while (i < size && ((data[i] >= '0' && data[i] <= '9')
|
225
229
|
|| (data[i] >= 'A' && data[i] <= 'Z')
|
226
230
|
|| (data[i] >= 'a' && data[i] <= 'z')))
|
227
|
-
i
|
231
|
+
i++;
|
228
232
|
if (i >= size) return 0;
|
229
233
|
|
230
234
|
/* binary search of the tag */
|
@@ -317,7 +321,7 @@ tag_length(char *data, size_t size, enum mkd_autolink *autolink)
|
|
317
321
|
if (data[i] == '\\') i += 2;
|
318
322
|
else if (data[i] == '>' || data[i] == '\'' ||
|
319
323
|
data[i] == '"' || isspace(data[i])) break;
|
320
|
-
else i
|
324
|
+
else i++;
|
321
325
|
}
|
322
326
|
|
323
327
|
if (i >= size) return 0;
|
@@ -327,7 +331,7 @@ tag_length(char *data, size_t size, enum mkd_autolink *autolink)
|
|
327
331
|
}
|
328
332
|
|
329
333
|
/* looking for sometinhg looking like a tag end */
|
330
|
-
while (i < size && data[i] != '>') i
|
334
|
+
while (i < size && data[i] != '>') i++;
|
331
335
|
if (i >= size) return 0;
|
332
336
|
return i + 1;
|
333
337
|
}
|
@@ -379,47 +383,72 @@ find_emph_char(char *data, size_t size, char c)
|
|
379
383
|
size_t i = 1;
|
380
384
|
|
381
385
|
while (i < size) {
|
382
|
-
while (i < size && data[i] != c
|
383
|
-
|
384
|
-
|
385
|
-
if (
|
386
|
+
while (i < size && data[i] != c && data[i] != '`' && data[i] != '[')
|
387
|
+
i++;
|
388
|
+
|
389
|
+
if (i == size)
|
390
|
+
return 0;
|
391
|
+
|
392
|
+
if (data[i] == c)
|
393
|
+
return i;
|
386
394
|
|
387
395
|
/* not counting escaped chars */
|
388
|
-
if (i && data[i - 1] == '\\') {
|
396
|
+
if (i && data[i - 1] == '\\') {
|
397
|
+
i++; continue;
|
398
|
+
}
|
389
399
|
|
390
400
|
/* skipping a code span */
|
391
401
|
if (data[i] == '`') {
|
392
402
|
size_t tmp_i = 0;
|
393
|
-
|
403
|
+
|
404
|
+
i++;
|
394
405
|
while (i < size && data[i] != '`') {
|
395
406
|
if (!tmp_i && data[i] == c) tmp_i = i;
|
396
|
-
i
|
397
|
-
|
398
|
-
|
407
|
+
i++;
|
408
|
+
}
|
409
|
+
|
410
|
+
if (i >= size)
|
411
|
+
return tmp_i;
|
399
412
|
|
413
|
+
i++;
|
414
|
+
}
|
400
415
|
/* skipping a link */
|
401
416
|
else if (data[i] == '[') {
|
402
417
|
size_t tmp_i = 0;
|
403
418
|
char cc;
|
404
|
-
|
419
|
+
|
420
|
+
i++;
|
405
421
|
while (i < size && data[i] != ']') {
|
406
422
|
if (!tmp_i && data[i] == c) tmp_i = i;
|
407
|
-
i
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
423
|
+
i++;
|
424
|
+
}
|
425
|
+
|
426
|
+
i++;
|
427
|
+
while (i < size && (data[i] == ' ' || data[i] == '\t' || data[i] == '\n'))
|
428
|
+
i++;
|
429
|
+
|
430
|
+
if (i >= size)
|
431
|
+
return tmp_i;
|
432
|
+
|
413
433
|
if (data[i] != '[' && data[i] != '(') { /* not a link*/
|
414
434
|
if (tmp_i) return tmp_i;
|
415
|
-
else continue;
|
435
|
+
else continue;
|
436
|
+
}
|
437
|
+
|
416
438
|
cc = data[i];
|
417
|
-
i
|
439
|
+
i++;
|
418
440
|
while (i < size && data[i] != cc) {
|
419
441
|
if (!tmp_i && data[i] == c) tmp_i = i;
|
420
|
-
i
|
421
|
-
|
422
|
-
|
442
|
+
i++;
|
443
|
+
}
|
444
|
+
|
445
|
+
if (i >= size)
|
446
|
+
return tmp_i;
|
447
|
+
|
448
|
+
i++;
|
449
|
+
}
|
450
|
+
}
|
451
|
+
|
423
452
|
return 0;
|
424
453
|
}
|
425
454
|
|
@@ -444,7 +473,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
|
|
444
473
|
if (i >= size) return 0;
|
445
474
|
|
446
475
|
if (i + 1 < size && data[i + 1] == c) {
|
447
|
-
i
|
476
|
+
i++;
|
448
477
|
continue;
|
449
478
|
}
|
450
479
|
|
@@ -668,7 +697,7 @@ char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size
|
|
668
697
|
end++;
|
669
698
|
|
670
699
|
if (end < size && data[end] == ';')
|
671
|
-
end
|
700
|
+
end++; /* real entity */
|
672
701
|
else
|
673
702
|
return 0; /* lone '&' */
|
674
703
|
|
@@ -719,7 +748,7 @@ char_autolink_www(struct buf *ob, struct render *rndr, char *data, size_t offset
|
|
719
748
|
|
720
749
|
link = rndr_newbuf(rndr, BUFFER_SPAN);
|
721
750
|
|
722
|
-
if ((link_len =
|
751
|
+
if ((link_len = sd_autolink__www(&rewind, link, data, offset, size)) > 0) {
|
723
752
|
link_url = rndr_newbuf(rndr, BUFFER_SPAN);
|
724
753
|
BUFPUTSL(link_url, "http://");
|
725
754
|
bufput(link_url, link->data, link->size);
|
@@ -744,7 +773,7 @@ char_autolink_email(struct buf *ob, struct render *rndr, char *data, size_t offs
|
|
744
773
|
|
745
774
|
link = rndr_newbuf(rndr, BUFFER_SPAN);
|
746
775
|
|
747
|
-
if ((link_len =
|
776
|
+
if ((link_len = sd_autolink__email(&rewind, link, data, offset, size)) > 0) {
|
748
777
|
ob->size -= rewind;
|
749
778
|
rndr->make.autolink(ob, link, MKDA_EMAIL, rndr->make.opaque);
|
750
779
|
}
|
@@ -764,7 +793,7 @@ char_autolink_url(struct buf *ob, struct render *rndr, char *data, size_t offset
|
|
764
793
|
|
765
794
|
link = rndr_newbuf(rndr, BUFFER_SPAN);
|
766
795
|
|
767
|
-
if ((link_len =
|
796
|
+
if ((link_len = sd_autolink__url(&rewind, link, data, offset, size)) > 0) {
|
768
797
|
ob->size -= rewind;
|
769
798
|
rndr->make.autolink(ob, link, MKDA_NORMAL, rndr->make.opaque);
|
770
799
|
}
|
@@ -791,7 +820,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
791
820
|
goto cleanup;
|
792
821
|
|
793
822
|
/* looking for the matching closing bracket */
|
794
|
-
for (level = 1; i < size; i
|
823
|
+
for (level = 1; i < size; i++) {
|
795
824
|
if (data[i] == '\n')
|
796
825
|
text_has_nl = 1;
|
797
826
|
|
@@ -812,7 +841,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
812
841
|
goto cleanup;
|
813
842
|
|
814
843
|
txt_e = i;
|
815
|
-
i
|
844
|
+
i++;
|
816
845
|
|
817
846
|
/* skip any amount of whitespace or newline */
|
818
847
|
/* (this is much more laxist than original markdown syntax) */
|
@@ -822,7 +851,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
822
851
|
/* inline style link */
|
823
852
|
if (i < size && data[i] == '(') {
|
824
853
|
/* skipping initial whitespace */
|
825
|
-
i
|
854
|
+
i++;
|
826
855
|
|
827
856
|
while (i < size && isspace(data[i]))
|
828
857
|
i++;
|
@@ -833,7 +862,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
833
862
|
while (i < size) {
|
834
863
|
if (data[i] == '\\') i += 2;
|
835
864
|
else if (data[i] == ')' || data[i] == '\'' || data[i] == '"') break;
|
836
|
-
else i
|
865
|
+
else i++;
|
837
866
|
}
|
838
867
|
|
839
868
|
if (i >= size) goto cleanup;
|
@@ -847,7 +876,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
847
876
|
while (i < size) {
|
848
877
|
if (data[i] == '\\') i += 2;
|
849
878
|
else if (data[i] == ')') break;
|
850
|
-
else i
|
879
|
+
else i++;
|
851
880
|
}
|
852
881
|
|
853
882
|
if (i >= size) goto cleanup;
|
@@ -892,7 +921,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
892
921
|
struct link_ref *lr;
|
893
922
|
|
894
923
|
/* looking for the id */
|
895
|
-
i
|
924
|
+
i++;
|
896
925
|
link_b = i;
|
897
926
|
while (i < size && data[i] != ']') i++;
|
898
927
|
if (i >= size) goto cleanup;
|
@@ -928,7 +957,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
928
957
|
/* keeping link and title from link_ref */
|
929
958
|
link = lr->link;
|
930
959
|
title = lr->title;
|
931
|
-
i
|
960
|
+
i++;
|
932
961
|
}
|
933
962
|
|
934
963
|
/* shortcut reference style link */
|
@@ -995,7 +1024,43 @@ cleanup:
|
|
995
1024
|
return ret ? i : 0;
|
996
1025
|
}
|
997
1026
|
|
1027
|
+
static size_t
|
1028
|
+
char_superscript(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
|
1029
|
+
{
|
1030
|
+
size_t sup_start, sup_len;
|
1031
|
+
struct buf *sup;
|
1032
|
+
|
1033
|
+
if (!rndr->make.superscript)
|
1034
|
+
return 0;
|
1035
|
+
|
1036
|
+
if (size < 2)
|
1037
|
+
return 0;
|
1038
|
+
|
1039
|
+
if (data[1] == '(') {
|
1040
|
+
sup_start = sup_len = 2;
|
1041
|
+
|
1042
|
+
while (sup_len < size && data[sup_len] != ')' && data[sup_len - 1] != '\\')
|
1043
|
+
sup_len++;
|
998
1044
|
|
1045
|
+
if (sup_len == size)
|
1046
|
+
return 0;
|
1047
|
+
} else {
|
1048
|
+
sup_start = sup_len = 1;
|
1049
|
+
|
1050
|
+
while (sup_len < size && !isspace(data[sup_len]))
|
1051
|
+
sup_len++;
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
if (sup_len - sup_start == 0)
|
1055
|
+
return (sup_start == 2) ? 3 : 0;
|
1056
|
+
|
1057
|
+
sup = rndr_newbuf(rndr, BUFFER_SPAN);
|
1058
|
+
parse_inline(sup, rndr, data + sup_start, sup_len - sup_start);
|
1059
|
+
rndr->make.superscript(ob, sup, rndr->make.opaque);
|
1060
|
+
rndr_popbuf(rndr, BUFFER_SPAN);
|
1061
|
+
|
1062
|
+
return (sup_start == 2) ? sup_len + 1 : sup_len;
|
1063
|
+
}
|
999
1064
|
|
1000
1065
|
/*********************************
|
1001
1066
|
* BLOCK-LEVEL PARSING FUNCTIONS *
|
@@ -1006,7 +1071,7 @@ static size_t
|
|
1006
1071
|
is_empty(char *data, size_t size)
|
1007
1072
|
{
|
1008
1073
|
size_t i;
|
1009
|
-
for (i = 0; i < size && data[i] != '\n'; i
|
1074
|
+
for (i = 0; i < size && data[i] != '\n'; i++)
|
1010
1075
|
if (data[i] != ' ' && data[i] != '\t') return 0;
|
1011
1076
|
return i + 1;
|
1012
1077
|
}
|
@@ -1020,9 +1085,9 @@ is_hrule(char *data, size_t size)
|
|
1020
1085
|
|
1021
1086
|
/* skipping initial spaces */
|
1022
1087
|
if (size < 3) return 0;
|
1023
|
-
if (data[0] == ' ') { i
|
1024
|
-
if (data[1] == ' ') { i
|
1025
|
-
if (data[2] == ' ') { i
|
1088
|
+
if (data[0] == ' ') { i++;
|
1089
|
+
if (data[1] == ' ') { i++;
|
1090
|
+
if (data[2] == ' ') { i++; } } }
|
1026
1091
|
|
1027
1092
|
/* looking at the hrule char */
|
1028
1093
|
if (i + 2 >= size
|
@@ -1032,10 +1097,10 @@ is_hrule(char *data, size_t size)
|
|
1032
1097
|
|
1033
1098
|
/* the whole line must be the char or whitespace */
|
1034
1099
|
while (i < size && data[i] != '\n') {
|
1035
|
-
if (data[i] == c) n
|
1100
|
+
if (data[i] == c) n++;
|
1036
1101
|
else if (data[i] != ' ' && data[i] != '\t')
|
1037
1102
|
return 0;
|
1038
|
-
i
|
1103
|
+
i++; }
|
1039
1104
|
|
1040
1105
|
return n >= 3;
|
1041
1106
|
}
|
@@ -1049,9 +1114,9 @@ is_codefence(char *data, size_t size, struct buf *syntax)
|
|
1049
1114
|
|
1050
1115
|
/* skipping initial spaces */
|
1051
1116
|
if (size < 3) return 0;
|
1052
|
-
if (data[0] == ' ') { i
|
1053
|
-
if (data[1] == ' ') { i
|
1054
|
-
if (data[2] == ' ') { i
|
1117
|
+
if (data[0] == ' ') { i++;
|
1118
|
+
if (data[1] == ' ') { i++;
|
1119
|
+
if (data[2] == ' ') { i++; } } }
|
1055
1120
|
|
1056
1121
|
/* looking at the hrule char */
|
1057
1122
|
if (i + 2 >= size || !(data[i] == '~' || data[i] == '`'))
|
@@ -1142,14 +1207,14 @@ is_headerline(char *data, size_t size)
|
|
1142
1207
|
|
1143
1208
|
/* test of level 1 header */
|
1144
1209
|
if (data[i] == '=') {
|
1145
|
-
for (i = 1; i < size && data[i] == '='; i
|
1146
|
-
while (i < size && (data[i] == ' ' || data[i] == '\t')) i
|
1210
|
+
for (i = 1; i < size && data[i] == '='; i++);
|
1211
|
+
while (i < size && (data[i] == ' ' || data[i] == '\t')) i++;
|
1147
1212
|
return (i >= size || data[i] == '\n') ? 1 : 0; }
|
1148
1213
|
|
1149
1214
|
/* test of level 2 header */
|
1150
1215
|
if (data[i] == '-') {
|
1151
|
-
for (i = 1; i < size && data[i] == '-'; i
|
1152
|
-
while (i < size && (data[i] == ' ' || data[i] == '\t')) i
|
1216
|
+
for (i = 1; i < size && data[i] == '-'; i++);
|
1217
|
+
while (i < size && (data[i] == ' ' || data[i] == '\t')) i++;
|
1153
1218
|
return (i >= size || data[i] == '\n') ? 2 : 0; }
|
1154
1219
|
|
1155
1220
|
return 0;
|
@@ -1160,9 +1225,9 @@ static size_t
|
|
1160
1225
|
prefix_quote(char *data, size_t size)
|
1161
1226
|
{
|
1162
1227
|
size_t i = 0;
|
1163
|
-
if (i < size && data[i] == ' ') i
|
1164
|
-
if (i < size && data[i] == ' ') i
|
1165
|
-
if (i < size && data[i] == ' ') i
|
1228
|
+
if (i < size && data[i] == ' ') i++;
|
1229
|
+
if (i < size && data[i] == ' ') i++;
|
1230
|
+
if (i < size && data[i] == ' ') i++;
|
1166
1231
|
if (i < size && data[i] == '>') {
|
1167
1232
|
if (i + 1 < size && (data[i + 1] == ' ' || data[i+1] == '\t'))
|
1168
1233
|
return i + 2;
|
@@ -1185,11 +1250,11 @@ static size_t
|
|
1185
1250
|
prefix_oli(char *data, size_t size)
|
1186
1251
|
{
|
1187
1252
|
size_t i = 0;
|
1188
|
-
if (i < size && data[i] == ' ') i
|
1189
|
-
if (i < size && data[i] == ' ') i
|
1190
|
-
if (i < size && data[i] == ' ') i
|
1253
|
+
if (i < size && data[i] == ' ') i++;
|
1254
|
+
if (i < size && data[i] == ' ') i++;
|
1255
|
+
if (i < size && data[i] == ' ') i++;
|
1191
1256
|
if (i >= size || data[i] < '0' || data[i] > '9') return 0;
|
1192
|
-
while (i < size && data[i] >= '0' && data[i] <= '9') i
|
1257
|
+
while (i < size && data[i] >= '0' && data[i] <= '9') i++;
|
1193
1258
|
if (i + 1 >= size || data[i] != '.'
|
1194
1259
|
|| (data[i + 1] != ' ' && data[i + 1] != '\t')) return 0;
|
1195
1260
|
return i + 2;
|
@@ -1200,9 +1265,9 @@ static size_t
|
|
1200
1265
|
prefix_uli(char *data, size_t size)
|
1201
1266
|
{
|
1202
1267
|
size_t i = 0;
|
1203
|
-
if (i < size && data[i] == ' ') i
|
1204
|
-
if (i < size && data[i] == ' ') i
|
1205
|
-
if (i < size && data[i] == ' ') i
|
1268
|
+
if (i < size && data[i] == ' ') i++;
|
1269
|
+
if (i < size && data[i] == ' ') i++;
|
1270
|
+
if (i < size && data[i] == ' ') i++;
|
1206
1271
|
if (i + 1 >= size
|
1207
1272
|
|| (data[i] != '*' && data[i] != '+' && data[i] != '-')
|
1208
1273
|
|| (data[i + 1] != ' ' && data[i + 1] != '\t'))
|
@@ -1363,7 +1428,7 @@ parse_fencedcode(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1363
1428
|
break;
|
1364
1429
|
}
|
1365
1430
|
|
1366
|
-
for (end = beg + 1; end < size && data[end - 1] != '\n'; end
|
1431
|
+
for (end = beg + 1; end < size && data[end - 1] != '\n'; end++);
|
1367
1432
|
|
1368
1433
|
if (beg < end) {
|
1369
1434
|
/* verbatim copy to the working buffer,
|
@@ -1677,10 +1742,10 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
|
|
1677
1742
|
if (size > 4 && (data[1] == 'h' || data[1] == 'H') && (data[2] == 'r' || data[2] == 'R')) {
|
1678
1743
|
i = 3;
|
1679
1744
|
while (i < size && data[i] != '>')
|
1680
|
-
i
|
1745
|
+
i++;
|
1681
1746
|
|
1682
1747
|
if (i + 1 < size) {
|
1683
|
-
i
|
1748
|
+
i++;
|
1684
1749
|
j = is_empty(data + i, size - i);
|
1685
1750
|
if (j) {
|
1686
1751
|
work.size = i + j;
|
@@ -1991,34 +2056,34 @@ is_ref(char *data, size_t beg, size_t end, size_t *last, struct array *refs)
|
|
1991
2056
|
|
1992
2057
|
/* id part: anything but a newline between brackets */
|
1993
2058
|
if (data[i] != '[') return 0;
|
1994
|
-
i
|
2059
|
+
i++;
|
1995
2060
|
id_offset = i;
|
1996
2061
|
while (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != ']')
|
1997
|
-
i
|
2062
|
+
i++;
|
1998
2063
|
if (i >= end || data[i] != ']') return 0;
|
1999
2064
|
id_end = i;
|
2000
2065
|
|
2001
2066
|
/* spacer: colon (space | tab)* newline? (space | tab)* */
|
2002
|
-
i
|
2067
|
+
i++;
|
2003
2068
|
if (i >= end || data[i] != ':') return 0;
|
2004
|
-
i
|
2005
|
-
while (i < end && (data[i] == ' ' || data[i] == '\t')) i
|
2069
|
+
i++;
|
2070
|
+
while (i < end && (data[i] == ' ' || data[i] == '\t')) i++;
|
2006
2071
|
if (i < end && (data[i] == '\n' || data[i] == '\r')) {
|
2007
|
-
i
|
2008
|
-
if (i < end && data[i] == '\r' && data[i - 1] == '\n') i
|
2009
|
-
while (i < end && (data[i] == ' ' || data[i] == '\t')) i
|
2072
|
+
i++;
|
2073
|
+
if (i < end && data[i] == '\r' && data[i - 1] == '\n') i++; }
|
2074
|
+
while (i < end && (data[i] == ' ' || data[i] == '\t')) i++;
|
2010
2075
|
if (i >= end) return 0;
|
2011
2076
|
|
2012
2077
|
/* link: whitespace-free sequence, optionally between angle brackets */
|
2013
|
-
if (data[i] == '<') i
|
2078
|
+
if (data[i] == '<') i++;
|
2014
2079
|
link_offset = i;
|
2015
2080
|
while (i < end && data[i] != ' ' && data[i] != '\t'
|
2016
|
-
&& data[i] != '\n' && data[i] != '\r') i
|
2081
|
+
&& data[i] != '\n' && data[i] != '\r') i++;
|
2017
2082
|
if (data[i - 1] == '>') link_end = i - 1;
|
2018
2083
|
else link_end = i;
|
2019
2084
|
|
2020
2085
|
/* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
|
2021
|
-
while (i < end && (data[i] == ' ' || data[i] == '\t')) i
|
2086
|
+
while (i < end && (data[i] == ' ' || data[i] == '\t')) i++;
|
2022
2087
|
if (i < end && data[i] != '\n' && data[i] != '\r'
|
2023
2088
|
&& data[i] != '\'' && data[i] != '"' && data[i] != '(')
|
2024
2089
|
return 0;
|
@@ -2031,17 +2096,17 @@ is_ref(char *data, size_t beg, size_t end, size_t *last, struct array *refs)
|
|
2031
2096
|
/* optional (space|tab)* spacer after a newline */
|
2032
2097
|
if (line_end) {
|
2033
2098
|
i = line_end + 1;
|
2034
|
-
while (i < end && (data[i] == ' ' || data[i] == '\t')) i
|
2099
|
+
while (i < end && (data[i] == ' ' || data[i] == '\t')) i++; }
|
2035
2100
|
|
2036
2101
|
/* optional title: any non-newline sequence enclosed in '"()
|
2037
2102
|
alone on its line */
|
2038
2103
|
title_offset = title_end = 0;
|
2039
2104
|
if (i + 1 < end
|
2040
2105
|
&& (data[i] == '\'' || data[i] == '"' || data[i] == '(')) {
|
2041
|
-
i
|
2106
|
+
i++;
|
2042
2107
|
title_offset = i;
|
2043
2108
|
/* looking for EOL */
|
2044
|
-
while (i < end && data[i] != '\n' && data[i] != '\r') i
|
2109
|
+
while (i < end && data[i] != '\n' && data[i] != '\r') i++;
|
2045
2110
|
if (i + 1 < end && data[i] == '\n' && data[i + 1] == '\r')
|
2046
2111
|
title_end = i + 1;
|
2047
2112
|
else title_end = i;
|
@@ -2102,7 +2167,7 @@ static void expand_tabs(struct buf *ob, const char *line, size_t size)
|
|
2102
2167
|
|
2103
2168
|
/* markdown • parses the input buffer and renders it into the output buffer */
|
2104
2169
|
void
|
2105
|
-
|
2170
|
+
sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer, unsigned int extensions) {
|
2106
2171
|
struct link_ref *lr;
|
2107
2172
|
struct buf *text;
|
2108
2173
|
size_t i, beg, end;
|
@@ -2124,7 +2189,7 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
|
|
2124
2189
|
parr_init(&rndr.work_bufs[BUFFER_BLOCK]);
|
2125
2190
|
parr_init(&rndr.work_bufs[BUFFER_SPAN]);
|
2126
2191
|
|
2127
|
-
for (i = 0; i < 256; i
|
2192
|
+
for (i = 0; i < 256; i++)
|
2128
2193
|
rndr.active_char[i] = 0;
|
2129
2194
|
|
2130
2195
|
if (rndr.make.emphasis || rndr.make.double_emphasis || rndr.make.triple_emphasis) {
|
@@ -2153,6 +2218,9 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
|
|
2153
2218
|
rndr.active_char['w'] = MD_CHAR_AUTOLINK_WWW;
|
2154
2219
|
}
|
2155
2220
|
|
2221
|
+
if (extensions & MKDEXT_SUPERSCRIPT)
|
2222
|
+
rndr.active_char['^'] = MD_CHAR_SUPERSCRIPT;
|
2223
|
+
|
2156
2224
|
/* Extension data */
|
2157
2225
|
rndr.ext_flags = extensions;
|
2158
2226
|
rndr.max_nesting = 16;
|
@@ -2165,7 +2233,7 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
|
|
2165
2233
|
else { /* skipping to the next line */
|
2166
2234
|
end = beg;
|
2167
2235
|
while (end < ib->size && ib->data[end] != '\n' && ib->data[end] != '\r')
|
2168
|
-
end
|
2236
|
+
end++;
|
2169
2237
|
|
2170
2238
|
/* adding the line body if present */
|
2171
2239
|
if (end > beg)
|
@@ -2175,7 +2243,7 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
|
|
2175
2243
|
/* add one \n per newline */
|
2176
2244
|
if (ib->data[end] == '\n' || (end + 1 < ib->size && ib->data[end + 1] != '\n'))
|
2177
2245
|
bufputc(text, '\n');
|
2178
|
-
end
|
2246
|
+
end++;
|
2179
2247
|
}
|
2180
2248
|
|
2181
2249
|
beg = end;
|
@@ -2203,7 +2271,7 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
|
|
2203
2271
|
/* clean-up */
|
2204
2272
|
bufrelease(text);
|
2205
2273
|
lr = rndr.refs.base;
|
2206
|
-
for (i = 0; i < (size_t)rndr.refs.size; i
|
2274
|
+
for (i = 0; i < (size_t)rndr.refs.size; i++) {
|
2207
2275
|
bufrelease(lr[i].id);
|
2208
2276
|
bufrelease(lr[i].link);
|
2209
2277
|
bufrelease(lr[i].title);
|
@@ -2225,7 +2293,7 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
|
|
2225
2293
|
}
|
2226
2294
|
|
2227
2295
|
void
|
2228
|
-
|
2296
|
+
sd_version(int *ver_major, int *ver_minor, int *ver_revision)
|
2229
2297
|
{
|
2230
2298
|
*ver_major = UPSKIRT_VER_MAJOR;
|
2231
2299
|
*ver_minor = UPSKIRT_VER_MINOR;
|