redcarpet 2.0.0b5 → 2.0.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.

@@ -142,7 +142,7 @@ instantiating the renderer:
142
142
  :safe_links_only - only generate links for protocols which are considered safe
143
143
 
144
144
  :with_toc_data - add HTML anchors to each header in the output HTML,
145
- to allow liking to each section.
145
+ to allow linking to each section.
146
146
 
147
147
  :hard_wrap - insert HTML `<br>` tags inside on paragraphs where the origin
148
148
  Markdown document had newlines (by default, Markdown ignores these
@@ -283,6 +283,34 @@ SmartyPants works on top of already-rendered HTML, and will ignore replacements
283
283
  inside the content of HTML tags and inside specific HTML blocks such as
284
284
  `<code>` or `<pre>`.
285
285
 
286
+ What? You really want to mix Markdown renderers?
287
+ ------------------------------------------------
288
+
289
+ What a terrible idea! Markdown is already ill-specified enough; if you create
290
+ software that is renderer-independent, the results will be completely unreliable!
291
+
292
+ Each renderer has its own API and its own set of extensions: you should choose one
293
+ (it doesn't have to be Redcarpet, though that would be great!), write your
294
+ software accordingly, and force your users to install it. That's the
295
+ only way to have reliable and predictable Markdown output on your program.
296
+
297
+ Still, if major forces (let's say, tornadoes or other natural disasters) force you
298
+ to keep a Markdown-compatibility later, Redcarpet also supports this:
299
+
300
+ require 'redcarpet/compat'
301
+
302
+ Requiring the compatibility library will declare a `Markdown` class with the
303
+ classical RedCloth API, e.g.
304
+
305
+ Markdown.new('this is my text').to_html
306
+
307
+ This class renders 100% standards compliant Markdown with 0 extensions. Nada.
308
+ Don't even try to enable extensions with a compatibility layer, because
309
+ that's a maintance nightmare and won't work.
310
+
311
+ On a related topic: if your Markdown gem has a `lib/markdown.rb` file that
312
+ monkeypatches the Markdown class, you're a terrible human being. Just saying.
313
+
286
314
  Boring legal stuff
287
315
  ------------------
288
316
 
@@ -24,9 +24,9 @@
24
24
  int
25
25
  sd_autolink_issafe(const uint8_t *link, size_t link_len)
26
26
  {
27
- static const size_t valid_uris_count = 4;
27
+ static const size_t valid_uris_count = 5;
28
28
  static const char *valid_uris[] = {
29
- "http://", "https://", "ftp://", "mailto://"
29
+ "/", "http://", "https://", "ftp://", "mailto:"
30
30
  };
31
31
 
32
32
  size_t i;
@@ -140,10 +140,9 @@ check_domain(uint8_t *data, size_t size)
140
140
  else if (!isalnum(data[i]) && data[i] != '-') break;
141
141
  }
142
142
 
143
- if (!isalnum(data[i - 1]) || np == 0)
144
- return 0;
145
-
146
- return i;
143
+ /* a valid domain needs to have at least a dot.
144
+ * that's as far as we get */
145
+ return np ? i : 0;
147
146
  }
148
147
 
149
148
  size_t
@@ -113,9 +113,35 @@ bufprintf(struct buf *buf, const char *fmt, ...)
113
113
  if (!buf || !buf->unit)
114
114
  return;
115
115
 
116
+ int n;
117
+
118
+ if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0)
119
+ return;
120
+
116
121
  va_start(ap, fmt);
117
- vbufprintf(buf, fmt, ap);
122
+ n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
118
123
  va_end(ap);
124
+
125
+ if (n < 0) {
126
+ #ifdef _MSC_VER
127
+ n = _vscprintf(fmt, ap);
128
+ #else
129
+ return;
130
+ #endif
131
+ }
132
+
133
+ if ((size_t)n >= buf->asize - buf->size) {
134
+ if (bufgrow(buf, buf->size + n + 1) < 0)
135
+ return;
136
+ va_start(ap, fmt);
137
+ n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
138
+ va_end(ap);
139
+ }
140
+
141
+ if (n < 0)
142
+ return;
143
+
144
+ buf->size += n;
119
145
  }
120
146
 
121
147
  /* bufput: appends raw data to a buffer */
@@ -198,31 +224,6 @@ bufslurp(struct buf *buf, size_t len)
198
224
  void
199
225
  vbufprintf(struct buf *buf, const char *fmt, va_list ap)
200
226
  {
201
- int n;
202
227
 
203
- if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0)
204
- return;
205
-
206
- n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
207
-
208
- if (n < 0) {
209
- #ifdef _MSC_VER
210
- n = _vscprintf(fmt, ap);
211
- #else
212
- return;
213
- #endif
214
- }
215
-
216
- if ((size_t)n >= buf->asize - buf->size) {
217
- if (bufgrow(buf, buf->size + n + 1) < 0)
218
- return;
219
-
220
- n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
221
- }
222
-
223
- if (n < 0)
224
- return;
225
-
226
- buf->size += n;
227
228
  }
228
229
 
@@ -15,8 +15,8 @@
15
15
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
16
  */
17
17
 
18
- #ifndef __GEN_BUFFER_H__
19
- #define __GEN_BUFFER_H__
18
+ #ifndef BUFFER_H__
19
+ #define BUFFER_H__
20
20
 
21
21
  #include <stddef.h>
22
22
  #include <stdarg.h>
@@ -85,7 +85,4 @@ void bufslurp(struct buf *, size_t);
85
85
  /* bufprintf: formatted printing to a buffer */
86
86
  void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
87
87
 
88
- /* vbufprintf: stdarg variant of formatted printing into a buffer */
89
- void vbufprintf(struct buf *, const char * , va_list);
90
-
91
88
  #endif
@@ -1,5 +1,5 @@
1
- #ifndef __HOUDINI_H__
2
- #define __HOUDINI_H__
1
+ #ifndef HOUDINI_H__
2
+ #define HOUDINI_H__
3
3
 
4
4
  #include "buffer.h"
5
5
 
@@ -17,6 +17,7 @@
17
17
  extern void houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size);
18
18
  extern void houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure);
19
19
  extern void houdini_unescape_html(struct buf *ob, const uint8_t *src, size_t size);
20
+ extern void houdini_escape_xml(struct buf *ob, const uint8_t *src, size_t size);
20
21
  extern void houdini_escape_uri(struct buf *ob, const uint8_t *src, size_t size);
21
22
  extern void houdini_escape_url(struct buf *ob, const uint8_t *src, size_t size);
22
23
  extern void houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size);
@@ -49,7 +49,7 @@ static const char *HTML_ESCAPES[] = {
49
49
  void
50
50
  houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure)
51
51
  {
52
- size_t i = 0, org, esc;
52
+ size_t i = 0, org, esc = 0;
53
53
 
54
54
  bufgrow(ob, ESCAPE_GROW_FACTOR(size));
55
55
 
@@ -147,7 +147,7 @@ find_block_tag (str, len)
147
147
  {
148
148
  enum
149
149
  {
150
- TOTAL_KEYWORDS = 23,
150
+ TOTAL_KEYWORDS = 24,
151
151
  MIN_WORD_LENGTH = 1,
152
152
  MAX_WORD_LENGTH = 10,
153
153
  MIN_HASH_VALUE = 1,
@@ -179,7 +179,8 @@ find_block_tag (str, len)
179
179
  "script",
180
180
  "h5",
181
181
  "noscript",
182
- "", "",
182
+ "",
183
+ "style",
183
184
  "iframe",
184
185
  "h4",
185
186
  "ins",
@@ -264,8 +264,10 @@ smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, uint8_t pr
264
264
  static size_t
265
265
  smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
266
266
  {
267
- static const char *skip_tags[] = {"pre", "code", "kbd", "script"};
268
- static const size_t skip_tags_count = 4;
267
+ static const char *skip_tags[] = {
268
+ "pre", "code", "var", "samp", "kbd", "math", "script", "style"
269
+ };
270
+ static const size_t skip_tags_count = 8;
269
271
 
270
272
  size_t tag, i = 0;
271
273
 
@@ -111,6 +111,7 @@ struct sd_markdown {
111
111
  struct stack work_bufs[2];
112
112
  unsigned int ext_flags;
113
113
  size_t max_nesting;
114
+ int in_link_body;
114
115
  };
115
116
 
116
117
  /***************************
@@ -372,7 +373,6 @@ parse_inline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t siz
372
373
  if (end >= size) break;
373
374
  i = end;
374
375
 
375
- /* calling the trigger */
376
376
  end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i, size - i);
377
377
  if (!end) /* no action from the callback */
378
378
  end = i + 1;
@@ -425,7 +425,6 @@ find_emph_char(uint8_t *data, size_t size, uint8_t c)
425
425
  }
426
426
 
427
427
  if (i >= size) return tmp_i;
428
- i++;
429
428
  }
430
429
  /* skipping a link */
431
430
  else if (data[i] == '[') {
@@ -682,7 +681,7 @@ char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of
682
681
  static size_t
683
682
  char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
684
683
  {
685
- static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>";
684
+ static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>^~";
686
685
  struct buf work = { 0, 0, 0, 0 };
687
686
 
688
687
  if (size > 1) {
@@ -758,10 +757,10 @@ char_langle_tag(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
758
757
  static size_t
759
758
  char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
760
759
  {
761
- struct buf *link, *link_url;
760
+ struct buf *link, *link_url, *link_text;
762
761
  size_t link_len, rewind;
763
762
 
764
- if (!rndr->cb.link)
763
+ if (!rndr->cb.link || rndr->in_link_body)
765
764
  return 0;
766
765
 
767
766
  link = rndr_newbuf(rndr, BUFFER_SPAN);
@@ -772,7 +771,14 @@ char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_
772
771
  bufput(link_url, link->data, link->size);
773
772
 
774
773
  ob->size -= rewind;
775
- rndr->cb.link(ob, link_url, NULL, link, rndr->opaque);
774
+ if (rndr->cb.normal_text) {
775
+ link_text = rndr_newbuf(rndr, BUFFER_SPAN);
776
+ rndr->cb.normal_text(link_text, link, rndr->opaque);
777
+ rndr->cb.link(ob, link_url, NULL, link_text, rndr->opaque);
778
+ rndr_popbuf(rndr, BUFFER_SPAN);
779
+ } else {
780
+ rndr->cb.link(ob, link_url, NULL, link, rndr->opaque);
781
+ }
776
782
  rndr_popbuf(rndr, BUFFER_SPAN);
777
783
  }
778
784
 
@@ -786,7 +792,7 @@ char_autolink_email(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, siz
786
792
  struct buf *link;
787
793
  size_t link_len, rewind;
788
794
 
789
- if (!rndr->cb.autolink)
795
+ if (!rndr->cb.autolink || rndr->in_link_body)
790
796
  return 0;
791
797
 
792
798
  link = rndr_newbuf(rndr, BUFFER_SPAN);
@@ -806,7 +812,7 @@ char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_
806
812
  struct buf *link;
807
813
  size_t link_len, rewind;
808
814
 
809
- if (!rndr->cb.autolink)
815
+ if (!rndr->cb.autolink || rndr->in_link_body)
810
816
  return 0;
811
817
 
812
818
  link = rndr_newbuf(rndr, BUFFER_SPAN);
@@ -832,6 +838,7 @@ char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset
832
838
  struct buf *u_link = 0;
833
839
  size_t org_work_size = rndr->work_bufs[BUFFER_SPAN].size;
834
840
  int text_has_nl = 0, ret = 0;
841
+ int in_title = 0, qtype = 0;
835
842
 
836
843
  /* checking whether the correct renderer exists */
837
844
  if ((is_img && !rndr->cb.image) || (!is_img && !rndr->cb.link))
@@ -888,12 +895,15 @@ char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset
888
895
 
889
896
  /* looking for title end if present */
890
897
  if (data[i] == '\'' || data[i] == '"') {
898
+ qtype = data[i];
899
+ in_title = 1;
891
900
  i++;
892
901
  title_b = i;
893
902
 
894
903
  while (i < size) {
895
904
  if (data[i] == '\\') i += 2;
896
- else if (data[i] == ')') break;
905
+ else if (data[i] == qtype) {in_title = 0; i++;}
906
+ else if ((data[i] == ')') && !in_title) break;
897
907
  else i++;
898
908
  }
899
909
 
@@ -1019,8 +1029,15 @@ char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset
1019
1029
  /* building content: img alt is escaped, link content is parsed */
1020
1030
  if (txt_e > 1) {
1021
1031
  content = rndr_newbuf(rndr, BUFFER_SPAN);
1022
- if (is_img) bufput(content, data + 1, txt_e - 1);
1023
- else parse_inline(content, rndr, data + 1, txt_e - 1);
1032
+ if (is_img) {
1033
+ bufput(content, data + 1, txt_e - 1);
1034
+ } else {
1035
+ /* disable autolinking when parsing inline the
1036
+ * content of a link */
1037
+ rndr->in_link_body = 1;
1038
+ parse_inline(content, rndr, data + 1, txt_e - 1);
1039
+ rndr->in_link_body = 0;
1040
+ }
1024
1041
  }
1025
1042
 
1026
1043
  if (link) {
@@ -1558,6 +1575,7 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s
1558
1575
  struct buf *work = 0, *inter = 0;
1559
1576
  size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
1560
1577
  int in_empty = 0, has_inside_empty = 0;
1578
+ int has_next_uli, has_next_oli;
1561
1579
 
1562
1580
  /* keeping track of the first indentation prefix */
1563
1581
  while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
@@ -1604,10 +1622,20 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s
1604
1622
 
1605
1623
  pre = i;
1606
1624
 
1625
+ has_next_uli = prefix_uli(data + beg + i, end - beg - i);
1626
+ has_next_oli = prefix_oli(data + beg + i, end - beg - i);
1627
+
1628
+ /* checking for ul/ol switch */
1629
+ if (in_empty && (
1630
+ ((*flags & MKD_LIST_ORDERED) && has_next_uli) ||
1631
+ (!(*flags & MKD_LIST_ORDERED) && has_next_oli)
1632
+ )){
1633
+ *flags |= MKD_LI_END;
1634
+ break; /* the following item must have same list type */
1635
+ }
1636
+
1607
1637
  /* checking for a new item */
1608
- if ((prefix_uli(data + beg + i, end - beg - i) &&
1609
- !is_hrule(data + beg + i, end - beg - i)) ||
1610
- prefix_oli(data + beg + i, end - beg - i)) {
1638
+ if ((has_next_uli && !is_hrule(data + beg + i, end - beg - i)) || has_next_oli) {
1611
1639
  if (in_empty)
1612
1640
  has_inside_empty = 1;
1613
1641
 
@@ -2325,6 +2353,7 @@ sd_markdown_new(
2325
2353
  md->ext_flags = extensions;
2326
2354
  md->opaque = opaque;
2327
2355
  md->max_nesting = max_nesting;
2356
+ md->in_link_body = 0;
2328
2357
 
2329
2358
  return md;
2330
2359
  }
@@ -1,5 +1,5 @@
1
- #ifndef __REDCARPET_H__
2
- #define __REDCARPET_H__
1
+ #ifndef REDCARPET_H__
2
+ #define REDCARPET_H__
3
3
 
4
4
  #define RSTRING_NOT_MODIFIED
5
5
  #include "ruby.h"
@@ -1,5 +1,5 @@
1
- #ifndef __CR_STACK_H__
2
- #define __CR_STACK_H__
1
+ #ifndef STACK_H__
2
+ #define STACK_H__
3
3
 
4
4
  #include <stdlib.h>
5
5
 
@@ -53,3 +53,21 @@ module Redcarpet
53
53
  end
54
54
  end
55
55
 
56
+ # Compatibility class;
57
+ # Creates a instance of Redcarpet with the RedCloth
58
+ # API. This instance has no extensions enabled whatsoever,
59
+ # and no accessors to change this. 100% pure, standard
60
+ # Markdown.
61
+ class RedcarpetCompat
62
+ attr_accessor :text
63
+
64
+ def initialize(text, *_dummy)
65
+ @text = text
66
+ @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
67
+ end
68
+
69
+ def to_html(*_dummy)
70
+ @markdown.render(@text)
71
+ end
72
+ end
73
+
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'redcarpet'
4
- s.version = '2.0.0b5'
4
+ s.version = '2.0.0'
5
5
  s.summary = "Markdown that smells nice"
6
6
  s.description = 'A fast, safe and extensible Markdown to (X)HTML parser'
7
7
  s.date = '2011-09-14'
@@ -91,7 +91,6 @@ class HTMLRenderTest < Test::Unit::TestCase
91
91
  rd = render_with(@rndr[:safe_links], "[IRC](irc://chat.freenode.org/#freenode)")
92
92
  html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd
93
93
  end
94
-
95
94
  end
96
95
 
97
96
  class MarkdownTest < Test::Unit::TestCase
metadata CHANGED
@@ -1,15 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redcarpet
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
5
- prerelease: 5
4
+ hash: 15
5
+ prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
9
  - 0
10
- - b
11
- - 5
12
- version: 2.0.0b5
10
+ version: 2.0.0
13
11
  platform: ruby
14
12
  authors:
15
13
  - "Natacha Port\xC3\xA9"
@@ -90,14 +88,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
88
  required_rubygems_version: !ruby/object:Gem::Requirement
91
89
  none: false
92
90
  requirements:
93
- - - ">"
91
+ - - ">="
94
92
  - !ruby/object:Gem::Version
95
- hash: 25
93
+ hash: 3
96
94
  segments:
97
- - 1
98
- - 3
99
- - 1
100
- version: 1.3.1
95
+ - 0
96
+ version: "0"
101
97
  requirements: []
102
98
 
103
99
  rubyforge_project: