rdiscount 2.2.0.1 → 2.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.markdown +11 -12
- data/Rakefile +11 -2
- data/bin/rdiscount +10 -3
- data/ext/Csio.c +2 -2
- data/ext/VERSION +1 -1
- data/ext/amalloc.c +1 -0
- data/ext/blocktags +2 -1
- data/ext/config.h +2 -0
- data/ext/css.c +5 -7
- data/ext/cstring.h +0 -1
- data/ext/docheader.c +6 -1
- data/ext/dumptree.c +11 -2
- data/ext/extconf.rb +1 -0
- data/ext/flags.c +4 -2
- data/ext/generate.c +339 -141
- data/ext/gethopt.c +286 -0
- data/ext/gethopt.h +43 -0
- data/ext/github_flavoured.c +8 -7
- data/ext/h1title.c +36 -0
- data/ext/html5.c +0 -1
- data/ext/markdown.c +189 -87
- data/ext/markdown.h +55 -27
- data/ext/mkdio.c +155 -58
- data/ext/mkdio.h +9 -5
- data/ext/mktags.c +3 -0
- data/ext/notspecial.c +44 -0
- data/ext/pgm_options.c +12 -12
- data/ext/pgm_options.h +2 -2
- data/ext/rdiscount.c +25 -22
- data/ext/resource.c +1 -0
- data/ext/setup.c +1 -1
- data/ext/tags.c +2 -0
- data/ext/toc.c +12 -14
- data/ext/version.c +3 -3
- data/ext/xml.c +6 -5
- data/ext/xmlpage.c +5 -8
- data/lib/rdiscount.rb +12 -1
- data/rdiscount.gemspec +8 -8
- data/test/markdown_test.rb +0 -1
- data/test/rdiscount_test.rb +46 -23
- metadata +14 -10
data/ext/markdown.h
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
#ifndef _MARKDOWN_D
|
2
2
|
#define _MARKDOWN_D
|
3
3
|
|
4
|
+
#include "config.h"
|
4
5
|
#include "cstring.h"
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
#ifdef HAVE_INTTYPES_H
|
8
|
+
# include <inttypes.h>
|
9
|
+
#elif HAVE_STDINT_H
|
10
|
+
# include <stdint.h>
|
11
|
+
#endif
|
12
|
+
|
13
|
+
/* flags, captured into a named type
|
8
14
|
*/
|
9
|
-
typedef
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
int dealloc; /* deallocation needed? */
|
15
|
-
int refnumber;
|
16
|
-
int flags;
|
17
|
-
#define EXTRA_BOOKMARK 0x01
|
18
|
-
#define REFERENCED 0x02
|
19
|
-
} Footnote;
|
15
|
+
typedef DWORD mkd_flag_t;
|
16
|
+
|
17
|
+
#define is_flag_set(flags, item) ((flags) & (item))
|
18
|
+
#define set_flag(flags, item) ((flags) |= (item))
|
19
|
+
#define clear_flag(flags, item) ((flags) &= ~(item))
|
20
20
|
|
21
21
|
/* each input line is read into a Line, which contains the line,
|
22
22
|
* the offset of the first non-space character [this assumes
|
@@ -49,16 +49,38 @@ typedef struct paragraph {
|
|
49
49
|
struct paragraph *down; /* recompiled contents of this paragraph */
|
50
50
|
struct line *text; /* all the text in this paragraph */
|
51
51
|
char *ident; /* %id% tag for QUOTE */
|
52
|
-
char *lang;
|
52
|
+
char *lang; /* lang attribute for CODE */
|
53
53
|
enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
|
54
54
|
HTML, STYLE, DL, UL, OL, AL, LISTITEM,
|
55
55
|
HDR, HR, TABLE, SOURCE } typ;
|
56
56
|
enum { IMPLICIT=0, PARA, CENTER} align;
|
57
57
|
int hnumber; /* <Hn> for typ == HDR */
|
58
|
+
#if GITHUB_CHECKBOX
|
59
|
+
int flags;
|
60
|
+
#define GITHUB_CHECK 0x01
|
61
|
+
#define IS_CHECKED 0x02
|
62
|
+
#endif
|
58
63
|
} Paragraph;
|
59
64
|
|
60
65
|
enum { ETX, SETEXT }; /* header types */
|
61
66
|
|
67
|
+
/* reference-style links (and images) are stored in an array
|
68
|
+
* of footnotes.
|
69
|
+
*/
|
70
|
+
typedef struct footnote {
|
71
|
+
Cstring tag; /* the tag for the reference link */
|
72
|
+
Cstring link; /* what this footnote points to */
|
73
|
+
Cstring title; /* what it's called (TITLE= attribute) */
|
74
|
+
Paragraph *text; /* EXTRA_FOOTNOTE content */
|
75
|
+
|
76
|
+
int height, width; /* dimensions (for image link) */
|
77
|
+
int dealloc; /* deallocation needed? */
|
78
|
+
int refnumber;
|
79
|
+
int flags;
|
80
|
+
#define EXTRA_FOOTNOTE 0x01
|
81
|
+
#define REFERENCED 0x02
|
82
|
+
} Footnote;
|
83
|
+
|
62
84
|
|
63
85
|
typedef struct block {
|
64
86
|
enum { bTEXT, bSTAR, bUNDER } b_type;
|
@@ -78,7 +100,9 @@ typedef struct callback_data {
|
|
78
100
|
void *e_data; /* private data for callbacks */
|
79
101
|
mkd_callback_t e_url; /* url edit callback */
|
80
102
|
mkd_callback_t e_flags; /* extra href flags callback */
|
103
|
+
mkd_callback_t e_anchor; /* callback for anchor types */
|
81
104
|
mkd_free_t e_free; /* edit/flags callback memory deallocator */
|
105
|
+
mkd_callback_t e_codefmt; /* codeblock formatter (for highlighting) */
|
82
106
|
} Callback_data;
|
83
107
|
|
84
108
|
|
@@ -101,11 +125,12 @@ typedef struct mmiot {
|
|
101
125
|
Cstring out;
|
102
126
|
Cstring in;
|
103
127
|
Qblock Q;
|
128
|
+
char last; /* last text character added to out */
|
104
129
|
int isp;
|
105
130
|
struct escaped *esc;
|
106
131
|
char *ref_prefix;
|
107
132
|
struct footnote_list *footnotes;
|
108
|
-
|
133
|
+
mkd_flag_t flags;
|
109
134
|
#define MKD_NOLINKS 0x00000001
|
110
135
|
#define MKD_NOIMAGE 0x00000002
|
111
136
|
#define MKD_NOPANTS 0x00000004
|
@@ -136,14 +161,16 @@ typedef struct mmiot {
|
|
136
161
|
#define MKD_GITHUBTAGS 0x08000000
|
137
162
|
#define MKD_URLENCODEDANCHOR 0x10000000
|
138
163
|
#define IS_LABEL 0x20000000
|
139
|
-
#define
|
164
|
+
#define MKD_LATEX 0x40000000
|
165
|
+
#define MKD_EXPLICITLIST 0x80000000
|
166
|
+
#define USER_FLAGS 0xFFFFFFFF
|
140
167
|
#define INPUT_MASK (MKD_NOHEADER|MKD_TABSTOP)
|
141
168
|
|
142
169
|
Callback_data *cb;
|
143
170
|
} MMIOT;
|
144
171
|
|
145
172
|
|
146
|
-
#define MKD_EOLN
|
173
|
+
#define MKD_EOLN '\r'
|
147
174
|
|
148
175
|
|
149
176
|
/*
|
@@ -162,6 +189,7 @@ typedef struct document {
|
|
162
189
|
ANCHOR(Line) content; /* uncompiled text, not valid after compile() */
|
163
190
|
Paragraph *code; /* intermediate code generated by compile() */
|
164
191
|
int compiled; /* set after mkd_compile() */
|
192
|
+
int dirty; /* flags or callbacks changed */
|
165
193
|
int html; /* set after (internal) htmlify() */
|
166
194
|
int tabstop; /* for properly expanding tabs (ick) */
|
167
195
|
char *ref_prefix;
|
@@ -181,7 +209,7 @@ struct string_stream {
|
|
181
209
|
|
182
210
|
|
183
211
|
extern int mkd_firstnonblank(Line *);
|
184
|
-
extern int mkd_compile(Document *,
|
212
|
+
extern int mkd_compile(Document *, mkd_flag_t);
|
185
213
|
extern int mkd_document(Document *, char **);
|
186
214
|
extern int mkd_generatehtml(Document *, FILE *);
|
187
215
|
extern int mkd_css(Document *, char **);
|
@@ -190,19 +218,19 @@ extern int mkd_generatecss(Document *, FILE *);
|
|
190
218
|
extern int mkd_xml(char *, int , char **);
|
191
219
|
extern int mkd_generatexml(char *, int, FILE *);
|
192
220
|
extern void mkd_cleanup(Document *);
|
193
|
-
extern int mkd_line(char *, int, char **,
|
194
|
-
extern int mkd_generateline(char *, int, FILE*,
|
221
|
+
extern int mkd_line(char *, int, char **, mkd_flag_t);
|
222
|
+
extern int mkd_generateline(char *, int, FILE*, mkd_flag_t);
|
195
223
|
#define mkd_text mkd_generateline
|
196
224
|
extern void mkd_basename(Document*, char *);
|
197
225
|
|
198
226
|
typedef int (*mkd_sta_function_t)(const int,const void*);
|
199
|
-
extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int,
|
227
|
+
extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int, MMIOT *);
|
200
228
|
|
201
|
-
extern Document *mkd_in(FILE *,
|
202
|
-
extern Document *mkd_string(const char*,int,
|
229
|
+
extern Document *mkd_in(FILE *, mkd_flag_t);
|
230
|
+
extern Document *mkd_string(const char*, int, mkd_flag_t);
|
203
231
|
|
204
|
-
extern Document *gfm_in(FILE *,
|
205
|
-
extern Document *gfm_string(const char*,int,
|
232
|
+
extern Document *gfm_in(FILE *, mkd_flag_t);
|
233
|
+
extern Document *gfm_string(const char*,int, mkd_flag_t);
|
206
234
|
|
207
235
|
extern void mkd_initialize();
|
208
236
|
extern void mkd_shlib_destructor();
|
@@ -220,13 +248,13 @@ extern void ___mkd_initmmiot(MMIOT *, void *);
|
|
220
248
|
extern void ___mkd_freemmiot(MMIOT *, void *);
|
221
249
|
extern void ___mkd_freeLineRange(Line *, Line *);
|
222
250
|
extern void ___mkd_xml(char *, int, FILE *);
|
223
|
-
extern void ___mkd_reparse(char *, int,
|
251
|
+
extern void ___mkd_reparse(char *, int, mkd_flag_t, MMIOT*, char*);
|
224
252
|
extern void ___mkd_emblock(MMIOT*);
|
225
253
|
extern void ___mkd_tidy(Cstring *);
|
226
254
|
|
227
255
|
extern Document *__mkd_new_Document();
|
228
256
|
extern void __mkd_enqueue(Document*, Cstring *);
|
229
|
-
extern void
|
257
|
+
extern void __mkd_trim_line(Line *, int);
|
230
258
|
|
231
259
|
extern int __mkd_io_strget(struct string_stream *);
|
232
260
|
|
data/ext/mkdio.c
CHANGED
@@ -74,13 +74,19 @@ __mkd_enqueue(Document* a, Cstring *line)
|
|
74
74
|
}
|
75
75
|
|
76
76
|
|
77
|
-
/* trim leading
|
77
|
+
/* trim leading characters from a line, then adjust the dle.
|
78
78
|
*/
|
79
79
|
void
|
80
|
-
|
80
|
+
__mkd_trim_line(Line *p, int clip)
|
81
81
|
{
|
82
|
-
|
83
|
-
|
82
|
+
if ( clip >= S(p->text) ) {
|
83
|
+
S(p->text) = p->dle = 0;
|
84
|
+
T(p->text)[0] = 0;
|
85
|
+
}
|
86
|
+
else if ( clip > 0 ) {
|
87
|
+
CLIP(p->text, 0, clip);
|
88
|
+
p->dle = mkd_firstnonblank(p);
|
89
|
+
}
|
84
90
|
}
|
85
91
|
|
86
92
|
|
@@ -89,7 +95,7 @@ __mkd_header_dle(Line *p)
|
|
89
95
|
typedef int (*getc_func)(void*);
|
90
96
|
|
91
97
|
Document *
|
92
|
-
populate(getc_func getc, void* ctx,
|
98
|
+
populate(getc_func getc, void* ctx, mkd_flag_t flags)
|
93
99
|
{
|
94
100
|
Cstring line;
|
95
101
|
Document *a = __mkd_new_Document();
|
@@ -98,7 +104,7 @@ populate(getc_func getc, void* ctx, int flags)
|
|
98
104
|
|
99
105
|
if ( !a ) return 0;
|
100
106
|
|
101
|
-
a->tabstop = (flags
|
107
|
+
a->tabstop = is_flag_set(flags, MKD_TABSTOP) ? 4 : TABSTOP;
|
102
108
|
|
103
109
|
CREATE(line);
|
104
110
|
|
@@ -122,16 +128,16 @@ populate(getc_func getc, void* ctx, int flags)
|
|
122
128
|
|
123
129
|
DELETE(line);
|
124
130
|
|
125
|
-
if ( (pandoc == 3) && !(flags
|
131
|
+
if ( (pandoc == 3) && !(is_flag_set(flags, MKD_NOHEADER) || is_flag_set(flags, MKD_STRICT)) ) {
|
126
132
|
/* the first three lines started with %, so we have a header.
|
127
133
|
* clip the first three lines out of content and hang them
|
128
134
|
* off header.
|
129
135
|
*/
|
130
136
|
Line *headers = T(a->content);
|
131
137
|
|
132
|
-
a->title = headers;
|
133
|
-
a->author= headers->next;
|
134
|
-
a->date = headers->next->next;
|
138
|
+
a->title = headers; __mkd_trim_line(a->title, 1);
|
139
|
+
a->author= headers->next; __mkd_trim_line(a->author, 1);
|
140
|
+
a->date = headers->next->next; __mkd_trim_line(a->date, 1);
|
135
141
|
|
136
142
|
T(a->content) = headers->next->next->next;
|
137
143
|
}
|
@@ -143,7 +149,7 @@ populate(getc_func getc, void* ctx, int flags)
|
|
143
149
|
/* convert a file into a linked list
|
144
150
|
*/
|
145
151
|
Document *
|
146
|
-
mkd_in(FILE *f,
|
152
|
+
mkd_in(FILE *f, mkd_flag_t flags)
|
147
153
|
{
|
148
154
|
return populate((getc_func)fgetc, f, flags & INPUT_MASK);
|
149
155
|
}
|
@@ -165,7 +171,7 @@ __mkd_io_strget(struct string_stream *in)
|
|
165
171
|
/* convert a block of text into a linked list
|
166
172
|
*/
|
167
173
|
Document *
|
168
|
-
mkd_string(const char *buf, int len,
|
174
|
+
mkd_string(const char *buf, int len, mkd_flag_t flags)
|
169
175
|
{
|
170
176
|
struct string_stream about;
|
171
177
|
|
@@ -185,7 +191,7 @@ mkd_generatehtml(Document *p, FILE *output)
|
|
185
191
|
int szdoc;
|
186
192
|
|
187
193
|
DO_OR_DIE( szdoc = mkd_document(p,&doc) );
|
188
|
-
if ( p->ctx->flags
|
194
|
+
if ( is_flag_set(p->ctx->flags, MKD_CDATA) )
|
189
195
|
DO_OR_DIE( mkd_generatexml(doc, szdoc, output) );
|
190
196
|
else if ( fwrite(doc, szdoc, 1, output) != 1 )
|
191
197
|
return EOF;
|
@@ -197,7 +203,7 @@ mkd_generatehtml(Document *p, FILE *output)
|
|
197
203
|
/* convert some markdown text to html
|
198
204
|
*/
|
199
205
|
int
|
200
|
-
markdown(Document *document, FILE *out,
|
206
|
+
markdown(Document *document, FILE *out, mkd_flag_t flags)
|
201
207
|
{
|
202
208
|
if ( mkd_compile(document, flags) ) {
|
203
209
|
mkd_generatehtml(document, out);
|
@@ -208,51 +214,103 @@ markdown(Document *document, FILE *out, int flags)
|
|
208
214
|
}
|
209
215
|
|
210
216
|
|
211
|
-
/*
|
217
|
+
/* anchor_format a string, returning the formatted string in malloc()ed space
|
218
|
+
* MKD_URLENCODEDANCHOR is now perverted to being a html5 anchor
|
219
|
+
*
|
220
|
+
* !labelformat: print all characters
|
221
|
+
* labelformat && h4anchor: prefix nonalpha label with L,
|
222
|
+
* expand all nonalnum, _, ':', '.' to hex
|
223
|
+
* except space which maps to -
|
224
|
+
* labelformat && !h4anchor:expand space to -, other isspace() & '%' to hex
|
212
225
|
*/
|
213
|
-
|
214
|
-
|
215
|
-
void *out, int labelformat,
|
216
|
-
DWORD flags)
|
226
|
+
static char *
|
227
|
+
mkd_anchor_format(char *s, int len, int labelformat, mkd_flag_t flags)
|
217
228
|
{
|
218
|
-
|
229
|
+
char *res;
|
219
230
|
unsigned char c;
|
231
|
+
int i, needed, out = 0;
|
232
|
+
int h4anchor = !is_flag_set(flags, MKD_URLENCODEDANCHOR);
|
233
|
+
static const unsigned char hexchars[] = "0123456789abcdef";
|
220
234
|
|
221
|
-
|
222
|
-
char *line;
|
235
|
+
needed = (labelformat ? (4*len) : len) + 2 /* 'L', trailing null */;
|
223
236
|
|
224
|
-
|
237
|
+
if ( (res = malloc(needed)) == NULL )
|
238
|
+
return NULL;
|
225
239
|
|
226
|
-
if ( !(
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
for ( i=0; i <
|
231
|
-
c =
|
240
|
+
if ( h4anchor && labelformat && !isalpha(s[0]) )
|
241
|
+
res[out++] = 'L';
|
242
|
+
|
243
|
+
|
244
|
+
for ( i=0; i < len ; i++ ) {
|
245
|
+
c = s[i];
|
232
246
|
if ( labelformat ) {
|
233
|
-
if (
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
247
|
+
if ( h4anchor
|
248
|
+
? (isalnum(c) || (c == '_') || (c == ':') || (c == '.' ) )
|
249
|
+
: !(isspace(c) || c == '%') )
|
250
|
+
res[out++] = c;
|
251
|
+
else if ( c == ' ' )
|
252
|
+
res[out++] = '-';
|
253
|
+
else {
|
254
|
+
res[out++] = h4anchor ? '-' : '%';
|
255
|
+
res[out++] = hexchars[c >> 4 & 0xf];
|
256
|
+
res[out++] = hexchars[c & 0xf];
|
257
|
+
if ( h4anchor )
|
258
|
+
res[out++] = '-';
|
239
259
|
}
|
240
|
-
else
|
241
|
-
(*outchar)('.', out);
|
242
260
|
}
|
243
261
|
else
|
244
|
-
|
262
|
+
res[out++] = c;
|
245
263
|
}
|
246
|
-
|
247
|
-
|
248
|
-
|
264
|
+
|
265
|
+
res[out++] = 0;
|
266
|
+
return res;
|
267
|
+
} /* mkd_anchor_format */
|
268
|
+
|
269
|
+
|
270
|
+
/* write out a Cstring, mangled into a form suitable for `<a href=` or `<a id=`
|
271
|
+
*/
|
272
|
+
void
|
273
|
+
mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
|
274
|
+
void *out, int labelformat,
|
275
|
+
MMIOT *f)
|
276
|
+
{
|
277
|
+
char *res;
|
278
|
+
char *line;
|
279
|
+
int size;
|
280
|
+
|
281
|
+
int i;
|
282
|
+
|
283
|
+
size = mkd_line(s, len, &line, IS_LABEL);
|
284
|
+
|
285
|
+
if ( !line )
|
286
|
+
return;
|
287
|
+
|
288
|
+
if ( f->cb->e_anchor )
|
289
|
+
res = (*(f->cb->e_anchor))(line, size, f->cb->e_data);
|
290
|
+
else
|
291
|
+
res = mkd_anchor_format(line, size, labelformat, f->flags);
|
292
|
+
|
293
|
+
free(line);
|
294
|
+
|
295
|
+
if ( !res )
|
296
|
+
return;
|
297
|
+
|
298
|
+
for ( i=0; res[i]; i++ )
|
299
|
+
(*outchar)(res[i], out);
|
300
|
+
|
301
|
+
if ( f->cb->e_anchor ) {
|
302
|
+
if ( f->cb->e_free )
|
303
|
+
(*(f->cb->e_free))(res, f->cb->e_data);
|
304
|
+
}
|
305
|
+
else
|
306
|
+
free(res);
|
249
307
|
}
|
250
308
|
|
251
309
|
|
252
310
|
/* ___mkd_reparse() a line
|
253
311
|
*/
|
254
312
|
static void
|
255
|
-
mkd_parse_line(char *bfr, int size, MMIOT *f,
|
313
|
+
mkd_parse_line(char *bfr, int size, MMIOT *f, mkd_flag_t flags)
|
256
314
|
{
|
257
315
|
___mkd_initmmiot(f, 0);
|
258
316
|
f->flags = flags & USER_FLAGS;
|
@@ -264,7 +322,7 @@ mkd_parse_line(char *bfr, int size, MMIOT *f, int flags)
|
|
264
322
|
/* ___mkd_reparse() a line, returning it in malloc()ed memory
|
265
323
|
*/
|
266
324
|
int
|
267
|
-
mkd_line(char *bfr, int size, char **res,
|
325
|
+
mkd_line(char *bfr, int size, char **res, mkd_flag_t flags)
|
268
326
|
{
|
269
327
|
MMIOT f;
|
270
328
|
int len;
|
@@ -272,15 +330,14 @@ mkd_line(char *bfr, int size, char **res, DWORD flags)
|
|
272
330
|
mkd_parse_line(bfr, size, &f, flags);
|
273
331
|
|
274
332
|
if ( len = S(f.out) ) {
|
275
|
-
/* kludge alert; we know that T(f.out) is malloced memory,
|
276
|
-
* so we can just steal it away. This is awful -- there
|
277
|
-
* should be an opaque method that transparently moves
|
278
|
-
* the pointer out of the embedded Cstring.
|
279
|
-
*/
|
280
333
|
EXPAND(f.out) = 0;
|
281
|
-
|
282
|
-
|
283
|
-
|
334
|
+
/* strdup() doesn't use amalloc(), so in an amalloc()ed
|
335
|
+
* build this copies the string safely out of our memory
|
336
|
+
* paranoia arena. In a non-amalloc world, it's a spurious
|
337
|
+
* memory allocation, but it avoids unintentional hilarity
|
338
|
+
* with amalloc()
|
339
|
+
*/
|
340
|
+
*res = strdup(T(f.out));
|
284
341
|
}
|
285
342
|
else {
|
286
343
|
*res = 0;
|
@@ -294,13 +351,13 @@ mkd_line(char *bfr, int size, char **res, DWORD flags)
|
|
294
351
|
/* ___mkd_reparse() a line, writing it to a FILE
|
295
352
|
*/
|
296
353
|
int
|
297
|
-
mkd_generateline(char *bfr, int size, FILE *output,
|
354
|
+
mkd_generateline(char *bfr, int size, FILE *output, mkd_flag_t flags)
|
298
355
|
{
|
299
356
|
MMIOT f;
|
300
357
|
int status;
|
301
358
|
|
302
359
|
mkd_parse_line(bfr, size, &f, flags);
|
303
|
-
if ( flags
|
360
|
+
if ( is_flag_set(flags, MKD_CDATA) )
|
304
361
|
status = mkd_generatexml(T(f.out), S(f.out), output) != EOF;
|
305
362
|
else
|
306
363
|
status = fwrite(T(f.out), S(f.out), 1, output) == S(f.out);
|
@@ -315,8 +372,11 @@ mkd_generateline(char *bfr, int size, FILE *output, DWORD flags)
|
|
315
372
|
void
|
316
373
|
mkd_e_url(Document *f, mkd_callback_t edit)
|
317
374
|
{
|
318
|
-
if ( f )
|
375
|
+
if ( f ) {
|
376
|
+
if ( f->cb.e_url != edit )
|
377
|
+
f->dirty = 1;
|
319
378
|
f->cb.e_url = edit;
|
379
|
+
}
|
320
380
|
}
|
321
381
|
|
322
382
|
|
@@ -325,8 +385,24 @@ mkd_e_url(Document *f, mkd_callback_t edit)
|
|
325
385
|
void
|
326
386
|
mkd_e_flags(Document *f, mkd_callback_t edit)
|
327
387
|
{
|
328
|
-
if ( f )
|
388
|
+
if ( f ) {
|
389
|
+
if ( f->cb.e_flags != edit )
|
390
|
+
f->dirty = 1;
|
329
391
|
f->cb.e_flags = edit;
|
392
|
+
}
|
393
|
+
}
|
394
|
+
|
395
|
+
|
396
|
+
/* set the anchor formatter
|
397
|
+
*/
|
398
|
+
void
|
399
|
+
mkd_e_anchor(Document *f, mkd_callback_t format)
|
400
|
+
{
|
401
|
+
if ( f ) {
|
402
|
+
if ( f->cb.e_anchor != format )
|
403
|
+
f->dirty = 1;
|
404
|
+
f->cb.e_anchor = format;
|
405
|
+
}
|
330
406
|
}
|
331
407
|
|
332
408
|
|
@@ -335,8 +411,11 @@ mkd_e_flags(Document *f, mkd_callback_t edit)
|
|
335
411
|
void
|
336
412
|
mkd_e_free(Document *f, mkd_free_t dealloc)
|
337
413
|
{
|
338
|
-
if ( f )
|
414
|
+
if ( f ) {
|
415
|
+
if ( f->cb.e_free != dealloc )
|
416
|
+
f->dirty = 1;
|
339
417
|
f->cb.e_free = dealloc;
|
418
|
+
}
|
340
419
|
}
|
341
420
|
|
342
421
|
|
@@ -345,8 +424,23 @@ mkd_e_free(Document *f, mkd_free_t dealloc)
|
|
345
424
|
void
|
346
425
|
mkd_e_data(Document *f, void *data)
|
347
426
|
{
|
348
|
-
if ( f )
|
427
|
+
if ( f ) {
|
428
|
+
if ( f->cb.e_data != data )
|
429
|
+
f->dirty = 1;
|
349
430
|
f->cb.e_data = data;
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
|
435
|
+
/* set the code block display callback
|
436
|
+
*/
|
437
|
+
void
|
438
|
+
mkd_e_code_format(Document *f, mkd_callback_t codefmt)
|
439
|
+
{
|
440
|
+
if ( f && (f->cb.e_codefmt != codefmt) ) {
|
441
|
+
f->dirty = 1;
|
442
|
+
f->cb.e_codefmt = codefmt;
|
443
|
+
}
|
350
444
|
}
|
351
445
|
|
352
446
|
|
@@ -355,6 +449,9 @@ mkd_e_data(Document *f, void *data)
|
|
355
449
|
void
|
356
450
|
mkd_ref_prefix(Document *f, char *data)
|
357
451
|
{
|
358
|
-
if ( f )
|
452
|
+
if ( f ) {
|
453
|
+
if ( f->ref_prefix != data )
|
454
|
+
f->dirty = 1;
|
359
455
|
f->ref_prefix = data;
|
456
|
+
}
|
360
457
|
}
|
data/ext/mkdio.h
CHANGED
@@ -3,9 +3,11 @@
|
|
3
3
|
|
4
4
|
#include <stdio.h>
|
5
5
|
|
6
|
+
#include <inttypes.h>
|
7
|
+
|
6
8
|
typedef void MMIOT;
|
7
9
|
|
8
|
-
typedef
|
10
|
+
typedef uint32_t mkd_flag_t;
|
9
11
|
|
10
12
|
/* line builder for markdown()
|
11
13
|
*/
|
@@ -30,12 +32,10 @@ void mkd_cleanup(MMIOT*);
|
|
30
32
|
|
31
33
|
/* markup functions
|
32
34
|
*/
|
33
|
-
int mkd_dump(MMIOT*, FILE*,
|
35
|
+
int mkd_dump(MMIOT*, FILE*, mkd_flag_t, char*);
|
34
36
|
int markdown(MMIOT*, FILE*, mkd_flag_t);
|
35
37
|
int mkd_line(char *, int, char **, mkd_flag_t);
|
36
|
-
|
37
|
-
void mkd_string_to_anchor(char *, int, mkd_sta_function_t, void*, int);
|
38
|
-
int mkd_xhtmlpage(MMIOT*,int,FILE*);
|
38
|
+
int mkd_xhtmlpage(MMIOT*,mkd_flag_t,FILE*);
|
39
39
|
|
40
40
|
/* header block access
|
41
41
|
*/
|
@@ -67,6 +67,8 @@ typedef void (*mkd_free_t)(char*, void*);
|
|
67
67
|
|
68
68
|
void mkd_e_url(void *, mkd_callback_t);
|
69
69
|
void mkd_e_flags(void *, mkd_callback_t);
|
70
|
+
void mkd_e_anchor(void *, mkd_callback_t);
|
71
|
+
void mkd_e_code_format(void*, mkd_callback_t);
|
70
72
|
void mkd_e_free(void *, mkd_free_t );
|
71
73
|
void mkd_e_data(void *, void *);
|
72
74
|
|
@@ -112,6 +114,8 @@ void mkd_ref_prefix(MMIOT*, char*);
|
|
112
114
|
#define MKD_IDANCHOR 0x04000000 /* use id= anchors for TOC links */
|
113
115
|
#define MKD_GITHUBTAGS 0x08000000 /* allow dash and underscore in element names */
|
114
116
|
#define MKD_URLENCODEDANCHOR 0x10000000 /* urlencode non-identifier chars instead of replacing with dots */
|
117
|
+
#define MKD_LATEX 0x40000000 /* handle embedded LaTeX escapes */
|
118
|
+
#define MKD_EXPLICITLIST 0x80000000 /* don't combine numbered/bulletted lists */
|
115
119
|
|
116
120
|
#define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
|
117
121
|
|
data/ext/mktags.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#include <stdio.h>
|
4
4
|
|
5
5
|
#define __WITHOUT_AMALLOC 1
|
6
|
+
#include "config.h"
|
6
7
|
#include "cstring.h"
|
7
8
|
#include "tags.h"
|
8
9
|
|
@@ -41,6 +42,7 @@ typedef int (*stfu)(const void*,const void*);
|
|
41
42
|
|
42
43
|
/* load in the standard collection of html tags that markdown supports
|
43
44
|
*/
|
45
|
+
int
|
44
46
|
main()
|
45
47
|
{
|
46
48
|
int i;
|
@@ -65,6 +67,7 @@ main()
|
|
65
67
|
KW("H6");
|
66
68
|
KW("LISTING");
|
67
69
|
KW("NOBR");
|
70
|
+
KW("FORM");
|
68
71
|
KW("UL");
|
69
72
|
KW("P");
|
70
73
|
KW("OL");
|
data/ext/notspecial.c
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
/*
|
2
|
+
* check a filename to see if it's a (fifo|character special|socket) object
|
3
|
+
* (if a stat() function doesn't exist, we can't stat so we'll just return
|
4
|
+
* true no matter what.)
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include "config.h"
|
8
|
+
|
9
|
+
#if HAVE_STAT && HAS_ISCHR && HAS_ISFIFO && HAS_ISSOCK
|
10
|
+
#include <sys/stat.h>
|
11
|
+
|
12
|
+
int
|
13
|
+
notspecial(char *file)
|
14
|
+
{
|
15
|
+
struct stat info;
|
16
|
+
|
17
|
+
if ( stat(file, &info) != 0 )
|
18
|
+
return 1;
|
19
|
+
|
20
|
+
return !( S_ISCHR(info.st_mode) || S_ISFIFO(info.st_mode) || S_ISSOCK(info.st_mode) );
|
21
|
+
}
|
22
|
+
#else
|
23
|
+
int
|
24
|
+
notspecial(char *file)
|
25
|
+
{
|
26
|
+
return 1;
|
27
|
+
}
|
28
|
+
#endif
|
29
|
+
|
30
|
+
|
31
|
+
#if DEBUG
|
32
|
+
|
33
|
+
#include <stdio.h>
|
34
|
+
|
35
|
+
int
|
36
|
+
main(argc, argv)
|
37
|
+
char **argv;
|
38
|
+
{
|
39
|
+
int i;
|
40
|
+
|
41
|
+
for ( i=1; i < argc; i++ )
|
42
|
+
printf("%s is %sspecial\n", argv[i], notspecial(argv[i]) ? "not " : "");
|
43
|
+
}
|
44
|
+
#endif
|