redcarpet 1.7.1 → 1.8.0
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/ext/markdown.c +88 -209
- data/ext/markdown.h +1 -1
- data/ext/redcarpet.c +3 -0
- data/ext/xhtml.c +31 -11
- data/ext/xhtml.h +1 -0
- data/lib/redcarpet.rb +4 -1
- data/redcarpet.gemspec +1 -1
- data/test/redcarpet_test.rb +10 -0
- metadata +4 -4
data/ext/markdown.c
CHANGED
@@ -66,6 +66,28 @@ struct html_tag {
|
|
66
66
|
size_t size;
|
67
67
|
};
|
68
68
|
|
69
|
+
static inline struct buf *
|
70
|
+
rndr_newbuf(struct render *rndr)
|
71
|
+
{
|
72
|
+
struct buf *work = NULL;
|
73
|
+
|
74
|
+
if (rndr->work.size < rndr->work.asize) {
|
75
|
+
work = rndr->work.item[rndr->work.size++];
|
76
|
+
work->size = 0;
|
77
|
+
} else {
|
78
|
+
work = bufnew(WORK_UNIT);
|
79
|
+
parr_push(&rndr->work, work);
|
80
|
+
}
|
81
|
+
|
82
|
+
return work;
|
83
|
+
}
|
84
|
+
|
85
|
+
static inline void
|
86
|
+
rndr_popbuf(struct render *rndr)
|
87
|
+
{
|
88
|
+
rndr->work.size--;
|
89
|
+
}
|
90
|
+
|
69
91
|
/********************
|
70
92
|
* GLOBAL VARIABLES *
|
71
93
|
********************/
|
@@ -373,17 +395,10 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
|
|
373
395
|
continue;
|
374
396
|
}
|
375
397
|
|
376
|
-
|
377
|
-
work = rndr->work.item[rndr->work.size ++];
|
378
|
-
work->size = 0;
|
379
|
-
} else {
|
380
|
-
work = bufnew(WORK_UNIT);
|
381
|
-
parr_push(&rndr->work, work);
|
382
|
-
}
|
383
|
-
|
398
|
+
work = rndr_newbuf(rndr);
|
384
399
|
parse_inline(work, rndr, data, i);
|
385
400
|
r = rndr->make.emphasis(ob, work, c, rndr->make.opaque);
|
386
|
-
rndr
|
401
|
+
rndr_popbuf(rndr);
|
387
402
|
return r ? i + 1 : 0;
|
388
403
|
}
|
389
404
|
}
|
@@ -408,17 +423,10 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
|
|
408
423
|
i += len;
|
409
424
|
|
410
425
|
if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !isspace(data[i - 1])) {
|
411
|
-
|
412
|
-
work = rndr->work.item[rndr->work.size ++];
|
413
|
-
work->size = 0;
|
414
|
-
} else {
|
415
|
-
work = bufnew(WORK_UNIT);
|
416
|
-
parr_push(&rndr->work, work);
|
417
|
-
}
|
418
|
-
|
426
|
+
work = rndr_newbuf(rndr);
|
419
427
|
parse_inline(work, rndr, data, i);
|
420
428
|
r = rndr->make.double_emphasis(ob, work, c, rndr->make.opaque);
|
421
|
-
rndr
|
429
|
+
rndr_popbuf(rndr);
|
422
430
|
return r ? i + 2 : 0;
|
423
431
|
}
|
424
432
|
i++;
|
@@ -445,18 +453,11 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c
|
|
445
453
|
|
446
454
|
if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && rndr->make.triple_emphasis) {
|
447
455
|
/* triple symbol found */
|
448
|
-
struct buf *work =
|
449
|
-
if (rndr->work.size < rndr->work.asize) {
|
450
|
-
work = rndr->work.item[rndr->work.size ++];
|
451
|
-
work->size = 0;
|
452
|
-
} else {
|
453
|
-
work = bufnew(WORK_UNIT);
|
454
|
-
parr_push(&rndr->work, work);
|
455
|
-
}
|
456
|
+
struct buf *work = rndr_newbuf(rndr);
|
456
457
|
|
457
458
|
parse_inline(work, rndr, data, i);
|
458
459
|
r = rndr->make.triple_emphasis(ob, work, c, rndr->make.opaque);
|
459
|
-
rndr
|
460
|
+
rndr_popbuf(rndr);
|
460
461
|
return r ? i + 3 : 0;
|
461
462
|
|
462
463
|
} else if (i + 1 < size && data[i + 1] == c) {
|
@@ -748,24 +749,12 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
748
749
|
|
749
750
|
/* building escaped link and title */
|
750
751
|
if (link_e > link_b) {
|
751
|
-
|
752
|
-
link = rndr->work.item[rndr->work.size ++];
|
753
|
-
link->size = 0;
|
754
|
-
} else {
|
755
|
-
link = bufnew(WORK_UNIT);
|
756
|
-
parr_push(&rndr->work, link);
|
757
|
-
}
|
752
|
+
link = rndr_newbuf(rndr);
|
758
753
|
bufput(link, data + link_b, link_e - link_b);
|
759
754
|
}
|
760
755
|
|
761
756
|
if (title_e > title_b) {
|
762
|
-
|
763
|
-
title = rndr->work.item[rndr->work.size ++];
|
764
|
-
title->size = 0;
|
765
|
-
} else {
|
766
|
-
title = bufnew(WORK_UNIT);
|
767
|
-
parr_push(&rndr->work, title);
|
768
|
-
}
|
757
|
+
title = rndr_newbuf(rndr);
|
769
758
|
bufput(title, data + title_b, title_e - title_b);
|
770
759
|
}
|
771
760
|
|
@@ -787,17 +776,9 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
787
776
|
/* finding the link_ref */
|
788
777
|
if (link_b == link_e) {
|
789
778
|
if (text_has_nl) {
|
790
|
-
struct buf *b =
|
779
|
+
struct buf *b = rndr_newbuf(rndr);
|
791
780
|
size_t j;
|
792
781
|
|
793
|
-
if (rndr->work.size < rndr->work.asize) {
|
794
|
-
b = rndr->work.item[rndr->work.size ++];
|
795
|
-
b->size = 0;
|
796
|
-
} else {
|
797
|
-
b = bufnew(WORK_UNIT);
|
798
|
-
parr_push(&rndr->work, b);
|
799
|
-
}
|
800
|
-
|
801
782
|
for (j = 1; j < txt_e; j++) {
|
802
783
|
if (data[j] != '\n')
|
803
784
|
bufputc(b, data[j]);
|
@@ -832,17 +813,9 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
832
813
|
|
833
814
|
/* crafting the id */
|
834
815
|
if (text_has_nl) {
|
835
|
-
struct buf *b =
|
816
|
+
struct buf *b = rndr_newbuf(rndr);
|
836
817
|
size_t j;
|
837
818
|
|
838
|
-
if (rndr->work.size < rndr->work.asize) {
|
839
|
-
b = rndr->work.item[rndr->work.size ++];
|
840
|
-
b->size = 0;
|
841
|
-
} else {
|
842
|
-
b = bufnew(WORK_UNIT);
|
843
|
-
parr_push(&rndr->work, b);
|
844
|
-
}
|
845
|
-
|
846
819
|
for (j = 1; j < txt_e; j++) {
|
847
820
|
if (data[j] != '\n')
|
848
821
|
bufputc(b, data[j]);
|
@@ -871,14 +844,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
|
|
871
844
|
|
872
845
|
/* building content: img alt is escaped, link content is parsed */
|
873
846
|
if (txt_e > 1) {
|
874
|
-
|
875
|
-
content = rndr->work.item[rndr->work.size ++];
|
876
|
-
content->size = 0;
|
877
|
-
} else {
|
878
|
-
content = bufnew(WORK_UNIT);
|
879
|
-
parr_push(&rndr->work, content);
|
880
|
-
}
|
881
|
-
|
847
|
+
content = rndr_newbuf(rndr);
|
882
848
|
if (is_img) bufput(content, data + 1, txt_e - 1);
|
883
849
|
else parse_inline(content, rndr, data + 1, txt_e - 1);
|
884
850
|
}
|
@@ -947,7 +913,7 @@ is_hrule(char *data, size_t size)
|
|
947
913
|
static size_t
|
948
914
|
is_codefence(char *data, size_t size, struct buf *syntax)
|
949
915
|
{
|
950
|
-
size_t i = 0, n = 0
|
916
|
+
size_t i = 0, n = 0;
|
951
917
|
char c;
|
952
918
|
|
953
919
|
/* skipping initial spaces */
|
@@ -970,29 +936,26 @@ is_codefence(char *data, size_t size, struct buf *syntax)
|
|
970
936
|
if (n < 3)
|
971
937
|
return 0;
|
972
938
|
|
973
|
-
if (syntax
|
974
|
-
|
975
|
-
if (!isspace(data[i]))
|
976
|
-
return 0;
|
939
|
+
if (syntax != NULL) {
|
940
|
+
size_t syn = 0;
|
977
941
|
|
942
|
+
while (i < size && (data[i] == ' ' || data[i] == '\t'))
|
978
943
|
i++;
|
979
|
-
|
980
|
-
} else {
|
944
|
+
|
981
945
|
syntax->data = data + i;
|
982
|
-
syn = 0;
|
983
946
|
|
984
|
-
while (i < size && data[i]
|
947
|
+
while (i < size && !isspace(data[i])) {
|
985
948
|
syn++; i++;
|
986
949
|
}
|
987
950
|
|
988
|
-
|
989
|
-
|
951
|
+
syntax->size = syn;
|
952
|
+
}
|
990
953
|
|
991
|
-
|
992
|
-
|
993
|
-
|
954
|
+
while (i < size && data[i] != '\n') {
|
955
|
+
if (!isspace(data[i]))
|
956
|
+
return 0;
|
994
957
|
|
995
|
-
|
958
|
+
i++;
|
996
959
|
}
|
997
960
|
|
998
961
|
return i + 1;
|
@@ -1088,13 +1051,7 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1088
1051
|
char *work_data = 0;
|
1089
1052
|
struct buf *out = 0;
|
1090
1053
|
|
1091
|
-
|
1092
|
-
out = rndr->work.item[rndr->work.size ++];
|
1093
|
-
out->size = 0; }
|
1094
|
-
else {
|
1095
|
-
out = bufnew(WORK_UNIT);
|
1096
|
-
parr_push(&rndr->work, out); }
|
1097
|
-
|
1054
|
+
out = rndr_newbuf(rndr);
|
1098
1055
|
beg = 0;
|
1099
1056
|
while (beg < size) {
|
1100
1057
|
for (end = beg + 1; end < size && data[end - 1] != '\n'; end++);
|
@@ -1124,7 +1081,7 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1124
1081
|
parse_block(out, rndr, work_data, work_size);
|
1125
1082
|
if (rndr->make.blockquote)
|
1126
1083
|
rndr->make.blockquote(ob, out, rndr->make.opaque);
|
1127
|
-
rndr
|
1084
|
+
rndr_popbuf(rndr);
|
1128
1085
|
return end;
|
1129
1086
|
}
|
1130
1087
|
|
@@ -1167,20 +1124,11 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1167
1124
|
work.size--;
|
1168
1125
|
|
1169
1126
|
if (!level) {
|
1170
|
-
struct buf *tmp =
|
1171
|
-
if (rndr->work.size < rndr->work.asize) {
|
1172
|
-
tmp = rndr->work.item[rndr->work.size ++];
|
1173
|
-
tmp->size = 0;
|
1174
|
-
} else {
|
1175
|
-
tmp = bufnew(WORK_UNIT);
|
1176
|
-
parr_push(&rndr->work, tmp);
|
1177
|
-
}
|
1178
|
-
|
1127
|
+
struct buf *tmp = rndr_newbuf(rndr);
|
1179
1128
|
parse_inline(tmp, rndr, work.data, work.size);
|
1180
1129
|
if (rndr->make.paragraph)
|
1181
1130
|
rndr->make.paragraph(ob, tmp, rndr->make.opaque);
|
1182
|
-
rndr
|
1183
|
-
|
1131
|
+
rndr_popbuf(rndr);
|
1184
1132
|
} else {
|
1185
1133
|
struct buf *header_work;
|
1186
1134
|
|
@@ -1197,42 +1145,26 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1197
1145
|
work.size -= 1;
|
1198
1146
|
|
1199
1147
|
if (work.size > 0) {
|
1200
|
-
struct buf *tmp =
|
1201
|
-
|
1202
|
-
if (rndr->work.size < rndr->work.asize) {
|
1203
|
-
tmp=rndr->work.item[rndr->work.size++];
|
1204
|
-
tmp->size = 0;
|
1205
|
-
} else {
|
1206
|
-
tmp = bufnew(WORK_UNIT);
|
1207
|
-
parr_push(&rndr->work, tmp);
|
1208
|
-
}
|
1209
|
-
|
1148
|
+
struct buf *tmp = rndr_newbuf(rndr);
|
1210
1149
|
parse_inline(tmp, rndr, work.data, work.size);
|
1211
1150
|
|
1212
1151
|
if (rndr->make.paragraph)
|
1213
1152
|
rndr->make.paragraph(ob, tmp, rndr->make.opaque);
|
1214
1153
|
|
1215
|
-
rndr
|
1154
|
+
rndr_popbuf(rndr);
|
1216
1155
|
work.data += beg;
|
1217
1156
|
work.size = i - beg;
|
1218
1157
|
}
|
1219
1158
|
else work.size = i;
|
1220
1159
|
}
|
1221
1160
|
|
1222
|
-
|
1223
|
-
header_work = rndr->work.item[rndr->work.size ++];
|
1224
|
-
header_work->size = 0;
|
1225
|
-
} else {
|
1226
|
-
header_work = bufnew(WORK_UNIT);
|
1227
|
-
parr_push(&rndr->work, header_work);
|
1228
|
-
}
|
1229
|
-
|
1161
|
+
header_work = rndr_newbuf(rndr);
|
1230
1162
|
parse_inline(header_work, rndr, work.data, work.size);
|
1231
1163
|
|
1232
1164
|
if (rndr->make.header)
|
1233
1165
|
rndr->make.header(ob, header_work, (int)level, rndr->make.opaque);
|
1234
1166
|
|
1235
|
-
rndr
|
1167
|
+
rndr_popbuf(rndr);
|
1236
1168
|
}
|
1237
1169
|
|
1238
1170
|
return end;
|
@@ -1244,18 +1176,12 @@ parse_fencedcode(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1244
1176
|
{
|
1245
1177
|
size_t beg, end;
|
1246
1178
|
struct buf *work = 0;
|
1247
|
-
struct buf
|
1179
|
+
struct buf lang = { 0, 0, 0, 0, 0 };
|
1248
1180
|
|
1249
|
-
beg = is_codefence(data, size, &
|
1181
|
+
beg = is_codefence(data, size, &lang);
|
1250
1182
|
if (beg == 0) return 0;
|
1251
1183
|
|
1252
|
-
|
1253
|
-
work = rndr->work.item[rndr->work.size ++];
|
1254
|
-
work->size = 0;
|
1255
|
-
} else {
|
1256
|
-
work = bufnew(WORK_UNIT);
|
1257
|
-
parr_push(&rndr->work, work);
|
1258
|
-
}
|
1184
|
+
work = rndr_newbuf(rndr);
|
1259
1185
|
|
1260
1186
|
while (beg < size) {
|
1261
1187
|
size_t fence_end;
|
@@ -1282,9 +1208,9 @@ parse_fencedcode(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1282
1208
|
bufputc(work, '\n');
|
1283
1209
|
|
1284
1210
|
if (rndr->make.blockcode)
|
1285
|
-
rndr->make.blockcode(ob, work,
|
1211
|
+
rndr->make.blockcode(ob, work, lang.size ? &lang : NULL, rndr->make.opaque);
|
1286
1212
|
|
1287
|
-
rndr
|
1213
|
+
rndr_popbuf(rndr);
|
1288
1214
|
return beg;
|
1289
1215
|
}
|
1290
1216
|
|
@@ -1294,36 +1220,38 @@ parse_blockcode(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1294
1220
|
size_t beg, end, pre;
|
1295
1221
|
struct buf *work = 0;
|
1296
1222
|
|
1297
|
-
|
1298
|
-
work = rndr->work.item[rndr->work.size ++];
|
1299
|
-
work->size = 0; }
|
1300
|
-
else {
|
1301
|
-
work = bufnew(WORK_UNIT);
|
1302
|
-
parr_push(&rndr->work, work); }
|
1223
|
+
work = rndr_newbuf(rndr);
|
1303
1224
|
|
1304
1225
|
beg = 0;
|
1305
1226
|
while (beg < size) {
|
1306
|
-
for (end = beg + 1; end < size && data[end - 1] != '\n';
|
1307
|
-
end += 1);
|
1227
|
+
for (end = beg + 1; end < size && data[end - 1] != '\n'; end++) {};
|
1308
1228
|
pre = prefix_code(data + beg, end - beg);
|
1309
|
-
|
1229
|
+
|
1230
|
+
if (pre)
|
1231
|
+
beg += pre; /* skipping prefix */
|
1310
1232
|
else if (!is_empty(data + beg, end - beg))
|
1311
1233
|
/* non-empty non-prefixed line breaks the pre */
|
1312
1234
|
break;
|
1235
|
+
|
1313
1236
|
if (beg < end) {
|
1314
1237
|
/* verbatim copy to the working buffer,
|
1315
1238
|
escaping entities */
|
1316
1239
|
if (is_empty(data + beg, end - beg))
|
1317
1240
|
bufputc(work, '\n');
|
1318
|
-
else bufput(work, data + beg, end - beg);
|
1319
|
-
|
1241
|
+
else bufput(work, data + beg, end - beg);
|
1242
|
+
}
|
1243
|
+
beg = end;
|
1244
|
+
}
|
1320
1245
|
|
1321
1246
|
while (work->size && work->data[work->size - 1] == '\n')
|
1322
1247
|
work->size -= 1;
|
1248
|
+
|
1323
1249
|
bufputc(work, '\n');
|
1250
|
+
|
1324
1251
|
if (rndr->make.blockcode)
|
1325
1252
|
rndr->make.blockcode(ob, work, NULL, rndr->make.opaque);
|
1326
|
-
|
1253
|
+
|
1254
|
+
rndr_popbuf(rndr);
|
1327
1255
|
return beg;
|
1328
1256
|
}
|
1329
1257
|
|
@@ -1353,21 +1281,8 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
|
|
1353
1281
|
end++;
|
1354
1282
|
|
1355
1283
|
/* getting working buffers */
|
1356
|
-
|
1357
|
-
|
1358
|
-
work->size = 0;
|
1359
|
-
} else {
|
1360
|
-
work = bufnew(WORK_UNIT);
|
1361
|
-
parr_push(&rndr->work, work);
|
1362
|
-
}
|
1363
|
-
|
1364
|
-
if (rndr->work.size < rndr->work.asize) {
|
1365
|
-
inter = rndr->work.item[rndr->work.size ++];
|
1366
|
-
inter->size = 0;
|
1367
|
-
} else {
|
1368
|
-
inter = bufnew(WORK_UNIT);
|
1369
|
-
parr_push(&rndr->work, inter);
|
1370
|
-
}
|
1284
|
+
work = rndr_newbuf(rndr);
|
1285
|
+
inter = rndr_newbuf(rndr);
|
1371
1286
|
|
1372
1287
|
/* putting the first line into the working buffer */
|
1373
1288
|
bufput(work, data + beg, end - beg);
|
@@ -1451,7 +1366,8 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
|
|
1451
1366
|
if (rndr->make.listitem)
|
1452
1367
|
rndr->make.listitem(ob, inter, *flags, rndr->make.opaque);
|
1453
1368
|
|
1454
|
-
rndr
|
1369
|
+
rndr_popbuf(rndr);
|
1370
|
+
rndr_popbuf(rndr);
|
1455
1371
|
return beg;
|
1456
1372
|
}
|
1457
1373
|
|
@@ -1463,12 +1379,7 @@ parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int fla
|
|
1463
1379
|
struct buf *work = 0;
|
1464
1380
|
size_t i = 0, j;
|
1465
1381
|
|
1466
|
-
|
1467
|
-
work = rndr->work.item[rndr->work.size ++];
|
1468
|
-
work->size = 0; }
|
1469
|
-
else {
|
1470
|
-
work = bufnew(WORK_UNIT);
|
1471
|
-
parr_push(&rndr->work, work); }
|
1382
|
+
work = rndr_newbuf(rndr);
|
1472
1383
|
|
1473
1384
|
while (i < size) {
|
1474
1385
|
j = parse_listitem(work, rndr, data + i, size - i, &flags);
|
@@ -1480,7 +1391,7 @@ parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int fla
|
|
1480
1391
|
|
1481
1392
|
if (rndr->make.list)
|
1482
1393
|
rndr->make.list(ob, work, flags, rndr->make.opaque);
|
1483
|
-
rndr
|
1394
|
+
rndr_popbuf(rndr);
|
1484
1395
|
return i;
|
1485
1396
|
}
|
1486
1397
|
|
@@ -1510,22 +1421,14 @@ parse_atxheader(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1510
1421
|
end--;
|
1511
1422
|
|
1512
1423
|
if (end > i) {
|
1513
|
-
struct buf *work;
|
1514
|
-
|
1515
|
-
if (rndr->work.size < rndr->work.asize) {
|
1516
|
-
work = rndr->work.item[rndr->work.size ++];
|
1517
|
-
work->size = 0;
|
1518
|
-
} else {
|
1519
|
-
work = bufnew(WORK_UNIT);
|
1520
|
-
parr_push(&rndr->work, work);
|
1521
|
-
}
|
1424
|
+
struct buf *work = rndr_newbuf(rndr);
|
1522
1425
|
|
1523
1426
|
parse_inline(work, rndr, data + i, end - i);
|
1524
1427
|
|
1525
1428
|
if (rndr->make.header)
|
1526
1429
|
rndr->make.header(ob, work, (int)level, rndr->make.opaque);
|
1527
1430
|
|
1528
|
-
rndr
|
1431
|
+
rndr_popbuf(rndr);
|
1529
1432
|
}
|
1530
1433
|
|
1531
1434
|
return skip;
|
@@ -1682,13 +1585,7 @@ parse_table_row(struct buf *ob, struct render *rndr, char *data, size_t size, si
|
|
1682
1585
|
size_t i = 0, col;
|
1683
1586
|
struct buf *row_work = 0;
|
1684
1587
|
|
1685
|
-
|
1686
|
-
row_work = rndr->work.item[rndr->work.size ++];
|
1687
|
-
row_work->size = 0;
|
1688
|
-
} else {
|
1689
|
-
row_work = bufnew(WORK_UNIT);
|
1690
|
-
parr_push(&rndr->work, row_work);
|
1691
|
-
}
|
1588
|
+
row_work = rndr_newbuf(rndr);
|
1692
1589
|
|
1693
1590
|
if (i < size && data[i] == '|')
|
1694
1591
|
i++;
|
@@ -1697,13 +1594,7 @@ parse_table_row(struct buf *ob, struct render *rndr, char *data, size_t size, si
|
|
1697
1594
|
size_t cell_start, cell_end;
|
1698
1595
|
struct buf *cell_work;
|
1699
1596
|
|
1700
|
-
|
1701
|
-
cell_work = rndr->work.item[rndr->work.size ++];
|
1702
|
-
cell_work->size = 0;
|
1703
|
-
} else {
|
1704
|
-
cell_work = bufnew(WORK_UNIT);
|
1705
|
-
parr_push(&rndr->work, cell_work);
|
1706
|
-
}
|
1597
|
+
cell_work = rndr_newbuf(rndr);
|
1707
1598
|
|
1708
1599
|
while (i < size && isspace(data[i]))
|
1709
1600
|
i++;
|
@@ -1722,7 +1613,7 @@ parse_table_row(struct buf *ob, struct render *rndr, char *data, size_t size, si
|
|
1722
1613
|
if (rndr->make.table_cell)
|
1723
1614
|
rndr->make.table_cell(row_work, cell_work, col_data ? col_data[col] : 0, rndr->make.opaque);
|
1724
1615
|
|
1725
|
-
rndr
|
1616
|
+
rndr_popbuf(rndr);
|
1726
1617
|
i++;
|
1727
1618
|
}
|
1728
1619
|
|
@@ -1735,7 +1626,7 @@ parse_table_row(struct buf *ob, struct render *rndr, char *data, size_t size, si
|
|
1735
1626
|
if (rndr->make.table_row)
|
1736
1627
|
rndr->make.table_row(ob, row_work, rndr->make.opaque);
|
1737
1628
|
|
1738
|
-
rndr
|
1629
|
+
rndr_popbuf(rndr);
|
1739
1630
|
}
|
1740
1631
|
|
1741
1632
|
static size_t
|
@@ -1808,21 +1699,8 @@ parse_table(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1808
1699
|
size_t columns;
|
1809
1700
|
int *col_data = NULL;
|
1810
1701
|
|
1811
|
-
|
1812
|
-
|
1813
|
-
header_work->size = 0;
|
1814
|
-
} else {
|
1815
|
-
header_work = bufnew(WORK_UNIT);
|
1816
|
-
parr_push(&rndr->work, header_work);
|
1817
|
-
}
|
1818
|
-
|
1819
|
-
if (rndr->work.size < rndr->work.asize) {
|
1820
|
-
body_work = rndr->work.item[rndr->work.size ++];
|
1821
|
-
body_work->size = 0;
|
1822
|
-
} else {
|
1823
|
-
body_work = bufnew(WORK_UNIT);
|
1824
|
-
parr_push(&rndr->work, body_work);
|
1825
|
-
}
|
1702
|
+
header_work = rndr_newbuf(rndr);
|
1703
|
+
body_work = rndr_newbuf(rndr);
|
1826
1704
|
|
1827
1705
|
i = parse_table_header(header_work, rndr, data, size, &columns, &col_data);
|
1828
1706
|
if (i > 0) {
|
@@ -1851,7 +1729,8 @@ parse_table(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|
1851
1729
|
}
|
1852
1730
|
|
1853
1731
|
free(col_data);
|
1854
|
-
rndr
|
1732
|
+
rndr_popbuf(rndr);
|
1733
|
+
rndr_popbuf(rndr);
|
1855
1734
|
return i;
|
1856
1735
|
}
|
1857
1736
|
|
data/ext/markdown.h
CHANGED
@@ -47,7 +47,7 @@ enum mkd_extensions {
|
|
47
47
|
/* mkd_renderer • functions for rendering parsed data */
|
48
48
|
struct mkd_renderer {
|
49
49
|
/* block level callbacks - NULL skips the block */
|
50
|
-
void (*blockcode)(struct buf *ob, struct buf *text, struct buf *
|
50
|
+
void (*blockcode)(struct buf *ob, struct buf *text, struct buf *lang, void *opaque);
|
51
51
|
void (*blockquote)(struct buf *ob, struct buf *text, void *opaque);
|
52
52
|
void (*blockhtml)(struct buf *ob, struct buf *text, void *opaque);
|
53
53
|
void (*header)(struct buf *ob, struct buf *text, int level, void *opaque);
|
data/ext/redcarpet.c
CHANGED
@@ -46,6 +46,9 @@ static void rb_redcarpet__get_flags(VALUE ruby_obj,
|
|
46
46
|
if (rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
|
47
47
|
render_flags |= XHTML_TOC;
|
48
48
|
|
49
|
+
if (rb_funcall(ruby_obj, rb_intern("hard_wrap"), 0) == Qtrue)
|
50
|
+
render_flags |= XHTML_HARD_WRAP;
|
51
|
+
|
49
52
|
/**
|
50
53
|
* Markdown extensions -- all disabled by default
|
51
54
|
*/
|
data/ext/xhtml.c
CHANGED
@@ -112,13 +112,13 @@ rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *op
|
|
112
112
|
}
|
113
113
|
|
114
114
|
static void
|
115
|
-
rndr_blockcode(struct buf *ob, struct buf *text, struct buf *
|
115
|
+
rndr_blockcode(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)
|
116
116
|
{
|
117
117
|
if (ob->size) bufputc(ob, '\n');
|
118
118
|
|
119
|
-
if (
|
119
|
+
if (lang && lang->size) {
|
120
120
|
BUFPUTSL(ob, "<pre lang=\"");
|
121
|
-
bufput(ob,
|
121
|
+
bufput(ob, lang->data, lang->size);
|
122
122
|
BUFPUTSL(ob, "\"><code>");
|
123
123
|
} else
|
124
124
|
BUFPUTSL(ob, "<pre><code>");
|
@@ -234,6 +234,7 @@ rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque)
|
|
234
234
|
static void
|
235
235
|
rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
|
236
236
|
{
|
237
|
+
struct xhtml_renderopt *options = opaque;
|
237
238
|
size_t i = 0;
|
238
239
|
|
239
240
|
if (ob->size) bufputc(ob, '\n');
|
@@ -243,11 +244,30 @@ rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
|
|
243
244
|
|
244
245
|
while (i < text->size && isspace(text->data[i])) i++;
|
245
246
|
|
246
|
-
if (i
|
247
|
-
|
247
|
+
if (i == text->size)
|
248
|
+
return;
|
249
|
+
|
250
|
+
BUFPUTSL(ob, "<p>");
|
251
|
+
if (options->flags & XHTML_HARD_WRAP) {
|
252
|
+
size_t org;
|
253
|
+
while (i < text->size) {
|
254
|
+
org = i;
|
255
|
+
while (i < text->size && text->data[i] != '\n')
|
256
|
+
i++;
|
257
|
+
|
258
|
+
if (i > org)
|
259
|
+
bufput(ob, text->data + org, i - org);
|
260
|
+
|
261
|
+
if (i >= text->size)
|
262
|
+
break;
|
263
|
+
|
264
|
+
BUFPUTSL(ob, "<br/>");
|
265
|
+
i++;
|
266
|
+
}
|
267
|
+
} else {
|
248
268
|
bufput(ob, &text->data[i], text->size - i);
|
249
|
-
BUFPUTSL(ob, "</p>\n");
|
250
269
|
}
|
270
|
+
BUFPUTSL(ob, "</p>\n");
|
251
271
|
}
|
252
272
|
|
253
273
|
static void
|
@@ -648,14 +668,14 @@ ups_toc_renderer(struct mkd_renderer *renderer)
|
|
648
668
|
NULL,
|
649
669
|
NULL,
|
650
670
|
|
651
|
-
|
671
|
+
NULL,
|
652
672
|
rndr_codespan,
|
653
673
|
rndr_double_emphasis,
|
654
674
|
rndr_emphasis,
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
675
|
+
NULL,
|
676
|
+
NULL,
|
677
|
+
NULL,
|
678
|
+
NULL,
|
659
679
|
rndr_triple_emphasis,
|
660
680
|
|
661
681
|
NULL,
|
data/ext/xhtml.h
CHANGED
data/lib/redcarpet.rb
CHANGED
@@ -26,7 +26,7 @@
|
|
26
26
|
# end
|
27
27
|
#
|
28
28
|
class Redcarpet
|
29
|
-
VERSION = '1.
|
29
|
+
VERSION = '1.8.0'
|
30
30
|
|
31
31
|
# Original Markdown formatted text.
|
32
32
|
attr_reader :text
|
@@ -46,6 +46,9 @@ class Redcarpet
|
|
46
46
|
# Do not process <tt>[]</tt> and remove <tt><a></tt> tags from the output.
|
47
47
|
attr_accessor :no_links
|
48
48
|
|
49
|
+
# Treat newlines in paragraphs as real line breaks, GitHub style
|
50
|
+
attr_accessor :hard_wrap
|
51
|
+
|
49
52
|
# Disable superscript and relaxed emphasis processing.
|
50
53
|
attr_accessor :strict
|
51
54
|
|
data/redcarpet.gemspec
CHANGED
data/test/redcarpet_test.rb
CHANGED
@@ -210,5 +210,15 @@ This a stupid link: https://github.com/rtomayko/tilt/issues?milestone=1&state=op
|
|
210
210
|
text
|
211
211
|
assert_equal "<p>This a stupid link: <a href=\"https://github.com/rtomayko/tilt/issues?milestone=1&state=open\">https://github.com/rtomayko/tilt/issues?milestone=1&state=open</a></p>\n", markdown.to_html
|
212
212
|
end
|
213
|
+
|
214
|
+
def test_hard_wrap
|
215
|
+
rd = Redcarpet.new(<<text, :hard_wrap)
|
216
|
+
This is just a test
|
217
|
+
this should have a line break
|
218
|
+
|
219
|
+
This is just a test.
|
220
|
+
text
|
213
221
|
|
222
|
+
assert rd.to_html =~ /<br\/>/
|
223
|
+
end
|
214
224
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redcarpet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 55
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 1.8.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Natacha Port\xC3\xA9"
|