redcarpet 1.5.3 → 1.6.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 CHANGED
@@ -100,8 +100,27 @@ static struct html_tag block_tags[] = {
100
100
  #define DEL_TAG (block_tags + 10)
101
101
 
102
102
  /***************************
103
- * STATIC HELPER FUNCTIONS *
103
+ * HELPER FUNCTIONS *
104
104
  ***************************/
105
+ int
106
+ is_safe_link(const char *link, size_t link_len)
107
+ {
108
+ static const size_t valid_uris_count = 4;
109
+ static const char *valid_uris[] = {
110
+ "http://", "https://", "ftp://", "mailto://"
111
+ };
112
+
113
+ size_t i;
114
+
115
+ for (i = 0; i < valid_uris_count; ++i) {
116
+ size_t len = strlen(valid_uris[i]);
117
+
118
+ if (link_len > len && memcmp(link, valid_uris[i], len) == 0)
119
+ return 1;
120
+ }
121
+
122
+ return 0;
123
+ }
105
124
 
106
125
  /* cmp_link_ref • comparison function for link_ref sorted arrays */
107
126
  static int
@@ -245,8 +264,9 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
245
264
 
246
265
  while (i < size) {
247
266
  /* copying inactive chars into the output */
248
- while (end < size && (action = rndr->active_char[(unsigned char)data[end]]) == 0)
267
+ while (end < size && (action = rndr->active_char[(unsigned char)data[end]]) == 0) {
249
268
  end++;
269
+ }
250
270
 
251
271
  if (rndr->make.normal_text) {
252
272
  work.data = data + i;
@@ -616,6 +636,25 @@ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset,
616
636
  else return end;
617
637
  }
618
638
 
639
+ static size_t
640
+ char_autolink(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
641
+ {
642
+ struct buf work = { data, 0, 0, 0, 0 };
643
+
644
+ if (offset > 0 && !isspace(data[-1]))
645
+ return 0;
646
+
647
+ if (!is_safe_link(data, size))
648
+ return 0;
649
+
650
+ while (work.size < size && !isspace(data[work.size]))
651
+ work.size++;
652
+
653
+ if (rndr->make.autolink)
654
+ rndr->make.autolink(ob, &work, MKDA_NORMAL, rndr->make.opaque);
655
+
656
+ return work.size;
657
+ }
619
658
 
620
659
  /* char_link • '[': parsing a link or an image */
621
660
  static size_t
@@ -2029,6 +2068,12 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer, unsi
2029
2068
  rndr.active_char['\\'] = char_escape;
2030
2069
  rndr.active_char['&'] = char_entity;
2031
2070
 
2071
+ if (extensions & MKDEXT_AUTOLINK) {
2072
+ rndr.active_char['h'] = char_autolink; // http, https
2073
+ rndr.active_char['f'] = char_autolink; // ftp
2074
+ rndr.active_char['m'] = char_autolink; // mailto
2075
+ }
2076
+
2032
2077
  /* Extension data */
2033
2078
  rndr.ext_flags = extensions;
2034
2079
  rndr.max_nesting = 16;
data/ext/markdown.h CHANGED
@@ -40,6 +40,7 @@ enum mkd_extensions {
40
40
  MKDEXT_LAX_EMPHASIS = (1 << 0),
41
41
  MKDEXT_TABLES = (1 << 1),
42
42
  MKDEXT_FENCED_CODE = (1 << 2),
43
+ MKDEXT_AUTOLINK = (1 << 3),
43
44
  };
44
45
 
45
46
  /* mkd_renderer • functions for rendering parsed data */
@@ -94,6 +95,12 @@ struct mkd_renderer {
94
95
  #define MKD_TABLE_ALIGN_R (1 << 1)
95
96
  #define MKD_TABLE_ALIGN_CENTER (MKD_TABLE_ALIGN_L | MKD_TABLE_ALIGN_R)
96
97
 
98
+ /*******************
99
+ * Auxiliar methods
100
+ *******************/
101
+ int
102
+ is_safe_link(const char *link, size_t link_len);
103
+
97
104
  /**********************
98
105
  * EXPORTED FUNCTIONS *
99
106
  **********************/
data/ext/redcarpet.c CHANGED
@@ -39,10 +39,6 @@ static void rb_redcarpet__get_flags(VALUE ruby_obj,
39
39
  if (rb_funcall(ruby_obj, rb_intern("filter_styles"), 0) == Qtrue)
40
40
  render_flags |= XHTML_SKIP_STYLE;
41
41
 
42
- /* autolink */
43
- if (rb_funcall(ruby_obj, rb_intern("autolink"), 0) == Qtrue)
44
- render_flags |= XHTML_AUTOLINK;
45
-
46
42
  /* safelink */
47
43
  if (rb_funcall(ruby_obj, rb_intern("safelink"), 0) == Qtrue)
48
44
  render_flags |= XHTML_SAFELINK;
@@ -62,6 +58,9 @@ static void rb_redcarpet__get_flags(VALUE ruby_obj,
62
58
  if (rb_funcall(ruby_obj, rb_intern("fenced_code"), 0) == Qtrue)
63
59
  extensions |= MKDEXT_FENCED_CODE;
64
60
 
61
+ if (rb_funcall(ruby_obj, rb_intern("autolink"), 0) == Qtrue)
62
+ extensions |= MKDEXT_AUTOLINK;
63
+
65
64
  if (rb_funcall(ruby_obj, rb_intern("strikethrough"), 0) == Qtrue)
66
65
  render_flags |= XHTML_STRIKETHROUGH;
67
66
 
data/ext/xhtml.c CHANGED
@@ -31,26 +31,6 @@ struct xhtml_renderopt {
31
31
  unsigned int flags;
32
32
  };
33
33
 
34
- static int
35
- is_safe_link(const char *link, size_t link_len)
36
- {
37
- static const size_t valid_uris_count = 4;
38
- static const char *valid_uris[] = {
39
- "http:", "https:", "ftp:", "mailto:"
40
- };
41
-
42
- size_t i;
43
-
44
- for (i = 0; i < valid_uris_count; ++i) {
45
- size_t len = strlen(valid_uris[i]);
46
-
47
- if (link_len > len && memcmp(link, valid_uris[i], len) == 0)
48
- return 1;
49
- }
50
-
51
- return 0;
52
- }
53
-
54
34
  static inline int
55
35
  put_scaped_char(struct buf *ob, char c)
56
36
  {
@@ -103,20 +83,6 @@ is_html_tag(struct buf *tag, const char *tagname)
103
83
  /********************
104
84
  * GENERIC RENDERER *
105
85
  ********************/
106
-
107
- static void
108
- rndr_autolink2(struct buf *ob, const char *link, size_t link_size, enum mkd_autolink type)
109
- {
110
- BUFPUTSL(ob, "<a href=\"");
111
- if (type == MKDA_IMPLICIT_EMAIL) BUFPUTSL(ob, "mailto:");
112
- lus_attr_escape(ob, link, link_size);
113
- BUFPUTSL(ob, "\">");
114
- if (type == MKDA_EXPLICIT_EMAIL && link_size > 7)
115
- lus_attr_escape(ob, link + 7, link_size - 7);
116
- else lus_attr_escape(ob, link, link_size);
117
- BUFPUTSL(ob, "</a>");
118
- }
119
-
120
86
  static int
121
87
  rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque)
122
88
  {
@@ -128,7 +94,19 @@ rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *op
128
94
  if ((options->flags & XHTML_SAFELINK) != 0 && !is_safe_link(link->data, link->size))
129
95
  return 0;
130
96
 
131
- rndr_autolink2(ob, link->data, link->size, type);
97
+ BUFPUTSL(ob, "<a href=\"");
98
+ if (type == MKDA_IMPLICIT_EMAIL)
99
+ BUFPUTSL(ob, "mailto:");
100
+ bufput(ob, link->data, link->size);
101
+ BUFPUTSL(ob, "\">");
102
+
103
+ if (type == MKDA_EXPLICIT_EMAIL && link->size > 7)
104
+ lus_attr_escape(ob, link->data + 7, link->size - 7);
105
+ else
106
+ lus_attr_escape(ob, link->data, link->size);
107
+
108
+ BUFPUTSL(ob, "</a>");
109
+
132
110
  return 1;
133
111
  }
134
112
 
@@ -492,140 +470,114 @@ smartypants_quotes(struct buf *ob, struct buf *text, size_t i, int is_open)
492
470
 
493
471
  static void
494
472
  rndr_normal_text(struct buf *ob, struct buf *text, void *opaque)
473
+ {
474
+ if (text)
475
+ lus_attr_escape(ob, text->data, text->size);
476
+ }
477
+
478
+ static void
479
+ rndr_smartypants(struct buf *ob, struct buf *text, void *opaque)
495
480
  {
496
481
  size_t i;
497
482
  int open_single = 0, open_double = 0, open_tag = 0;
498
- struct xhtml_renderopt *options = opaque;
499
-
500
- int autolink = (options->flags & XHTML_AUTOLINK);
501
- int smartypants = (options->flags & XHTML_SMARTYPANTS);
502
483
 
503
484
  if (!text)
504
485
  return;
505
486
 
506
- if (!autolink && !smartypants) {
507
- lus_attr_escape(ob, text->data, text->size);
508
- return;
509
- }
510
-
511
487
  for (i = 0; i < text->size; ++i) {
512
488
  size_t sub;
513
489
  char c = text->data[i];
514
490
 
515
- /*
516
- * Autolinking
517
- */
518
- if (autolink) {
519
- /* Autolinking is not standarized in the Markdown spec.
520
- * We only check for links immediately after a space */
521
- if ((i == 0 || isspace(text->data[i - 1])) &&
522
- is_safe_link(text->data + i, text->size - i)) {
523
- size_t j = i;
524
-
525
- while (j < text->size && !isspace(text->data[j]))
526
- j++;
527
-
528
- rndr_autolink2(ob, &text->data[i], j - i, MKDA_NORMAL);
529
- i = j - 1;
530
- continue;
531
- }
532
- }
533
-
534
- /*
535
- * Smartypants subsitutions
536
- */
537
- if (smartypants) {
538
- for (sub = 0; sub < SUBS_COUNT; ++sub) {
539
- if (c == smartypants_subs[sub].c0 &&
540
- smartypants_cmpsub(text, i, smartypants_subs[sub].pattern)) {
491
+ for (sub = 0; sub < SUBS_COUNT; ++sub) {
492
+ if (c == smartypants_subs[sub].c0 &&
493
+ smartypants_cmpsub(text, i, smartypants_subs[sub].pattern)) {
541
494
 
542
- if (smartypants_subs[sub].entity)
543
- bufputs(ob, smartypants_subs[sub].entity);
495
+ if (smartypants_subs[sub].entity)
496
+ bufputs(ob, smartypants_subs[sub].entity);
544
497
 
545
- i += smartypants_subs[sub].skip;
546
- break;
547
- }
498
+ i += smartypants_subs[sub].skip;
499
+ break;
548
500
  }
501
+ }
549
502
 
550
- if (sub < SUBS_COUNT)
551
- continue;
503
+ if (sub < SUBS_COUNT)
504
+ continue;
552
505
 
553
- switch (c) {
554
- case '<':
555
- open_tag = 1;
556
- break;
506
+ switch (c) {
507
+ case '<':
508
+ open_tag = 1;
509
+ break;
557
510
 
558
- case '>':
559
- open_tag = 0;
560
- break;
511
+ case '>':
512
+ open_tag = 0;
513
+ break;
561
514
 
562
515
  #if 0
563
- /*
564
- * FIXME: this is bongos.
565
- *
566
- * The markdown spec defines that code blocks can be delimited
567
- * by more than one backtick, e.g.
568
- *
569
- * ``There is a literal backtick (`) here.``
570
- * <p><code>There is a literal backtick (`) here.</code></p>
571
- *
572
- * Obviously, there's no way to differentiate between the start
573
- * of a code block and the start of a quoted string for smartypants
574
- *
575
- * Look at this piece of Python code:
576
- *
577
- * ``result = ''.join(['this', 'is', 'bongos'])``
578
- *
579
- * This MD expression is clearly ambiguous since it can be parsed as:
580
- *
581
- * <p>&ldquo;result = &rdquo;.join ...</p>
582
- *
583
- * Or also as:
584
- *
585
- * <p><code>result = ''.join(['this', 'is', 'bongos'])</code></p>
586
- *
587
- * Fuck everything about this. This is temporarily disabled, because at GitHub
588
- * it's probably smarter to prioritize code blocks than pretty cutesy punctuation.
589
- *
590
- * The equivalent closing tag for the (``), ('') has also been disabled, because
591
- * it makes no sense to have closing tags without opening tags.
592
- */
593
- case '`':
594
- if (open_tag == 0) {
595
- if (i + 1 < text->size && text->data[i + 1] == '`') {
596
- BUFPUTSL(ob, "&ldquo;"); i++;
597
- continue;
598
- }
516
+ /*
517
+ * FIXME: this is bongos.
518
+ *
519
+ * The markdown spec defines that code blocks can be delimited
520
+ * by more than one backtick, e.g.
521
+ *
522
+ * ``There is a literal backtick (`) here.``
523
+ * <p><code>There is a literal backtick (`) here.</code></p>
524
+ *
525
+ * Obviously, there's no way to differentiate between the start
526
+ * of a code block and the start of a quoted string for smartypants
527
+ *
528
+ * Look at this piece of Python code:
529
+ *
530
+ * ``result = ''.join(['this', 'is', 'bongos'])``
531
+ *
532
+ * This MD expression is clearly ambiguous since it can be parsed as:
533
+ *
534
+ * <p>&ldquo;result = &rdquo;.join ...</p>
535
+ *
536
+ * Or also as:
537
+ *
538
+ * <p><code>result = ''.join(['this', 'is', 'bongos'])</code></p>
539
+ *
540
+ * Fuck everything about this. This is temporarily disabled, because at GitHub
541
+ * it's probably smarter to prioritize code blocks than pretty cutesy punctuation.
542
+ *
543
+ * The equivalent closing tag for the (``), ('') has also been disabled, because
544
+ * it makes no sense to have closing tags without opening tags.
545
+ */
546
+ case '`':
547
+ if (open_tag == 0) {
548
+ if (i + 1 < text->size && text->data[i + 1] == '`') {
549
+ BUFPUTSL(ob, "&ldquo;"); i++;
550
+ continue;
599
551
  }
600
- break;
552
+ }
553
+ break;
601
554
  #endif
602
555
 
603
- case '\"':
604
- if (open_tag == 0) {
605
- if (smartypants_quotes(ob, text, i, open_double)) {
606
- open_double = !open_double;
607
- continue;
608
- }
556
+ case '\"':
557
+ if (open_tag == 0) {
558
+ if (smartypants_quotes(ob, text, i, open_double)) {
559
+ open_double = !open_double;
560
+ continue;
609
561
  }
610
- break;
562
+ }
563
+ break;
611
564
 
612
- case '\'':
613
- if (open_tag == 0) {
565
+ case '\'':
566
+ if (open_tag == 0) {
614
567
 
615
568
  #if 0 /* temporarily disabled, see previous comment */
616
- if (i + 1 < text->size && text->data[i + 1] == '\'') {
617
- BUFPUTSL(ob, "&rdquo;"); i++;
618
- continue;
619
- }
569
+ if (i + 1 < text->size && text->data[i + 1] == '\'') {
570
+ BUFPUTSL(ob, "&rdquo;"); i++;
571
+ continue;
572
+ }
620
573
  #endif
621
574
 
622
- if (smartypants_quotes(ob, text, i, open_single)) {
623
- open_single = !open_single;
624
- continue;
625
- }
575
+ if (smartypants_quotes(ob, text, i, open_single)) {
576
+ open_single = !open_single;
577
+ continue;
626
578
  }
627
- break;
628
579
  }
580
+ break;
629
581
  }
630
582
 
631
583
  /*
@@ -769,6 +721,9 @@ init_xhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags)
769
721
  renderer->link = NULL;
770
722
  renderer->autolink = NULL;
771
723
  }
724
+
725
+ if (render_flags & XHTML_SMARTYPANTS)
726
+ renderer->normal_text = rndr_smartypants;
772
727
  }
773
728
 
774
729
  void
data/ext/xhtml.h CHANGED
@@ -24,7 +24,6 @@ typedef enum {
24
24
  XHTML_SKIP_LINKS = (1 << 3),
25
25
  XHTML_SMARTYPANTS = (1 << 4),
26
26
  XHTML_EXPAND_TABS = (1 << 5),
27
- XHTML_AUTOLINK = (1 << 6),
28
27
  XHTML_SAFELINK = (1 << 7),
29
28
  XHTML_TOC = (1 << 8),
30
29
  XHTML_STRIKETHROUGH = (1 << 10),
data/lib/redcarpet.rb CHANGED
@@ -26,7 +26,7 @@
26
26
  # end
27
27
  #
28
28
  class Redcarpet
29
- VERSION = '1.5.3'
29
+ VERSION = '1.6.0'
30
30
 
31
31
  # Original Markdown formatted text.
32
32
  attr_reader :text
@@ -49,15 +49,15 @@ class Redcarpet
49
49
  # Disable superscript and relaxed emphasis processing.
50
50
  attr_accessor :strict
51
51
 
52
- # Convert URL in links, even if they aren't encased in <tt><></tt>
53
- attr_accessor :autolink
54
-
55
52
  # Don't make hyperlinks from <tt>[][]</tt> links that have unknown URL types.
56
53
  attr_accessor :safelink
57
54
 
58
55
  # Add TOC anchors to every header
59
56
  attr_accessor :generate_toc
60
57
 
58
+ # Enable the Autolinking extension
59
+ attr_accessor :autolink
60
+
61
61
  # Enable PHP-Markdown tables extension
62
62
  attr_accessor :tables
63
63
 
data/redcarpet.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'redcarpet'
3
- s.version = '1.5.3'
3
+ s.version = '1.6.0'
4
4
  s.summary = "Ruby bindings for libupskirt"
5
5
  s.date = '2011-04-12'
6
6
  s.email = 'vicent@github.com'
@@ -199,8 +199,15 @@ EOS
199
199
  end
200
200
 
201
201
  def test_that_headers_are_linkable
202
- markdown = Markdown.new('### Hello [GitHub](http://github.com)')
202
+ markdown = Redcarpet.new('### Hello [GitHub](http://github.com)')
203
203
  assert_equal "<h3>Hello <a href=\"http://github.com\">GitHub</a></h3>", markdown.to_html.strip
204
204
  end
205
+
206
+ def test_autolinking_with_ent_chars
207
+ markdown = Redcarpet.new(<<text, :autolink)
208
+ This a stupid link: https://github.com/rtomayko/tilt/issues?milestone=1&state=open
209
+ text
210
+ 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&amp;state=open</a></p>\n", markdown.to_html
211
+ end
205
212
 
206
213
  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: 5
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 5
9
- - 3
10
- version: 1.5.3
8
+ - 6
9
+ - 0
10
+ version: 1.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Natacha Port\xC3\xA9"