redcarpet 2.0.0b → 2.0.0b3

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 CHANGED
@@ -123,7 +123,7 @@ renderers are actually implemented in C, and hence offer a brilliant
123
123
  performance, several degrees of magnitude faster than other Ruby Markdown
124
124
  solutions.
125
125
 
126
- The `HTML` renderer has an alternate version, `Redcarpet::Render::HTML_toc`,
126
+ The `HTML` renderer has an alternate version, `Redcarpet::Render::HTML_TOC`,
127
127
  which will output a table of contents in HTML based on the headers of the
128
128
  Markdown document.
129
129
 
@@ -180,7 +180,7 @@ The following instance methods may be implemented by the renderer:
180
180
  header(text, header_level)
181
181
  hrule()
182
182
  list(contents, list_type)
183
- list_item(text)
183
+ list_item(text, list_type)
184
184
  paragraph(text)
185
185
  table(header, body)
186
186
  table_row(content)
data/ext/redcarpet/html.c CHANGED
@@ -25,17 +25,6 @@
25
25
 
26
26
  #define USE_XHTML(opt) (opt->flags & HTML_USE_XHTML)
27
27
 
28
- struct html_renderopt {
29
- void *extra;
30
-
31
- struct {
32
- int header_count;
33
- int current_level;
34
- } toc_data;
35
-
36
- unsigned int flags;
37
- };
38
-
39
28
  static inline void
40
29
  put_scaped_char(struct buf *ob, char c)
41
30
  {
@@ -122,7 +111,14 @@ rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *op
122
111
  if (type == MKDA_EMAIL)
123
112
  BUFPUTSL(ob, "mailto:");
124
113
  bufput(ob, link->data, link->size);
125
- BUFPUTSL(ob, "\">");
114
+
115
+ if (options->link_attributes) {
116
+ bufputc(ob, '\"');
117
+ options->link_attributes(ob, link, opaque);
118
+ bufputc(ob, '>');
119
+ } else {
120
+ BUFPUTSL(ob, "\">");
121
+ }
126
122
 
127
123
  /*
128
124
  * Pretty printing: if we get an email address as
@@ -308,11 +304,23 @@ rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *conte
308
304
  return 0;
309
305
 
310
306
  BUFPUTSL(ob, "<a href=\"");
311
- if (link && link->size) bufput(ob, link->data, link->size);
307
+
308
+ if (link && link->size)
309
+ bufput(ob, link->data, link->size);
310
+
312
311
  if (title && title->size) {
313
312
  BUFPUTSL(ob, "\" title=\"");
314
- sdhtml_escape(ob, title->data, title->size); }
315
- BUFPUTSL(ob, "\">");
313
+ sdhtml_escape(ob, title->data, title->size);
314
+ }
315
+
316
+ if (options->link_attributes) {
317
+ bufputc(ob, '\"');
318
+ options->link_attributes(ob, link, opaque);
319
+ bufputc(ob, '>');
320
+ } else {
321
+ BUFPUTSL(ob, "\">");
322
+ }
323
+
316
324
  if (content && content->size) bufput(ob, content->data, content->size);
317
325
  BUFPUTSL(ob, "</a>");
318
326
  return 1;
@@ -558,9 +566,9 @@ toc_finalize(struct buf *ob, void *opaque)
558
566
  }
559
567
 
560
568
  void
561
- sdhtml_toc_renderer(struct mkd_renderer *renderer, void *extra)
569
+ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options)
562
570
  {
563
- static const struct mkd_renderer toc_render = {
571
+ static const struct sd_callbacks cb_default = {
564
572
  NULL,
565
573
  NULL,
566
574
  NULL,
@@ -590,23 +598,18 @@ sdhtml_toc_renderer(struct mkd_renderer *renderer, void *extra)
590
598
 
591
599
  NULL,
592
600
  toc_finalize,
593
-
594
- NULL
595
601
  };
596
602
 
597
- struct html_renderopt *options;
598
- options = calloc(1, sizeof(struct html_renderopt));
603
+ memset(options, 0x0, sizeof(struct html_renderopt));
599
604
  options->flags = HTML_TOC;
600
- options->extra = extra;
601
605
 
602
- memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
603
- renderer->opaque = options;
606
+ memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks));
604
607
  }
605
608
 
606
609
  void
607
- sdhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags, void *extra)
610
+ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options, unsigned int render_flags)
608
611
  {
609
- static const struct mkd_renderer renderer_default = {
612
+ static const struct sd_callbacks cb_default = {
610
613
  rndr_blockcode,
611
614
  rndr_blockquote,
612
615
  rndr_raw_block,
@@ -636,36 +639,26 @@ sdhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags, void *
636
639
 
637
640
  NULL,
638
641
  NULL,
639
-
640
- NULL
641
642
  };
642
643
 
643
- struct html_renderopt *options;
644
- options = calloc(1, sizeof(struct html_renderopt));
644
+ /* Prepare the options pointer */
645
+ memset(options, 0x0, sizeof(struct html_renderopt));
645
646
  options->flags = render_flags;
646
- options->extra = extra;
647
647
 
648
- memcpy(renderer, &renderer_default, sizeof(struct mkd_renderer));
649
- renderer->opaque = options;
648
+ /* Prepare the callbacks */
649
+ memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks));
650
650
 
651
651
  if (render_flags & HTML_SKIP_IMAGES)
652
- renderer->image = NULL;
652
+ callbacks->image = NULL;
653
653
 
654
654
  if (render_flags & HTML_SKIP_LINKS) {
655
- renderer->link = NULL;
656
- renderer->autolink = NULL;
655
+ callbacks->link = NULL;
656
+ callbacks->autolink = NULL;
657
657
  }
658
658
 
659
659
  if (render_flags & HTML_SKIP_HTML)
660
- renderer->blockhtml = NULL;
660
+ callbacks->blockhtml = NULL;
661
661
 
662
662
  if (render_flags & HTML_GITHUB_BLOCKCODE)
663
- renderer->blockcode = rndr_blockcode_github;
663
+ callbacks->blockcode = rndr_blockcode_github;
664
664
  }
665
-
666
- void
667
- sdhtml_free_renderer(struct mkd_renderer *renderer)
668
- {
669
- free(renderer->opaque);
670
- }
671
-
data/ext/redcarpet/html.h CHANGED
@@ -21,6 +21,18 @@
21
21
  #include "buffer.h"
22
22
  #include <stdlib.h>
23
23
 
24
+ struct html_renderopt {
25
+ struct {
26
+ int header_count;
27
+ int current_level;
28
+ } toc_data;
29
+
30
+ unsigned int flags;
31
+
32
+ /* extra callbacks */
33
+ void (*link_attributes)(struct buf *ob, struct buf *url, void *self);
34
+ };
35
+
24
36
  typedef enum {
25
37
  HTML_SKIP_HTML = (1 << 0),
26
38
  HTML_SKIP_STYLE = (1 << 1),
@@ -32,7 +44,7 @@ typedef enum {
32
44
  HTML_HARD_WRAP = (1 << 9),
33
45
  HTML_GITHUB_BLOCKCODE = (1 << 10),
34
46
  HTML_USE_XHTML = (1 << 11),
35
- } render_mode;
47
+ } html_render_mode;
36
48
 
37
49
  typedef enum {
38
50
  HTML_TAG_NONE = 0,
@@ -47,13 +59,10 @@ int
47
59
  sdhtml_tag(const char *tag_data, size_t tag_size, const char *tagname);
48
60
 
49
61
  extern void
50
- sdhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags, void *extra);
51
-
52
- extern void
53
- sdhtml_toc_renderer(struct mkd_renderer *renderer, void *extra);
62
+ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options_ptr, unsigned int render_flags);
54
63
 
55
64
  extern void
56
- sdhtml_free_renderer(struct mkd_renderer *renderer);
65
+ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options_ptr);
57
66
 
58
67
  extern void
59
68
  sdhtml_smartypants(struct buf *ob, struct buf *text);
@@ -94,7 +94,9 @@ static char_trigger markdown_char_ptrs[] = {
94
94
 
95
95
  /* render • structure containing one particular render */
96
96
  struct render {
97
- struct mkd_renderer make;
97
+ struct sd_callbacks cb;
98
+ void *opaque;
99
+
98
100
  struct array refs;
99
101
  char active_char[256];
100
102
  struct parray work_bufs[2];
@@ -354,10 +356,10 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
354
356
  end++;
355
357
  }
356
358
 
357
- if (rndr->make.normal_text) {
359
+ if (rndr->cb.normal_text) {
358
360
  work.data = data + i;
359
361
  work.size = end - i;
360
- rndr->make.normal_text(ob, &work, rndr->make.opaque);
362
+ rndr->cb.normal_text(ob, &work, rndr->opaque);
361
363
  }
362
364
  else
363
365
  bufput(ob, data + i, end - i);
@@ -461,7 +463,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
461
463
  struct buf *work = 0;
462
464
  int r;
463
465
 
464
- if (!rndr->make.emphasis) return 0;
466
+ if (!rndr->cb.emphasis) return 0;
465
467
 
466
468
  /* skipping one symbol if coming from emph3 */
467
469
  if (size > 1 && data[0] == c && data[1] == c) i = 1;
@@ -486,7 +488,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
486
488
 
487
489
  work = rndr_newbuf(rndr, BUFFER_SPAN);
488
490
  parse_inline(work, rndr, data, i);
489
- r = rndr->make.emphasis(ob, work, rndr->make.opaque);
491
+ r = rndr->cb.emphasis(ob, work, rndr->opaque);
490
492
  rndr_popbuf(rndr, BUFFER_SPAN);
491
493
  return r ? i + 1 : 0;
492
494
  }
@@ -504,7 +506,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
504
506
  struct buf *work = 0;
505
507
  int r;
506
508
 
507
- render_method = (c == '~') ? rndr->make.strikethrough : rndr->make.double_emphasis;
509
+ render_method = (c == '~') ? rndr->cb.strikethrough : rndr->cb.double_emphasis;
508
510
 
509
511
  if (!render_method)
510
512
  return 0;
@@ -517,7 +519,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
517
519
  if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !isspace(data[i - 1])) {
518
520
  work = rndr_newbuf(rndr, BUFFER_SPAN);
519
521
  parse_inline(work, rndr, data, i);
520
- r = render_method(ob, work, rndr->make.opaque);
522
+ r = render_method(ob, work, rndr->opaque);
521
523
  rndr_popbuf(rndr, BUFFER_SPAN);
522
524
  return r ? i + 2 : 0;
523
525
  }
@@ -543,12 +545,12 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c
543
545
  if (data[i] != c || isspace(data[i - 1]))
544
546
  continue;
545
547
 
546
- if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && rndr->make.triple_emphasis) {
548
+ if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && rndr->cb.triple_emphasis) {
547
549
  /* triple symbol found */
548
550
  struct buf *work = rndr_newbuf(rndr, BUFFER_SPAN);
549
551
 
550
552
  parse_inline(work, rndr, data, i);
551
- r = rndr->make.triple_emphasis(ob, work, rndr->make.opaque);
553
+ r = rndr->cb.triple_emphasis(ob, work, rndr->opaque);
552
554
  rndr_popbuf(rndr, BUFFER_SPAN);
553
555
  return r ? i + 3 : 0;
554
556
 
@@ -613,7 +615,7 @@ char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, s
613
615
  while (ob->size && ob->data[ob->size - 1] == ' ')
614
616
  ob->size--;
615
617
 
616
- return rndr->make.linebreak(ob, rndr->make.opaque) ? 1 : 0;
618
+ return rndr->cb.linebreak(ob, rndr->opaque) ? 1 : 0;
617
619
  }
618
620
 
619
621
 
@@ -649,10 +651,10 @@ char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, si
649
651
  /* real code span */
650
652
  if (f_begin < f_end) {
651
653
  struct buf work = { data + f_begin, f_end - f_begin, 0, 0, 0 };
652
- if (!rndr->make.codespan(ob, &work, rndr->make.opaque))
654
+ if (!rndr->cb.codespan(ob, &work, rndr->opaque))
653
655
  end = 0;
654
656
  } else {
655
- if (!rndr->make.codespan(ob, 0, rndr->make.opaque))
657
+ if (!rndr->cb.codespan(ob, 0, rndr->opaque))
656
658
  end = 0;
657
659
  }
658
660
 
@@ -671,10 +673,10 @@ char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size
671
673
  if (strchr(escape_chars, data[1]) == NULL)
672
674
  return 0;
673
675
 
674
- if (rndr->make.normal_text) {
676
+ if (rndr->cb.normal_text) {
675
677
  work.data = data + 1;
676
678
  work.size = 1;
677
- rndr->make.normal_text(ob, &work, rndr->make.opaque);
679
+ rndr->cb.normal_text(ob, &work, rndr->opaque);
678
680
  }
679
681
  else bufputc(ob, data[1]);
680
682
  }
@@ -701,10 +703,10 @@ char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size
701
703
  else
702
704
  return 0; /* lone '&' */
703
705
 
704
- if (rndr->make.entity) {
706
+ if (rndr->cb.entity) {
705
707
  work.data = data;
706
708
  work.size = end;
707
- rndr->make.entity(ob, &work, rndr->make.opaque);
709
+ rndr->cb.entity(ob, &work, rndr->opaque);
708
710
  }
709
711
  else bufput(ob, data, end);
710
712
 
@@ -721,16 +723,16 @@ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset,
721
723
  int ret = 0;
722
724
 
723
725
  if (end > 2) {
724
- if (rndr->make.autolink && altype != MKDA_NOT_AUTOLINK) {
726
+ if (rndr->cb.autolink && altype != MKDA_NOT_AUTOLINK) {
725
727
  struct buf *u_link = rndr_newbuf(rndr, BUFFER_SPAN);
726
728
  work.data = data + 1;
727
729
  work.size = end - 2;
728
730
  unscape_text(u_link, &work);
729
- ret = rndr->make.autolink(ob, u_link, altype, rndr->make.opaque);
731
+ ret = rndr->cb.autolink(ob, u_link, altype, rndr->opaque);
730
732
  rndr_popbuf(rndr, BUFFER_SPAN);
731
733
  }
732
- else if (rndr->make.raw_html_tag)
733
- ret = rndr->make.raw_html_tag(ob, &work, rndr->make.opaque);
734
+ else if (rndr->cb.raw_html_tag)
735
+ ret = rndr->cb.raw_html_tag(ob, &work, rndr->opaque);
734
736
  }
735
737
 
736
738
  if (!ret) return 0;
@@ -743,7 +745,7 @@ char_autolink_www(struct buf *ob, struct render *rndr, char *data, size_t offset
743
745
  struct buf *link, *link_url;
744
746
  size_t link_len, rewind;
745
747
 
746
- if (!rndr->make.link)
748
+ if (!rndr->cb.link)
747
749
  return 0;
748
750
 
749
751
  link = rndr_newbuf(rndr, BUFFER_SPAN);
@@ -754,7 +756,7 @@ char_autolink_www(struct buf *ob, struct render *rndr, char *data, size_t offset
754
756
  bufput(link_url, link->data, link->size);
755
757
 
756
758
  ob->size -= rewind;
757
- rndr->make.link(ob, link_url, NULL, link, rndr->make.opaque);
759
+ rndr->cb.link(ob, link_url, NULL, link, rndr->opaque);
758
760
  rndr_popbuf(rndr, BUFFER_SPAN);
759
761
  }
760
762
 
@@ -768,14 +770,14 @@ char_autolink_email(struct buf *ob, struct render *rndr, char *data, size_t offs
768
770
  struct buf *link;
769
771
  size_t link_len, rewind;
770
772
 
771
- if (!rndr->make.autolink)
773
+ if (!rndr->cb.autolink)
772
774
  return 0;
773
775
 
774
776
  link = rndr_newbuf(rndr, BUFFER_SPAN);
775
777
 
776
778
  if ((link_len = sd_autolink__email(&rewind, link, data, offset, size)) > 0) {
777
779
  ob->size -= rewind;
778
- rndr->make.autolink(ob, link, MKDA_EMAIL, rndr->make.opaque);
780
+ rndr->cb.autolink(ob, link, MKDA_EMAIL, rndr->opaque);
779
781
  }
780
782
 
781
783
  rndr_popbuf(rndr, BUFFER_SPAN);
@@ -788,14 +790,14 @@ char_autolink_url(struct buf *ob, struct render *rndr, char *data, size_t offset
788
790
  struct buf *link;
789
791
  size_t link_len, rewind;
790
792
 
791
- if (!rndr->make.autolink)
793
+ if (!rndr->cb.autolink)
792
794
  return 0;
793
795
 
794
796
  link = rndr_newbuf(rndr, BUFFER_SPAN);
795
797
 
796
798
  if ((link_len = sd_autolink__url(&rewind, link, data, offset, size)) > 0) {
797
799
  ob->size -= rewind;
798
- rndr->make.autolink(ob, link, MKDA_NORMAL, rndr->make.opaque);
800
+ rndr->cb.autolink(ob, link, MKDA_NORMAL, rndr->opaque);
799
801
  }
800
802
 
801
803
  rndr_popbuf(rndr, BUFFER_SPAN);
@@ -816,7 +818,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
816
818
  int text_has_nl = 0, ret = 0;
817
819
 
818
820
  /* checking whether the correct renderer exists */
819
- if ((is_img && !rndr->make.image) || (!is_img && !rndr->make.link))
821
+ if ((is_img && !rndr->cb.image) || (!is_img && !rndr->cb.link))
820
822
  goto cleanup;
821
823
 
822
824
  /* looking for the matching closing bracket */
@@ -1013,9 +1015,9 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
1013
1015
  if (ob->size && ob->data[ob->size - 1] == '!')
1014
1016
  ob->size -= 1;
1015
1017
 
1016
- ret = rndr->make.image(ob, u_link, title, content, rndr->make.opaque);
1018
+ ret = rndr->cb.image(ob, u_link, title, content, rndr->opaque);
1017
1019
  } else {
1018
- ret = rndr->make.link(ob, u_link, title, content, rndr->make.opaque);
1020
+ ret = rndr->cb.link(ob, u_link, title, content, rndr->opaque);
1019
1021
  }
1020
1022
 
1021
1023
  /* cleanup */
@@ -1030,7 +1032,7 @@ char_superscript(struct buf *ob, struct render *rndr, char *data, size_t offset,
1030
1032
  size_t sup_start, sup_len;
1031
1033
  struct buf *sup;
1032
1034
 
1033
- if (!rndr->make.superscript)
1035
+ if (!rndr->cb.superscript)
1034
1036
  return 0;
1035
1037
 
1036
1038
  if (size < 2)
@@ -1056,7 +1058,7 @@ char_superscript(struct buf *ob, struct render *rndr, char *data, size_t offset,
1056
1058
 
1057
1059
  sup = rndr_newbuf(rndr, BUFFER_SPAN);
1058
1060
  parse_inline(sup, rndr, data + sup_start, sup_len - sup_start);
1059
- rndr->make.superscript(ob, sup, rndr->make.opaque);
1061
+ rndr->cb.superscript(ob, sup, rndr->opaque);
1060
1062
  rndr_popbuf(rndr, BUFFER_SPAN);
1061
1063
 
1062
1064
  return (sup_start == 2) ? sup_len + 1 : sup_len;
@@ -1317,8 +1319,8 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size)
1317
1319
  }
1318
1320
 
1319
1321
  parse_block(out, rndr, work_data, work_size);
1320
- if (rndr->make.blockquote)
1321
- rndr->make.blockquote(ob, out, rndr->make.opaque);
1322
+ if (rndr->cb.blockquote)
1323
+ rndr->cb.blockquote(ob, out, rndr->opaque);
1322
1324
  rndr_popbuf(rndr, BUFFER_BLOCK);
1323
1325
  return end;
1324
1326
  }
@@ -1341,7 +1343,7 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
1341
1343
  break;
1342
1344
 
1343
1345
  if (rndr->ext_flags & MKDEXT_LAX_HTML_BLOCKS) {
1344
- if (data[i] == '<' && rndr->make.blockhtml && parse_htmlblock(ob, rndr, data + i, size - i, 0)) {
1346
+ if (data[i] == '<' && rndr->cb.blockhtml && parse_htmlblock(ob, rndr, data + i, size - i, 0)) {
1345
1347
  end = i;
1346
1348
  break;
1347
1349
  }
@@ -1362,8 +1364,8 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
1362
1364
  if (!level) {
1363
1365
  struct buf *tmp = rndr_newbuf(rndr, BUFFER_BLOCK);
1364
1366
  parse_inline(tmp, rndr, work.data, work.size);
1365
- if (rndr->make.paragraph)
1366
- rndr->make.paragraph(ob, tmp, rndr->make.opaque);
1367
+ if (rndr->cb.paragraph)
1368
+ rndr->cb.paragraph(ob, tmp, rndr->opaque);
1367
1369
  rndr_popbuf(rndr, BUFFER_BLOCK);
1368
1370
  } else {
1369
1371
  struct buf *header_work;
@@ -1384,8 +1386,8 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
1384
1386
  struct buf *tmp = rndr_newbuf(rndr, BUFFER_BLOCK);
1385
1387
  parse_inline(tmp, rndr, work.data, work.size);
1386
1388
 
1387
- if (rndr->make.paragraph)
1388
- rndr->make.paragraph(ob, tmp, rndr->make.opaque);
1389
+ if (rndr->cb.paragraph)
1390
+ rndr->cb.paragraph(ob, tmp, rndr->opaque);
1389
1391
 
1390
1392
  rndr_popbuf(rndr, BUFFER_BLOCK);
1391
1393
  work.data += beg;
@@ -1397,8 +1399,8 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
1397
1399
  header_work = rndr_newbuf(rndr, BUFFER_SPAN);
1398
1400
  parse_inline(header_work, rndr, work.data, work.size);
1399
1401
 
1400
- if (rndr->make.header)
1401
- rndr->make.header(ob, header_work, (int)level, rndr->make.opaque);
1402
+ if (rndr->cb.header)
1403
+ rndr->cb.header(ob, header_work, (int)level, rndr->opaque);
1402
1404
 
1403
1405
  rndr_popbuf(rndr, BUFFER_SPAN);
1404
1406
  }
@@ -1443,8 +1445,8 @@ parse_fencedcode(struct buf *ob, struct render *rndr, char *data, size_t size)
1443
1445
  if (work->size && work->data[work->size - 1] != '\n')
1444
1446
  bufputc(work, '\n');
1445
1447
 
1446
- if (rndr->make.blockcode)
1447
- rndr->make.blockcode(ob, work, lang.size ? &lang : NULL, rndr->make.opaque);
1448
+ if (rndr->cb.blockcode)
1449
+ rndr->cb.blockcode(ob, work, lang.size ? &lang : NULL, rndr->opaque);
1448
1450
 
1449
1451
  rndr_popbuf(rndr, BUFFER_BLOCK);
1450
1452
  return beg;
@@ -1484,8 +1486,8 @@ parse_blockcode(struct buf *ob, struct render *rndr, char *data, size_t size)
1484
1486
 
1485
1487
  bufputc(work, '\n');
1486
1488
 
1487
- if (rndr->make.blockcode)
1488
- rndr->make.blockcode(ob, work, NULL, rndr->make.opaque);
1489
+ if (rndr->cb.blockcode)
1490
+ rndr->cb.blockcode(ob, work, NULL, rndr->opaque);
1489
1491
 
1490
1492
  rndr_popbuf(rndr, BUFFER_BLOCK);
1491
1493
  return beg;
@@ -1599,8 +1601,8 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
1599
1601
  }
1600
1602
 
1601
1603
  /* render of li itself */
1602
- if (rndr->make.listitem)
1603
- rndr->make.listitem(ob, inter, *flags, rndr->make.opaque);
1604
+ if (rndr->cb.listitem)
1605
+ rndr->cb.listitem(ob, inter, *flags, rndr->opaque);
1604
1606
 
1605
1607
  rndr_popbuf(rndr, BUFFER_SPAN);
1606
1608
  rndr_popbuf(rndr, BUFFER_SPAN);
@@ -1625,8 +1627,8 @@ parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int fla
1625
1627
  break;
1626
1628
  }
1627
1629
 
1628
- if (rndr->make.list)
1629
- rndr->make.list(ob, work, flags, rndr->make.opaque);
1630
+ if (rndr->cb.list)
1631
+ rndr->cb.list(ob, work, flags, rndr->opaque);
1630
1632
  rndr_popbuf(rndr, BUFFER_BLOCK);
1631
1633
  return i;
1632
1634
  }
@@ -1657,8 +1659,8 @@ parse_atxheader(struct buf *ob, struct render *rndr, char *data, size_t size)
1657
1659
 
1658
1660
  parse_inline(work, rndr, data + i, end - i);
1659
1661
 
1660
- if (rndr->make.header)
1661
- rndr->make.header(ob, work, (int)level, rndr->make.opaque);
1662
+ if (rndr->cb.header)
1663
+ rndr->cb.header(ob, work, (int)level, rndr->opaque);
1662
1664
 
1663
1665
  rndr_popbuf(rndr, BUFFER_SPAN);
1664
1666
  }
@@ -1732,8 +1734,8 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
1732
1734
 
1733
1735
  if (j) {
1734
1736
  work.size = i + j;
1735
- if (do_render && rndr->make.blockhtml)
1736
- rndr->make.blockhtml(ob, &work, rndr->make.opaque);
1737
+ if (do_render && rndr->cb.blockhtml)
1738
+ rndr->cb.blockhtml(ob, &work, rndr->opaque);
1737
1739
  return work.size;
1738
1740
  }
1739
1741
  }
@@ -1749,8 +1751,8 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
1749
1751
  j = is_empty(data + i, size - i);
1750
1752
  if (j) {
1751
1753
  work.size = i + j;
1752
- if (do_render && rndr->make.blockhtml)
1753
- rndr->make.blockhtml(ob, &work, rndr->make.opaque);
1754
+ if (do_render && rndr->cb.blockhtml)
1755
+ rndr->cb.blockhtml(ob, &work, rndr->opaque);
1754
1756
  return work.size;
1755
1757
  }
1756
1758
  }
@@ -1791,8 +1793,8 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
1791
1793
 
1792
1794
  /* the end of the block has been found */
1793
1795
  work.size = i;
1794
- if (do_render && rndr->make.blockhtml)
1795
- rndr->make.blockhtml(ob, &work, rndr->make.opaque);
1796
+ if (do_render && rndr->cb.blockhtml)
1797
+ rndr->cb.blockhtml(ob, &work, rndr->opaque);
1796
1798
 
1797
1799
  return i;
1798
1800
  }
@@ -1828,8 +1830,8 @@ parse_table_row(struct buf *ob, struct render *rndr, char *data, size_t size, si
1828
1830
  cell_end--;
1829
1831
 
1830
1832
  parse_inline(cell_work, rndr, data + cell_start, 1 + cell_end - cell_start);
1831
- if (rndr->make.table_cell)
1832
- rndr->make.table_cell(row_work, cell_work, col_data ? col_data[col] : 0, rndr->make.opaque);
1833
+ if (rndr->cb.table_cell)
1834
+ rndr->cb.table_cell(row_work, cell_work, col_data ? col_data[col] : 0, rndr->opaque);
1833
1835
 
1834
1836
  rndr_popbuf(rndr, BUFFER_SPAN);
1835
1837
  i++;
@@ -1837,12 +1839,12 @@ parse_table_row(struct buf *ob, struct render *rndr, char *data, size_t size, si
1837
1839
 
1838
1840
  for (; col < columns; ++col) {
1839
1841
  struct buf empty_cell = {0, 0, 0, 0, 0};
1840
- if (rndr->make.table_cell)
1841
- rndr->make.table_cell(row_work, &empty_cell, col_data ? col_data[col] : 0, rndr->make.opaque);
1842
+ if (rndr->cb.table_cell)
1843
+ rndr->cb.table_cell(row_work, &empty_cell, col_data ? col_data[col] : 0, rndr->opaque);
1842
1844
  }
1843
1845
 
1844
- if (rndr->make.table_row)
1845
- rndr->make.table_row(ob, row_work, rndr->make.opaque);
1846
+ if (rndr->cb.table_row)
1847
+ rndr->cb.table_row(ob, row_work, rndr->opaque);
1846
1848
 
1847
1849
  rndr_popbuf(rndr, BUFFER_SPAN);
1848
1850
  }
@@ -1956,8 +1958,8 @@ parse_table(struct buf *ob, struct render *rndr, char *data, size_t size)
1956
1958
  i++;
1957
1959
  }
1958
1960
 
1959
- if (rndr->make.table)
1960
- rndr->make.table(ob, header_work, body_work, rndr->make.opaque);
1961
+ if (rndr->cb.table)
1962
+ rndr->cb.table(ob, header_work, body_work, rndr->opaque);
1961
1963
  }
1962
1964
 
1963
1965
  free(col_data);
@@ -1985,7 +1987,7 @@ parse_block(struct buf *ob, struct render *rndr, char *data, size_t size)
1985
1987
  if (is_atxheader(rndr, txt_data, end))
1986
1988
  beg += parse_atxheader(ob, rndr, txt_data, end);
1987
1989
 
1988
- else if (data[beg] == '<' && rndr->make.blockhtml &&
1990
+ else if (data[beg] == '<' && rndr->cb.blockhtml &&
1989
1991
  (i = parse_htmlblock(ob, rndr, txt_data, end, 1)) != 0)
1990
1992
  beg += i;
1991
1993
 
@@ -1993,8 +1995,8 @@ parse_block(struct buf *ob, struct render *rndr, char *data, size_t size)
1993
1995
  beg += i;
1994
1996
 
1995
1997
  else if (is_hrule(txt_data, end)) {
1996
- if (rndr->make.hrule)
1997
- rndr->make.hrule(ob, rndr->make.opaque);
1998
+ if (rndr->cb.hrule)
1999
+ rndr->cb.hrule(ob, rndr->opaque);
1998
2000
 
1999
2001
  while (beg < size && data[beg] != '\n')
2000
2002
  beg++;
@@ -2167,14 +2169,21 @@ static void expand_tabs(struct buf *ob, const char *line, size_t size)
2167
2169
 
2168
2170
  /* markdown • parses the input buffer and renders it into the output buffer */
2169
2171
  void
2170
- sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer, unsigned int extensions) {
2172
+ sd_markdown(struct buf *ob,
2173
+ const struct buf *ib,
2174
+ unsigned int extensions,
2175
+ const struct sd_callbacks *callbacks,
2176
+ void *opaque) {
2177
+
2178
+ static const float MARKDOWN_GROW_FACTOR = 1.4f;
2179
+
2171
2180
  struct link_ref *lr;
2172
2181
  struct buf *text;
2173
2182
  size_t i, beg, end;
2174
2183
  struct render rndr;
2175
2184
 
2176
2185
  /* filling the render structure */
2177
- if (!rndrer)
2186
+ if (!callbacks)
2178
2187
  return;
2179
2188
 
2180
2189
  text = bufnew(64);
@@ -2184,28 +2193,30 @@ sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer, u
2184
2193
  /* Preallocate enough space for our buffer to avoid expanding while copying */
2185
2194
  bufgrow(text, ib->size);
2186
2195
 
2187
- memcpy(&rndr.make, rndrer, sizeof(struct mkd_renderer));
2196
+ memcpy(&rndr.cb, callbacks, sizeof(struct sd_callbacks));
2188
2197
  arr_init(&rndr.refs, sizeof (struct link_ref));
2189
2198
  parr_init(&rndr.work_bufs[BUFFER_BLOCK]);
2190
2199
  parr_init(&rndr.work_bufs[BUFFER_SPAN]);
2191
2200
 
2192
- for (i = 0; i < 256; i++)
2193
- rndr.active_char[i] = 0;
2201
+ /* for (i = 0; i < 256; i++)
2202
+ rndr.active_char[i] = 0; */
2194
2203
 
2195
- if (rndr.make.emphasis || rndr.make.double_emphasis || rndr.make.triple_emphasis) {
2204
+ memset(rndr.active_char, 0x0, 256);
2205
+
2206
+ if (rndr.cb.emphasis || rndr.cb.double_emphasis || rndr.cb.triple_emphasis) {
2196
2207
  rndr.active_char['*'] = MD_CHAR_EMPHASIS;
2197
2208
  rndr.active_char['_'] = MD_CHAR_EMPHASIS;
2198
2209
  if (extensions & MKDEXT_STRIKETHROUGH)
2199
2210
  rndr.active_char['~'] = MD_CHAR_EMPHASIS;
2200
2211
  }
2201
2212
 
2202
- if (rndr.make.codespan)
2213
+ if (rndr.cb.codespan)
2203
2214
  rndr.active_char['`'] = MD_CHAR_CODESPAN;
2204
2215
 
2205
- if (rndr.make.linebreak)
2216
+ if (rndr.cb.linebreak)
2206
2217
  rndr.active_char['\n'] = MD_CHAR_LINEBREAK;
2207
2218
 
2208
- if (rndr.make.image || rndr.make.link)
2219
+ if (rndr.cb.image || rndr.cb.link)
2209
2220
  rndr.active_char['['] = MD_CHAR_LINK;
2210
2221
 
2211
2222
  rndr.active_char['<'] = MD_CHAR_LANGLE;
@@ -2223,6 +2234,7 @@ sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer, u
2223
2234
 
2224
2235
  /* Extension data */
2225
2236
  rndr.ext_flags = extensions;
2237
+ rndr.opaque = opaque;
2226
2238
  rndr.max_nesting = 16;
2227
2239
 
2228
2240
  /* first pass: looking for references, copying everything else */
@@ -2253,9 +2265,12 @@ sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer, u
2253
2265
  if (rndr.refs.size)
2254
2266
  qsort(rndr.refs.base, rndr.refs.size, rndr.refs.unit, cmp_link_ref_sort);
2255
2267
 
2268
+ /* pre-grow the output buffer to minimize allocations */
2269
+ bufgrow(ob, text->size * MARKDOWN_GROW_FACTOR);
2270
+
2256
2271
  /* second pass: actual rendering */
2257
- if (rndr.make.doc_header)
2258
- rndr.make.doc_header(ob, rndr.make.opaque);
2272
+ if (rndr.cb.doc_header)
2273
+ rndr.cb.doc_header(ob, rndr.opaque);
2259
2274
 
2260
2275
  if (text->size) {
2261
2276
  /* adding a final newline if not already present */
@@ -2265,8 +2280,8 @@ sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer, u
2265
2280
  parse_block(ob, &rndr, text->data, text->size);
2266
2281
  }
2267
2282
 
2268
- if (rndr.make.doc_footer)
2269
- rndr.make.doc_footer(ob, rndr.make.opaque);
2283
+ if (rndr.cb.doc_footer)
2284
+ rndr.cb.doc_footer(ob, rndr.opaque);
2270
2285
 
2271
2286
  /* clean-up */
2272
2287
  bufrelease(text);
@@ -31,7 +31,7 @@
31
31
  * TYPE DEFINITIONS *
32
32
  ********************/
33
33
 
34
- /* mkd_autolink type of autolink */
34
+ /* mkd_autolink - type of autolink */
35
35
  enum mkd_autolink {
36
36
  MKDA_NOT_AUTOLINK, /* used internally when it is not an autolink*/
37
37
  MKDA_NORMAL, /* normal http/http/ftp/mailto/etc link */
@@ -49,8 +49,8 @@ enum mkd_extensions {
49
49
  MKDEXT_SUPERSCRIPT = (1 << 7),
50
50
  };
51
51
 
52
- /* mkd_renderer functions for rendering parsed data */
53
- struct mkd_renderer {
52
+ /* sd_callbacks - functions for rendering parsed data */
53
+ struct sd_callbacks {
54
54
  /* block level callbacks - NULL skips the block */
55
55
  void (*blockcode)(struct buf *ob, struct buf *text, struct buf *lang, void *opaque);
56
56
  void (*blockquote)(struct buf *ob, struct buf *text, void *opaque);
@@ -85,9 +85,6 @@ struct mkd_renderer {
85
85
  /* header and footer */
86
86
  void (*doc_header)(struct buf *ob, void *opaque);
87
87
  void (*doc_footer)(struct buf *ob, void *opaque);
88
-
89
- /* user data */
90
- void *opaque;
91
88
  };
92
89
 
93
90
  /*********
@@ -108,7 +105,7 @@ struct mkd_renderer {
108
105
 
109
106
  /* sd_markdown * parses the input buffer and renders it into the output buffer */
110
107
  extern void
111
- sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndr, unsigned int extensions);
108
+ sd_markdown(struct buf *ob, const struct buf *ib, unsigned int extensions, const struct sd_callbacks *rndr, void *opaque);
112
109
 
113
110
  /* sd_version * returns the library version as major.minor.rev */
114
111
  extern void
@@ -1,15 +1,19 @@
1
- #define RSTRING_NOT_MODIFIED
2
-
3
- #include <stdio.h>
4
- #include "ruby.h"
5
-
6
- #ifdef HAVE_RUBY_ENCODING_H
7
- #include <ruby/encoding.h>
8
- #else
9
- #define rb_enc_copy(dst, src)
10
- #endif
11
-
12
- #include "markdown.h"
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
+ #include "redcarpet.h"
13
17
 
14
18
  VALUE rb_mRedcarpet;
15
19
  VALUE rb_cMarkdown;
@@ -54,7 +58,7 @@ static VALUE rb_redcarpet_md_render_with(VALUE self, VALUE rb_rndr, VALUE text)
54
58
  {
55
59
  VALUE result;
56
60
 
57
- struct mkd_renderer *renderer;
61
+ struct rb_redcarpet_rndr *rndr;
58
62
  struct buf input_buf, *output_buf;
59
63
  unsigned int enabled_extensions = 0;
60
64
 
@@ -66,17 +70,18 @@ static VALUE rb_redcarpet_md_render_with(VALUE self, VALUE rb_rndr, VALUE text)
66
70
  if (rb_respond_to(rb_rndr, rb_intern("preprocess")))
67
71
  text = rb_funcall(rb_rndr, rb_intern("preprocess"), 1, text);
68
72
 
73
+ Data_Get_Struct(rb_rndr, struct rb_redcarpet_rndr, rndr);
74
+
75
+ /* initialize buffers */
69
76
  memset(&input_buf, 0x0, sizeof(struct buf));
70
77
  input_buf.data = RSTRING_PTR(text);
71
78
  input_buf.size = RSTRING_LEN(text);
72
79
 
73
80
  output_buf = bufnew(128);
74
- bufgrow(output_buf, RSTRING_LEN(text) * 1.4f);
75
-
76
- Data_Get_Struct(rb_rndr, struct mkd_renderer, renderer);
77
81
 
82
+ /* render the magic */
78
83
  rb_redcarpet_md_flags(self, &enabled_extensions);
79
- sd_markdown(output_buf, &input_buf, renderer, enabled_extensions);
84
+ sd_markdown(output_buf, &input_buf, enabled_extensions, &rndr->callbacks, &rndr->options);
80
85
  result = rb_str_new(output_buf->data, output_buf->size);
81
86
  rb_enc_copy(result, text);
82
87
 
@@ -93,8 +98,6 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
93
98
  return rb_redcarpet_md_render_with(self, rb_iv_get(self, "@renderer"), text);
94
99
  }
95
100
 
96
- extern void Init_redcarpet_rndr();
97
-
98
101
  void Init_redcarpet()
99
102
  {
100
103
  rb_mRedcarpet = rb_define_module("Redcarpet");
@@ -14,23 +14,11 @@
14
14
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
15
  */
16
16
 
17
- #define RSTRING_NOT_MODIFIED
18
-
19
- #include <ruby.h>
20
- #include "markdown.h"
21
- #include "html.h"
22
-
23
- #ifdef HAVE_RUBY_ENCODING_H
24
- #include <ruby/encoding.h>
25
- #else
26
- #define rb_enc_copy(dst, src)
27
- #endif
28
-
29
- #define CSTR2SYM(s) (ID2SYM(rb_intern((s))))
17
+ #include "redcarpet.h"
30
18
 
31
19
  #define SPAN_CALLBACK(method_name, ...) {\
32
- struct redcarpet_pload *load = opaque;\
33
- VALUE ret = rb_funcall(load->self, rb_intern(method_name), __VA_ARGS__);\
20
+ struct redcarpet_renderopt *opt = opaque;\
21
+ VALUE ret = rb_funcall(opt->self, rb_intern(method_name), __VA_ARGS__);\
34
22
  if (NIL_P(ret)) return 0;\
35
23
  Check_Type(ret, T_STRING);\
36
24
  bufput(ob, RSTRING_PTR(ret), RSTRING_LEN(ret));\
@@ -38,8 +26,8 @@
38
26
  }
39
27
 
40
28
  #define BLOCK_CALLBACK(method_name, ...) {\
41
- struct redcarpet_pload *load = opaque;\
42
- VALUE ret = rb_funcall(load->self, rb_intern(method_name), __VA_ARGS__);\
29
+ struct redcarpet_renderopt *opt = opaque;\
30
+ VALUE ret = rb_funcall(opt->self, rb_intern(method_name), __VA_ARGS__);\
43
31
  if (NIL_P(ret)) return;\
44
32
  Check_Type(ret, T_STRING);\
45
33
  bufput(ob, RSTRING_PTR(ret), RSTRING_LEN(ret));\
@@ -52,10 +40,6 @@ VALUE rb_cRenderHTML;
52
40
  VALUE rb_cRenderHTML_TOC;
53
41
  VALUE rb_mSmartyPants;
54
42
 
55
- struct redcarpet_pload {
56
- VALUE self;
57
- };
58
-
59
43
  static inline VALUE
60
44
  buf2str(struct buf *text)
61
45
  {
@@ -104,7 +88,8 @@ rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque)
104
88
  static void
105
89
  rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque)
106
90
  {
107
- BLOCK_CALLBACK("list_item", 1, buf2str(text));
91
+ BLOCK_CALLBACK("list_item", 2, buf2str(text),
92
+ (flags & MKD_LIST_ORDERED) ? CSTR2SYM("ordered") : CSTR2SYM("unordered"));
108
93
  }
109
94
 
110
95
  static void
@@ -251,7 +236,7 @@ rndr_doc_footer(struct buf *ob, void *opaque)
251
236
  BLOCK_CALLBACK("doc_footer", 0);
252
237
  }
253
238
 
254
- static struct mkd_renderer rb_redcarpet_rndr = {
239
+ static struct sd_callbacks rb_redcarpet_callbacks = {
255
240
  rndr_blockcode,
256
241
  rndr_blockquote,
257
242
  rndr_raw_block,
@@ -281,8 +266,6 @@ static struct mkd_renderer rb_redcarpet_rndr = {
281
266
 
282
267
  rndr_doc_header,
283
268
  rndr_doc_footer,
284
-
285
- NULL
286
269
  };
287
270
 
288
271
  static const char *rb_redcarpet_method_names[] = {
@@ -319,58 +302,51 @@ static const char *rb_redcarpet_method_names[] = {
319
302
 
320
303
  static const size_t rb_redcarpet_method_count = sizeof(rb_redcarpet_method_names)/sizeof(char *);
321
304
 
322
- static void rb_redcarpet_rbase_free(struct mkd_renderer *rndr)
323
- {
324
- xfree(rndr->opaque);
325
- xfree(rndr);
326
- }
327
-
328
305
  static VALUE rb_redcarpet_rbase_alloc(VALUE klass)
329
306
  {
330
- struct mkd_renderer *rndr = ALLOC(struct mkd_renderer);
331
- memset(rndr, 0x0, sizeof(struct mkd_renderer));
332
- return Data_Wrap_Struct(klass, NULL, rb_redcarpet_rbase_free, rndr);
307
+ struct rb_redcarpet_rndr *rndr = ALLOC(struct rb_redcarpet_rndr);
308
+ memset(rndr, 0x0, sizeof(struct rb_redcarpet_rndr));
309
+ return Data_Wrap_Struct(klass, NULL, NULL, rndr);
333
310
  }
334
311
 
335
- static void rb_redcarpet__overload(VALUE self)
312
+ static void rb_redcarpet__overload(VALUE self, VALUE base_class)
336
313
  {
337
- size_t i;
338
- struct mkd_renderer *rndr;
314
+ struct rb_redcarpet_rndr *rndr;
315
+
316
+ Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);
317
+ rndr->options.self = self;
318
+ rndr->options.base_class = base_class;
339
319
 
340
- void **source = (void **)&rb_redcarpet_rndr;
341
- void **dest;
320
+ if (rb_obj_class(self) == rb_cRenderBase)
321
+ rb_raise(rb_eRuntimeError,
322
+ "The Redcarpet::Render::Base class cannot be instantiated. "
323
+ "Create an inheriting class instead to implement a custom renderer.");
342
324
 
343
- Data_Get_Struct(self, struct mkd_renderer, rndr);
344
- dest = (void **)rndr;
325
+ if (rb_obj_class(self) != base_class) {
326
+ void **source = (void **)&rb_redcarpet_callbacks;
327
+ void **dest = (void **)&rndr->callbacks;
328
+ size_t i;
345
329
 
346
- for (i = 0; i < rb_redcarpet_method_count; ++i) {
347
- if (rb_respond_to(self, rb_intern(rb_redcarpet_method_names[i])))
348
- dest[i] = source[i];
330
+ for (i = 0; i < rb_redcarpet_method_count; ++i) {
331
+ if (rb_respond_to(self, rb_intern(rb_redcarpet_method_names[i])))
332
+ dest[i] = source[i];
333
+ }
349
334
  }
350
335
  }
351
336
 
352
337
  static VALUE rb_redcarpet_rbase_init(VALUE self)
353
338
  {
354
- struct mkd_renderer *rndr;
355
- struct redcarpet_pload *payload;
356
-
357
- Data_Get_Struct(self, struct mkd_renderer, rndr);
358
- rb_redcarpet__overload(self);
359
-
360
- payload = ALLOC(struct redcarpet_pload);
361
- payload->self = self;
362
-
363
- rndr->opaque = payload;
339
+ rb_redcarpet__overload(self, rb_cRenderBase);
364
340
  return Qnil;
365
341
  }
366
342
 
367
343
  static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
368
344
  {
369
- struct mkd_renderer *rndr;
345
+ struct rb_redcarpet_rndr *rndr;
370
346
  unsigned int render_flags = 0;
371
347
  VALUE hash;
372
348
 
373
- Data_Get_Struct(self, struct mkd_renderer, rndr);
349
+ Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);
374
350
 
375
351
  if (rb_scan_args(argc, argv, "01", &hash) == 1)
376
352
  {
@@ -406,23 +382,19 @@ static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
406
382
  render_flags |= HTML_USE_XHTML;
407
383
  }
408
384
 
409
- sdhtml_renderer(rndr, render_flags, (void *)self);
410
-
411
- if (rb_obj_class(self) != rb_cRenderHTML)
412
- rb_redcarpet__overload(self);
385
+ sdhtml_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
386
+ rb_redcarpet__overload(self, rb_cRenderHTML);
413
387
 
414
388
  return Qnil;
415
389
  }
416
390
 
417
391
  static VALUE rb_redcarpet_htmltoc_init(VALUE self)
418
392
  {
419
- struct mkd_renderer *rndr;
420
- Data_Get_Struct(self, struct mkd_renderer, rndr);
393
+ struct rb_redcarpet_rndr *rndr;
394
+ Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);
421
395
 
422
- sdhtml_toc_renderer(rndr, (void *)self);
423
-
424
- if (rb_obj_class(self) != rb_cRenderHTML_TOC)
425
- rb_redcarpet__overload(self);
396
+ sdhtml_toc_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html);
397
+ rb_redcarpet__overload(self, rb_cRenderHTML_TOC);
426
398
 
427
399
  return Qnil;
428
400
  }
@@ -449,7 +421,6 @@ static VALUE rb_redcarpet_smartypants_render(VALUE self, VALUE text)
449
421
  return result;
450
422
  }
451
423
 
452
-
453
424
  void Init_redcarpet_rndr()
454
425
  {
455
426
  rb_mRender = rb_define_module_under(rb_mRedcarpet, "Render");
@@ -465,5 +436,5 @@ void Init_redcarpet_rndr()
465
436
  rb_define_method(rb_cRenderHTML_TOC, "initialize", rb_redcarpet_htmltoc_init, 0);
466
437
 
467
438
  rb_mSmartyPants = rb_define_module_under(rb_mRender, "SmartyPants");
468
- rb_define_singleton_method(rb_mSmartyPants, "postprocess", rb_redcarpet_smartypants_render, 1);
439
+ rb_define_method(rb_mSmartyPants, "postprocess", rb_redcarpet_smartypants_render, 1);
469
440
  }
@@ -0,0 +1,32 @@
1
+ #ifndef __REDCARPET_H__
2
+ #define __REDCARPET_H__
3
+
4
+ #define RSTRING_NOT_MODIFIED
5
+ #include "ruby.h"
6
+ #include <stdio.h>
7
+
8
+ #ifdef HAVE_RUBY_ENCODING_H
9
+ #include <ruby/encoding.h>
10
+ #else
11
+ #define rb_enc_copy(dst, src)
12
+ #endif
13
+
14
+ #include "markdown.h"
15
+ #include "html.h"
16
+
17
+ #define CSTR2SYM(s) (ID2SYM(rb_intern((s))))
18
+
19
+ extern void Init_redcarpet_rndr();
20
+
21
+ struct redcarpet_renderopt {
22
+ struct html_renderopt html;
23
+ VALUE self;
24
+ VALUE base_class;
25
+ };
26
+
27
+ struct rb_redcarpet_rndr {
28
+ struct sd_callbacks callbacks;
29
+ struct redcarpet_renderopt options;
30
+ };
31
+
32
+ #endif
data/lib/redcarpet.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'redcarpet.so'
2
2
 
3
3
  module Redcarpet
4
- VERSION = '2.0.0b'
4
+ VERSION = '2.0.0b3'
5
5
 
6
6
  class Markdown
7
7
  # Available Markdown extensions
@@ -0,0 +1,65 @@
1
+ module Redcarpet
2
+ module Render
3
+ class ManPage < Base
4
+
5
+ def normal_text(text)
6
+ text.gsub('-', '\\-').strip
7
+ end
8
+
9
+ def block_code(code, language)
10
+ "\n.nf\n#{normal_text(code)}\n.fi\n"
11
+ end
12
+
13
+ def codespan(code)
14
+ block_code(code, nil)
15
+ end
16
+
17
+ def header(title, level)
18
+ case level
19
+ when 1
20
+ "\n.TH #{title}\n"
21
+
22
+ when 2
23
+ "\n.SH #{title}\n"
24
+
25
+ when 3
26
+ "\n.SS #{title}\n"
27
+ end
28
+ end
29
+
30
+ def double_emphasis(text)
31
+ "\\fB#{text}\\fP"
32
+ end
33
+
34
+ def emphasis(text)
35
+ "\\fI#{text}\\fP"
36
+ end
37
+
38
+ def linebreak
39
+ "\n.LP\n"
40
+ end
41
+
42
+ def paragraph(text)
43
+ "\n.TP\n#{text}\n"
44
+ end
45
+
46
+ def list(content, list_type)
47
+ case list_type
48
+ when :ordered
49
+ "\n\n.nr step 0 1\n#{content}\n"
50
+ when :unordered
51
+ "\n.\n#{content}\n"
52
+ end
53
+ end
54
+
55
+ def list_item(content, list_type)
56
+ case list_type
57
+ when :ordered
58
+ ".IP \\n+[step]\n#{content.strip}\n"
59
+ when :unordered
60
+ ".IP \\[bu] 2 \n#{content.strip}\n"
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
data/redcarpet.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'redcarpet'
3
- s.version = '2.0.0b'
3
+ s.version = '2.0.0b3'
4
4
  s.summary = "Markdown that smells nice"
5
5
  s.description = 'A fast, safe and extensible Markdown to (X)HTML parser'
6
- s.date = '2011-08-03'
6
+ s.date = '2011-08-09'
7
7
  s.email = 'vicent@github.com'
8
8
  s.homepage = 'http://github.com/tanoku/redcarpet'
9
9
  s.authors = ["Natacha Porté", "Vicent Martí"]
@@ -27,7 +27,9 @@ Gem::Specification.new do |s|
27
27
  ext/redcarpet/markdown.h
28
28
  ext/redcarpet/rc_markdown.c
29
29
  ext/redcarpet/rc_render.c
30
+ ext/redcarpet/redcarpet.h
30
31
  lib/redcarpet.rb
32
+ lib/redcarpet/render_man.rb
31
33
  redcarpet.gemspec
32
34
  sundown
33
35
  test/redcarpet_test.rb
@@ -38,4 +40,5 @@ Gem::Specification.new do |s|
38
40
  s.extensions = ["ext/redcarpet/extconf.rb"]
39
41
  s.executables = ["redcarpet"]
40
42
  s.require_paths = ["lib"]
43
+ s.add_development_dependency "rake-compiler"
41
44
  end
@@ -1,8 +1,10 @@
1
+ # coding: UTF-8
1
2
  rootdir = File.dirname(File.dirname(__FILE__))
2
3
  $LOAD_PATH.unshift "#{rootdir}/lib"
3
4
 
4
5
  require 'test/unit'
5
6
  require 'redcarpet'
7
+ require 'redcarpet/render_man'
6
8
  require 'nokogiri'
7
9
 
8
10
  def html_equal(html_a, html_b)
@@ -46,6 +48,12 @@ class SmartyPantsTest < Test::Unit::TestCase
46
48
  end
47
49
  end
48
50
 
51
+ class SmartyHTMLTests < SmartyPantsTest
52
+ def setup
53
+ @pants = Redcarpet::Markdown.new Redcarpet::Render::SmartyHTML
54
+ end
55
+ end
56
+
49
57
  class HTMLRenderTest < Test::Unit::TestCase
50
58
  def setup
51
59
  @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
metadata CHANGED
@@ -1,35 +1,37 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: redcarpet
3
- version: !ruby/object:Gem::Version
4
- hash: 11
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0b3
5
5
  prerelease: 5
6
- segments:
7
- - 2
8
- - 0
9
- - 0
10
- - b
11
- version: 2.0.0b
12
6
  platform: ruby
13
- authors:
14
- - "Natacha Port\xC3\xA9"
15
- - "Vicent Mart\xC3\xAD"
7
+ authors:
8
+ - Natacha Porté
9
+ - Vicent Martí
16
10
  autorequire:
17
11
  bindir: bin
18
12
  cert_chain: []
19
-
20
- date: 2011-08-03 00:00:00 +02:00
21
- default_executable:
22
- dependencies: []
23
-
13
+ date: 2011-08-09 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake-compiler
17
+ requirement: &70234078705880 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *70234078705880
24
26
  description: A fast, safe and extensible Markdown to (X)HTML parser
25
27
  email: vicent@github.com
26
- executables:
28
+ executables:
27
29
  - redcarpet
28
- extensions:
30
+ extensions:
29
31
  - ext/redcarpet/extconf.rb
30
- extra_rdoc_files:
32
+ extra_rdoc_files:
31
33
  - COPYING
32
- files:
34
+ files:
33
35
  - COPYING
34
36
  - README.markdown
35
37
  - Rakefile
@@ -48,44 +50,34 @@ files:
48
50
  - ext/redcarpet/markdown.h
49
51
  - ext/redcarpet/rc_markdown.c
50
52
  - ext/redcarpet/rc_render.c
53
+ - ext/redcarpet/redcarpet.h
51
54
  - lib/redcarpet.rb
55
+ - lib/redcarpet/render_man.rb
52
56
  - redcarpet.gemspec
53
57
  - test/redcarpet_test.rb
54
- has_rdoc: true
55
58
  homepage: http://github.com/tanoku/redcarpet
56
59
  licenses: []
57
-
58
60
  post_install_message:
59
61
  rdoc_options: []
60
-
61
- require_paths:
62
+ require_paths:
62
63
  - lib
63
- required_ruby_version: !ruby/object:Gem::Requirement
64
+ required_ruby_version: !ruby/object:Gem::Requirement
64
65
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- hash: 3
69
- segments:
70
- - 0
71
- version: "0"
72
- required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
71
  none: false
74
- requirements:
75
- - - ">"
76
- - !ruby/object:Gem::Version
77
- hash: 25
78
- segments:
79
- - 1
80
- - 3
81
- - 1
72
+ requirements:
73
+ - - ! '>'
74
+ - !ruby/object:Gem::Version
82
75
  version: 1.3.1
83
76
  requirements: []
84
-
85
77
  rubyforge_project:
86
- rubygems_version: 1.6.2
78
+ rubygems_version: 1.8.6
87
79
  signing_key:
88
80
  specification_version: 3
89
81
  summary: Markdown that smells nice
90
- test_files:
82
+ test_files:
91
83
  - test/redcarpet_test.rb