redcarpet 1.17.2 → 2.0.0b
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 +232 -37
- data/Rakefile +13 -15
- data/bin/redcarpet +1 -1
- data/ext/redcarpet/autolink.c +5 -5
- data/ext/redcarpet/autolink.h +7 -4
- data/ext/redcarpet/html.c +83 -71
- data/ext/redcarpet/html.h +14 -5
- data/ext/redcarpet/html_smartypants.c +35 -11
- data/ext/redcarpet/markdown.c +153 -85
- data/ext/redcarpet/markdown.h +6 -10
- data/ext/redcarpet/rc_markdown.c +108 -0
- data/ext/redcarpet/rc_render.c +469 -0
- data/lib/redcarpet.rb +68 -106
- data/redcarpet.gemspec +8 -11
- data/test/redcarpet_test.rb +206 -122
- metadata +17 -18
- data/ext/redcarpet/redcarpet.c +0 -161
- data/lib/markdown.rb +0 -1
- data/test/benchmark.rb +0 -56
- data/test/benchmark.txt +0 -306
- data/test/markdown_test.rb +0 -186
data/ext/redcarpet/markdown.h
CHANGED
@@ -46,6 +46,7 @@ enum mkd_extensions {
|
|
46
46
|
MKDEXT_STRIKETHROUGH = (1 << 4),
|
47
47
|
MKDEXT_LAX_HTML_BLOCKS = (1 << 5),
|
48
48
|
MKDEXT_SPACE_HEADERS = (1 << 6),
|
49
|
+
MKDEXT_SUPERSCRIPT = (1 << 7),
|
49
50
|
};
|
50
51
|
|
51
52
|
/* mkd_renderer • functions for rendering parsed data */
|
@@ -75,6 +76,7 @@ struct mkd_renderer {
|
|
75
76
|
int (*raw_html_tag)(struct buf *ob, struct buf *tag, void *opaque);
|
76
77
|
int (*triple_emphasis)(struct buf *ob, struct buf *text, void *opaque);
|
77
78
|
int (*strikethrough)(struct buf *ob, struct buf *text, void *opaque);
|
79
|
+
int (*superscript)(struct buf *ob, struct buf *text, void *opaque);
|
78
80
|
|
79
81
|
/* low level callbacks - NULL copies input directly into the output */
|
80
82
|
void (*entity)(struct buf *ob, struct buf *entity, void *opaque);
|
@@ -100,23 +102,17 @@ struct mkd_renderer {
|
|
100
102
|
#define MKD_TABLE_ALIGN_R (1 << 1)
|
101
103
|
#define MKD_TABLE_ALIGN_CENTER (MKD_TABLE_ALIGN_L | MKD_TABLE_ALIGN_R)
|
102
104
|
|
103
|
-
/*******************
|
104
|
-
* Auxiliar methods
|
105
|
-
*******************/
|
106
|
-
int
|
107
|
-
is_safe_link(const char *link, size_t link_len);
|
108
|
-
|
109
105
|
/**********************
|
110
106
|
* EXPORTED FUNCTIONS *
|
111
107
|
**********************/
|
112
108
|
|
113
|
-
/*
|
109
|
+
/* sd_markdown * parses the input buffer and renders it into the output buffer */
|
114
110
|
extern void
|
115
|
-
|
111
|
+
sd_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndr, unsigned int extensions);
|
116
112
|
|
117
|
-
/*
|
113
|
+
/* sd_version * returns the library version as major.minor.rev */
|
118
114
|
extern void
|
119
|
-
|
115
|
+
sd_version(int *major, int *minor, int *revision);
|
120
116
|
|
121
117
|
#endif
|
122
118
|
|
@@ -0,0 +1,108 @@
|
|
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"
|
13
|
+
|
14
|
+
VALUE rb_mRedcarpet;
|
15
|
+
VALUE rb_cMarkdown;
|
16
|
+
|
17
|
+
extern VALUE rb_cRenderBase;
|
18
|
+
|
19
|
+
static void rb_redcarpet_md_flags(VALUE ruby_obj, unsigned int *enabled_extensions_p)
|
20
|
+
{
|
21
|
+
unsigned int extensions = 0;
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Markdown extensions -- all disabled by default
|
25
|
+
*/
|
26
|
+
if (rb_funcall(ruby_obj, rb_intern("no_intra_emphasis"), 0) == Qtrue)
|
27
|
+
extensions |= MKDEXT_NO_INTRA_EMPHASIS;
|
28
|
+
|
29
|
+
if (rb_funcall(ruby_obj, rb_intern("tables"), 0) == Qtrue)
|
30
|
+
extensions |= MKDEXT_TABLES;
|
31
|
+
|
32
|
+
if (rb_funcall(ruby_obj, rb_intern("fenced_code_blocks"), 0) == Qtrue)
|
33
|
+
extensions |= MKDEXT_FENCED_CODE;
|
34
|
+
|
35
|
+
if (rb_funcall(ruby_obj, rb_intern("autolink"), 0) == Qtrue)
|
36
|
+
extensions |= MKDEXT_AUTOLINK;
|
37
|
+
|
38
|
+
if (rb_funcall(ruby_obj, rb_intern("strikethrough"), 0) == Qtrue)
|
39
|
+
extensions |= MKDEXT_STRIKETHROUGH;
|
40
|
+
|
41
|
+
if (rb_funcall(ruby_obj, rb_intern("lax_html_blocks"), 0) == Qtrue)
|
42
|
+
extensions |= MKDEXT_LAX_HTML_BLOCKS;
|
43
|
+
|
44
|
+
if (rb_funcall(ruby_obj, rb_intern("space_after_headers"), 0) == Qtrue)
|
45
|
+
extensions |= MKDEXT_SPACE_HEADERS;
|
46
|
+
|
47
|
+
if (rb_funcall(ruby_obj, rb_intern("superscript"), 0) == Qtrue)
|
48
|
+
extensions |= MKDEXT_SUPERSCRIPT;
|
49
|
+
|
50
|
+
*enabled_extensions_p = extensions;
|
51
|
+
}
|
52
|
+
|
53
|
+
static VALUE rb_redcarpet_md_render_with(VALUE self, VALUE rb_rndr, VALUE text)
|
54
|
+
{
|
55
|
+
VALUE result;
|
56
|
+
|
57
|
+
struct mkd_renderer *renderer;
|
58
|
+
struct buf input_buf, *output_buf;
|
59
|
+
unsigned int enabled_extensions = 0;
|
60
|
+
|
61
|
+
Check_Type(text, T_STRING);
|
62
|
+
|
63
|
+
if (!rb_obj_is_kind_of(rb_rndr, rb_cRenderBase))
|
64
|
+
rb_raise(rb_eTypeError, "Invalid Renderer instance");
|
65
|
+
|
66
|
+
if (rb_respond_to(rb_rndr, rb_intern("preprocess")))
|
67
|
+
text = rb_funcall(rb_rndr, rb_intern("preprocess"), 1, text);
|
68
|
+
|
69
|
+
memset(&input_buf, 0x0, sizeof(struct buf));
|
70
|
+
input_buf.data = RSTRING_PTR(text);
|
71
|
+
input_buf.size = RSTRING_LEN(text);
|
72
|
+
|
73
|
+
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
|
+
|
78
|
+
rb_redcarpet_md_flags(self, &enabled_extensions);
|
79
|
+
sd_markdown(output_buf, &input_buf, renderer, enabled_extensions);
|
80
|
+
result = rb_str_new(output_buf->data, output_buf->size);
|
81
|
+
rb_enc_copy(result, text);
|
82
|
+
|
83
|
+
bufrelease(output_buf);
|
84
|
+
|
85
|
+
if (rb_respond_to(rb_rndr, rb_intern("postprocess")))
|
86
|
+
result = rb_funcall(rb_rndr, rb_intern("postprocess"), 1, result);
|
87
|
+
|
88
|
+
return result;
|
89
|
+
}
|
90
|
+
|
91
|
+
static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
92
|
+
{
|
93
|
+
return rb_redcarpet_md_render_with(self, rb_iv_get(self, "@renderer"), text);
|
94
|
+
}
|
95
|
+
|
96
|
+
extern void Init_redcarpet_rndr();
|
97
|
+
|
98
|
+
void Init_redcarpet()
|
99
|
+
{
|
100
|
+
rb_mRedcarpet = rb_define_module("Redcarpet");
|
101
|
+
|
102
|
+
rb_cMarkdown = rb_define_class_under(rb_mRedcarpet, "Markdown", rb_cObject);
|
103
|
+
rb_define_method(rb_cMarkdown, "render", rb_redcarpet_md_render, 1);
|
104
|
+
rb_define_method(rb_cMarkdown, "render_with", rb_redcarpet_md_render_with, 2);
|
105
|
+
|
106
|
+
Init_redcarpet_rndr();
|
107
|
+
}
|
108
|
+
|
@@ -0,0 +1,469 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2011, Vicent Marti
|
3
|
+
*
|
4
|
+
* Permission to use, copy, modify, and distribute this software for any
|
5
|
+
* purpose with or without fee is hereby granted, provided that the above
|
6
|
+
* copyright notice and this permission notice appear in all copies.
|
7
|
+
*
|
8
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
9
|
+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
10
|
+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
11
|
+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
12
|
+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
13
|
+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
14
|
+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#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))))
|
30
|
+
|
31
|
+
#define SPAN_CALLBACK(method_name, ...) {\
|
32
|
+
struct redcarpet_pload *load = opaque;\
|
33
|
+
VALUE ret = rb_funcall(load->self, rb_intern(method_name), __VA_ARGS__);\
|
34
|
+
if (NIL_P(ret)) return 0;\
|
35
|
+
Check_Type(ret, T_STRING);\
|
36
|
+
bufput(ob, RSTRING_PTR(ret), RSTRING_LEN(ret));\
|
37
|
+
return 1;\
|
38
|
+
}
|
39
|
+
|
40
|
+
#define BLOCK_CALLBACK(method_name, ...) {\
|
41
|
+
struct redcarpet_pload *load = opaque;\
|
42
|
+
VALUE ret = rb_funcall(load->self, rb_intern(method_name), __VA_ARGS__);\
|
43
|
+
if (NIL_P(ret)) return;\
|
44
|
+
Check_Type(ret, T_STRING);\
|
45
|
+
bufput(ob, RSTRING_PTR(ret), RSTRING_LEN(ret));\
|
46
|
+
}
|
47
|
+
|
48
|
+
extern VALUE rb_mRedcarpet;
|
49
|
+
VALUE rb_mRender;
|
50
|
+
VALUE rb_cRenderBase;
|
51
|
+
VALUE rb_cRenderHTML;
|
52
|
+
VALUE rb_cRenderHTML_TOC;
|
53
|
+
VALUE rb_mSmartyPants;
|
54
|
+
|
55
|
+
struct redcarpet_pload {
|
56
|
+
VALUE self;
|
57
|
+
};
|
58
|
+
|
59
|
+
static inline VALUE
|
60
|
+
buf2str(struct buf *text)
|
61
|
+
{
|
62
|
+
if (!text || !text->size) return Qnil;
|
63
|
+
return rb_str_new(text->data, text->size);
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
static void
|
68
|
+
rndr_blockcode(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)
|
69
|
+
{
|
70
|
+
BLOCK_CALLBACK("block_code", 2, buf2str(text), buf2str(lang));
|
71
|
+
}
|
72
|
+
|
73
|
+
static void
|
74
|
+
rndr_blockquote(struct buf *ob, struct buf *text, void *opaque)
|
75
|
+
{
|
76
|
+
BLOCK_CALLBACK("block_quote", 1, buf2str(text));
|
77
|
+
}
|
78
|
+
|
79
|
+
static void
|
80
|
+
rndr_raw_block(struct buf *ob, struct buf *text, void *opaque)
|
81
|
+
{
|
82
|
+
BLOCK_CALLBACK("block_html", 1, buf2str(text));
|
83
|
+
}
|
84
|
+
|
85
|
+
static void
|
86
|
+
rndr_header(struct buf *ob, struct buf *text, int level, void *opaque)
|
87
|
+
{
|
88
|
+
BLOCK_CALLBACK("header", 2, buf2str(text), INT2FIX(level));
|
89
|
+
}
|
90
|
+
|
91
|
+
static void
|
92
|
+
rndr_hrule(struct buf *ob, void *opaque)
|
93
|
+
{
|
94
|
+
BLOCK_CALLBACK("hrule", 0);
|
95
|
+
}
|
96
|
+
|
97
|
+
static void
|
98
|
+
rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque)
|
99
|
+
{
|
100
|
+
BLOCK_CALLBACK("list", 2, buf2str(text),
|
101
|
+
(flags & MKD_LIST_ORDERED) ? CSTR2SYM("ordered") : CSTR2SYM("unordered"));
|
102
|
+
}
|
103
|
+
|
104
|
+
static void
|
105
|
+
rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque)
|
106
|
+
{
|
107
|
+
BLOCK_CALLBACK("list_item", 1, buf2str(text));
|
108
|
+
}
|
109
|
+
|
110
|
+
static void
|
111
|
+
rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
|
112
|
+
{
|
113
|
+
BLOCK_CALLBACK("paragraph", 1, buf2str(text));
|
114
|
+
}
|
115
|
+
|
116
|
+
static void
|
117
|
+
rndr_table(struct buf *ob, struct buf *header, struct buf *body, void *opaque)
|
118
|
+
{
|
119
|
+
BLOCK_CALLBACK("table", 2, buf2str(header), buf2str(body));
|
120
|
+
}
|
121
|
+
|
122
|
+
static void
|
123
|
+
rndr_tablerow(struct buf *ob, struct buf *text, void *opaque)
|
124
|
+
{
|
125
|
+
BLOCK_CALLBACK("table_row", 1, buf2str(text));
|
126
|
+
}
|
127
|
+
|
128
|
+
static void
|
129
|
+
rndr_tablecell(struct buf *ob, struct buf *text, int align, void *opaque)
|
130
|
+
{
|
131
|
+
VALUE rb_align;
|
132
|
+
|
133
|
+
switch (align) {
|
134
|
+
case MKD_TABLE_ALIGN_L:
|
135
|
+
rb_align = CSTR2SYM("left");
|
136
|
+
break;
|
137
|
+
|
138
|
+
case MKD_TABLE_ALIGN_R:
|
139
|
+
rb_align = CSTR2SYM("right");
|
140
|
+
break;
|
141
|
+
|
142
|
+
case MKD_TABLE_ALIGN_CENTER:
|
143
|
+
rb_align = CSTR2SYM("center");
|
144
|
+
break;
|
145
|
+
|
146
|
+
default:
|
147
|
+
rb_align = Qnil;
|
148
|
+
break;
|
149
|
+
}
|
150
|
+
|
151
|
+
BLOCK_CALLBACK("table_cell", 2, buf2str(text), rb_align);
|
152
|
+
}
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
/***
|
158
|
+
* SPAN LEVEL
|
159
|
+
*/
|
160
|
+
static int
|
161
|
+
rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque)
|
162
|
+
{
|
163
|
+
SPAN_CALLBACK("autolink", 2, buf2str(link),
|
164
|
+
type == MKDA_NORMAL ? CSTR2SYM("url") : CSTR2SYM("email"));
|
165
|
+
}
|
166
|
+
|
167
|
+
static int
|
168
|
+
rndr_codespan(struct buf *ob, struct buf *text, void *opaque)
|
169
|
+
{
|
170
|
+
SPAN_CALLBACK("codespan", 1, buf2str(text));
|
171
|
+
}
|
172
|
+
|
173
|
+
static int
|
174
|
+
rndr_double_emphasis(struct buf *ob, struct buf *text, void *opaque)
|
175
|
+
{
|
176
|
+
SPAN_CALLBACK("double_emphasis", 1, buf2str(text));
|
177
|
+
}
|
178
|
+
|
179
|
+
static int
|
180
|
+
rndr_emphasis(struct buf *ob, struct buf *text, void *opaque)
|
181
|
+
{
|
182
|
+
SPAN_CALLBACK("emphasis", 1, buf2str(text));
|
183
|
+
}
|
184
|
+
|
185
|
+
static int
|
186
|
+
rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, void *opaque)
|
187
|
+
{
|
188
|
+
SPAN_CALLBACK("image", 3, buf2str(link), buf2str(title), buf2str(alt));
|
189
|
+
}
|
190
|
+
|
191
|
+
static int
|
192
|
+
rndr_linebreak(struct buf *ob, void *opaque)
|
193
|
+
{
|
194
|
+
SPAN_CALLBACK("linebreak", 0);
|
195
|
+
}
|
196
|
+
|
197
|
+
static int
|
198
|
+
rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque)
|
199
|
+
{
|
200
|
+
SPAN_CALLBACK("link", 3, buf2str(link), buf2str(title), buf2str(content));
|
201
|
+
}
|
202
|
+
|
203
|
+
static int
|
204
|
+
rndr_raw_html(struct buf *ob, struct buf *text, void *opaque)
|
205
|
+
{
|
206
|
+
SPAN_CALLBACK("raw_html", 1, buf2str(text));
|
207
|
+
}
|
208
|
+
|
209
|
+
static int
|
210
|
+
rndr_triple_emphasis(struct buf *ob, struct buf *text, void *opaque)
|
211
|
+
{
|
212
|
+
SPAN_CALLBACK("triple_emphasis", 1, buf2str(text));
|
213
|
+
}
|
214
|
+
|
215
|
+
static int
|
216
|
+
rndr_strikethrough(struct buf *ob, struct buf *text, void *opaque)
|
217
|
+
{
|
218
|
+
SPAN_CALLBACK("strikethrough", 1, buf2str(text));
|
219
|
+
}
|
220
|
+
|
221
|
+
static int
|
222
|
+
rndr_superscript(struct buf *ob, struct buf *text, void *opaque)
|
223
|
+
{
|
224
|
+
SPAN_CALLBACK("superscript", 1, buf2str(text));
|
225
|
+
}
|
226
|
+
|
227
|
+
/**
|
228
|
+
* direct writes
|
229
|
+
*/
|
230
|
+
static void
|
231
|
+
rndr_entity(struct buf *ob, struct buf *text, void *opaque)
|
232
|
+
{
|
233
|
+
BLOCK_CALLBACK("entity", 1, buf2str(text));
|
234
|
+
}
|
235
|
+
|
236
|
+
static void
|
237
|
+
rndr_normal_text(struct buf *ob, struct buf *text, void *opaque)
|
238
|
+
{
|
239
|
+
BLOCK_CALLBACK("normal_text", 1, buf2str(text));
|
240
|
+
}
|
241
|
+
|
242
|
+
static void
|
243
|
+
rndr_doc_header(struct buf *ob, void *opaque)
|
244
|
+
{
|
245
|
+
BLOCK_CALLBACK("doc_header", 0);
|
246
|
+
}
|
247
|
+
|
248
|
+
static void
|
249
|
+
rndr_doc_footer(struct buf *ob, void *opaque)
|
250
|
+
{
|
251
|
+
BLOCK_CALLBACK("doc_footer", 0);
|
252
|
+
}
|
253
|
+
|
254
|
+
static struct mkd_renderer rb_redcarpet_rndr = {
|
255
|
+
rndr_blockcode,
|
256
|
+
rndr_blockquote,
|
257
|
+
rndr_raw_block,
|
258
|
+
rndr_header,
|
259
|
+
rndr_hrule,
|
260
|
+
rndr_list,
|
261
|
+
rndr_listitem,
|
262
|
+
rndr_paragraph,
|
263
|
+
rndr_table,
|
264
|
+
rndr_tablerow,
|
265
|
+
rndr_tablecell,
|
266
|
+
|
267
|
+
rndr_autolink,
|
268
|
+
rndr_codespan,
|
269
|
+
rndr_double_emphasis,
|
270
|
+
rndr_emphasis,
|
271
|
+
rndr_image,
|
272
|
+
rndr_linebreak,
|
273
|
+
rndr_link,
|
274
|
+
rndr_raw_html,
|
275
|
+
rndr_triple_emphasis,
|
276
|
+
rndr_strikethrough,
|
277
|
+
rndr_superscript,
|
278
|
+
|
279
|
+
rndr_entity,
|
280
|
+
rndr_normal_text,
|
281
|
+
|
282
|
+
rndr_doc_header,
|
283
|
+
rndr_doc_footer,
|
284
|
+
|
285
|
+
NULL
|
286
|
+
};
|
287
|
+
|
288
|
+
static const char *rb_redcarpet_method_names[] = {
|
289
|
+
"block_code",
|
290
|
+
"block_quote",
|
291
|
+
"block_html",
|
292
|
+
"header",
|
293
|
+
"hrule",
|
294
|
+
"list",
|
295
|
+
"list_item",
|
296
|
+
"paragraph",
|
297
|
+
"table",
|
298
|
+
"table_row",
|
299
|
+
"table_cell",
|
300
|
+
|
301
|
+
"autolink",
|
302
|
+
"codespan",
|
303
|
+
"double_emphasis",
|
304
|
+
"emphasis",
|
305
|
+
"image",
|
306
|
+
"linebreak",
|
307
|
+
"link",
|
308
|
+
"raw_html",
|
309
|
+
"triple_emphasis",
|
310
|
+
"strikethrough",
|
311
|
+
"superscript",
|
312
|
+
|
313
|
+
"entity",
|
314
|
+
"normal_text",
|
315
|
+
|
316
|
+
"doc_header",
|
317
|
+
"doc_footer"
|
318
|
+
};
|
319
|
+
|
320
|
+
static const size_t rb_redcarpet_method_count = sizeof(rb_redcarpet_method_names)/sizeof(char *);
|
321
|
+
|
322
|
+
static void rb_redcarpet_rbase_free(struct mkd_renderer *rndr)
|
323
|
+
{
|
324
|
+
xfree(rndr->opaque);
|
325
|
+
xfree(rndr);
|
326
|
+
}
|
327
|
+
|
328
|
+
static VALUE rb_redcarpet_rbase_alloc(VALUE klass)
|
329
|
+
{
|
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);
|
333
|
+
}
|
334
|
+
|
335
|
+
static void rb_redcarpet__overload(VALUE self)
|
336
|
+
{
|
337
|
+
size_t i;
|
338
|
+
struct mkd_renderer *rndr;
|
339
|
+
|
340
|
+
void **source = (void **)&rb_redcarpet_rndr;
|
341
|
+
void **dest;
|
342
|
+
|
343
|
+
Data_Get_Struct(self, struct mkd_renderer, rndr);
|
344
|
+
dest = (void **)rndr;
|
345
|
+
|
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];
|
349
|
+
}
|
350
|
+
}
|
351
|
+
|
352
|
+
static VALUE rb_redcarpet_rbase_init(VALUE self)
|
353
|
+
{
|
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;
|
364
|
+
return Qnil;
|
365
|
+
}
|
366
|
+
|
367
|
+
static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
|
368
|
+
{
|
369
|
+
struct mkd_renderer *rndr;
|
370
|
+
unsigned int render_flags = 0;
|
371
|
+
VALUE hash;
|
372
|
+
|
373
|
+
Data_Get_Struct(self, struct mkd_renderer, rndr);
|
374
|
+
|
375
|
+
if (rb_scan_args(argc, argv, "01", &hash) == 1)
|
376
|
+
{
|
377
|
+
Check_Type(hash, T_HASH);
|
378
|
+
|
379
|
+
/* filter_html */
|
380
|
+
if (rb_hash_aref(hash, CSTR2SYM("filter_html")) == Qtrue)
|
381
|
+
render_flags |= HTML_SKIP_HTML;
|
382
|
+
|
383
|
+
/* no_image */
|
384
|
+
if (rb_hash_aref(hash, CSTR2SYM("no_image")) == Qtrue)
|
385
|
+
render_flags |= HTML_SKIP_IMAGES;
|
386
|
+
|
387
|
+
/* no_links */
|
388
|
+
if (rb_hash_aref(hash, CSTR2SYM("no_links")) == Qtrue)
|
389
|
+
render_flags |= HTML_SKIP_LINKS;
|
390
|
+
|
391
|
+
/* filter_style */
|
392
|
+
if (rb_hash_aref(hash, CSTR2SYM("no_styles")) == Qtrue)
|
393
|
+
render_flags |= HTML_SKIP_STYLE;
|
394
|
+
|
395
|
+
/* safelink */
|
396
|
+
if (rb_hash_aref(hash, CSTR2SYM("safe_links_only")) == Qtrue)
|
397
|
+
render_flags |= HTML_SAFELINK;
|
398
|
+
|
399
|
+
if (rb_hash_aref(hash, CSTR2SYM("with_toc_data")) == Qtrue)
|
400
|
+
render_flags |= HTML_TOC;
|
401
|
+
|
402
|
+
if (rb_hash_aref(hash, CSTR2SYM("hard_wrap")) == Qtrue)
|
403
|
+
render_flags |= HTML_HARD_WRAP;
|
404
|
+
|
405
|
+
if (rb_hash_aref(hash, CSTR2SYM("xhtml")) == Qtrue)
|
406
|
+
render_flags |= HTML_USE_XHTML;
|
407
|
+
}
|
408
|
+
|
409
|
+
sdhtml_renderer(rndr, render_flags, (void *)self);
|
410
|
+
|
411
|
+
if (rb_obj_class(self) != rb_cRenderHTML)
|
412
|
+
rb_redcarpet__overload(self);
|
413
|
+
|
414
|
+
return Qnil;
|
415
|
+
}
|
416
|
+
|
417
|
+
static VALUE rb_redcarpet_htmltoc_init(VALUE self)
|
418
|
+
{
|
419
|
+
struct mkd_renderer *rndr;
|
420
|
+
Data_Get_Struct(self, struct mkd_renderer, rndr);
|
421
|
+
|
422
|
+
sdhtml_toc_renderer(rndr, (void *)self);
|
423
|
+
|
424
|
+
if (rb_obj_class(self) != rb_cRenderHTML_TOC)
|
425
|
+
rb_redcarpet__overload(self);
|
426
|
+
|
427
|
+
return Qnil;
|
428
|
+
}
|
429
|
+
|
430
|
+
static VALUE rb_redcarpet_smartypants_render(VALUE self, VALUE text)
|
431
|
+
{
|
432
|
+
VALUE result;
|
433
|
+
struct buf input_buf, *output_buf;
|
434
|
+
|
435
|
+
Check_Type(text, T_STRING);
|
436
|
+
|
437
|
+
memset(&input_buf, 0x0, sizeof(struct buf));
|
438
|
+
input_buf.data = RSTRING_PTR(text);
|
439
|
+
input_buf.size = RSTRING_LEN(text);
|
440
|
+
|
441
|
+
output_buf = bufnew(128);
|
442
|
+
bufgrow(output_buf, RSTRING_LEN(text) * 1.1f);
|
443
|
+
|
444
|
+
sdhtml_smartypants(output_buf, &input_buf);
|
445
|
+
result = rb_str_new(output_buf->data, output_buf->size);
|
446
|
+
rb_enc_copy(result, text);
|
447
|
+
|
448
|
+
bufrelease(output_buf);
|
449
|
+
return result;
|
450
|
+
}
|
451
|
+
|
452
|
+
|
453
|
+
void Init_redcarpet_rndr()
|
454
|
+
{
|
455
|
+
rb_mRender = rb_define_module_under(rb_mRedcarpet, "Render");
|
456
|
+
|
457
|
+
rb_cRenderBase = rb_define_class_under(rb_mRender, "Base", rb_cObject);
|
458
|
+
rb_define_alloc_func(rb_cRenderBase, rb_redcarpet_rbase_alloc);
|
459
|
+
rb_define_method(rb_cRenderBase, "initialize", rb_redcarpet_rbase_init, 0);
|
460
|
+
|
461
|
+
rb_cRenderHTML = rb_define_class_under(rb_mRender, "HTML", rb_cRenderBase);
|
462
|
+
rb_define_method(rb_cRenderHTML, "initialize", rb_redcarpet_html_init, -1);
|
463
|
+
|
464
|
+
rb_cRenderHTML_TOC = rb_define_class_under(rb_mRender, "HTML_TOC", rb_cRenderBase);
|
465
|
+
rb_define_method(rb_cRenderHTML_TOC, "initialize", rb_redcarpet_htmltoc_init, 0);
|
466
|
+
|
467
|
+
rb_mSmartyPants = rb_define_module_under(rb_mRender, "SmartyPants");
|
468
|
+
rb_define_singleton_method(rb_mSmartyPants, "postprocess", rb_redcarpet_smartypants_render, 1);
|
469
|
+
}
|