redcarpet 1.2.2 → 1.3.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/array.c CHANGED
@@ -211,7 +211,7 @@ int
211
211
  parr_insert(struct parray *parr, int nb, int n) {
212
212
  char *src, *dst;
213
213
  size_t len, i;
214
- if (!parr || nb == 0 || n < 0
214
+ if (!parr || nb <= 0 || n < 0
215
215
  || !parr_grow(parr, parr->size + nb))
216
216
  return 0;
217
217
  if (n < parr->size) {
data/ext/buffer.c CHANGED
@@ -302,10 +302,11 @@ vbufprintf(struct buf *buf, const char *fmt, va_list ap) {
302
302
  n = vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap);
303
303
 
304
304
  if (n < 0 || (size_t)n >= buf->asize - buf->size) {
305
- if (!bufgrow (buf, buf->size + n + 1))
305
+ size_t new_size = (n > 0) ? n : buf->size;
306
+ if (!bufgrow (buf, buf->size + new_size + 1))
306
307
  return;
307
308
 
308
- n = vsnprintf (buf->data + buf->size, buf->asize - buf->size, fmt, ap_save);
309
+ n = vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap_save);
309
310
  }
310
311
  va_end(ap_save);
311
312
 
data/ext/markdown.c CHANGED
@@ -47,7 +47,7 @@ struct link_ref {
47
47
  /* offset is the number of valid chars before data */
48
48
  struct render;
49
49
  typedef size_t
50
- (*char_trigger)(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth);
50
+ (*char_trigger)(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
51
51
 
52
52
 
53
53
  /* render • structure containing one particular render */
@@ -56,7 +56,6 @@ struct render {
56
56
  struct array refs;
57
57
  char_trigger active_char[256];
58
58
  struct parray work;
59
- int header_count;
60
59
  };
61
60
 
62
61
  /* html_tag • structure for quick HTML tag search (inspired from discount) */
@@ -233,13 +232,13 @@ tag_length(char *data, size_t size, enum mkd_autolink *autolink)
233
232
 
234
233
  /* parse_inline • parses inline markdown elements */
235
234
  static void
236
- parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size, int depth)
235
+ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
237
236
  {
238
237
  size_t i = 0, end = 0;
239
238
  char_trigger action = 0;
240
239
  struct buf work = { 0, 0, 0, 0, 0 };
241
240
 
242
- if (depth >= rndr->make.parser_options.recursion_depth)
241
+ if (rndr->work.size > rndr->make.parser_options.recursion_depth)
243
242
  return;
244
243
 
245
244
  while (i < size) {
@@ -259,7 +258,7 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size, int d
259
258
  i = end;
260
259
 
261
260
  /* calling the trigger */
262
- end = action(ob, rndr, data + i, i, size - i, depth + 1);
261
+ end = action(ob, rndr, data + i, i, size - i);
263
262
  if (!end) /* no action from the callback */
264
263
  end = i + 1;
265
264
  else {
@@ -323,7 +322,7 @@ find_emph_char(char *data, size_t size, char c)
323
322
  /* parse_emph1 • parsing single emphase */
324
323
  /* closed by a symbol not preceded by whitespace and not followed by symbol */
325
324
  static size_t
326
- parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c, int depth)
325
+ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
327
326
  {
328
327
  size_t i = 0, len;
329
328
  struct buf *work = 0;
@@ -347,7 +346,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
347
346
 
348
347
  if (data[i] == c && !isspace(data[i - 1])) {
349
348
 
350
- if ((rndr->make.parser_options.flags & PARSER_STRICT) == 0) {
349
+ if ((rndr->make.parser_options.flags & MKD_LAX_EMPHASIS) == 0) {
351
350
  if (!(i + 1 == size || isspace(data[i + 1]) || ispunct(data[i + 1])))
352
351
  continue;
353
352
  }
@@ -360,7 +359,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
360
359
  parr_push(&rndr->work, work);
361
360
  }
362
361
 
363
- parse_inline(work, rndr, data, i, depth + 1);
362
+ parse_inline(work, rndr, data, i);
364
363
  r = rndr->make.emphasis(ob, work, c, &rndr->make.render_options);
365
364
  rndr->work.size -= 1;
366
365
  return r ? i + 1 : 0;
@@ -372,13 +371,14 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
372
371
 
373
372
  /* parse_emph2 • parsing single emphase */
374
373
  static size_t
375
- parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c, int depth)
374
+ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
376
375
  {
377
376
  size_t i = 0, len;
378
377
  struct buf *work = 0;
379
378
  int r;
380
379
 
381
- if (!rndr->make.double_emphasis) return 0;
380
+ if (!rndr->make.double_emphasis)
381
+ return 0;
382
382
 
383
383
  while (i < size) {
384
384
  len = find_emph_char(data + i, size - i, c);
@@ -394,7 +394,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
394
394
  parr_push(&rndr->work, work);
395
395
  }
396
396
 
397
- parse_inline(work, rndr, data, i, depth + 1);
397
+ parse_inline(work, rndr, data, i);
398
398
  r = rndr->make.double_emphasis(ob, work, c, &rndr->make.render_options);
399
399
  rndr->work.size -= 1;
400
400
  return r ? i + 2 : 0;
@@ -407,7 +407,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
407
407
  /* parse_emph3 • parsing single emphase */
408
408
  /* finds the first closing tag, and delegates to the other emph */
409
409
  static size_t
410
- parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c, int depth)
410
+ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
411
411
  {
412
412
  size_t i = 0, len;
413
413
  int r;
@@ -432,20 +432,20 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c
432
432
  parr_push(&rndr->work, work);
433
433
  }
434
434
 
435
- parse_inline(work, rndr, data, i, depth + 1);
435
+ parse_inline(work, rndr, data, i);
436
436
  r = rndr->make.triple_emphasis(ob, work, c, &rndr->make.render_options);
437
437
  rndr->work.size -= 1;
438
438
  return r ? i + 3 : 0;
439
439
 
440
440
  } else if (i + 1 < size && data[i + 1] == c) {
441
441
  /* double symbol found, handing over to emph1 */
442
- len = parse_emph1(ob, rndr, data - 2, size + 2, c, depth + 1);
442
+ len = parse_emph1(ob, rndr, data - 2, size + 2, c);
443
443
  if (!len) return 0;
444
444
  else return len - 2;
445
445
 
446
446
  } else {
447
447
  /* single symbol found, handing over to emph2 */
448
- len = parse_emph2(ob, rndr, data - 1, size + 1, c, depth + 1);
448
+ len = parse_emph2(ob, rndr, data - 1, size + 1, c);
449
449
  if (!len) return 0;
450
450
  else return len - 1;
451
451
  }
@@ -455,28 +455,28 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c
455
455
 
456
456
  /* char_emphasis • single and double emphasis parsing */
457
457
  static size_t
458
- char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
458
+ char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
459
459
  {
460
460
  char c = data[0];
461
461
  size_t ret;
462
462
 
463
463
  if (size > 2 && data[1] != c) {
464
464
  /* whitespace cannot follow an opening emphasis */
465
- if (isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c, depth + 1)) == 0)
465
+ if (isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)
466
466
  return 0;
467
467
 
468
468
  return ret + 1;
469
469
  }
470
470
 
471
471
  if (size > 3 && data[1] == c && data[2] != c) {
472
- if (isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c, depth + 1)) == 0)
472
+ if (isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c)) == 0)
473
473
  return 0;
474
474
 
475
475
  return ret + 2;
476
476
  }
477
477
 
478
478
  if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {
479
- if (isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c, depth + 1)) == 0)
479
+ if (isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)
480
480
  return 0;
481
481
 
482
482
  return ret + 3;
@@ -488,7 +488,7 @@ char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, si
488
488
 
489
489
  /* char_linebreak • '\n' preceded by two spaces (assuming linebreak != 0) */
490
490
  static size_t
491
- char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
491
+ char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
492
492
  {
493
493
  if (offset < 2 || data[-1] != ' ' || data[-2] != ' ')
494
494
  return 0;
@@ -503,7 +503,7 @@ char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, s
503
503
 
504
504
  /* char_codespan • '`' parsing a code span (assuming codespan != 0) */
505
505
  static size_t
506
- char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
506
+ char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
507
507
  {
508
508
  size_t end, nb = 0, i, f_begin, f_end;
509
509
 
@@ -546,7 +546,7 @@ char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, si
546
546
 
547
547
  /* char_escape • '\\' backslash escape */
548
548
  static size_t
549
- char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
549
+ char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
550
550
  {
551
551
  struct buf work = { 0, 0, 0, 0, 0 };
552
552
 
@@ -565,7 +565,7 @@ char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size
565
565
  /* char_entity • '&' escaped when it doesn't belong to an entity */
566
566
  /* valid entities are assumed to be anything mathing &#?[A-Za-z0-9]+; */
567
567
  static size_t
568
- char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
568
+ char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
569
569
  {
570
570
  size_t end = 1;
571
571
  struct buf work;
@@ -593,7 +593,7 @@ char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size
593
593
 
594
594
  /* char_langle_tag • '<' when tags or autolinks are allowed */
595
595
  static size_t
596
- char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
596
+ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
597
597
  {
598
598
  enum mkd_autolink altype = MKDA_NOT_AUTOLINK;
599
599
  size_t end = tag_length(data, size, &altype);
@@ -617,7 +617,7 @@ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset,
617
617
 
618
618
  /* char_link • '[': parsing a link or an image */
619
619
  static size_t
620
- char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
620
+ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
621
621
  {
622
622
  int is_img = (offset && data[-1] == '!'), level;
623
623
  size_t i = 1, txt_e, link_b = 0, link_e = 0, title_b = 0, title_e = 0;
@@ -802,7 +802,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
802
802
  }
803
803
 
804
804
  if (is_img) bufput(content, data + 1, txt_e - 1);
805
- else parse_inline(content, rndr, data + 1, txt_e - 1, depth + 1);
805
+ else parse_inline(content, rndr, data + 1, txt_e - 1);
806
806
  }
807
807
 
808
808
  /* calling the relevant rendering function */
@@ -944,12 +944,12 @@ prefix_uli(char *data, size_t size)
944
944
 
945
945
  /* parse_block • parsing of one block, returning next char to parse */
946
946
  static void parse_block(struct buf *ob, struct render *rndr,
947
- char *data, size_t size, int depth);
947
+ char *data, size_t size);
948
948
 
949
949
 
950
950
  /* parse_blockquote • hanldes parsing of a blockquote fragment */
951
951
  static size_t
952
- parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size, int depth)
952
+ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size)
953
953
  {
954
954
  size_t beg, end = 0, pre, work_size = 0;
955
955
  char *work_data = 0;
@@ -964,8 +964,7 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size, i
964
964
 
965
965
  beg = 0;
966
966
  while (beg < size) {
967
- for (end = beg + 1; end < size && data[end - 1] != '\n';
968
- end += 1);
967
+ for (end = beg + 1; end < size && data[end - 1] != '\n'; end += 1);
969
968
  pre = prefix_quote(data + beg, end - beg);
970
969
  if (pre) beg += pre; /* skipping prefix */
971
970
  else if (is_empty(data + beg, end - beg)
@@ -983,7 +982,7 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size, i
983
982
  work_size += end - beg; }
984
983
  beg = end; }
985
984
 
986
- parse_block(out, rndr, work_data, work_size, depth + 1);
985
+ parse_block(out, rndr, work_data, work_size);
987
986
  if (rndr->make.blockquote)
988
987
  rndr->make.blockquote(ob, out, &rndr->make.render_options);
989
988
  rndr->work.size -= 1;
@@ -995,7 +994,7 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
995
994
 
996
995
  /* parse_blockquote • hanldes parsing of a regular paragraph */
997
996
  static size_t
998
- parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size, int depth)
997
+ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
999
998
  {
1000
999
  size_t i = 0, end = 0;
1001
1000
  int level = 0;
@@ -1037,7 +1036,7 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size, in
1037
1036
  else {
1038
1037
  tmp = bufnew(WORK_UNIT);
1039
1038
  parr_push(&rndr->work, tmp); }
1040
- parse_inline(tmp, rndr, work.data, work.size, depth + 1);
1039
+ parse_inline(tmp, rndr, work.data, work.size);
1041
1040
  if (rndr->make.paragraph)
1042
1041
  rndr->make.paragraph(ob, tmp, &rndr->make.render_options);
1043
1042
  rndr->work.size -= 1; }
@@ -1059,16 +1058,15 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size, in
1059
1058
  else {
1060
1059
  tmp = bufnew(WORK_UNIT);
1061
1060
  parr_push(&rndr->work, tmp); }
1062
- parse_inline(tmp, rndr, work.data, work.size, depth + 1);
1061
+ parse_inline(tmp, rndr, work.data, work.size);
1063
1062
  if (rndr->make.paragraph)
1064
- rndr->make.paragraph(ob, tmp,
1065
- &rndr->make.render_options);
1063
+ rndr->make.paragraph(ob, tmp, &rndr->make.render_options);
1066
1064
  rndr->work.size -= 1;
1067
1065
  work.data += beg;
1068
1066
  work.size = i - beg; }
1069
1067
  else work.size = i; }
1070
1068
  if (rndr->make.header)
1071
- rndr->make.header(ob, &work, level, rndr->header_count++, &rndr->make.render_options);}
1069
+ rndr->make.header(ob, &work, level, &rndr->make.render_options);}
1072
1070
  return end;
1073
1071
  }
1074
1072
 
@@ -1115,7 +1113,7 @@ parse_blockcode(struct buf *ob, struct render *rndr, char *data, size_t size)
1115
1113
  /* parse_listitem • parsing of a single list item */
1116
1114
  /* assuming initial prefix is already removed */
1117
1115
  static size_t
1118
- parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int *flags, int depth)
1116
+ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int *flags)
1119
1117
  {
1120
1118
  struct buf *work = 0, *inter = 0;
1121
1119
  size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
@@ -1215,19 +1213,19 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
1215
1213
  if (*flags & MKD_LI_BLOCK) {
1216
1214
  /* intermediate render of block li */
1217
1215
  if (sublist && sublist < work->size) {
1218
- parse_block(inter, rndr, work->data, sublist, depth + 1);
1219
- parse_block(inter, rndr, work->data + sublist, work->size - sublist, depth + 1);
1216
+ parse_block(inter, rndr, work->data, sublist);
1217
+ parse_block(inter, rndr, work->data + sublist, work->size - sublist);
1220
1218
  }
1221
1219
  else
1222
- parse_block(inter, rndr, work->data, work->size, depth + 1);
1220
+ parse_block(inter, rndr, work->data, work->size);
1223
1221
  } else {
1224
1222
  /* intermediate render of inline li */
1225
1223
  if (sublist && sublist < work->size) {
1226
- parse_inline(inter, rndr, work->data, sublist, depth + 1);
1227
- parse_block(inter, rndr, work->data + sublist, work->size - sublist, depth + 1);
1224
+ parse_inline(inter, rndr, work->data, sublist);
1225
+ parse_block(inter, rndr, work->data + sublist, work->size - sublist);
1228
1226
  }
1229
1227
  else
1230
- parse_inline(inter, rndr, work->data, work->size, depth + 1);
1228
+ parse_inline(inter, rndr, work->data, work->size);
1231
1229
  }
1232
1230
 
1233
1231
  /* render of li itself */
@@ -1241,7 +1239,7 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
1241
1239
 
1242
1240
  /* parse_list • parsing ordered or unordered list block */
1243
1241
  static size_t
1244
- parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int flags, int depth)
1242
+ parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int flags)
1245
1243
  {
1246
1244
  struct buf *work = 0;
1247
1245
  size_t i = 0, j;
@@ -1254,7 +1252,7 @@ parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int fla
1254
1252
  parr_push(&rndr->work, work); }
1255
1253
 
1256
1254
  while (i < size) {
1257
- j = parse_listitem(work, rndr, data + i, size - i, &flags, depth + 1);
1255
+ j = parse_listitem(work, rndr, data + i, size - i, &flags);
1258
1256
  i += j;
1259
1257
 
1260
1258
  if (!j || (flags & MKD_LI_END))
@@ -1287,7 +1285,7 @@ parse_atxheader(struct buf *ob, struct render *rndr, char *data, size_t size)
1287
1285
  while (end && (data[end - 1] == ' ' || data[end - 1] == '\t')) end -= 1;
1288
1286
  work.size = end - i;
1289
1287
  if (rndr->make.header)
1290
- rndr->make.header(ob, &work, (int)level, rndr->header_count++, &rndr->make.render_options);
1288
+ rndr->make.header(ob, &work, (int)level, &rndr->make.render_options);
1291
1289
  return skip;
1292
1290
  }
1293
1291
 
@@ -1439,40 +1437,52 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
1439
1437
 
1440
1438
  /* parse_block • parsing of one block, returning next char to parse */
1441
1439
  static void
1442
- parse_block(struct buf *ob, struct render *rndr, char *data, size_t size, int depth)
1440
+ parse_block(struct buf *ob, struct render *rndr, char *data, size_t size)
1443
1441
  {
1444
1442
  size_t beg, end, i;
1445
1443
  char *txt_data;
1446
1444
  beg = 0;
1447
1445
 
1448
- if (depth >= rndr->make.parser_options.recursion_depth)
1446
+ if (rndr->work.size > rndr->make.parser_options.recursion_depth)
1449
1447
  return;
1450
1448
 
1451
1449
  while (beg < size) {
1452
1450
  txt_data = data + beg;
1453
1451
  end = size - beg;
1452
+
1454
1453
  if (data[beg] == '#')
1455
1454
  beg += parse_atxheader(ob, rndr, txt_data, end);
1456
- else if (data[beg] == '<' && rndr->make.blockhtml
1457
- && (i = parse_htmlblock(ob, rndr, txt_data, end, 1)) != 0)
1455
+
1456
+ else if (data[beg] == '<' && rndr->make.blockhtml && (i = parse_htmlblock(ob, rndr, txt_data, end, 1)) != 0)
1458
1457
  beg += i;
1458
+
1459
1459
  else if ((i = is_empty(txt_data, end)) != 0)
1460
1460
  beg += i;
1461
+
1461
1462
  else if (is_hrule(txt_data, end)) {
1462
1463
  if (rndr->make.hrule)
1463
1464
  rndr->make.hrule(ob, &rndr->make.render_options);
1464
- while (beg < size && data[beg] != '\n') beg += 1;
1465
- beg += 1; }
1465
+
1466
+ while (beg < size && data[beg] != '\n')
1467
+ beg++;
1468
+
1469
+ beg++;
1470
+ }
1471
+
1466
1472
  else if (prefix_quote(txt_data, end))
1467
- beg += parse_blockquote(ob, rndr, txt_data, end, depth + 1);
1473
+ beg += parse_blockquote(ob, rndr, txt_data, end);
1474
+
1468
1475
  else if (prefix_code(txt_data, end))
1469
1476
  beg += parse_blockcode(ob, rndr, txt_data, end);
1477
+
1470
1478
  else if (prefix_uli(txt_data, end))
1471
- beg += parse_list(ob, rndr, txt_data, end, 0, depth + 1);
1479
+ beg += parse_list(ob, rndr, txt_data, end, 0);
1480
+
1472
1481
  else if (prefix_oli(txt_data, end))
1473
- beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED, depth + 1);
1482
+ beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED);
1483
+
1474
1484
  else
1475
- beg += parse_paragraph(ob, rndr, txt_data, end, depth + 1);
1485
+ beg += parse_paragraph(ob, rndr, txt_data, end);
1476
1486
  }
1477
1487
  }
1478
1488
 
@@ -1652,8 +1662,6 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer) {
1652
1662
  rndr.active_char['\\'] = char_escape;
1653
1663
  rndr.active_char['&'] = char_entity;
1654
1664
 
1655
- rndr.header_count = 1;
1656
-
1657
1665
  /* first pass: looking for references, copying everything else */
1658
1666
  beg = 0;
1659
1667
  while (beg < ib->size) /* iterating over lines */
@@ -1690,9 +1698,13 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer) {
1690
1698
  bufputc(text, '\n');
1691
1699
 
1692
1700
  /* second pass: actual rendering */
1693
- parse_block(ob, &rndr, text->data, text->size, 0 /* initial depth */);
1694
- if (rndr.make.finalize)
1695
- rndr.make.finalize(ob, &rndr.make.render_options);
1701
+ if (rndr.make.doc_header)
1702
+ rndr.make.doc_header(ob, &rndr.make.render_options);
1703
+
1704
+ parse_block(ob, &rndr, text->data, text->size);
1705
+
1706
+ if (rndr.make.doc_footer)
1707
+ rndr.make.doc_footer(ob, &rndr.make.render_options);
1696
1708
 
1697
1709
  /* clean-up */
1698
1710
  bufrelease(text);
@@ -1705,10 +1717,7 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer) {
1705
1717
 
1706
1718
  arr_free(&rndr.refs);
1707
1719
 
1708
- /* Do not assert this; a malformed Markdown
1709
- * file will result in parts of the work queue not being
1710
- * printed. We cannot crash the library in that case. Duh. */
1711
- //assert(rndr.work.size == 0);
1720
+ assert(rndr.work.size == 0);
1712
1721
 
1713
1722
  for (i = 0; i < (size_t)rndr.work.asize; i += 1)
1714
1723
  bufrelease(rndr.work.item[i]);
data/ext/markdown.h CHANGED
@@ -16,8 +16,8 @@
16
16
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
17
  */
18
18
 
19
- #ifndef LITHIUM_MARKDOWN_H
20
- #define LITHIUM_MARKDOWN_H
19
+ #ifndef UPSKIRT_MARKDOWN_H
20
+ #define UPSKIRT_MARKDOWN_H
21
21
 
22
22
  #include "buffer.h"
23
23
 
@@ -36,12 +36,12 @@ enum mkd_autolink {
36
36
  MKDA_IMPLICIT_EMAIL /* e-mail link without mailto: */
37
37
  };
38
38
 
39
- struct mkd_renderopt {
40
- union {
41
- int data;
42
- void *ptr;
43
- } opaque;
39
+ typedef enum {
40
+ MKD_LAX_EMPHASIS = (1 << 0),
41
+ } mkd_parser_mode;
44
42
 
43
+ struct mkd_renderopt {
44
+ void *opaque;
45
45
  unsigned int flags;
46
46
  };
47
47
 
@@ -56,7 +56,7 @@ struct mkd_renderer {
56
56
  void (*blockcode)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
57
57
  void (*blockquote)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
58
58
  void (*blockhtml)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
59
- void (*header)(struct buf *ob, struct buf *text, int level, int header_count, struct mkd_renderopt *opaque);
59
+ void (*header)(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *opaque);
60
60
  void (*hrule)(struct buf *ob, struct mkd_renderopt *opaque);
61
61
  void (*list)(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opaque);
62
62
  void (*listitem)(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opaque);
@@ -77,8 +77,9 @@ struct mkd_renderer {
77
77
  void (*entity)(struct buf *ob, struct buf *entity, struct mkd_renderopt *opaque);
78
78
  void (*normal_text)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
79
79
 
80
- /* finalizer */
81
- void (*finalize)(struct buf *ob, struct mkd_renderopt *opaque);
80
+ /* header and footer */
81
+ void (*doc_header)(struct buf *ob, struct mkd_renderopt *opaque);
82
+ void (*doc_footer)(struct buf *ob, struct mkd_renderopt *opaque);
82
83
 
83
84
  /* renderer data */
84
85
  const char *emph_chars; /* chars that trigger emphasis rendering */
@@ -87,8 +88,6 @@ struct mkd_renderer {
87
88
  struct mkd_parseropt parser_options;
88
89
  };
89
90
 
90
-
91
-
92
91
  /*********
93
92
  * FLAGS *
94
93
  *********/
@@ -97,22 +96,6 @@ struct mkd_renderer {
97
96
  #define MKD_LIST_ORDERED 1
98
97
  #define MKD_LI_BLOCK 2 /* <li> containing block data */
99
98
 
100
- typedef enum {
101
- RENDER_SKIP_HTML = (1 << 0),
102
- RENDER_SKIP_STYLE = (1 << 1),
103
- RENDER_SKIP_IMAGES = (1 << 2),
104
- RENDER_SKIP_LINKS = (1 << 3),
105
- RENDER_SMARTYPANTS = (1 << 4),
106
- RENDER_EXPAND_TABS = (1 << 5),
107
- RENDER_AUTOLINK = (1 << 6),
108
- RENDER_SAFELINK = (1 << 7),
109
- RENDER_TOC = (1 << 8),
110
- } render_mode;
111
-
112
- typedef enum {
113
- PARSER_STRICT = (1 << 0),
114
- } parser_mode;
115
-
116
99
  /**********************
117
100
  * EXPORTED FUNCTIONS *
118
101
  **********************/
@@ -121,14 +104,6 @@ typedef enum {
121
104
  void
122
105
  markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndr);
123
106
 
124
- void
125
- init_xhtml_renderer(struct mkd_renderer *renderer,
126
- unsigned int render_flags,
127
- unsigned int parser_flags, int recursion_depth);
128
-
129
- void
130
- init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth);
131
-
132
- #endif /* ndef LITHIUM_MARKDOWN_H */
107
+ #endif
133
108
 
134
109
  /* vim: set filetype=c: */
data/ext/redcarpet.c CHANGED
@@ -2,6 +2,7 @@
2
2
  #include "ruby.h"
3
3
 
4
4
  #include "markdown.h"
5
+ #include "xhtml.h"
5
6
 
6
7
  #define REDCARPET_RECURSION_LIMIT 16
7
8
 
@@ -49,9 +50,13 @@ static void rb_redcarpet__setup_xhtml(struct mkd_renderer *rnd, VALUE ruby_obj)
49
50
  if (rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
50
51
  render_flags |= RENDER_TOC;
51
52
 
52
- /* parser - strict */
53
+ /* parser - strict
54
+ * This is fucking stupid; what the 'strict' flag actually
55
+ * enforces is laxer emphasis parsing. So we use a properly
56
+ * named flag internally, even if outside we have retarded
57
+ * naming because of compat. issues .*/
53
58
  if (rb_funcall(ruby_obj, rb_intern("strict"), 0) == Qtrue)
54
- parser_flags |= PARSER_STRICT;
59
+ parser_flags |= MKD_LAX_EMPHASIS;
55
60
 
56
61
  init_xhtml_renderer(rnd, render_flags, parser_flags, REDCARPET_RECURSION_LIMIT);
57
62
  }
@@ -90,6 +95,7 @@ static VALUE rb_redcarpet__render(VALUE self, RendererType render_type)
90
95
 
91
96
  result = rb_str_new(output_buf->data, output_buf->size);
92
97
  bufrelease(output_buf);
98
+ free_renderer(&renderer);
93
99
 
94
100
  /* force the input encoding */
95
101
  if (rb_respond_to(text, rb_intern("encoding"))) {
@@ -16,11 +16,16 @@
16
16
  */
17
17
 
18
18
  #include "markdown.h"
19
+ #include "xhtml.h"
19
20
 
20
21
  #include <strings.h>
21
22
  #include <stdlib.h>
22
23
  #include <stdio.h>
23
24
 
25
+ struct toc_data {
26
+ int header_count;
27
+ int current_level;
28
+ };
24
29
 
25
30
  static int
26
31
  is_safe_link(const char *link, size_t link_len)
@@ -48,7 +53,7 @@ is_uri_char(char c)
48
53
  return isalnum(c) || strchr("/:$-_.+!*'(),", c) != NULL;
49
54
  }
50
55
 
51
- static int
56
+ static inline int
52
57
  put_scaped_char(struct buf *ob, char c)
53
58
  {
54
59
  switch (c) {
@@ -174,13 +179,15 @@ rndr_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *op
174
179
  }
175
180
 
176
181
  static void
177
- rndr_header(struct buf *ob, struct buf *text, int level, int header_count, struct mkd_renderopt *options)
182
+ rndr_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
178
183
  {
179
184
  if (ob->size)
180
185
  bufputc(ob, '\n');
181
186
 
182
- if (options->flags & RENDER_TOC)
183
- bufprintf(ob, "<a name=\"toc_%d\"></a>", header_count);
187
+ if (options->flags & RENDER_TOC) {
188
+ struct toc_data *data = options->opaque;
189
+ bufprintf(ob, "<a name=\"toc_%d\"></a>", data->header_count++);
190
+ }
184
191
 
185
192
  bufprintf(ob, "<h%d>", level);
186
193
  if (text) bufput(ob, text->data, text->size);
@@ -561,6 +568,87 @@ rndr_normal_text(struct buf *ob, struct buf *text, struct mkd_renderopt *options
561
568
  }
562
569
  }
563
570
 
571
+ static void
572
+ toc_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
573
+ {
574
+ struct toc_data *data = (struct toc_data *)options->opaque;
575
+
576
+ if (level > data->current_level) {
577
+ if (level > 1)
578
+ BUFPUTSL(ob, "<li>");
579
+ BUFPUTSL(ob, "<ul>\n");
580
+ }
581
+
582
+ if (level < data->current_level) {
583
+ BUFPUTSL(ob, "</ul>");
584
+ if (data->current_level > 1)
585
+ BUFPUTSL(ob, "</li>\n");
586
+ }
587
+
588
+ data->current_level = level;
589
+
590
+ bufprintf(ob, "<li><a href=\"#toc_%d\">", data->header_count++);
591
+ if (text)
592
+ bufput(ob, text->data, text->size);
593
+ BUFPUTSL(ob, "</a></li>\n");
594
+ }
595
+
596
+ static void
597
+ toc_finalize(struct buf *ob, struct mkd_renderopt *options)
598
+ {
599
+ struct toc_data *data = (struct toc_data *)options->opaque;
600
+
601
+ while (data->current_level > 1) {
602
+ BUFPUTSL(ob, "</ul></li>\n");
603
+ data->current_level--;
604
+ }
605
+
606
+ if (data->current_level)
607
+ BUFPUTSL(ob, "</ul>\n");
608
+ }
609
+
610
+ void
611
+ init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth)
612
+ {
613
+ static const struct mkd_renderer toc_render = {
614
+ NULL,
615
+ NULL,
616
+ NULL,
617
+ toc_header,
618
+ NULL,
619
+ NULL,
620
+ NULL,
621
+ NULL,
622
+
623
+ rndr_autolink,
624
+ rndr_codespan,
625
+ rndr_double_emphasis,
626
+ rndr_emphasis,
627
+ rndr_image,
628
+ rndr_linebreak,
629
+ rndr_link,
630
+ rndr_raw_html,
631
+ rndr_triple_emphasis,
632
+
633
+ NULL,
634
+ NULL,
635
+
636
+ NULL,
637
+ toc_finalize,
638
+
639
+ NULL,
640
+
641
+ { 0, 0 },
642
+ { 0, 0 },
643
+ };
644
+
645
+ memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
646
+
647
+ renderer->parser_options.recursion_depth = recursion_depth;
648
+ renderer->render_options.flags = RENDER_TOC;
649
+ renderer->render_options.opaque = calloc(1, sizeof(struct toc_data));
650
+ }
651
+
564
652
  void
565
653
  init_xhtml_renderer(struct mkd_renderer *renderer,
566
654
  unsigned int render_flags,
@@ -588,6 +676,8 @@ init_xhtml_renderer(struct mkd_renderer *renderer,
588
676
 
589
677
  NULL,
590
678
  rndr_normal_text,
679
+
680
+ NULL,
591
681
  NULL,
592
682
 
593
683
  "*_",
@@ -608,6 +698,15 @@ init_xhtml_renderer(struct mkd_renderer *renderer,
608
698
 
609
699
  renderer->parser_options.recursion_depth = recursion_depth;
610
700
  renderer->parser_options.flags = parser_flags;
701
+
611
702
  renderer->render_options.flags = render_flags;
703
+ if (render_flags & RENDER_TOC)
704
+ renderer->render_options.opaque = calloc(1, sizeof(struct toc_data));
705
+ }
706
+
707
+ void
708
+ free_renderer(struct mkd_renderer *renderer)
709
+ {
710
+ free(renderer->render_options.opaque);
612
711
  }
613
712
 
data/ext/xhtml.h ADDED
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Copyright (c) 2011, Vicent Marti
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #ifndef UPSKIRT_XHTML_H
18
+ #define UPSKIRT_XHTML_H
19
+ typedef enum {
20
+ RENDER_SKIP_HTML = (1 << 0),
21
+ RENDER_SKIP_STYLE = (1 << 1),
22
+ RENDER_SKIP_IMAGES = (1 << 2),
23
+ RENDER_SKIP_LINKS = (1 << 3),
24
+ RENDER_SMARTYPANTS = (1 << 4),
25
+ RENDER_EXPAND_TABS = (1 << 5),
26
+ RENDER_AUTOLINK = (1 << 6),
27
+ RENDER_SAFELINK = (1 << 7),
28
+ RENDER_TOC = (1 << 8),
29
+ } render_mode;
30
+
31
+ void
32
+ init_xhtml_renderer(struct mkd_renderer *renderer,
33
+ unsigned int render_flags,
34
+ unsigned int parser_flags, int recursion_depth);
35
+
36
+ void
37
+ init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth);
38
+
39
+ void
40
+ free_renderer(struct mkd_renderer *renderer);
41
+
42
+ #endif
43
+
data/lib/redcarpet.rb CHANGED
@@ -26,7 +26,7 @@
26
26
  # end
27
27
  #
28
28
  class Redcarpet
29
- VERSION = '1.2.2'
29
+ VERSION = '1.3.0'
30
30
 
31
31
  # Original Markdown formatted text.
32
32
  attr_reader :text
data/redcarpet.gemspec CHANGED
@@ -1,8 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'redcarpet'
3
- s.version = '1.2.2'
3
+ s.version = '1.3.0'
4
4
  s.summary = "Ruby bindings for libupskirt"
5
- s.date = '2011-04-04'
5
+ s.date = '2011-04-05'
6
6
  s.email = 'vicent@github.com'
7
7
  s.homepage = 'http://github.com/tanoku/redcarpet'
8
8
  s.has_rdoc = true
@@ -21,8 +21,8 @@ Gem::Specification.new do |s|
21
21
  ext/markdown.c
22
22
  ext/markdown.h
23
23
  ext/redcarpet.c
24
- ext/render.c
25
- ext/toc.c
24
+ ext/xhtml.c
25
+ ext/xhtml.h
26
26
  lib/markdown.rb
27
27
  lib/redcarpet.rb
28
28
  redcarpet.gemspec
@@ -113,12 +113,12 @@ class RedcarpetTest < Test::Unit::TestCase
113
113
  def test_that_generate_toc_sets_toc_ids
114
114
  rd = Redcarpet.new("# Level 1\n\n## Level 2", :generate_toc)
115
115
  assert rd.generate_toc
116
- assert_equal %(<a name="toc_1"></a><h1>Level 1</h1>\n\n<a name="toc_2"></a><h2>Level 2</h2>\n), rd.to_html
116
+ assert_equal %(<a name="toc_0"></a><h1>Level 1</h1>\n\n<a name="toc_1"></a><h2>Level 2</h2>\n), rd.to_html
117
117
  end
118
118
 
119
119
  def test_should_get_the_generated_toc
120
120
  rd = Redcarpet.new("# Level 1\n\n## Level 2", :generate_toc)
121
- exp = %(<ul>\n<li><a href="#toc_1">Level 1</a></li>\n<li><ul>\n<li><a href="#toc_2">Level 2</a></li>\n</ul></li>\n</ul>)
121
+ exp = %(<ul>\n<li><a href="#toc_0">Level 1</a></li>\n<li><ul>\n<li><a href="#toc_1">Level 2</a></li>\n</ul></li>\n</ul>)
122
122
  assert_equal exp, rd.toc_content.strip
123
123
  end
124
124
 
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 2
9
- - 2
10
- version: 1.2.2
8
+ - 3
9
+ - 0
10
+ version: 1.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Natacha Port\xC3\xA9"
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-04-04 00:00:00 +03:00
19
+ date: 2011-04-05 00:00:00 +03:00
20
20
  default_executable:
21
21
  dependencies: []
22
22
 
@@ -41,8 +41,8 @@ files:
41
41
  - ext/markdown.c
42
42
  - ext/markdown.h
43
43
  - ext/redcarpet.c
44
- - ext/render.c
45
- - ext/toc.c
44
+ - ext/xhtml.c
45
+ - ext/xhtml.h
46
46
  - lib/markdown.rb
47
47
  - lib/redcarpet.rb
48
48
  - redcarpet.gemspec
data/ext/toc.c DELETED
@@ -1,101 +0,0 @@
1
- /*
2
- * Copyright (c) 2011, Vicent Marti
3
- *
4
- * Permission to use, copy, modify, and distribute this software for any
5
- * purpose with or without fee is hereby granted, provided that the above
6
- * copyright notice and this permission notice appear in all copies.
7
- *
8
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
- */
16
-
17
- #include "markdown.h"
18
-
19
- #include <strings.h>
20
- #include <stdlib.h>
21
- #include <stdio.h>
22
-
23
- static void
24
- toc_header(struct buf *ob, struct buf *text, int level, int header_id, struct mkd_renderopt *options)
25
- {
26
- int current_level = (int)options->opaque.data;
27
-
28
- if (level > current_level) {
29
- if (level > 1)
30
- BUFPUTSL(ob, "<li>");
31
- BUFPUTSL(ob, "<ul>\n");
32
- }
33
-
34
- if (level < current_level) {
35
- BUFPUTSL(ob, "</ul>");
36
- if (current_level > 1)
37
- BUFPUTSL(ob, "</li>\n");
38
- }
39
-
40
- options->opaque.data = level;
41
-
42
- bufprintf(ob, "<li><a href=\"#toc_%d\">", header_id);
43
- if (text)
44
- bufput(ob, text->data, text->size);
45
- BUFPUTSL(ob, "</a></li>\n");
46
- }
47
-
48
- static void
49
- toc_finalize(struct buf *ob, struct mkd_renderopt *options)
50
- {
51
- int current_level = (int)options->opaque.data;
52
-
53
- while (current_level > 1) {
54
- BUFPUTSL(ob, "</ul></li>\n");
55
- current_level--;
56
- }
57
-
58
- if (current_level)
59
- BUFPUTSL(ob, "</ul>\n");
60
- }
61
-
62
- void
63
- init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth)
64
- {
65
- static const struct mkd_renderer toc_render = {
66
- NULL,
67
- NULL,
68
- NULL,
69
- toc_header,
70
- NULL,
71
- NULL,
72
- NULL,
73
- NULL,
74
-
75
- NULL,
76
- NULL,
77
- NULL,
78
- NULL,
79
- NULL,
80
- NULL,
81
- NULL,
82
- NULL,
83
- NULL,
84
-
85
- NULL,
86
- NULL,
87
- toc_finalize,
88
-
89
- NULL,
90
-
91
- { 0, 0 },
92
- { 0, 0 },
93
- };
94
-
95
- memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
96
-
97
- renderer->parser_options.recursion_depth = recursion_depth;
98
- renderer->render_options.flags = RENDER_TOC;
99
- renderer->render_options.opaque.data = 0;
100
- }
101
-