redcarpet 1.3.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of redcarpet might be problematic. Click here for more details.

data/ext/markdown.h CHANGED
@@ -36,56 +36,50 @@ enum mkd_autolink {
36
36
  MKDA_IMPLICIT_EMAIL /* e-mail link without mailto: */
37
37
  };
38
38
 
39
- typedef enum {
40
- MKD_LAX_EMPHASIS = (1 << 0),
41
- } mkd_parser_mode;
42
-
43
- struct mkd_renderopt {
44
- void *opaque;
45
- unsigned int flags;
46
- };
47
-
48
- struct mkd_parseropt {
49
- unsigned int flags;
50
- int recursion_depth;
39
+ enum mkd_extensions {
40
+ MKDEXT_LAX_EMPHASIS = (1 << 0),
41
+ MKDEXT_TABLES = (1 << 1),
42
+ MKDEXT_FENCED_CODE = (1 << 2),
51
43
  };
52
44
 
53
45
  /* mkd_renderer • functions for rendering parsed data */
54
46
  struct mkd_renderer {
55
47
  /* block level callbacks - NULL skips the block */
56
- void (*blockcode)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
57
- void (*blockquote)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
58
- void (*blockhtml)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
59
- void (*header)(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *opaque);
60
- void (*hrule)(struct buf *ob, struct mkd_renderopt *opaque);
61
- void (*list)(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opaque);
62
- void (*listitem)(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opaque);
63
- void (*paragraph)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
48
+ void (*blockcode)(struct buf *ob, struct buf *text, void *opaque);
49
+ void (*blockquote)(struct buf *ob, struct buf *text, void *opaque);
50
+ void (*blockhtml)(struct buf *ob, struct buf *text, void *opaque);
51
+ void (*header)(struct buf *ob, struct buf *text, int level, void *opaque);
52
+ void (*hrule)(struct buf *ob, void *opaque);
53
+ void (*list)(struct buf *ob, struct buf *text, int flags, void *opaque);
54
+ void (*listitem)(struct buf *ob, struct buf *text, int flags, void *opaque);
55
+ void (*paragraph)(struct buf *ob, struct buf *text, void *opaque);
56
+ void (*table)(struct buf *ob, struct buf *header, struct buf *body, void *opaque);
57
+ void (*table_row)(struct buf *ob, struct buf *text, void *opaque);
58
+ void (*table_cell)(struct buf *ob, struct buf *text, int flags, void *opaque);
59
+
64
60
 
65
61
  /* span level callbacks - NULL or return 0 prints the span verbatim */
66
- int (*autolink)(struct buf *ob, struct buf *link, enum mkd_autolink type, struct mkd_renderopt *opaque);
67
- int (*codespan)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
68
- int (*double_emphasis)(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *opaque);
69
- int (*emphasis)(struct buf *ob, struct buf *text, char c,struct mkd_renderopt *opaque);
70
- int (*image)(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, struct mkd_renderopt *opaque);
71
- int (*linebreak)(struct buf *ob, struct mkd_renderopt *opaque);
72
- int (*link)(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, struct mkd_renderopt *opaque);
73
- int (*raw_html_tag)(struct buf *ob, struct buf *tag, struct mkd_renderopt *opaque);
74
- int (*triple_emphasis)(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *opaque);
62
+ int (*autolink)(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque);
63
+ int (*codespan)(struct buf *ob, struct buf *text, void *opaque);
64
+ int (*double_emphasis)(struct buf *ob, struct buf *text, char c, void *opaque);
65
+ int (*emphasis)(struct buf *ob, struct buf *text, char c,void *opaque);
66
+ int (*image)(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, void *opaque);
67
+ int (*linebreak)(struct buf *ob, void *opaque);
68
+ int (*link)(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque);
69
+ int (*raw_html_tag)(struct buf *ob, struct buf *tag, void *opaque);
70
+ int (*triple_emphasis)(struct buf *ob, struct buf *text, char c, void *opaque);
75
71
 
76
72
  /* low level callbacks - NULL copies input directly into the output */
77
- void (*entity)(struct buf *ob, struct buf *entity, struct mkd_renderopt *opaque);
78
- void (*normal_text)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
73
+ void (*entity)(struct buf *ob, struct buf *entity, void *opaque);
74
+ void (*normal_text)(struct buf *ob, struct buf *text, void *opaque);
79
75
 
80
76
  /* header and footer */
81
- void (*doc_header)(struct buf *ob, struct mkd_renderopt *opaque);
82
- void (*doc_footer)(struct buf *ob, struct mkd_renderopt *opaque);
77
+ void (*doc_header)(struct buf *ob, void *opaque);
78
+ void (*doc_footer)(struct buf *ob, void *opaque);
83
79
 
84
80
  /* renderer data */
85
81
  const char *emph_chars; /* chars that trigger emphasis rendering */
86
-
87
- struct mkd_renderopt render_options;
88
- struct mkd_parseropt parser_options;
82
+ void *opaque;
89
83
  };
90
84
 
91
85
  /*********
@@ -96,13 +90,17 @@ struct mkd_renderer {
96
90
  #define MKD_LIST_ORDERED 1
97
91
  #define MKD_LI_BLOCK 2 /* <li> containing block data */
98
92
 
93
+ #define MKD_TABLE_ALIGN_L (1 << 0)
94
+ #define MKD_TABLE_ALIGN_R (1 << 1)
95
+ #define MKD_TABLE_ALIGN_CENTER (MKD_TABLE_ALIGN_L | MKD_TABLE_ALIGN_R)
96
+
99
97
  /**********************
100
98
  * EXPORTED FUNCTIONS *
101
99
  **********************/
102
100
 
103
101
  /* markdown • parses the input buffer and renders it into the output buffer */
104
102
  void
105
- markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndr);
103
+ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndr, unsigned int extensions);
106
104
 
107
105
  #endif
108
106
 
data/ext/redcarpet.c CHANGED
@@ -4,8 +4,6 @@
4
4
  #include "markdown.h"
5
5
  #include "xhtml.h"
6
6
 
7
- #define REDCARPET_RECURSION_LIMIT 16
8
-
9
7
  typedef enum
10
8
  {
11
9
  REDCARPET_RENDER_XHTML,
@@ -14,41 +12,46 @@ typedef enum
14
12
 
15
13
  static VALUE rb_cRedcarpet;
16
14
 
17
- static void rb_redcarpet__setup_xhtml(struct mkd_renderer *rnd, VALUE ruby_obj)
15
+ static void rb_redcarpet__get_flags(VALUE ruby_obj,
16
+ unsigned int *enabled_extensions_p,
17
+ unsigned int *render_flags_p)
18
18
  {
19
- unsigned int render_flags = RENDER_EXPAND_TABS;
20
- unsigned int parser_flags = 0;
19
+ unsigned int render_flags = XHTML_EXPAND_TABS;
20
+ unsigned int extensions = 0;
21
21
 
22
22
  /* smart */
23
23
  if (rb_funcall(ruby_obj, rb_intern("smart"), 0) == Qtrue)
24
- render_flags |= RENDER_SMARTYPANTS;
24
+ render_flags |= XHTML_SMARTYPANTS;
25
25
 
26
26
  /* filter_html */
27
27
  if (rb_funcall(ruby_obj, rb_intern("filter_html"), 0) == Qtrue)
28
- render_flags |= RENDER_SKIP_HTML;
28
+ render_flags |= XHTML_SKIP_HTML;
29
29
 
30
30
  /* no_image */
31
31
  if (rb_funcall(ruby_obj, rb_intern("no_image"), 0) == Qtrue)
32
- render_flags |= RENDER_SKIP_IMAGES;
32
+ render_flags |= XHTML_SKIP_IMAGES;
33
33
 
34
34
  /* no_links */
35
35
  if (rb_funcall(ruby_obj, rb_intern("no_links"), 0) == Qtrue)
36
- render_flags |= RENDER_SKIP_LINKS;
36
+ render_flags |= XHTML_SKIP_LINKS;
37
37
 
38
38
  /* filter_style */
39
39
  if (rb_funcall(ruby_obj, rb_intern("filter_styles"), 0) == Qtrue)
40
- render_flags |= RENDER_SKIP_STYLE;
40
+ render_flags |= XHTML_SKIP_STYLE;
41
41
 
42
42
  /* autolink */
43
43
  if (rb_funcall(ruby_obj, rb_intern("autolink"), 0) == Qtrue)
44
- render_flags |= RENDER_AUTOLINK;
44
+ render_flags |= XHTML_AUTOLINK;
45
45
 
46
46
  /* safelink */
47
47
  if (rb_funcall(ruby_obj, rb_intern("safelink"), 0) == Qtrue)
48
- render_flags |= RENDER_SAFELINK;
48
+ render_flags |= XHTML_SAFELINK;
49
49
 
50
50
  if (rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
51
- render_flags |= RENDER_TOC;
51
+ render_flags |= XHTML_TOC;
52
+
53
+ if (rb_funcall(ruby_obj, rb_intern("no_strikethrough"), 0) == Qtrue)
54
+ render_flags |= XHTML_SKIP_STRIKETHROUGH;
52
55
 
53
56
  /* parser - strict
54
57
  * This is fucking stupid; what the 'strict' flag actually
@@ -56,9 +59,16 @@ static void rb_redcarpet__setup_xhtml(struct mkd_renderer *rnd, VALUE ruby_obj)
56
59
  * named flag internally, even if outside we have retarded
57
60
  * naming because of compat. issues .*/
58
61
  if (rb_funcall(ruby_obj, rb_intern("strict"), 0) == Qtrue)
59
- parser_flags |= MKD_LAX_EMPHASIS;
62
+ extensions |= MKDEXT_LAX_EMPHASIS;
63
+
64
+ if (rb_funcall(ruby_obj, rb_intern("no_tables"), 0) != Qtrue)
65
+ extensions |= MKDEXT_TABLES;
60
66
 
61
- init_xhtml_renderer(rnd, render_flags, parser_flags, REDCARPET_RECURSION_LIMIT);
67
+ if (rb_funcall(ruby_obj, rb_intern("no_fencedcode"), 0) != Qtrue)
68
+ extensions |= MKDEXT_FENCED_CODE;
69
+
70
+ *enabled_extensions_p = extensions;
71
+ *render_flags_p = render_flags;
62
72
  }
63
73
 
64
74
  static VALUE rb_redcarpet__render(VALUE self, RendererType render_type)
@@ -68,6 +78,7 @@ static VALUE rb_redcarpet__render(VALUE self, RendererType render_type)
68
78
 
69
79
  struct buf input_buf, *output_buf;
70
80
  struct mkd_renderer renderer;
81
+ unsigned int enabled_extensions, render_flags;
71
82
 
72
83
  Check_Type(text, T_STRING);
73
84
 
@@ -78,20 +89,22 @@ static VALUE rb_redcarpet__render(VALUE self, RendererType render_type)
78
89
  output_buf = bufnew(128);
79
90
  bufgrow(output_buf, RSTRING_LEN(text) * 1.2f);
80
91
 
92
+ rb_redcarpet__get_flags(self, &enabled_extensions, &render_flags);
93
+
81
94
  switch (render_type) {
82
95
  case REDCARPET_RENDER_XHTML:
83
- rb_redcarpet__setup_xhtml(&renderer, self);
96
+ init_xhtml_renderer(&renderer, render_flags);
84
97
  break;
85
98
 
86
99
  case REDCARPET_RENDER_TOC:
87
- init_toc_renderer(&renderer, REDCARPET_RECURSION_LIMIT);
100
+ init_toc_renderer(&renderer);
88
101
  break;
89
102
 
90
103
  default:
91
104
  return Qnil;
92
105
  }
93
106
 
94
- markdown(output_buf, &input_buf, &renderer);
107
+ markdown(output_buf, &input_buf, &renderer, enabled_extensions);
95
108
 
96
109
  result = rb_str_new(output_buf->data, output_buf->size);
97
110
  bufrelease(output_buf);
data/ext/xhtml.c CHANGED
@@ -22,9 +22,13 @@
22
22
  #include <stdlib.h>
23
23
  #include <stdio.h>
24
24
 
25
- struct toc_data {
26
- int header_count;
27
- int current_level;
25
+ struct xhtml_renderopt {
26
+ struct {
27
+ int header_count;
28
+ int current_level;
29
+ } toc_data;
30
+
31
+ unsigned int flags;
28
32
  };
29
33
 
30
34
  static int
@@ -114,12 +118,14 @@ rndr_autolink2(struct buf *ob, const char *link, size_t link_size, enum mkd_auto
114
118
  }
115
119
 
116
120
  static int
117
- rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, struct mkd_renderopt *options)
121
+ rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque)
118
122
  {
123
+ struct xhtml_renderopt *options = opaque;
124
+
119
125
  if (!link || !link->size)
120
126
  return 0;
121
127
 
122
- if ((options->flags & RENDER_SAFELINK) != 0 && !is_safe_link(link->data, link->size))
128
+ if ((options->flags & XHTML_SAFELINK) != 0 && !is_safe_link(link->data, link->size))
123
129
  return 0;
124
130
 
125
131
  rndr_autolink2(ob, link->data, link->size, type);
@@ -127,7 +133,7 @@ rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, struct m
127
133
  }
128
134
 
129
135
  static void
130
- rndr_blockcode(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
136
+ rndr_blockcode(struct buf *ob, struct buf *text, void *opaque)
131
137
  {
132
138
  if (ob->size) bufputc(ob, '\n');
133
139
  BUFPUTSL(ob, "<pre><code>");
@@ -136,7 +142,7 @@ rndr_blockcode(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
136
142
  }
137
143
 
138
144
  static void
139
- rndr_blockquote(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
145
+ rndr_blockquote(struct buf *ob, struct buf *text, void *opaque)
140
146
  {
141
147
  BUFPUTSL(ob, "<blockquote>\n");
142
148
  if (text) bufput(ob, text->data, text->size);
@@ -144,7 +150,7 @@ rndr_blockquote(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
144
150
  }
145
151
 
146
152
  static int
147
- rndr_codespan(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
153
+ rndr_codespan(struct buf *ob, struct buf *text, void *opaque)
148
154
  {
149
155
  BUFPUTSL(ob, "<code>");
150
156
  if (text) lus_attr_escape(ob, text->data, text->size);
@@ -153,19 +159,33 @@ rndr_codespan(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
153
159
  }
154
160
 
155
161
  static int
156
- rndr_double_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
162
+ rndr_double_emphasis(struct buf *ob, struct buf *text, char c, void *opaque)
157
163
  {
158
- if (!text || !text->size) return 0;
159
- BUFPUTSL(ob, "<strong>");
160
- bufput(ob, text->data, text->size);
161
- BUFPUTSL(ob, "</strong>");
164
+ struct xhtml_renderopt *options = opaque;
165
+
166
+ if (!text || !text->size)
167
+ return 0;
168
+
169
+ if (c == '~') {
170
+ if (options->flags & XHTML_SKIP_STRIKETHROUGH)
171
+ return 0;
172
+
173
+ BUFPUTSL(ob, "<span style=\"text-decoration:line-through;\">");
174
+ bufput(ob, text->data, text->size);
175
+ BUFPUTSL(ob, "</span>");
176
+ } else {
177
+ BUFPUTSL(ob, "<strong>");
178
+ bufput(ob, text->data, text->size);
179
+ BUFPUTSL(ob, "</strong>");
180
+ }
181
+
162
182
  return 1;
163
183
  }
164
184
 
165
185
  static int
166
- rndr_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
186
+ rndr_emphasis(struct buf *ob, struct buf *text, char c, void *opaque)
167
187
  {
168
- if (!text || !text->size) return 0;
188
+ if (!text || !text->size || c == '~') return 0;
169
189
  BUFPUTSL(ob, "<em>");
170
190
  if (text) bufput(ob, text->data, text->size);
171
191
  BUFPUTSL(ob, "</em>");
@@ -173,14 +193,15 @@ rndr_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *op
173
193
  }
174
194
 
175
195
  static void
176
- rndr_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
196
+ rndr_header(struct buf *ob, struct buf *text, int level, void *opaque)
177
197
  {
198
+ struct xhtml_renderopt *options = opaque;
199
+
178
200
  if (ob->size)
179
201
  bufputc(ob, '\n');
180
202
 
181
- if (options->flags & RENDER_TOC) {
182
- struct toc_data *data = options->opaque;
183
- bufprintf(ob, "<a name=\"toc_%d\"></a>", data->header_count++);
203
+ if (options->flags & XHTML_TOC) {
204
+ bufprintf(ob, "<a name=\"toc_%d\"></a>", options->toc_data.header_count++);
184
205
  }
185
206
 
186
207
  bufprintf(ob, "<h%d>", level);
@@ -189,9 +210,11 @@ rndr_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *o
189
210
  }
190
211
 
191
212
  static int
192
- rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, struct mkd_renderopt *options)
213
+ rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque)
193
214
  {
194
- if ((options->flags & RENDER_SAFELINK) != 0 && !is_safe_link(link->data, link->size))
215
+ struct xhtml_renderopt *options = opaque;
216
+
217
+ if ((options->flags & XHTML_SAFELINK) != 0 && !is_safe_link(link->data, link->size))
195
218
  return 0;
196
219
 
197
220
  BUFPUTSL(ob, "<a href=\"");
@@ -206,7 +229,7 @@ rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *conte
206
229
  }
207
230
 
208
231
  static void
209
- rndr_list(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *options)
232
+ rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque)
210
233
  {
211
234
  if (ob->size) bufputc(ob, '\n');
212
235
  bufput(ob, flags & MKD_LIST_ORDERED ? "<ol>\n" : "<ul>\n", 5);
@@ -215,7 +238,7 @@ rndr_list(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opt
215
238
  }
216
239
 
217
240
  static void
218
- rndr_listitem(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *options)
241
+ rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque)
219
242
  {
220
243
  BUFPUTSL(ob, "<li>");
221
244
  if (text) {
@@ -226,7 +249,7 @@ rndr_listitem(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt
226
249
  }
227
250
 
228
251
  static void
229
- rndr_paragraph(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
252
+ rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
230
253
  {
231
254
  size_t i = 0;
232
255
 
@@ -245,7 +268,7 @@ rndr_paragraph(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
245
268
  }
246
269
 
247
270
  static void
248
- rndr_raw_block(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
271
+ rndr_raw_block(struct buf *ob, struct buf *text, void *opaque)
249
272
  {
250
273
  size_t org, sz;
251
274
  if (!text) return;
@@ -260,7 +283,7 @@ rndr_raw_block(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
260
283
  }
261
284
 
262
285
  static int
263
- rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
286
+ rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, void *opaque)
264
287
  {
265
288
  if (!text || !text->size) return 0;
266
289
  BUFPUTSL(ob, "<strong><em>");
@@ -275,14 +298,14 @@ rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_render
275
298
  **********************/
276
299
 
277
300
  static void
278
- rndr_hrule(struct buf *ob, struct mkd_renderopt *options)
301
+ rndr_hrule(struct buf *ob, void *opaque)
279
302
  {
280
303
  if (ob->size) bufputc(ob, '\n');
281
304
  BUFPUTSL(ob, "<hr />\n");
282
305
  }
283
306
 
284
307
  static int
285
- rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, struct mkd_renderopt *options)
308
+ rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, void *opaque)
286
309
  {
287
310
  if (!link || !link->size) return 0;
288
311
  BUFPUTSL(ob, "<img src=\"");
@@ -298,27 +321,28 @@ rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt,
298
321
  }
299
322
 
300
323
  static int
301
- rndr_linebreak(struct buf *ob, struct mkd_renderopt *options)
324
+ rndr_linebreak(struct buf *ob, void *opaque)
302
325
  {
303
326
  BUFPUTSL(ob, "<br />\n");
304
327
  return 1;
305
328
  }
306
329
 
307
330
  static int
308
- rndr_raw_html(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
331
+ rndr_raw_html(struct buf *ob, struct buf *text, void *opaque)
309
332
  {
333
+ struct xhtml_renderopt *options = opaque;
310
334
  int escape_html = 0;
311
335
 
312
- if (options->flags & RENDER_SKIP_HTML)
336
+ if (options->flags & XHTML_SKIP_HTML)
313
337
  escape_html = 1;
314
338
 
315
- else if ((options->flags & RENDER_SKIP_STYLE) != 0 && is_html_tag(text, "<style>"))
339
+ else if ((options->flags & XHTML_SKIP_STYLE) != 0 && is_html_tag(text, "<style>"))
316
340
  escape_html = 1;
317
341
 
318
- else if ((options->flags & RENDER_SKIP_LINKS) != 0 && is_html_tag(text, "<a>"))
342
+ else if ((options->flags & XHTML_SKIP_LINKS) != 0 && is_html_tag(text, "<a>"))
319
343
  escape_html = 1;
320
344
 
321
- else if ((options->flags & RENDER_SKIP_IMAGES) != 0 && is_html_tag(text, "<img>"))
345
+ else if ((options->flags & XHTML_SKIP_IMAGES) != 0 && is_html_tag(text, "<img>"))
322
346
  escape_html = 1;
323
347
 
324
348
 
@@ -330,6 +354,55 @@ rndr_raw_html(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
330
354
  return 1;
331
355
  }
332
356
 
357
+ static void
358
+ rndr_table(struct buf *ob, struct buf *header, struct buf *body, void *opaque)
359
+ {
360
+ if (ob->size) bufputc(ob, '\n');
361
+ BUFPUTSL(ob, "<table><thead>\n");
362
+ if (header)
363
+ bufput(ob, header->data, header->size);
364
+ BUFPUTSL(ob, "\n</thead><tbody>\n");
365
+ if (body)
366
+ bufput(ob, body->data, body->size);
367
+ BUFPUTSL(ob, "\n</tbody></table>");
368
+ }
369
+
370
+ static void
371
+ rndr_tablerow(struct buf *ob, struct buf *text, void *opaque)
372
+ {
373
+ if (ob->size) bufputc(ob, '\n');
374
+ BUFPUTSL(ob, "<tr>\n");
375
+ if (text)
376
+ bufput(ob, text->data, text->size);
377
+ BUFPUTSL(ob, "\n</tr>");
378
+ }
379
+
380
+ static void
381
+ rndr_tablecell(struct buf *ob, struct buf *text, int align, void *opaque)
382
+ {
383
+ if (ob->size) bufputc(ob, '\n');
384
+ switch (align) {
385
+ case MKD_TABLE_ALIGN_L:
386
+ BUFPUTSL(ob, "<td align=\"left\">");
387
+ break;
388
+
389
+ case MKD_TABLE_ALIGN_R:
390
+ BUFPUTSL(ob, "<td align=\"right\">");
391
+ break;
392
+
393
+ case MKD_TABLE_ALIGN_CENTER:
394
+ BUFPUTSL(ob, "<td align=\"center\">");
395
+ break;
396
+
397
+ default:
398
+ BUFPUTSL(ob, "<td>");
399
+ break;
400
+ }
401
+
402
+ if (text)
403
+ bufput(ob, text->data, text->size);
404
+ BUFPUTSL(ob, "</td>");
405
+ }
333
406
 
334
407
  static struct {
335
408
  char c0;
@@ -418,13 +491,14 @@ smartypants_quotes(struct buf *ob, struct buf *text, size_t i, int is_open)
418
491
  }
419
492
 
420
493
  static void
421
- rndr_normal_text(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
494
+ rndr_normal_text(struct buf *ob, struct buf *text, void *opaque)
422
495
  {
423
496
  size_t i;
424
497
  int open_single = 0, open_double = 0, open_tag = 0;
498
+ struct xhtml_renderopt *options = opaque;
425
499
 
426
- int autolink = (options->flags & RENDER_AUTOLINK);
427
- int smartypants = (options->flags & RENDER_SMARTYPANTS);
500
+ int autolink = (options->flags & XHTML_AUTOLINK);
501
+ int smartypants = (options->flags & XHTML_SMARTYPANTS);
428
502
 
429
503
  if (!text)
430
504
  return;
@@ -563,46 +637,46 @@ rndr_normal_text(struct buf *ob, struct buf *text, struct mkd_renderopt *options
563
637
  }
564
638
 
565
639
  static void
566
- toc_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
640
+ toc_header(struct buf *ob, struct buf *text, int level, void *opaque)
567
641
  {
568
- struct toc_data *data = (struct toc_data *)options->opaque;
642
+ struct xhtml_renderopt *options = opaque;
569
643
 
570
- if (level > data->current_level) {
644
+ if (level > options->toc_data.current_level) {
571
645
  if (level > 1)
572
646
  BUFPUTSL(ob, "<li>");
573
647
  BUFPUTSL(ob, "<ul>\n");
574
648
  }
575
649
 
576
- if (level < data->current_level) {
650
+ if (level < options->toc_data.current_level) {
577
651
  BUFPUTSL(ob, "</ul>");
578
- if (data->current_level > 1)
652
+ if (options->toc_data.current_level > 1)
579
653
  BUFPUTSL(ob, "</li>\n");
580
654
  }
581
655
 
582
- data->current_level = level;
656
+ options->toc_data.current_level = level;
583
657
 
584
- bufprintf(ob, "<li><a href=\"#toc_%d\">", data->header_count++);
658
+ bufprintf(ob, "<li><a href=\"#toc_%d\">", options->toc_data.header_count++);
585
659
  if (text)
586
660
  bufput(ob, text->data, text->size);
587
661
  BUFPUTSL(ob, "</a></li>\n");
588
662
  }
589
663
 
590
664
  static void
591
- toc_finalize(struct buf *ob, struct mkd_renderopt *options)
665
+ toc_finalize(struct buf *ob, void *opaque)
592
666
  {
593
- struct toc_data *data = (struct toc_data *)options->opaque;
667
+ struct xhtml_renderopt *options = opaque;
594
668
 
595
- while (data->current_level > 1) {
669
+ while (options->toc_data.current_level > 1) {
596
670
  BUFPUTSL(ob, "</ul></li>\n");
597
- data->current_level--;
671
+ options->toc_data.current_level--;
598
672
  }
599
673
 
600
- if (data->current_level)
674
+ if (options->toc_data.current_level)
601
675
  BUFPUTSL(ob, "</ul>\n");
602
676
  }
603
677
 
604
678
  void
605
- init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth)
679
+ init_toc_renderer(struct mkd_renderer *renderer)
606
680
  {
607
681
  static const struct mkd_renderer toc_render = {
608
682
  NULL,
@@ -613,6 +687,9 @@ init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth)
613
687
  NULL,
614
688
  NULL,
615
689
  NULL,
690
+ NULL,
691
+ NULL,
692
+ NULL,
616
693
 
617
694
  rndr_autolink,
618
695
  rndr_codespan,
@@ -630,23 +707,20 @@ init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth)
630
707
  NULL,
631
708
  toc_finalize,
632
709
 
633
- NULL,
634
-
635
- { 0, 0 },
636
- { 0, 0 },
710
+ "*-~",
711
+ NULL
637
712
  };
638
713
 
639
- memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
714
+ struct xhtml_renderopt *options;
715
+ options = calloc(1, sizeof(struct xhtml_renderopt));
716
+ options->flags = XHTML_TOC;
640
717
 
641
- renderer->parser_options.recursion_depth = recursion_depth;
642
- renderer->render_options.flags = RENDER_TOC;
643
- renderer->render_options.opaque = calloc(1, sizeof(struct toc_data));
718
+ memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
719
+ renderer->opaque = options;
644
720
  }
645
721
 
646
722
  void
647
- init_xhtml_renderer(struct mkd_renderer *renderer,
648
- unsigned int render_flags,
649
- unsigned int parser_flags, int recursion_depth)
723
+ init_xhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags)
650
724
  {
651
725
  static const struct mkd_renderer renderer_default = {
652
726
  rndr_blockcode,
@@ -657,6 +731,9 @@ init_xhtml_renderer(struct mkd_renderer *renderer,
657
731
  rndr_list,
658
732
  rndr_listitem,
659
733
  rndr_paragraph,
734
+ rndr_table,
735
+ rndr_tablerow,
736
+ rndr_tablecell,
660
737
 
661
738
  rndr_autolink,
662
739
  rndr_codespan,
@@ -674,33 +751,29 @@ init_xhtml_renderer(struct mkd_renderer *renderer,
674
751
  NULL,
675
752
  NULL,
676
753
 
677
- "*_",
678
-
679
- { 0, 0 },
680
- { 0, 0 },
754
+ "*_~",
755
+ NULL
681
756
  };
682
757
 
758
+ struct xhtml_renderopt *options;
759
+ options = calloc(1, sizeof(struct xhtml_renderopt));
760
+ options->flags = render_flags;
761
+
683
762
  memcpy(renderer, &renderer_default, sizeof(struct mkd_renderer));
763
+ renderer->opaque = options;
684
764
 
685
- if (render_flags & RENDER_SKIP_IMAGES)
765
+ if (render_flags & XHTML_SKIP_IMAGES)
686
766
  renderer->image = NULL;
687
767
 
688
- if (render_flags & RENDER_SKIP_LINKS) {
768
+ if (render_flags & XHTML_SKIP_LINKS) {
689
769
  renderer->link = NULL;
690
770
  renderer->autolink = NULL;
691
771
  }
692
-
693
- renderer->parser_options.recursion_depth = recursion_depth;
694
- renderer->parser_options.flags = parser_flags;
695
-
696
- renderer->render_options.flags = render_flags;
697
- if (render_flags & RENDER_TOC)
698
- renderer->render_options.opaque = calloc(1, sizeof(struct toc_data));
699
772
  }
700
773
 
701
774
  void
702
775
  free_renderer(struct mkd_renderer *renderer)
703
776
  {
704
- free(renderer->render_options.opaque);
777
+ free(renderer->opaque);
705
778
  }
706
779