rdiscount 1.3.1.1 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +6 -3
- data/ext/Csio.c +49 -0
- data/ext/cstring.h +5 -0
- data/ext/extconf.rb +0 -6
- data/ext/generate.c +33 -23
- data/ext/markdown.c +18 -7
- data/ext/markdown.h +4 -0
- data/ext/mkdio.h +1 -0
- data/ext/rdiscount.c +24 -11
- data/ext/toc.c +38 -14
- data/lib/rdiscount.rb +1 -1
- data/rdiscount.gemspec +3 -4
- metadata +3 -4
- data/ext/rbstrio.c +0 -48
- data/ext/rbstrio.h +0 -4
data/Rakefile
CHANGED
@@ -99,14 +99,17 @@ end
|
|
99
99
|
desc 'Run conformance tests (MARKDOWN_TEST_VER=1.0)'
|
100
100
|
task 'test:conformance' => [:build] do |t|
|
101
101
|
script = "#{pwd}/bin/rdiscount"
|
102
|
-
test_version = ENV['MARKDOWN_TEST_VER'] || '1.0'
|
102
|
+
test_version = ENV['MARKDOWN_TEST_VER'] || '1.0.3'
|
103
103
|
chdir("test/MarkdownTest_#{test_version}") do
|
104
104
|
sh "./MarkdownTest.pl --script='#{script}' --tidy"
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
108
|
desc 'Run version 1.0 conformance suite'
|
109
|
-
task 'test:conformance:1.0' =>
|
109
|
+
task 'test:conformance:1.0' => [:build] do |t|
|
110
|
+
ENV['MARKDOWN_TEST_VER'] = '1.0'
|
111
|
+
Rake::Task['test:conformance'].invoke
|
112
|
+
end
|
110
113
|
|
111
114
|
desc 'Run 1.0.3 conformance suite'
|
112
115
|
task 'test:conformance:1.0.3' => [:build] do |t|
|
@@ -172,7 +175,7 @@ task :gather => 'discount' do |t|
|
|
172
175
|
files =
|
173
176
|
FileList[
|
174
177
|
'discount/{markdown,mkdio,amalloc,cstring}.h',
|
175
|
-
'discount/{markdown,docheader,dumptree,generate,mkdio,resource}.c'
|
178
|
+
'discount/{markdown,docheader,dumptree,generate,mkdio,resource,toc,Csio}.c'
|
176
179
|
]
|
177
180
|
cp files, 'ext/',
|
178
181
|
:preserve => true,
|
data/ext/Csio.c
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include <stdarg.h>
|
4
|
+
#include "cstring.h"
|
5
|
+
#include "markdown.h"
|
6
|
+
#include "amalloc.h"
|
7
|
+
|
8
|
+
|
9
|
+
/* putc() into a cstring
|
10
|
+
*/
|
11
|
+
void
|
12
|
+
Csputc(int c, Cstring *iot)
|
13
|
+
{
|
14
|
+
EXPAND(*iot) = c;
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
/* printf() into a cstring
|
19
|
+
*/
|
20
|
+
int
|
21
|
+
Csprintf(Cstring *iot, char *fmt, ...)
|
22
|
+
{
|
23
|
+
va_list ptr;
|
24
|
+
int siz=100;
|
25
|
+
|
26
|
+
do {
|
27
|
+
RESERVE(*iot, siz);
|
28
|
+
va_start(ptr, fmt);
|
29
|
+
siz = vsnprintf(T(*iot)+S(*iot), ALL(*iot)-S(*iot), fmt, ptr);
|
30
|
+
va_end(ptr);
|
31
|
+
} while ( siz > (ALL(*iot)-S(*iot)) );
|
32
|
+
|
33
|
+
S(*iot) += siz;
|
34
|
+
return siz;
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
/* reparse() into a cstring
|
39
|
+
*/
|
40
|
+
void
|
41
|
+
Csreparse(Cstring *iot, char *buf, int size, int flags)
|
42
|
+
{
|
43
|
+
MMIOT f;
|
44
|
+
___mkd_initmmiot(&f, 0);
|
45
|
+
___mkd_reparse(buf, size, 0, &f);
|
46
|
+
___mkd_emblock(&f);
|
47
|
+
SUFFIX(*iot, T(f.out), S(f.out));
|
48
|
+
___mkd_freemmiot(&f, 0);
|
49
|
+
}
|
data/ext/cstring.h
CHANGED
@@ -50,6 +50,7 @@
|
|
50
50
|
*/
|
51
51
|
#define T(x) (x).text
|
52
52
|
#define S(x) (x).size
|
53
|
+
#define ALL(x) (x).alloc
|
53
54
|
|
54
55
|
/* abstract anchor type that defines a list base
|
55
56
|
* with a function that attaches an element to
|
@@ -65,4 +66,8 @@
|
|
65
66
|
|
66
67
|
typedef STRING(char) Cstring;
|
67
68
|
|
69
|
+
extern void Csputc(int, Cstring *);
|
70
|
+
extern int Csprintf(Cstring *, char *, ...);
|
71
|
+
extern void Csreparse(Cstring *, char *, int, int);
|
72
|
+
|
68
73
|
#endif/*_CSTRING_D*/
|
data/ext/extconf.rb
CHANGED
@@ -4,11 +4,5 @@ dir_config('rdiscount')
|
|
4
4
|
|
5
5
|
HAVE_RANDOM = have_func('random')
|
6
6
|
HAVE_SRANDOM = have_func('srandom')
|
7
|
-
HAVE_FUNOPEN = have_func('funopen')
|
8
|
-
HAVE_FOPENCOOKIE = have_func('fopencookie')
|
9
|
-
|
10
|
-
unless HAVE_FUNOPEN || HAVE_FOPENCOOKIE
|
11
|
-
fail "No funopen or fopencookie support available."
|
12
|
-
end
|
13
7
|
|
14
8
|
create_makefile('rdiscount')
|
data/ext/generate.c
CHANGED
@@ -277,10 +277,10 @@ emmatch(MMIOT *f, int go)
|
|
277
277
|
}
|
278
278
|
|
279
279
|
|
280
|
-
/*
|
280
|
+
/* ___mkd_emblock()
|
281
281
|
*/
|
282
|
-
|
283
|
-
|
282
|
+
void
|
283
|
+
___mkd_emblock(MMIOT *f)
|
284
284
|
{
|
285
285
|
int i;
|
286
286
|
block *p;
|
@@ -301,8 +301,8 @@ emblock(MMIOT *f)
|
|
301
301
|
|
302
302
|
/* generate html from a markup fragment
|
303
303
|
*/
|
304
|
-
|
305
|
-
|
304
|
+
void
|
305
|
+
___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
|
306
306
|
{
|
307
307
|
MMIOT sub;
|
308
308
|
|
@@ -316,7 +316,7 @@ reparse(char *bfr, int size, int flags, MMIOT *f)
|
|
316
316
|
S(sub.in)--;
|
317
317
|
|
318
318
|
text(&sub);
|
319
|
-
|
319
|
+
___mkd_emblock(&sub);
|
320
320
|
|
321
321
|
Qwrite(T(sub.out), S(sub.out), f);
|
322
322
|
|
@@ -497,12 +497,14 @@ linkykey(int image, Footnote *val, MMIOT *f)
|
|
497
497
|
{
|
498
498
|
Footnote *ret;
|
499
499
|
Cstring mylabel;
|
500
|
+
int here;
|
500
501
|
|
501
502
|
memset(val, 0, sizeof *val);
|
502
503
|
|
503
504
|
if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
|
504
505
|
return 0;
|
505
506
|
|
507
|
+
here = mmiottell(f);
|
506
508
|
eatspace(f);
|
507
509
|
switch ( pull(f) ) {
|
508
510
|
case '(':
|
@@ -517,14 +519,21 @@ linkykey(int image, Footnote *val, MMIOT *f)
|
|
517
519
|
|
518
520
|
return peek(f,0) == ')';
|
519
521
|
|
520
|
-
case '[':
|
522
|
+
case '[': /* footnote links /as defined in the standard/ */
|
523
|
+
default: /* footnote links -- undocumented extension */
|
521
524
|
/* footnote link */
|
522
525
|
mylabel = val->tag;
|
523
|
-
if ( (
|
524
|
-
|
526
|
+
if ( peek(f,0) == '[' ) {
|
527
|
+
if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
|
528
|
+
return 0;
|
525
529
|
|
526
|
-
|
527
|
-
|
530
|
+
if ( !S(val->tag) )
|
531
|
+
val->tag = mylabel;
|
532
|
+
}
|
533
|
+
else if ( f->flags & MKD_1_COMPAT )
|
534
|
+
break;
|
535
|
+
else
|
536
|
+
mmiotseek(f,here);
|
528
537
|
|
529
538
|
ret = bsearch(val, T(*f->footnotes), S(*f->footnotes),
|
530
539
|
sizeof *val, (stfu)__mkd_footsort);
|
@@ -633,12 +642,12 @@ linkylinky(int image, MMIOT *f)
|
|
633
642
|
|
634
643
|
if ( S(link.title) ) {
|
635
644
|
Qstring(" title=\"", f);
|
636
|
-
|
645
|
+
___mkd_reparse(T(link.title), S(link.title), INSIDE_TAG, f);
|
637
646
|
Qchar('"', f);
|
638
647
|
}
|
639
648
|
|
640
649
|
Qstring(tag->text_pfx, f);
|
641
|
-
|
650
|
+
___mkd_reparse(T(link.tag), S(link.tag), tag->flags, f);
|
642
651
|
Qstring(tag->text_sfx, f);
|
643
652
|
}
|
644
653
|
else
|
@@ -885,7 +894,7 @@ smartypants(int c, int *flags, MMIOT *f)
|
|
885
894
|
break;
|
886
895
|
else if ( c == '\'' && peek(f, j+1) == '\'' ) {
|
887
896
|
Qstring("“", f);
|
888
|
-
|
897
|
+
___mkd_reparse(cursor(f)+1, j-2, 0, f);
|
889
898
|
Qstring("”", f);
|
890
899
|
shift(f,j+1);
|
891
900
|
return 1;
|
@@ -951,7 +960,7 @@ text(MMIOT *f)
|
|
951
960
|
++len;
|
952
961
|
}
|
953
962
|
shift(f,len);
|
954
|
-
|
963
|
+
___mkd_reparse(sup, len, 0, f);
|
955
964
|
Qstring("</sup>", f);
|
956
965
|
}
|
957
966
|
break;
|
@@ -1134,6 +1143,7 @@ printblock(Paragraph *pp, MMIOT *f)
|
|
1134
1143
|
push("<br/>\n", 6, f);
|
1135
1144
|
}
|
1136
1145
|
else {
|
1146
|
+
___mkd_tidy(t);
|
1137
1147
|
push(T(t->text), S(t->text), f);
|
1138
1148
|
if ( t->next )
|
1139
1149
|
push("\n", 1, f);
|
@@ -1191,19 +1201,19 @@ printhtml(Line *t, MMIOT *f)
|
|
1191
1201
|
static void
|
1192
1202
|
htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f)
|
1193
1203
|
{
|
1194
|
-
|
1204
|
+
___mkd_emblock(f);
|
1195
1205
|
if ( block )
|
1196
1206
|
Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments);
|
1197
|
-
|
1207
|
+
___mkd_emblock(f);
|
1198
1208
|
|
1199
1209
|
while (( p = display(p, f) )) {
|
1200
|
-
|
1210
|
+
___mkd_emblock(f);
|
1201
1211
|
Qstring("\n\n", f);
|
1202
1212
|
}
|
1203
1213
|
|
1204
1214
|
if ( block )
|
1205
1215
|
Qprintf(f, "</%s>", block);
|
1206
|
-
|
1216
|
+
___mkd_emblock(f);
|
1207
1217
|
}
|
1208
1218
|
|
1209
1219
|
|
@@ -1219,7 +1229,7 @@ definitionlist(Paragraph *p, MMIOT *f)
|
|
1219
1229
|
for ( ; p ; p = p->next) {
|
1220
1230
|
for ( tag = p->text; tag; tag = tag->next ) {
|
1221
1231
|
Qstring("<dt>", f);
|
1222
|
-
|
1232
|
+
___mkd_reparse(T(tag->text), S(tag->text), 0, f);
|
1223
1233
|
Qstring("</dt>\n", f);
|
1224
1234
|
}
|
1225
1235
|
|
@@ -1345,7 +1355,7 @@ mkd_document(Document *p, char **res)
|
|
1345
1355
|
}
|
1346
1356
|
|
1347
1357
|
|
1348
|
-
/* public interface for
|
1358
|
+
/* public interface for ___mkd_reparse()
|
1349
1359
|
*/
|
1350
1360
|
int
|
1351
1361
|
mkd_text(char *bfr, int size, FILE *output, int flags)
|
@@ -1355,8 +1365,8 @@ mkd_text(char *bfr, int size, FILE *output, int flags)
|
|
1355
1365
|
___mkd_initmmiot(&f, 0);
|
1356
1366
|
f.flags = flags & USER_FLAGS;
|
1357
1367
|
|
1358
|
-
|
1359
|
-
|
1368
|
+
___mkd_reparse(bfr, size, 0, &f);
|
1369
|
+
___mkd_emblock(&f);
|
1360
1370
|
if ( flags & CDATA_OUTPUT )
|
1361
1371
|
___mkd_xml(T(f.out), S(f.out), output);
|
1362
1372
|
else
|
data/ext/markdown.c
CHANGED
@@ -124,6 +124,14 @@ skipempty(Line *p)
|
|
124
124
|
}
|
125
125
|
|
126
126
|
|
127
|
+
void
|
128
|
+
___mkd_tidy(Line *t)
|
129
|
+
{
|
130
|
+
while ( S(t->text) && isspace(T(t->text)[S(t->text)-1]) )
|
131
|
+
--S(t->text);
|
132
|
+
}
|
133
|
+
|
134
|
+
|
127
135
|
static char *
|
128
136
|
isopentag(Line *p)
|
129
137
|
{
|
@@ -434,12 +442,6 @@ codeblock(Paragraph *p)
|
|
434
442
|
{
|
435
443
|
Line *t = p->text, *r;
|
436
444
|
|
437
|
-
/* HORRIBLE STANDARDS KLUDGE: the first line of every block
|
438
|
-
* has trailing whitespace trimmed off.
|
439
|
-
*/
|
440
|
-
while ( S(t->text) && isspace(T(t->text)[S(t->text)-1]) )
|
441
|
-
--S(t->text);
|
442
|
-
|
443
445
|
for ( ; t; t = r ) {
|
444
446
|
CLIP(t->text,0,4);
|
445
447
|
t->dle = mkd_firstnonblank(t);
|
@@ -492,12 +494,13 @@ textblock(Paragraph *p, int toplevel)
|
|
492
494
|
{
|
493
495
|
Line *t, *next;
|
494
496
|
|
495
|
-
for ( t = p->text; t ; t = next )
|
497
|
+
for ( t = p->text; t ; t = next ) {
|
496
498
|
if ( ((next = t->next) == 0) || endoftextblock(next, toplevel) ) {
|
497
499
|
p->align = centered(p->text, t);
|
498
500
|
t->next = 0;
|
499
501
|
return next;
|
500
502
|
}
|
503
|
+
}
|
501
504
|
return t;
|
502
505
|
}
|
503
506
|
|
@@ -833,6 +836,14 @@ compile(Line *ptr, int toplevel, MMIOT *f)
|
|
833
836
|
}
|
834
837
|
else if ( iscode(ptr) ) {
|
835
838
|
p = Pp(&d, ptr, CODE);
|
839
|
+
|
840
|
+
if ( f->flags & MKD_1_COMPAT) {
|
841
|
+
/* HORRIBLE STANDARDS KLUDGE: the first line of every block
|
842
|
+
* has trailing whitespace trimmed off.
|
843
|
+
*/
|
844
|
+
___mkd_tidy(p->text);
|
845
|
+
}
|
846
|
+
|
836
847
|
ptr = codeblock(p);
|
837
848
|
}
|
838
849
|
else if ( ishr(ptr) ) {
|
data/ext/markdown.h
CHANGED
@@ -74,6 +74,7 @@ typedef struct mmiot {
|
|
74
74
|
#define NO_PSEUDO_PROTO 0x0040
|
75
75
|
#define CDATA_OUTPUT 0x0080
|
76
76
|
#define TOC 0x1000
|
77
|
+
#define MKD_1_COMPAT 0x2000
|
77
78
|
#define USER_FLAGS 0xF0FF
|
78
79
|
#define EMBEDDED DENY_A|DENY_IMG|NO_PSEUDO_PROTO|CDATA_OUTPUT
|
79
80
|
char *base;
|
@@ -127,5 +128,8 @@ extern void ___mkd_initmmiot(MMIOT *, void *);
|
|
127
128
|
extern void ___mkd_freemmiot(MMIOT *, void *);
|
128
129
|
extern void ___mkd_freeLineRange(Line *, Line *);
|
129
130
|
extern void ___mkd_xml(char *, int, FILE *);
|
131
|
+
extern void ___mkd_reparse(char *, int, int, MMIOT*);
|
132
|
+
extern void ___mkd_emblock(MMIOT*);
|
133
|
+
extern void ___mkd_tidy(Line *);
|
130
134
|
|
131
135
|
#endif/*_MARKDOWN_D*/
|
data/ext/mkdio.h
CHANGED
@@ -54,6 +54,7 @@ extern char markdown_version[];
|
|
54
54
|
#define MKD_NO_EXT 0x0040 /* don't allow pseudo-protocols */
|
55
55
|
#define MKD_CDATA 0x0080 /* generate code for xml ![CDATA[...]] */
|
56
56
|
#define MKD_TOC 0x1000 /* do table-of-contents processing */
|
57
|
+
#define MKD_1_COMPAT 0x2000 /* compatability with MarkdownTest_1.0 */
|
57
58
|
#define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
|
58
59
|
|
59
60
|
/* special flags for mkd_in() and mkd_string()
|
data/ext/rdiscount.c
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#include <stdio.h>
|
2
2
|
#include "ruby.h"
|
3
3
|
#include "mkdio.h"
|
4
|
-
#include "rbstrio.h"
|
5
4
|
|
6
5
|
static VALUE rb_cRDiscount;
|
7
6
|
|
@@ -9,19 +8,25 @@ static VALUE
|
|
9
8
|
rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
|
10
9
|
{
|
11
10
|
/* grab char pointer to markdown input text */
|
11
|
+
char *res;
|
12
|
+
int szres;
|
12
13
|
VALUE text = rb_funcall(self, rb_intern("text"), 0);
|
14
|
+
VALUE buf = rb_str_buf_new(1024);
|
13
15
|
Check_Type(text, T_STRING);
|
14
16
|
|
15
|
-
/* allocate a ruby string buffer and wrap it in a stream */
|
16
|
-
VALUE buf = rb_str_buf_new(4096);
|
17
|
-
FILE *stream = rb_str_io_new(buf);
|
18
|
-
|
19
17
|
int flags = rb_rdiscount__get_flags(self);
|
20
18
|
|
21
19
|
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
22
|
-
markdown(doc, stream, flags);
|
23
20
|
|
24
|
-
|
21
|
+
if ( mkd_compile(doc, flags) ) {
|
22
|
+
szres = mkd_document(doc, &res);
|
23
|
+
|
24
|
+
if ( szres != EOF ) {
|
25
|
+
rb_str_cat(buf, res, szres);
|
26
|
+
rb_str_cat(buf, "\n", 1);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
mkd_cleanup(doc);
|
25
30
|
|
26
31
|
return buf;
|
27
32
|
}
|
@@ -29,6 +34,9 @@ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
|
|
29
34
|
static VALUE
|
30
35
|
rb_rdiscount_toc_content(int argc, VALUE *argv, VALUE self)
|
31
36
|
{
|
37
|
+
char *res;
|
38
|
+
int szres;
|
39
|
+
|
32
40
|
int flags = rb_rdiscount__get_flags(self);
|
33
41
|
|
34
42
|
/* grab char pointer to markdown input text */
|
@@ -37,13 +45,18 @@ rb_rdiscount_toc_content(int argc, VALUE *argv, VALUE self)
|
|
37
45
|
|
38
46
|
/* allocate a ruby string buffer and wrap it in a stream */
|
39
47
|
VALUE buf = rb_str_buf_new(4096);
|
40
|
-
FILE *stream = rb_str_io_new(buf);
|
41
48
|
|
42
49
|
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
43
|
-
mkd_compile(doc, flags);
|
44
|
-
mkd_generatetoc(doc, stream);
|
45
50
|
|
46
|
-
|
51
|
+
if ( mkd_compile(doc, flags) ) {
|
52
|
+
szres = mkd_toc(doc, &res);
|
53
|
+
|
54
|
+
if ( szres != EOF ) {
|
55
|
+
rb_str_cat(buf, res, szres);
|
56
|
+
rb_str_cat(buf, "\n", 1);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
mkd_cleanup(doc);
|
47
60
|
|
48
61
|
return buf;
|
49
62
|
}
|
data/ext/toc.c
CHANGED
@@ -17,12 +17,16 @@
|
|
17
17
|
/* write an header index
|
18
18
|
*/
|
19
19
|
int
|
20
|
-
|
20
|
+
mkd_toc(Document *p, char **doc)
|
21
21
|
{
|
22
22
|
Paragraph *pp;
|
23
|
+
int last_hnumber = 0;
|
24
|
+
Cstring res;
|
25
|
+
|
26
|
+
CREATE(res);
|
27
|
+
RESERVE(res, 100);
|
23
28
|
|
24
|
-
|
25
|
-
first_hnumber = 0;
|
29
|
+
*doc = 0;
|
26
30
|
|
27
31
|
if ( !(p && p->ctx) ) return -1;
|
28
32
|
if ( ! (p->ctx->flags & TOC) ) return 0;
|
@@ -31,32 +35,52 @@ mkd_generatetoc(Document *p, FILE *output)
|
|
31
35
|
if ( pp->typ == HDR && pp->text ) {
|
32
36
|
|
33
37
|
if ( last_hnumber == pp->hnumber )
|
34
|
-
|
38
|
+
Csprintf(&res, "%*s</li>\n", pp->hnumber, "");
|
35
39
|
else while ( last_hnumber > pp->hnumber ) {
|
36
|
-
|
40
|
+
Csprintf(&res, "%*s</li>\n%*s</ul>\n",
|
37
41
|
last_hnumber, "",
|
38
42
|
last_hnumber-1,"");
|
39
43
|
--last_hnumber;
|
40
44
|
}
|
41
45
|
|
42
46
|
while ( pp->hnumber > last_hnumber ) {
|
43
|
-
|
47
|
+
Csprintf(&res, "\n%*s<ul>\n", pp->hnumber, "");
|
44
48
|
++last_hnumber;
|
45
49
|
}
|
46
|
-
|
47
|
-
mkd_string_to_anchor(T(pp->text->text), S(pp->text->text),
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
Csprintf(&res, "%*s<li><a href=\"#", pp->hnumber, "");
|
51
|
+
mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Csputc, &res);
|
52
|
+
Csprintf(&res, "\">");
|
53
|
+
Csreparse(&res, T(pp->text->text), S(pp->text->text), 0);
|
54
|
+
Csprintf(&res, "</a>");
|
51
55
|
}
|
52
56
|
}
|
53
57
|
|
54
58
|
while ( last_hnumber > 0 ) {
|
55
|
-
|
59
|
+
Csprintf(&res, "%*s</li>\n%*s</ul>\n",
|
56
60
|
last_hnumber, "", last_hnumber, "");
|
57
61
|
--last_hnumber;
|
58
62
|
}
|
59
|
-
|
60
|
-
|
63
|
+
/* HACK ALERT! HACK ALERT! HACK ALERT! */
|
64
|
+
*doc = T(res); /* we know that a T(Cstring) is a character pointer */
|
65
|
+
/* so we can simply pick it up and carry it away, */
|
66
|
+
return S(res); /* leaving the husk of the Ctring on the stack */
|
67
|
+
/* END HACK ALERT */
|
61
68
|
}
|
62
69
|
|
70
|
+
|
71
|
+
/* write an header index
|
72
|
+
*/
|
73
|
+
int
|
74
|
+
mkd_generatetoc(Document *p, FILE *out)
|
75
|
+
{
|
76
|
+
char *buf = 0;
|
77
|
+
int sz = mkd_toc(p, &buf);
|
78
|
+
int ret = EOF;
|
79
|
+
|
80
|
+
if ( sz > 0 )
|
81
|
+
ret = fwrite(buf, sz, 1, out);
|
82
|
+
|
83
|
+
if ( buf ) free(buf);
|
84
|
+
|
85
|
+
return ret;
|
86
|
+
}
|
data/lib/rdiscount.rb
CHANGED
data/rdiscount.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rdiscount'
|
3
|
-
s.version = '1.3.
|
3
|
+
s.version = '1.3.4'
|
4
4
|
s.summary = "Fast Implementation of Gruber's Markdown in C"
|
5
|
-
s.date = '2009-
|
5
|
+
s.date = '2009-03-04'
|
6
6
|
s.email = 'r@tomayko.com'
|
7
7
|
s.homepage = 'http://github.com/rtomayko/rdiscount'
|
8
8
|
s.has_rdoc = true
|
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
README.markdown
|
14
14
|
Rakefile
|
15
15
|
bin/rdiscount
|
16
|
+
ext/Csio.c
|
16
17
|
ext/amalloc.h
|
17
18
|
ext/config.h
|
18
19
|
ext/cstring.h
|
@@ -24,8 +25,6 @@ Gem::Specification.new do |s|
|
|
24
25
|
ext/markdown.h
|
25
26
|
ext/mkdio.c
|
26
27
|
ext/mkdio.h
|
27
|
-
ext/rbstrio.c
|
28
|
-
ext/rbstrio.h
|
29
28
|
ext/rdiscount.c
|
30
29
|
ext/resource.c
|
31
30
|
ext/toc.c
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdiscount
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Tomayko
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-
|
13
|
+
date: 2009-03-04 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -27,6 +27,7 @@ files:
|
|
27
27
|
- README.markdown
|
28
28
|
- Rakefile
|
29
29
|
- bin/rdiscount
|
30
|
+
- ext/Csio.c
|
30
31
|
- ext/amalloc.h
|
31
32
|
- ext/config.h
|
32
33
|
- ext/cstring.h
|
@@ -38,8 +39,6 @@ files:
|
|
38
39
|
- ext/markdown.h
|
39
40
|
- ext/mkdio.c
|
40
41
|
- ext/mkdio.h
|
41
|
-
- ext/rbstrio.c
|
42
|
-
- ext/rbstrio.h
|
43
42
|
- ext/rdiscount.c
|
44
43
|
- ext/resource.c
|
45
44
|
- ext/toc.c
|
data/ext/rbstrio.c
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
#if defined(HAVE_FOPENCOOKIE)
|
2
|
-
# define _GNU_SOURCE
|
3
|
-
#endif
|
4
|
-
|
5
|
-
#include <stdlib.h>
|
6
|
-
#include "rbstrio.h"
|
7
|
-
|
8
|
-
#define INCREMENT 1024
|
9
|
-
|
10
|
-
/* called when data is written to the stream. */
|
11
|
-
static int rb_str_io_write(void *cookie, const char *data, int len) {
|
12
|
-
VALUE buf = (VALUE)cookie;
|
13
|
-
rb_str_cat(buf, data, len);
|
14
|
-
return len;
|
15
|
-
}
|
16
|
-
|
17
|
-
/* called when the stream is closed */
|
18
|
-
static int rb_str_io_close(void *cookie) {
|
19
|
-
VALUE buf = (VALUE)cookie;
|
20
|
-
rb_gc_unregister_address(&buf);
|
21
|
-
return 0;
|
22
|
-
}
|
23
|
-
|
24
|
-
#if defined(HAVE_FOPENCOOKIE)
|
25
|
-
cookie_io_functions_t rb_str_io_functions =
|
26
|
-
{
|
27
|
-
(cookie_read_function_t*)NULL,
|
28
|
-
(cookie_write_function_t*)rb_str_io_write,
|
29
|
-
(cookie_seek_function_t*)NULL,
|
30
|
-
(cookie_close_function_t*)rb_str_io_close
|
31
|
-
};
|
32
|
-
#endif
|
33
|
-
|
34
|
-
/* create a stream backed by a Ruby string. */
|
35
|
-
FILE *rb_str_io_new(VALUE buf) {
|
36
|
-
FILE *rv;
|
37
|
-
Check_Type(buf, T_STRING);
|
38
|
-
#if defined(HAVE_FOPENCOOKIE)
|
39
|
-
rv = fopencookie((void*)buf, "w", rb_str_io_functions);
|
40
|
-
#else
|
41
|
-
rv = funopen((void*)buf, NULL, rb_str_io_write, NULL, rb_str_io_close);
|
42
|
-
#endif
|
43
|
-
/* TODO if (rv == NULL) */
|
44
|
-
rb_gc_register_address(&buf);
|
45
|
-
return rv;
|
46
|
-
}
|
47
|
-
|
48
|
-
/* vim: set ts=4 sw=4: */
|
data/ext/rbstrio.h
DELETED