redcarpet 3.3.2 → 3.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/COPYING +17 -11
- data/Gemfile +2 -2
- data/README.markdown +66 -48
- data/ext/redcarpet/autolink.c +24 -12
- data/ext/redcarpet/autolink.h +17 -11
- data/ext/redcarpet/buffer.c +18 -11
- data/ext/redcarpet/buffer.h +17 -12
- data/ext/redcarpet/houdini.h +22 -0
- data/ext/redcarpet/houdini_href_e.c +27 -11
- data/ext/redcarpet/houdini_html_e.c +22 -1
- data/ext/redcarpet/html.c +52 -19
- data/ext/redcarpet/html.h +18 -13
- data/ext/redcarpet/html_blocks.h +68 -70
- data/ext/redcarpet/html_smartypants.c +47 -20
- data/ext/redcarpet/markdown.c +22 -20
- data/ext/redcarpet/markdown.h +17 -12
- data/ext/redcarpet/rc_markdown.c +35 -13
- data/ext/redcarpet/rc_render.c +51 -17
- data/ext/redcarpet/redcarpet.h +22 -0
- data/ext/redcarpet/stack.c +22 -0
- data/ext/redcarpet/stack.h +22 -0
- data/lib/redcarpet.rb +1 -1
- data/lib/redcarpet/cli.rb +1 -1
- data/lib/redcarpet/compat.rb +0 -2
- data/lib/redcarpet/render_strip.rb +13 -1
- data/redcarpet.gemspec +5 -4
- data/test/custom_render_test.rb +40 -1
- data/test/html5_test.rb +51 -38
- data/test/html_render_test.rb +92 -59
- data/test/html_toc_render_test.rb +41 -4
- data/test/markdown_test.rb +234 -177
- data/test/redcarpet_bin_test.rb +2 -2
- data/test/safe_render_test.rb +5 -6
- data/test/smarty_html_test.rb +19 -13
- data/test/smarty_pants_test.rb +10 -0
- data/test/stripdown_render_test.rb +38 -9
- data/test/test_helper.rb +17 -3
- metadata +24 -11
@@ -1,17 +1,23 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) 2015, Vicent Marti
|
3
3
|
*
|
4
|
-
* Permission
|
5
|
-
*
|
6
|
-
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9
|
+
* furnished to do so, subject to the following conditions:
|
7
10
|
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
* OR
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
12
|
+
* all copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
* THE SOFTWARE.
|
15
21
|
*/
|
16
22
|
|
17
23
|
#include "buffer.h"
|
@@ -83,6 +89,12 @@ word_boundary(uint8_t c)
|
|
83
89
|
return c == 0 || isspace(c) || ispunct(c);
|
84
90
|
}
|
85
91
|
|
92
|
+
static inline int
|
93
|
+
fraction_boundary(uint8_t c)
|
94
|
+
{
|
95
|
+
return c == 0 || isspace(c) || (c != '/' && ispunct(c));
|
96
|
+
}
|
97
|
+
|
86
98
|
// If 'text' begins with any kind of single quote (e.g. "'" or "'" etc.),
|
87
99
|
// returns the length of the sequence of characters that makes up the single-
|
88
100
|
// quote. Otherwise, returns zero.
|
@@ -139,6 +151,9 @@ smartypants_squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previo
|
|
139
151
|
return next_squote_len;
|
140
152
|
}
|
141
153
|
|
154
|
+
if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote))
|
155
|
+
return 0;
|
156
|
+
|
142
157
|
// trailing single quotes: students', tryin'
|
143
158
|
if (word_boundary(t1)) {
|
144
159
|
BUFPUTSL(ob, "’");
|
@@ -166,9 +181,6 @@ smartypants_squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previo
|
|
166
181
|
}
|
167
182
|
}
|
168
183
|
|
169
|
-
if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote))
|
170
|
-
return 0;
|
171
|
-
|
172
184
|
bufput(ob, squote_text, squote_size);
|
173
185
|
return 0;
|
174
186
|
}
|
@@ -282,16 +294,16 @@ smartypants_cb__backtick(struct buf *ob, struct smartypants_data *smrt, uint8_t
|
|
282
294
|
static size_t
|
283
295
|
smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
284
296
|
{
|
285
|
-
if (
|
297
|
+
if (fraction_boundary(previous_char) && size >= 3) {
|
286
298
|
if (text[0] == '1' && text[1] == '/' && text[2] == '2') {
|
287
|
-
if (size == 3 ||
|
299
|
+
if (size == 3 || fraction_boundary(text[3])) {
|
288
300
|
BUFPUTSL(ob, "½");
|
289
301
|
return 2;
|
290
302
|
}
|
291
303
|
}
|
292
304
|
|
293
305
|
if (text[0] == '1' && text[1] == '/' && text[2] == '4') {
|
294
|
-
if (size == 3 ||
|
306
|
+
if (size == 3 || fraction_boundary(text[3]) ||
|
295
307
|
(size >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h')) {
|
296
308
|
BUFPUTSL(ob, "¼");
|
297
309
|
return 2;
|
@@ -299,7 +311,7 @@ smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, uint8_t pr
|
|
299
311
|
}
|
300
312
|
|
301
313
|
if (text[0] == '3' && text[1] == '/' && text[2] == '4') {
|
302
|
-
if (size == 3 ||
|
314
|
+
if (size == 3 || fraction_boundary(text[3]) ||
|
303
315
|
(size >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's')) {
|
304
316
|
BUFPUTSL(ob, "¾");
|
305
317
|
return 2;
|
@@ -329,6 +341,7 @@ smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t prev
|
|
329
341
|
};
|
330
342
|
static const size_t skip_tags_count = 8;
|
331
343
|
|
344
|
+
size_t next_to_closing_a = 0;
|
332
345
|
size_t tag, i = 0;
|
333
346
|
|
334
347
|
while (i < size && text[i] != '>')
|
@@ -357,7 +370,23 @@ smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t prev
|
|
357
370
|
i++;
|
358
371
|
}
|
359
372
|
|
373
|
+
if (sdhtml_is_tag(text, size, "a") == HTML_TAG_CLOSE) {
|
374
|
+
while (i < size && text[i] != '>')
|
375
|
+
i++;
|
376
|
+
|
377
|
+
next_to_closing_a = 1;
|
378
|
+
}
|
379
|
+
|
360
380
|
bufput(ob, text, i + 1);
|
381
|
+
|
382
|
+
// Pretty tricky: since people may refer to something or someone
|
383
|
+
// with a link but use the possessive form right after it, we need
|
384
|
+
// to check whether a single quote is next to a closing "</a"> tag.
|
385
|
+
if (next_to_closing_a && strncmp("'", text+(i+1), 5) == 0) {
|
386
|
+
bufput(ob, "’", 7);
|
387
|
+
i += 5;
|
388
|
+
}
|
389
|
+
|
361
390
|
return i;
|
362
391
|
}
|
363
392
|
|
@@ -441,5 +470,3 @@ sdhtml_smartypants(struct buf *ob, const uint8_t *text, size_t size)
|
|
441
470
|
}
|
442
471
|
}
|
443
472
|
}
|
444
|
-
|
445
|
-
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -1,20 +1,24 @@
|
|
1
|
-
/* markdown.c - generic markdown parser */
|
2
|
-
|
3
1
|
/*
|
4
2
|
* Copyright (c) 2009, Natacha Porté
|
5
|
-
* Copyright (c)
|
3
|
+
* Copyright (c) 2015, Vicent Marti
|
4
|
+
*
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
10
|
+
* furnished to do so, subject to the following conditions:
|
6
11
|
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
* copyright notice and this permission notice appear in all copies.
|
12
|
+
* The above copyright notice and this permission notice shall be included in
|
13
|
+
* all copies or substantial portions of the Software.
|
10
14
|
*
|
11
|
-
* THE SOFTWARE IS PROVIDED "AS IS"
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
16
|
-
*
|
17
|
-
*
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
* THE SOFTWARE.
|
18
22
|
*/
|
19
23
|
|
20
24
|
#include "markdown.h"
|
@@ -88,7 +92,6 @@ typedef size_t
|
|
88
92
|
|
89
93
|
static size_t char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
90
94
|
static size_t char_underline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
91
|
-
static size_t char_highlight(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
92
95
|
static size_t char_quote(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
93
96
|
static size_t char_linebreak(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
94
97
|
static size_t char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
@@ -609,7 +612,7 @@ parse_emph1(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
609
612
|
if (data[i] == c && !_isspace(data[i - 1])) {
|
610
613
|
|
611
614
|
if (rndr->ext_flags & MKDEXT_NO_INTRA_EMPHASIS) {
|
612
|
-
if (i +
|
615
|
+
if (i + 1 < size && _isalnum(data[i + 1]))
|
613
616
|
continue;
|
614
617
|
}
|
615
618
|
|
@@ -841,7 +844,6 @@ char_quote(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offse
|
|
841
844
|
return end;
|
842
845
|
}
|
843
846
|
|
844
|
-
|
845
847
|
/* char_escape • '\\' backslash escape */
|
846
848
|
static size_t
|
847
849
|
char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
|
@@ -2335,7 +2337,7 @@ parse_table_header(
|
|
2335
2337
|
if (i < under_end && data[i] != '|' && data[i] != '+')
|
2336
2338
|
break;
|
2337
2339
|
|
2338
|
-
if (dashes <
|
2340
|
+
if (dashes < 1)
|
2339
2341
|
break;
|
2340
2342
|
|
2341
2343
|
i++;
|
@@ -2753,10 +2755,13 @@ sd_markdown_new(
|
|
2753
2755
|
if (md->cb.emphasis || md->cb.double_emphasis || md->cb.triple_emphasis) {
|
2754
2756
|
md->active_char['*'] = MD_CHAR_EMPHASIS;
|
2755
2757
|
md->active_char['_'] = MD_CHAR_EMPHASIS;
|
2758
|
+
|
2756
2759
|
if (extensions & MKDEXT_STRIKETHROUGH)
|
2757
2760
|
md->active_char['~'] = MD_CHAR_EMPHASIS;
|
2758
2761
|
if (extensions & MKDEXT_HIGHLIGHT)
|
2759
2762
|
md->active_char['='] = MD_CHAR_EMPHASIS;
|
2763
|
+
if (extensions & MKDEXT_QUOTE)
|
2764
|
+
md->active_char['"'] = MD_CHAR_QUOTE;
|
2760
2765
|
}
|
2761
2766
|
|
2762
2767
|
if (md->cb.codespan)
|
@@ -2781,9 +2786,6 @@ sd_markdown_new(
|
|
2781
2786
|
if (extensions & MKDEXT_SUPERSCRIPT)
|
2782
2787
|
md->active_char['^'] = MD_CHAR_SUPERSCRIPT;
|
2783
2788
|
|
2784
|
-
if (extensions & MKDEXT_QUOTE)
|
2785
|
-
md->active_char['"'] = MD_CHAR_QUOTE;
|
2786
|
-
|
2787
2789
|
/* Extension data */
|
2788
2790
|
md->ext_flags = extensions;
|
2789
2791
|
md->opaque = opaque;
|
data/ext/redcarpet/markdown.h
CHANGED
@@ -1,19 +1,24 @@
|
|
1
|
-
/* markdown.h - generic markdown parser */
|
2
|
-
|
3
1
|
/*
|
4
2
|
* Copyright (c) 2009, Natacha Porté
|
3
|
+
* Copyright (c) 2015, Vicent Marti
|
4
|
+
*
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
10
|
+
* furnished to do so, subject to the following conditions:
|
5
11
|
*
|
6
|
-
*
|
7
|
-
*
|
8
|
-
* copyright notice and this permission notice appear in all copies.
|
12
|
+
* The above copyright notice and this permission notice shall be included in
|
13
|
+
* all copies or substantial portions of the Software.
|
9
14
|
*
|
10
|
-
* THE SOFTWARE IS PROVIDED "AS IS"
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
16
|
-
*
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
* THE SOFTWARE.
|
17
22
|
*/
|
18
23
|
|
19
24
|
#ifndef MARKDOWN_H__
|
data/ext/redcarpet/rc_markdown.c
CHANGED
@@ -1,22 +1,30 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) 2015, Vicent Marti
|
3
3
|
*
|
4
|
-
* Permission
|
5
|
-
*
|
6
|
-
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9
|
+
* furnished to do so, subject to the following conditions:
|
7
10
|
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
* OR
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
12
|
+
* all copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
* THE SOFTWARE.
|
15
21
|
*/
|
22
|
+
|
16
23
|
#include "redcarpet.h"
|
17
24
|
|
18
25
|
VALUE rb_mRedcarpet;
|
19
26
|
VALUE rb_cMarkdown;
|
27
|
+
VALUE rb_cRenderHTML_TOC;
|
20
28
|
|
21
29
|
extern VALUE rb_cRenderBase;
|
22
30
|
|
@@ -79,7 +87,7 @@ rb_redcarpet_md__free(void *markdown)
|
|
79
87
|
|
80
88
|
static VALUE rb_redcarpet_md__new(int argc, VALUE *argv, VALUE klass)
|
81
89
|
{
|
82
|
-
VALUE rb_markdown, rb_rndr, hash;
|
90
|
+
VALUE rb_markdown, rb_rndr, hash, rndr_options;
|
83
91
|
unsigned int extensions = 0;
|
84
92
|
|
85
93
|
struct rb_redcarpet_rndr *rndr;
|
@@ -94,8 +102,23 @@ static VALUE rb_redcarpet_md__new(int argc, VALUE *argv, VALUE klass)
|
|
94
102
|
if (!rb_obj_is_kind_of(rb_rndr, rb_cRenderBase))
|
95
103
|
rb_raise(rb_eTypeError, "Invalid Renderer instance given");
|
96
104
|
|
105
|
+
/**
|
106
|
+
* Automatically enable the `fenced_code_blocks` option if
|
107
|
+
* given a kind of `HTML_TOC` object since many languages
|
108
|
+
* like Ruby use the sharp to comment code so these comments
|
109
|
+
* would be processed as titles.
|
110
|
+
*/
|
111
|
+
if (rb_obj_is_kind_of(rb_rndr, rb_cRenderHTML_TOC))
|
112
|
+
extensions |= MKDEXT_FENCED_CODE;
|
113
|
+
|
97
114
|
Data_Get_Struct(rb_rndr, struct rb_redcarpet_rndr, rndr);
|
98
115
|
|
116
|
+
/* Merge the current options in the @options hash */
|
117
|
+
if (hash != Qnil) {
|
118
|
+
rndr_options = rb_funcall(rb_iv_get(rb_rndr, "@options"), rb_intern("merge"), 1, hash);
|
119
|
+
rb_iv_set(rb_rndr, "@options", rndr_options);
|
120
|
+
}
|
121
|
+
|
99
122
|
markdown = sd_markdown_new(extensions, 16, &rndr->callbacks, &rndr->options);
|
100
123
|
if (!markdown)
|
101
124
|
rb_raise(rb_eRuntimeError, "Failed to create new Renderer class");
|
@@ -158,4 +181,3 @@ void Init_redcarpet()
|
|
158
181
|
|
159
182
|
Init_redcarpet_rndr();
|
160
183
|
}
|
161
|
-
|
data/ext/redcarpet/rc_render.c
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) 2015, Vicent Marti
|
3
3
|
*
|
4
|
-
* Permission
|
5
|
-
*
|
6
|
-
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9
|
+
* furnished to do so, subject to the following conditions:
|
7
10
|
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
* OR
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
12
|
+
* all copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
* THE SOFTWARE.
|
15
21
|
*/
|
16
22
|
|
17
23
|
#include "redcarpet.h"
|
@@ -34,10 +40,10 @@
|
|
34
40
|
}
|
35
41
|
|
36
42
|
extern VALUE rb_mRedcarpet;
|
43
|
+
extern VALUE rb_cRenderHTML_TOC;
|
37
44
|
VALUE rb_mRender;
|
38
45
|
VALUE rb_cRenderBase;
|
39
46
|
VALUE rb_cRenderHTML;
|
40
|
-
VALUE rb_cRenderHTML_TOC;
|
41
47
|
VALUE rb_mSmartyPants;
|
42
48
|
|
43
49
|
#define buf2str(t) ((t) ? rb_enc_str_new((const char*)(t)->data, (t)->size, opt->active_enc) : Qnil)
|
@@ -369,16 +375,22 @@ static void rb_redcarpet_rbase_mark(struct rb_redcarpet_rndr *rndr)
|
|
369
375
|
rb_gc_mark(rndr->options.link_attributes);
|
370
376
|
}
|
371
377
|
|
378
|
+
static void rndr_deallocate(void *rndr)
|
379
|
+
{
|
380
|
+
xfree(rndr);
|
381
|
+
}
|
382
|
+
|
372
383
|
static VALUE rb_redcarpet_rbase_alloc(VALUE klass)
|
373
384
|
{
|
374
385
|
struct rb_redcarpet_rndr *rndr = ALLOC(struct rb_redcarpet_rndr);
|
375
386
|
memset(rndr, 0x0, sizeof(struct rb_redcarpet_rndr));
|
376
|
-
return Data_Wrap_Struct(klass, rb_redcarpet_rbase_mark,
|
387
|
+
return Data_Wrap_Struct(klass, rb_redcarpet_rbase_mark, rndr_deallocate, rndr);
|
377
388
|
}
|
378
389
|
|
379
390
|
static void rb_redcarpet__overload(VALUE self, VALUE base_class)
|
380
391
|
{
|
381
392
|
struct rb_redcarpet_rndr *rndr;
|
393
|
+
VALUE options_ivar;
|
382
394
|
|
383
395
|
Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);
|
384
396
|
rndr->options.self = self;
|
@@ -399,6 +411,10 @@ static void rb_redcarpet__overload(VALUE self, VALUE base_class)
|
|
399
411
|
dest[i] = source[i];
|
400
412
|
}
|
401
413
|
}
|
414
|
+
|
415
|
+
options_ivar = rb_attr_get(self, rb_intern("@options"));
|
416
|
+
if (options_ivar == Qundef || options_ivar == Qnil)
|
417
|
+
rb_iv_set(self, "@options", rb_hash_new());
|
402
418
|
}
|
403
419
|
|
404
420
|
static VALUE rb_redcarpet_rbase_init(VALUE self)
|
@@ -418,6 +434,9 @@ static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
|
|
418
434
|
if (rb_scan_args(argc, argv, "01", &hash) == 1) {
|
419
435
|
Check_Type(hash, T_HASH);
|
420
436
|
|
437
|
+
/* Give access to the passed options through `@options` */
|
438
|
+
rb_iv_set(self, "@options", hash);
|
439
|
+
|
421
440
|
/* escape_html */
|
422
441
|
if (rb_hash_aref(hash, CSTR2SYM("escape_html")) == Qtrue)
|
423
442
|
render_flags |= HTML_ESCAPE;
|
@@ -480,6 +499,9 @@ static VALUE rb_redcarpet_htmltoc_init(int argc, VALUE *argv, VALUE self)
|
|
480
499
|
if (rb_scan_args(argc, argv, "01", &hash) == 1) {
|
481
500
|
Check_Type(hash, T_HASH);
|
482
501
|
|
502
|
+
/* Give access to the passed options through `@options` */
|
503
|
+
rb_iv_set(self, "@options", hash);
|
504
|
+
|
483
505
|
/* escape_html */
|
484
506
|
if (rb_hash_aref(hash, CSTR2SYM("escape_html")) == Qtrue)
|
485
507
|
render_flags |= HTML_ESCAPE;
|
@@ -491,10 +513,22 @@ static VALUE rb_redcarpet_htmltoc_init(int argc, VALUE *argv, VALUE self)
|
|
491
513
|
sdhtml_toc_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
|
492
514
|
rb_redcarpet__overload(self, rb_cRenderHTML_TOC);
|
493
515
|
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
516
|
+
/* Check whether we are dealing with a Range object by
|
517
|
+
checking whether the object responds to min and max */
|
518
|
+
if (rb_respond_to(nesting_level, rb_intern("min")) &&
|
519
|
+
rb_respond_to(nesting_level, rb_intern("max"))) {
|
520
|
+
int min = NUM2INT(rb_funcall(nesting_level, rb_intern("min"), 0));
|
521
|
+
int max = NUM2INT(rb_funcall(nesting_level, rb_intern("max"), 0));
|
522
|
+
|
523
|
+
rndr->options.html.toc_data.nesting_bounds[0] = min;
|
524
|
+
rndr->options.html.toc_data.nesting_bounds[1] = max;
|
525
|
+
} else if (FIXNUM_P(nesting_level)) {
|
526
|
+
rndr->options.html.toc_data.nesting_bounds[0] = 1;
|
527
|
+
rndr->options.html.toc_data.nesting_bounds[1] = NUM2INT(nesting_level);
|
528
|
+
} else {
|
529
|
+
rndr->options.html.toc_data.nesting_bounds[0] = 1;
|
530
|
+
rndr->options.html.toc_data.nesting_bounds[1] = 6;
|
531
|
+
}
|
498
532
|
|
499
533
|
return Qnil;
|
500
534
|
}
|