rdiscount 2.2.0.1 → 2.2.7
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.
- 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/gethopt.c
ADDED
@@ -0,0 +1,286 @@
|
|
1
|
+
/*
|
2
|
+
* gehopt; options processing with both single-character and whole-word
|
3
|
+
* options both introduced with -
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <string.h>
|
8
|
+
|
9
|
+
#include "gethopt.h"
|
10
|
+
|
11
|
+
|
12
|
+
void
|
13
|
+
hoptset(ctx, argc, argv)
|
14
|
+
struct h_context *ctx;
|
15
|
+
int argc;
|
16
|
+
char **argv;
|
17
|
+
{
|
18
|
+
memset(ctx, 0, sizeof *ctx);
|
19
|
+
ctx->argc = argc;
|
20
|
+
ctx->argv = argv;
|
21
|
+
ctx->optind = 1;
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
char *
|
26
|
+
hoptarg(ctx)
|
27
|
+
struct h_context *ctx;
|
28
|
+
{
|
29
|
+
return ctx->optarg;
|
30
|
+
}
|
31
|
+
|
32
|
+
int
|
33
|
+
hoptind(ctx)
|
34
|
+
struct h_context *ctx;
|
35
|
+
{
|
36
|
+
return ctx->optind;
|
37
|
+
}
|
38
|
+
|
39
|
+
char
|
40
|
+
hoptopt(ctx)
|
41
|
+
struct h_context *ctx;
|
42
|
+
{
|
43
|
+
return ctx->optopt;
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
int
|
48
|
+
hopterr(ctx,val)
|
49
|
+
struct h_context *ctx;
|
50
|
+
{
|
51
|
+
int old = ctx->opterr;
|
52
|
+
|
53
|
+
ctx->opterr = !!val;
|
54
|
+
return old;
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
struct h_opt *
|
59
|
+
gethopt(ctx, opts, nropts)
|
60
|
+
struct h_context *ctx;
|
61
|
+
struct h_opt *opts;
|
62
|
+
int nropts;
|
63
|
+
{
|
64
|
+
int i;
|
65
|
+
int dashes;
|
66
|
+
|
67
|
+
|
68
|
+
if ( (ctx == 0) || ctx->optend || (ctx->optind >= ctx->argc) )
|
69
|
+
return 0;
|
70
|
+
|
71
|
+
ctx->optarg = 0;
|
72
|
+
ctx->optopt = 0;
|
73
|
+
|
74
|
+
if ( ctx->optchar == 0) {
|
75
|
+
/* check for leading -
|
76
|
+
*/
|
77
|
+
if ( ctx->argv[ctx->optind][0] != '-' ) {
|
78
|
+
/* out of arguments */
|
79
|
+
ctx->optend = 1;
|
80
|
+
return 0;
|
81
|
+
}
|
82
|
+
|
83
|
+
if ( ctx->argv[ctx->optind][1] == 0
|
84
|
+
|| strcmp(ctx->argv[ctx->optind], "--") == 0 ) {
|
85
|
+
/* option list finishes with - or -- token
|
86
|
+
*/
|
87
|
+
ctx->optend = 1;
|
88
|
+
ctx->optind++;
|
89
|
+
return 0;
|
90
|
+
}
|
91
|
+
|
92
|
+
dashes = 1;
|
93
|
+
if ( ctx->argv[ctx->optind][dashes] == '-' ) {
|
94
|
+
/* support GNU-style long option double-dash prefix
|
95
|
+
* (if gethopt is passed an unknown option with a double-dash
|
96
|
+
* prefix, it won't match a word and then the second dash
|
97
|
+
* will be scanned as if it was a regular old single-character
|
98
|
+
* option.)
|
99
|
+
*/
|
100
|
+
dashes = 2;
|
101
|
+
}
|
102
|
+
|
103
|
+
for ( i=0; i < nropts; i++ ) {
|
104
|
+
if ( ! opts[i].optword )
|
105
|
+
continue;
|
106
|
+
|
107
|
+
if (strcmp(opts[i].optword, dashes+(ctx->argv[ctx->optind]) ) == 0 ) {
|
108
|
+
if ( opts[i].opthasarg ) {
|
109
|
+
if ( ctx->argc > ctx->optind ) {
|
110
|
+
ctx->optarg = ctx->argv[ctx->optind+1];
|
111
|
+
ctx->optind += 2;
|
112
|
+
}
|
113
|
+
else {
|
114
|
+
/* word argument with required arg at end of
|
115
|
+
*command line
|
116
|
+
*/
|
117
|
+
if ( ctx->opterr )
|
118
|
+
fprintf(stderr,
|
119
|
+
"%s: option requires an argument -- %s\n",
|
120
|
+
ctx->argv[0], opts[i].optword);
|
121
|
+
ctx->optind ++;
|
122
|
+
return HOPTERR;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
else {
|
126
|
+
ctx->optind ++;
|
127
|
+
}
|
128
|
+
return &opts[i];
|
129
|
+
}
|
130
|
+
}
|
131
|
+
ctx->optchar = 1;
|
132
|
+
}
|
133
|
+
|
134
|
+
ctx->optopt = ctx->argv[ctx->optind][ctx->optchar++];
|
135
|
+
|
136
|
+
if ( !ctx->optopt ) {
|
137
|
+
/* fell off the end of this argument */
|
138
|
+
ctx->optind ++;
|
139
|
+
ctx->optchar = 0;
|
140
|
+
return gethopt(ctx, opts, nropts);
|
141
|
+
}
|
142
|
+
|
143
|
+
for ( i=0; i<nropts; i++ ) {
|
144
|
+
if ( opts[i].optchar == ctx->optopt ) {
|
145
|
+
/* found a single-char option!
|
146
|
+
*/
|
147
|
+
if ( opts[i].opthasarg ) {
|
148
|
+
if ( ctx->argv[ctx->optind][ctx->optchar] ) {
|
149
|
+
/* argument immediately follows this options (-Oc)
|
150
|
+
*/
|
151
|
+
ctx->optarg = &ctx->argv[ctx->optind][ctx->optchar];
|
152
|
+
ctx->optind ++;
|
153
|
+
ctx->optchar = 0;
|
154
|
+
}
|
155
|
+
else if ( ctx->optind < ctx->argc-1 ) {
|
156
|
+
/* argument is next arg (-O c)
|
157
|
+
*/
|
158
|
+
ctx->optarg = &ctx->argv[ctx->optind+1][0];
|
159
|
+
ctx->optind += 2;
|
160
|
+
ctx->optchar = 0;
|
161
|
+
}
|
162
|
+
else {
|
163
|
+
/* end of arg string (-O); set optarg to null, return
|
164
|
+
* (should it opterr on me?)
|
165
|
+
*/
|
166
|
+
ctx->optarg = 0;
|
167
|
+
ctx->optind ++;
|
168
|
+
ctx->optchar = 0;
|
169
|
+
if ( ctx->opterr )
|
170
|
+
fprintf(stderr,
|
171
|
+
"%s: option requires an argument -- %c\n",
|
172
|
+
ctx->argv[0], opts[i].optchar);
|
173
|
+
return HOPTERR;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
else {
|
177
|
+
if ( !ctx->argv[ctx->optind][ctx->optchar] ) {
|
178
|
+
ctx->optind ++;
|
179
|
+
ctx->optchar = 0;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
return &opts[i];
|
183
|
+
}
|
184
|
+
}
|
185
|
+
if ( ctx->opterr )
|
186
|
+
fprintf(stderr, "%s: illegal option -- %c\n", ctx->argv[0], ctx->optopt);
|
187
|
+
return HOPTERR;
|
188
|
+
}
|
189
|
+
|
190
|
+
|
191
|
+
void
|
192
|
+
hoptusage(char *pgm, struct h_opt opts[], int nropts, char *arguments)
|
193
|
+
{
|
194
|
+
int i;
|
195
|
+
int optcount;
|
196
|
+
|
197
|
+
fprintf(stderr, "usage: %s", pgm);
|
198
|
+
|
199
|
+
/* print out the options that don't have flags first */
|
200
|
+
|
201
|
+
for ( optcount=i=0; i < nropts; i++ ) {
|
202
|
+
if ( opts[i].optchar && !opts[i].opthasarg) {
|
203
|
+
if (optcount == 0 )
|
204
|
+
fputs(" [-", stderr);
|
205
|
+
fputc(opts[i].optchar, stderr);
|
206
|
+
optcount++;
|
207
|
+
}
|
208
|
+
}
|
209
|
+
if ( optcount )
|
210
|
+
fputc(']', stderr);
|
211
|
+
|
212
|
+
/* print out the options WITH flags */
|
213
|
+
for ( i = 0; i < nropts; i++ )
|
214
|
+
if ( opts[i].optchar && opts[i].opthasarg)
|
215
|
+
fprintf(stderr, " [-%c %s]", opts[i].optchar, opts[i].opthasarg);
|
216
|
+
|
217
|
+
/* print out the long options */
|
218
|
+
for ( i = 0; i < nropts; i++ )
|
219
|
+
if ( opts[i].optword ) {
|
220
|
+
fprintf(stderr, " [-%s", opts[i].optword);
|
221
|
+
if ( opts[i].opthasarg )
|
222
|
+
fprintf(stderr, " %s", opts[i].opthasarg);
|
223
|
+
fputc(']', stderr);
|
224
|
+
}
|
225
|
+
|
226
|
+
/* print out the arguments string, if any */
|
227
|
+
|
228
|
+
if ( arguments )
|
229
|
+
fprintf(stderr, " %s", arguments);
|
230
|
+
|
231
|
+
/* and we're done */
|
232
|
+
fputc('\n', stderr);
|
233
|
+
}
|
234
|
+
|
235
|
+
|
236
|
+
#if DEBUG
|
237
|
+
struct h_opt opts[] = {
|
238
|
+
{ 0, "css", 0, 1, "css file" },
|
239
|
+
{ 1, "header", 0, 1, "header file" },
|
240
|
+
{ 2, 0, 'a', 0, "option a (no arg)" },
|
241
|
+
{ 3, 0, 'b', 1, "option B (with arg)" },
|
242
|
+
{ 4, "help", '?', 0, "help message" },
|
243
|
+
} ;
|
244
|
+
|
245
|
+
#define NROPT (sizeof opts/sizeof opts[0])
|
246
|
+
|
247
|
+
|
248
|
+
int
|
249
|
+
main(argc, argv)
|
250
|
+
char **argv;
|
251
|
+
{
|
252
|
+
struct h_opt *ret;
|
253
|
+
struct h_context ctx;
|
254
|
+
int i;
|
255
|
+
|
256
|
+
|
257
|
+
hoptset(&ctx, argc, argv);
|
258
|
+
hopterr(&ctx, 1);
|
259
|
+
|
260
|
+
while (( ret = gethopt(&ctx, opts, NROPT) )) {
|
261
|
+
|
262
|
+
if ( ret != HOPTERR ) {
|
263
|
+
if ( ret->optword )
|
264
|
+
printf("%s", ret->optword);
|
265
|
+
else
|
266
|
+
printf("%c", ret->optchar);
|
267
|
+
|
268
|
+
if ( ret->opthasarg ) {
|
269
|
+
if ( hoptarg(&ctx) )
|
270
|
+
printf(" with argument \"%s\"", hoptarg(&ctx));
|
271
|
+
else
|
272
|
+
printf(" with no argument?");
|
273
|
+
}
|
274
|
+
printf(" (%s)\n", ret->optdesc);
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
argc -= hoptind(&ctx);
|
279
|
+
argv += hoptind(&ctx);
|
280
|
+
|
281
|
+
for ( i=0; i < argc; i++ )
|
282
|
+
printf("%d: %s\n", i, argv[i]);
|
283
|
+
return 0;
|
284
|
+
}
|
285
|
+
|
286
|
+
#endif /*DEBUG*/
|
data/ext/gethopt.h
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
/*
|
2
|
+
* gethopt; options processing with both single-character and whole-work
|
3
|
+
* options both introduced with -
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef __GETHOPT_D
|
7
|
+
#define __GETHOPT_D
|
8
|
+
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <string.h>
|
11
|
+
|
12
|
+
|
13
|
+
struct h_opt {
|
14
|
+
int option;
|
15
|
+
char *optword;
|
16
|
+
char optchar;
|
17
|
+
char *opthasarg;
|
18
|
+
char *optdesc;
|
19
|
+
} ;
|
20
|
+
|
21
|
+
#define HOPTERR ((struct h_opt*)-1)
|
22
|
+
|
23
|
+
struct h_context {
|
24
|
+
char **argv;
|
25
|
+
int argc;
|
26
|
+
int optchar;
|
27
|
+
int optind;
|
28
|
+
char *optarg;
|
29
|
+
char optopt;
|
30
|
+
int opterr:1;
|
31
|
+
int optend:1;
|
32
|
+
} ;
|
33
|
+
|
34
|
+
extern char *hoptarg(struct h_context *);
|
35
|
+
extern int hoptind(struct h_context *);
|
36
|
+
extern char hoptopt(struct h_context *);
|
37
|
+
extern void hoptset(struct h_context *, int, char **);
|
38
|
+
extern int hopterr(struct h_context *, int);
|
39
|
+
extern struct h_opt *gethopt(struct h_context *, struct h_opt*, int);
|
40
|
+
|
41
|
+
extern void hoptusage(char *, struct h_opt*, int, char *);
|
42
|
+
|
43
|
+
#endif/*__GETHOPT_D*/
|
data/ext/github_flavoured.c
CHANGED
@@ -30,7 +30,7 @@ gfm_populate(getc_func getc, void* ctx, int flags)
|
|
30
30
|
|
31
31
|
if ( !a ) return 0;
|
32
32
|
|
33
|
-
a->tabstop = (flags
|
33
|
+
a->tabstop = is_flag_set(flags, MKD_TABSTOP) ? 4 : TABSTOP;
|
34
34
|
|
35
35
|
CREATE(line);
|
36
36
|
|
@@ -59,16 +59,17 @@ gfm_populate(getc_func getc, void* ctx, int flags)
|
|
59
59
|
|
60
60
|
DELETE(line);
|
61
61
|
|
62
|
-
if ( (pandoc == 3) && !(flags
|
62
|
+
if ( (pandoc == 3) && !(is_flag_set(flags, MKD_NOHEADER)
|
63
|
+
|| is_flag_set(flags, MKD_STRICT)) ) {
|
63
64
|
/* the first three lines started with %, so we have a header.
|
64
65
|
* clip the first three lines out of content and hang them
|
65
66
|
* off header.
|
66
67
|
*/
|
67
68
|
Line *headers = T(a->content);
|
68
69
|
|
69
|
-
a->title = headers;
|
70
|
-
a->author= headers->next;
|
71
|
-
a->date = headers->next->next;
|
70
|
+
a->title = headers; __mkd_trim_line(a->title, 1);
|
71
|
+
a->author= headers->next; __mkd_trim_line(a->author, 1);
|
72
|
+
a->date = headers->next->next; __mkd_trim_line(a->date, 1);
|
72
73
|
|
73
74
|
T(a->content) = headers->next->next->next;
|
74
75
|
}
|
@@ -80,7 +81,7 @@ gfm_populate(getc_func getc, void* ctx, int flags)
|
|
80
81
|
/* convert a block of text into a linked list
|
81
82
|
*/
|
82
83
|
Document *
|
83
|
-
gfm_string(const char *buf, int len,
|
84
|
+
gfm_string(const char *buf, int len, mkd_flag_t flags)
|
84
85
|
{
|
85
86
|
struct string_stream about;
|
86
87
|
|
@@ -94,7 +95,7 @@ gfm_string(const char *buf, int len, DWORD flags)
|
|
94
95
|
/* convert a file into a linked list
|
95
96
|
*/
|
96
97
|
Document *
|
97
|
-
gfm_in(FILE *f,
|
98
|
+
gfm_in(FILE *f, mkd_flag_t flags)
|
98
99
|
{
|
99
100
|
return gfm_populate((getc_func)fgetc, f, flags & INPUT_MASK);
|
100
101
|
}
|
data/ext/h1title.c
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include "markdown.h"
|
3
|
+
|
4
|
+
static Paragraph *
|
5
|
+
mkd_h1(Paragraph *p)
|
6
|
+
{
|
7
|
+
Paragraph *found;
|
8
|
+
|
9
|
+
while ( p ) {
|
10
|
+
if ( p->typ == HDR && p->hnumber == 1 )
|
11
|
+
return p;
|
12
|
+
if ( p->down && (found = mkd_h1(p->down)) )
|
13
|
+
return found;
|
14
|
+
p = p->next;
|
15
|
+
}
|
16
|
+
return 0;
|
17
|
+
}
|
18
|
+
|
19
|
+
char *
|
20
|
+
mkd_h1_title(Document *doc, int flags)
|
21
|
+
{
|
22
|
+
Paragraph *title;
|
23
|
+
|
24
|
+
if (doc && (title = mkd_h1(doc->code)) ) {
|
25
|
+
char *generated;
|
26
|
+
int size;
|
27
|
+
|
28
|
+
/* assert that a H1 header is one line long, so that's
|
29
|
+
* the only thing needed
|
30
|
+
*/
|
31
|
+
size = mkd_line(T(title->text->text),
|
32
|
+
S(title->text->text), &generated, flags|MKD_TAGTEXT);
|
33
|
+
if ( size ) return generated;
|
34
|
+
}
|
35
|
+
return 0;
|
36
|
+
}
|
data/ext/html5.c
CHANGED