patcito-rdiscount 1.6.8
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.
- data/BUILDING +34 -0
- data/COPYING +52 -0
- data/README.markdown +71 -0
- data/Rakefile +182 -0
- data/bin/rdiscount +13 -0
- data/ext/Csio.c +61 -0
- data/ext/amalloc.h +29 -0
- data/ext/basename.c +43 -0
- data/ext/config.h +23 -0
- data/ext/css.c +85 -0
- data/ext/cstring.h +77 -0
- data/ext/docheader.c +49 -0
- data/ext/dumptree.c +152 -0
- data/ext/emmatch.c +188 -0
- data/ext/extconf.rb +23 -0
- data/ext/generate.c +1708 -0
- data/ext/html5.c +24 -0
- data/ext/markdown.c +1215 -0
- data/ext/markdown.h +171 -0
- data/ext/mkdio.c +344 -0
- data/ext/mkdio.h +101 -0
- data/ext/rdiscount.c +132 -0
- data/ext/resource.c +157 -0
- data/ext/tags.c +123 -0
- data/ext/tags.h +19 -0
- data/ext/toc.c +101 -0
- data/ext/xml.c +82 -0
- data/lib/markdown.rb +1 -0
- data/lib/rdiscount.rb +101 -0
- data/man/markdown.7 +1020 -0
- data/man/rdiscount.1 +22 -0
- data/man/rdiscount.1.ronn +24 -0
- data/rdiscount.gemspec +57 -0
- data/test/benchmark.rb +56 -0
- data/test/benchmark.txt +306 -0
- data/test/markdown_test.rb +158 -0
- data/test/rdiscount_test.rb +111 -0
- metadata +88 -0
data/ext/rdiscount.c
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "mkdio.h"
|
4
|
+
|
5
|
+
static VALUE rb_cRDiscount;
|
6
|
+
|
7
|
+
static VALUE
|
8
|
+
rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
|
9
|
+
{
|
10
|
+
/* grab char pointer to markdown input text */
|
11
|
+
char *res;
|
12
|
+
int szres;
|
13
|
+
VALUE encoding;
|
14
|
+
VALUE text = rb_funcall(self, rb_intern("text"), 0);
|
15
|
+
VALUE buf = rb_str_buf_new(1024);
|
16
|
+
Check_Type(text, T_STRING);
|
17
|
+
|
18
|
+
int flags = rb_rdiscount__get_flags(self);
|
19
|
+
|
20
|
+
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
21
|
+
|
22
|
+
if ( mkd_compile(doc, flags) ) {
|
23
|
+
szres = mkd_document(doc, &res);
|
24
|
+
|
25
|
+
if ( szres != EOF ) {
|
26
|
+
rb_str_cat(buf, res, szres);
|
27
|
+
rb_str_cat(buf, "\n", 1);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
mkd_cleanup(doc);
|
31
|
+
|
32
|
+
|
33
|
+
/* force the input encoding */
|
34
|
+
if ( rb_respond_to(text, rb_intern("encoding")) ) {
|
35
|
+
encoding = rb_funcall(text, rb_intern("encoding"), 0);
|
36
|
+
rb_funcall(buf, rb_intern("force_encoding"), 1, encoding);
|
37
|
+
}
|
38
|
+
|
39
|
+
return buf;
|
40
|
+
}
|
41
|
+
|
42
|
+
static VALUE
|
43
|
+
rb_rdiscount_toc_content(int argc, VALUE *argv, VALUE self)
|
44
|
+
{
|
45
|
+
char *res;
|
46
|
+
int szres;
|
47
|
+
|
48
|
+
int flags = rb_rdiscount__get_flags(self);
|
49
|
+
|
50
|
+
/* grab char pointer to markdown input text */
|
51
|
+
VALUE text = rb_funcall(self, rb_intern("text"), 0);
|
52
|
+
Check_Type(text, T_STRING);
|
53
|
+
|
54
|
+
/* allocate a ruby string buffer and wrap it in a stream */
|
55
|
+
VALUE buf = rb_str_buf_new(4096);
|
56
|
+
|
57
|
+
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
58
|
+
|
59
|
+
if ( mkd_compile(doc, flags) ) {
|
60
|
+
szres = mkd_toc(doc, &res);
|
61
|
+
|
62
|
+
if ( szres != EOF ) {
|
63
|
+
rb_str_cat(buf, res, szres);
|
64
|
+
rb_str_cat(buf, "\n", 1);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
mkd_cleanup(doc);
|
68
|
+
|
69
|
+
return buf;
|
70
|
+
}
|
71
|
+
|
72
|
+
int rb_rdiscount__get_flags(VALUE ruby_obj)
|
73
|
+
{
|
74
|
+
/* compile flags */
|
75
|
+
int flags = MKD_TABSTOP | MKD_NOHEADER;
|
76
|
+
|
77
|
+
/* smart */
|
78
|
+
if ( rb_funcall(ruby_obj, rb_intern("smart"), 0) != Qtrue )
|
79
|
+
flags = flags | MKD_NOPANTS;
|
80
|
+
|
81
|
+
/* filter_html */
|
82
|
+
if ( rb_funcall(ruby_obj, rb_intern("filter_html"), 0) == Qtrue )
|
83
|
+
flags = flags | MKD_NOHTML;
|
84
|
+
|
85
|
+
/* generate_toc */
|
86
|
+
if ( rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
|
87
|
+
flags = flags | MKD_TOC;
|
88
|
+
|
89
|
+
/* no_image */
|
90
|
+
if ( rb_funcall(ruby_obj, rb_intern("no_image"), 0) == Qtrue)
|
91
|
+
flags = flags | MKD_NOIMAGE;
|
92
|
+
|
93
|
+
/* no_links */
|
94
|
+
if ( rb_funcall(ruby_obj, rb_intern("no_links"), 0) == Qtrue)
|
95
|
+
flags = flags | MKD_NOLINKS;
|
96
|
+
|
97
|
+
/* no_tables */
|
98
|
+
if ( rb_funcall(ruby_obj, rb_intern("no_tables"), 0) == Qtrue)
|
99
|
+
flags = flags | MKD_NOTABLES;
|
100
|
+
|
101
|
+
/* strict */
|
102
|
+
if ( rb_funcall(ruby_obj, rb_intern("strict"), 0) == Qtrue)
|
103
|
+
flags = flags | MKD_STRICT;
|
104
|
+
|
105
|
+
/* autolink */
|
106
|
+
if ( rb_funcall(ruby_obj, rb_intern("autolink"), 0) == Qtrue)
|
107
|
+
flags = flags | MKD_AUTOLINK;
|
108
|
+
|
109
|
+
/* safelink */
|
110
|
+
if ( rb_funcall(ruby_obj, rb_intern("safelink"), 0) == Qtrue)
|
111
|
+
flags = flags | MKD_SAFELINK;
|
112
|
+
|
113
|
+
/* no_pseudo_protocols */
|
114
|
+
if ( rb_funcall(ruby_obj, rb_intern("no_pseudo_protocols"), 0) == Qtrue)
|
115
|
+
flags = flags | MKD_NO_EXT;
|
116
|
+
|
117
|
+
/* protect_math */
|
118
|
+
if ( rb_funcall(ruby_obj, rb_intern("protect_math"), 0) == Qtrue)
|
119
|
+
flags = flags | MKD_PROTECTMATH;
|
120
|
+
|
121
|
+
return flags;
|
122
|
+
}
|
123
|
+
|
124
|
+
|
125
|
+
void Init_rdiscount()
|
126
|
+
{
|
127
|
+
rb_cRDiscount = rb_define_class("RDiscount", rb_cObject);
|
128
|
+
rb_define_method(rb_cRDiscount, "to_html", rb_rdiscount_to_html, -1);
|
129
|
+
rb_define_method(rb_cRDiscount, "toc_content", rb_rdiscount_toc_content, -1);
|
130
|
+
}
|
131
|
+
|
132
|
+
/* vim: set ts=4 sw=4: */
|
data/ext/resource.c
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
2
|
+
*
|
3
|
+
* Copyright (C) 2007 David L Parsons.
|
4
|
+
* The redistribution terms are provided in the COPYRIGHT file that must
|
5
|
+
* be distributed with this source code.
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <string.h>
|
9
|
+
#include <stdarg.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <time.h>
|
12
|
+
#include <ctype.h>
|
13
|
+
|
14
|
+
#include "config.h"
|
15
|
+
|
16
|
+
#include "cstring.h"
|
17
|
+
#include "markdown.h"
|
18
|
+
#include "amalloc.h"
|
19
|
+
|
20
|
+
/* free a (single) line
|
21
|
+
*/
|
22
|
+
void
|
23
|
+
___mkd_freeLine(Line *ptr)
|
24
|
+
{
|
25
|
+
DELETE(ptr->text);
|
26
|
+
free(ptr);
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
/* free a list of lines
|
31
|
+
*/
|
32
|
+
void
|
33
|
+
___mkd_freeLines(Line *p)
|
34
|
+
{
|
35
|
+
if (p->next)
|
36
|
+
___mkd_freeLines(p->next);
|
37
|
+
___mkd_freeLine(p);
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
/* bye bye paragraph.
|
42
|
+
*/
|
43
|
+
void
|
44
|
+
___mkd_freeParagraph(Paragraph *p)
|
45
|
+
{
|
46
|
+
if (p->next)
|
47
|
+
___mkd_freeParagraph(p->next);
|
48
|
+
if (p->down)
|
49
|
+
___mkd_freeParagraph(p->down);
|
50
|
+
if (p->text)
|
51
|
+
___mkd_freeLines(p->text);
|
52
|
+
if (p->ident)
|
53
|
+
free(p->ident);
|
54
|
+
free(p);
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
/* bye bye footnote.
|
59
|
+
*/
|
60
|
+
void
|
61
|
+
___mkd_freefootnote(Footnote *f)
|
62
|
+
{
|
63
|
+
DELETE(f->tag);
|
64
|
+
DELETE(f->link);
|
65
|
+
DELETE(f->title);
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
/* bye bye footnotes.
|
70
|
+
*/
|
71
|
+
void
|
72
|
+
___mkd_freefootnotes(MMIOT *f)
|
73
|
+
{
|
74
|
+
int i;
|
75
|
+
|
76
|
+
if ( f->footnotes ) {
|
77
|
+
for (i=0; i < S(*f->footnotes); i++)
|
78
|
+
___mkd_freefootnote( &T(*f->footnotes)[i] );
|
79
|
+
DELETE(*f->footnotes);
|
80
|
+
free(f->footnotes);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
|
85
|
+
/* initialize a new MMIOT
|
86
|
+
*/
|
87
|
+
void
|
88
|
+
___mkd_initmmiot(MMIOT *f, void *footnotes)
|
89
|
+
{
|
90
|
+
if ( f ) {
|
91
|
+
memset(f, 0, sizeof *f);
|
92
|
+
CREATE(f->in);
|
93
|
+
CREATE(f->out);
|
94
|
+
CREATE(f->Q);
|
95
|
+
if ( footnotes )
|
96
|
+
f->footnotes = footnotes;
|
97
|
+
else {
|
98
|
+
f->footnotes = malloc(sizeof f->footnotes[0]);
|
99
|
+
CREATE(*f->footnotes);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
/* free the contents of a MMIOT, but leave the object alone.
|
106
|
+
*/
|
107
|
+
void
|
108
|
+
___mkd_freemmiot(MMIOT *f, void *footnotes)
|
109
|
+
{
|
110
|
+
if ( f ) {
|
111
|
+
DELETE(f->in);
|
112
|
+
DELETE(f->out);
|
113
|
+
DELETE(f->Q);
|
114
|
+
if ( f->footnotes != footnotes )
|
115
|
+
___mkd_freefootnotes(f);
|
116
|
+
memset(f, 0, sizeof *f);
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
/* free lines up to an barrier.
|
122
|
+
*/
|
123
|
+
void
|
124
|
+
___mkd_freeLineRange(Line *anchor, Line *stop)
|
125
|
+
{
|
126
|
+
Line *r = anchor->next;
|
127
|
+
|
128
|
+
if ( r != stop ) {
|
129
|
+
while ( r && (r->next != stop) )
|
130
|
+
r = r->next;
|
131
|
+
if ( r ) r->next = 0;
|
132
|
+
___mkd_freeLines(anchor->next);
|
133
|
+
}
|
134
|
+
anchor->next = 0;
|
135
|
+
}
|
136
|
+
|
137
|
+
|
138
|
+
/* clean up everything allocated in __mkd_compile()
|
139
|
+
*/
|
140
|
+
void
|
141
|
+
mkd_cleanup(Document *doc)
|
142
|
+
{
|
143
|
+
if ( doc && (doc->magic == VALID_DOCUMENT) ) {
|
144
|
+
if ( doc->ctx ) {
|
145
|
+
___mkd_freemmiot(doc->ctx, 0);
|
146
|
+
free(doc->ctx);
|
147
|
+
}
|
148
|
+
|
149
|
+
if ( doc->code) ___mkd_freeParagraph(doc->code);
|
150
|
+
if ( doc->title) ___mkd_freeLine(doc->title);
|
151
|
+
if ( doc->author) ___mkd_freeLine(doc->author);
|
152
|
+
if ( doc->date) ___mkd_freeLine(doc->date);
|
153
|
+
if ( T(doc->content) ) ___mkd_freeLines(T(doc->content));
|
154
|
+
memset(doc, 0, sizeof doc[0]);
|
155
|
+
free(doc);
|
156
|
+
}
|
157
|
+
}
|
data/ext/tags.c
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
/* block-level tags for passing html blocks through the blender
|
2
|
+
*/
|
3
|
+
#define __WITHOUT_AMALLOC 1
|
4
|
+
#include "cstring.h"
|
5
|
+
#include "tags.h"
|
6
|
+
|
7
|
+
STRING(struct kw) blocktags;
|
8
|
+
|
9
|
+
|
10
|
+
/* define a html block tag
|
11
|
+
*/
|
12
|
+
void
|
13
|
+
mkd_define_tag(char *id, int selfclose)
|
14
|
+
{
|
15
|
+
struct kw *p = &EXPAND(blocktags);
|
16
|
+
|
17
|
+
p->id = id;
|
18
|
+
p->size = strlen(id);
|
19
|
+
p->selfclose = selfclose;
|
20
|
+
}
|
21
|
+
|
22
|
+
|
23
|
+
/* case insensitive string sort (for qsort() and bsearch() of block tags)
|
24
|
+
*/
|
25
|
+
static int
|
26
|
+
casort(struct kw *a, struct kw *b)
|
27
|
+
{
|
28
|
+
if ( a->size != b->size )
|
29
|
+
return a->size - b->size;
|
30
|
+
return strncasecmp(a->id, b->id, b->size);
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
/* stupid cast to make gcc shut up about the function types being
|
35
|
+
* passed into qsort() and bsearch()
|
36
|
+
*/
|
37
|
+
typedef int (*stfu)(const void*,const void*);
|
38
|
+
|
39
|
+
|
40
|
+
/* sort the list of html block tags for later searching
|
41
|
+
*/
|
42
|
+
void
|
43
|
+
mkd_sort_tags()
|
44
|
+
{
|
45
|
+
qsort(T(blocktags), S(blocktags), sizeof(struct kw), (stfu)casort);
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
/* look for a token in the html block tag list
|
51
|
+
*/
|
52
|
+
struct kw*
|
53
|
+
mkd_search_tags(char *pat, int len)
|
54
|
+
{
|
55
|
+
struct kw key;
|
56
|
+
|
57
|
+
key.id = pat;
|
58
|
+
key.size = len;
|
59
|
+
|
60
|
+
return bsearch(&key, T(blocktags), S(blocktags), sizeof key, (stfu)casort);
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
static int populated = 0;
|
65
|
+
|
66
|
+
|
67
|
+
/* load in the standard collection of html tags that markdown supports
|
68
|
+
*/
|
69
|
+
void
|
70
|
+
mkd_prepare_tags()
|
71
|
+
{
|
72
|
+
|
73
|
+
#define KW(x) mkd_define_tag(x, 0)
|
74
|
+
#define SC(x) mkd_define_tag(x, 1)
|
75
|
+
|
76
|
+
if ( populated ) return;
|
77
|
+
populated = 1;
|
78
|
+
|
79
|
+
KW("STYLE");
|
80
|
+
KW("SCRIPT");
|
81
|
+
KW("ADDRESS");
|
82
|
+
KW("BDO");
|
83
|
+
KW("BLOCKQUOTE");
|
84
|
+
KW("CENTER");
|
85
|
+
KW("DFN");
|
86
|
+
KW("DIV");
|
87
|
+
KW("OBJECT");
|
88
|
+
KW("H1");
|
89
|
+
KW("H2");
|
90
|
+
KW("H3");
|
91
|
+
KW("H4");
|
92
|
+
KW("H5");
|
93
|
+
KW("H6");
|
94
|
+
KW("LISTING");
|
95
|
+
KW("NOBR");
|
96
|
+
KW("UL");
|
97
|
+
KW("P");
|
98
|
+
KW("OL");
|
99
|
+
KW("DL");
|
100
|
+
KW("PLAINTEXT");
|
101
|
+
KW("PRE");
|
102
|
+
KW("TABLE");
|
103
|
+
KW("WBR");
|
104
|
+
KW("XMP");
|
105
|
+
SC("HR");
|
106
|
+
SC("BR");
|
107
|
+
KW("IFRAME");
|
108
|
+
KW("MAP");
|
109
|
+
|
110
|
+
mkd_sort_tags();
|
111
|
+
} /* mkd_prepare_tags */
|
112
|
+
|
113
|
+
|
114
|
+
/* destroy the blocktags list (for shared libraries)
|
115
|
+
*/
|
116
|
+
void
|
117
|
+
mkd_deallocate_tags()
|
118
|
+
{
|
119
|
+
if ( S(blocktags) > 0 ) {
|
120
|
+
populated = 0;
|
121
|
+
DELETE(blocktags);
|
122
|
+
}
|
123
|
+
} /* mkd_deallocate_tags */
|
data/ext/tags.h
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
/* block-level tags for passing html blocks through the blender
|
2
|
+
*/
|
3
|
+
#ifndef _TAGS_D
|
4
|
+
#define _TAGS_D
|
5
|
+
|
6
|
+
struct kw {
|
7
|
+
char *id;
|
8
|
+
int size;
|
9
|
+
int selfclose;
|
10
|
+
} ;
|
11
|
+
|
12
|
+
|
13
|
+
struct kw* mkd_search_tags(char *, int);
|
14
|
+
void mkd_prepare_tags();
|
15
|
+
void mkd_deallocate_tags();
|
16
|
+
void mkd_sort_tags();
|
17
|
+
void mkd_define_tag(char *, int);
|
18
|
+
|
19
|
+
#endif
|
data/ext/toc.c
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
/*
|
2
|
+
* toc -- spit out a table of contents based on header blocks
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008 Jjgod Jiang, David L Parsons.
|
5
|
+
* The redistribution terms are provided in the COPYRIGHT file that must
|
6
|
+
* be distributed with this source code.
|
7
|
+
*/
|
8
|
+
#include "config.h"
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <ctype.h>
|
12
|
+
|
13
|
+
#include "cstring.h"
|
14
|
+
#include "markdown.h"
|
15
|
+
#include "amalloc.h"
|
16
|
+
|
17
|
+
/* write an header index
|
18
|
+
*/
|
19
|
+
int
|
20
|
+
mkd_toc(Document *p, char **doc)
|
21
|
+
{
|
22
|
+
Paragraph *tp, *srcp;
|
23
|
+
int last_hnumber = 0;
|
24
|
+
Cstring res;
|
25
|
+
int size;
|
26
|
+
|
27
|
+
if ( !(doc && p && p->ctx) ) return -1;
|
28
|
+
|
29
|
+
*doc = 0;
|
30
|
+
|
31
|
+
if ( ! (p->ctx->flags & MKD_TOC) ) return 0;
|
32
|
+
|
33
|
+
CREATE(res);
|
34
|
+
RESERVE(res, 100);
|
35
|
+
|
36
|
+
for ( tp = p->code; tp ; tp = tp->next ) {
|
37
|
+
if ( tp->typ == SOURCE ) {
|
38
|
+
for ( srcp = tp->down; srcp; srcp = srcp->next ) {
|
39
|
+
if ( srcp->typ == HDR && srcp->text ) {
|
40
|
+
|
41
|
+
if ( last_hnumber >= srcp->hnumber ) {
|
42
|
+
while ( last_hnumber > srcp->hnumber ) {
|
43
|
+
Csprintf(&res, "%*s</ul></li>\n", last_hnumber-1,"");
|
44
|
+
--last_hnumber;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
while ( srcp->hnumber > last_hnumber ) {
|
49
|
+
Csprintf(&res, "%*s%s<ul>\n", last_hnumber, "",
|
50
|
+
last_hnumber ? "<li>" : "");
|
51
|
+
++last_hnumber;
|
52
|
+
}
|
53
|
+
Csprintf(&res, "%*s<li><a href=\"#", srcp->hnumber, "");
|
54
|
+
mkd_string_to_anchor(T(srcp->text->text),
|
55
|
+
S(srcp->text->text), Csputc, &res,1);
|
56
|
+
Csprintf(&res, "\">");
|
57
|
+
mkd_string_to_anchor(T(srcp->text->text),
|
58
|
+
S(srcp->text->text), Csputc, &res,0);
|
59
|
+
Csprintf(&res, "</a>");
|
60
|
+
Csprintf(&res, "</li>\n");
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
while ( last_hnumber > 0 ) {
|
67
|
+
--last_hnumber;
|
68
|
+
Csprintf(&res, last_hnumber ? "%*s</ul></li>\n" : "%*s</ul>\n", last_hnumber, "");
|
69
|
+
}
|
70
|
+
|
71
|
+
if ( (size = S(res)) > 0 ) {
|
72
|
+
EXPAND(res) = 0;
|
73
|
+
/* HACK ALERT! HACK ALERT! HACK ALERT! */
|
74
|
+
*doc = T(res); /* we know that a T(Cstring) is a character pointer
|
75
|
+
* so we can simply pick it up and carry it away,
|
76
|
+
* leaving the husk of the Ctring on the stack
|
77
|
+
* END HACK ALERT
|
78
|
+
*/
|
79
|
+
}
|
80
|
+
else
|
81
|
+
DELETE(res);
|
82
|
+
return size;
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
/* write an header index
|
87
|
+
*/
|
88
|
+
int
|
89
|
+
mkd_generatetoc(Document *p, FILE *out)
|
90
|
+
{
|
91
|
+
char *buf = 0;
|
92
|
+
int sz = mkd_toc(p, &buf);
|
93
|
+
int ret = EOF;
|
94
|
+
|
95
|
+
if ( sz > 0 )
|
96
|
+
ret = fwrite(buf, 1, sz, out);
|
97
|
+
|
98
|
+
if ( buf ) free(buf);
|
99
|
+
|
100
|
+
return (ret == sz) ? ret : EOF;
|
101
|
+
}
|
data/ext/xml.c
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
2
|
+
*
|
3
|
+
* Copyright (C) 2007 David L Parsons.
|
4
|
+
* The redistribution terms are provided in the COPYRIGHT file that must
|
5
|
+
* be distributed with this source code.
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <string.h>
|
9
|
+
#include <stdarg.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <time.h>
|
12
|
+
#include <ctype.h>
|
13
|
+
|
14
|
+
#include "config.h"
|
15
|
+
|
16
|
+
#include "cstring.h"
|
17
|
+
#include "markdown.h"
|
18
|
+
#include "amalloc.h"
|
19
|
+
|
20
|
+
/* return the xml version of a character
|
21
|
+
*/
|
22
|
+
static char *
|
23
|
+
mkd_xmlchar(unsigned char c)
|
24
|
+
{
|
25
|
+
switch (c) {
|
26
|
+
case '<': return "<";
|
27
|
+
case '>': return ">";
|
28
|
+
case '&': return "&";
|
29
|
+
case '"': return """;
|
30
|
+
case '\'': return "'";
|
31
|
+
default: if ( isascii(c) || (c & 0x80) )
|
32
|
+
return 0;
|
33
|
+
return "";
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
/* write output in XML format
|
39
|
+
*/
|
40
|
+
int
|
41
|
+
mkd_generatexml(char *p, int size, FILE *out)
|
42
|
+
{
|
43
|
+
unsigned char c;
|
44
|
+
char *entity;
|
45
|
+
|
46
|
+
while ( size-- > 0 ) {
|
47
|
+
c = *p++;
|
48
|
+
|
49
|
+
if ( entity = mkd_xmlchar(c) )
|
50
|
+
fputs(entity, out);
|
51
|
+
else
|
52
|
+
fputc(c, out);
|
53
|
+
}
|
54
|
+
return 0;
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
/* build a xml'ed version of a string
|
59
|
+
*/
|
60
|
+
int
|
61
|
+
mkd_xml(char *p, int size, char **res)
|
62
|
+
{
|
63
|
+
unsigned char c;
|
64
|
+
char *entity;
|
65
|
+
Cstring f;
|
66
|
+
|
67
|
+
CREATE(f);
|
68
|
+
RESERVE(f, 100);
|
69
|
+
|
70
|
+
while ( size-- > 0 ) {
|
71
|
+
c = *p++;
|
72
|
+
if ( entity = mkd_xmlchar(c) )
|
73
|
+
Cswrite(&f, entity, strlen(entity));
|
74
|
+
else
|
75
|
+
Csputc(c, &f);
|
76
|
+
}
|
77
|
+
/* HACK ALERT! HACK ALERT! HACK ALERT! */
|
78
|
+
*res = T(f); /* we know that a T(Cstring) is a character pointer */
|
79
|
+
/* so we can simply pick it up and carry it away, */
|
80
|
+
return S(f); /* leaving the husk of the Ctring on the stack */
|
81
|
+
/* END HACK ALERT */
|
82
|
+
}
|
data/lib/markdown.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rdiscount'
|
data/lib/rdiscount.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Discount is an implementation of John Gruber's Markdown markup
|
2
|
+
# language in C. It implements all of the language as described in
|
3
|
+
# {Markdown Syntax}[http://daringfireball.net/projects/markdown/syntax]
|
4
|
+
# and passes the Markdown 1.0 test suite. The RDiscount extension makes
|
5
|
+
# the Discount processor available via a Ruby C Extension library.
|
6
|
+
#
|
7
|
+
# == Usage
|
8
|
+
#
|
9
|
+
# RDiscount implements the basic protocol popularized by RedCloth and adopted
|
10
|
+
# by BlueCloth:
|
11
|
+
# require 'rdiscount'
|
12
|
+
# markdown = RDiscount.new("Hello World!")
|
13
|
+
# puts markdown.to_html
|
14
|
+
#
|
15
|
+
# == Replacing BlueCloth
|
16
|
+
#
|
17
|
+
# Inject RDiscount into your BlueCloth-using code by replacing your bluecloth
|
18
|
+
# require statements with the following:
|
19
|
+
# begin
|
20
|
+
# require 'rdiscount'
|
21
|
+
# BlueCloth = RDiscount
|
22
|
+
# rescue LoadError
|
23
|
+
# require 'bluecloth'
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
class RDiscount
|
27
|
+
VERSION = '1.6.8'
|
28
|
+
|
29
|
+
# Original Markdown formatted text.
|
30
|
+
attr_reader :text
|
31
|
+
|
32
|
+
# Set true to have smarty-like quote translation performed.
|
33
|
+
attr_accessor :smart
|
34
|
+
|
35
|
+
# Do not output <tt><style></tt> tags included in the source text.
|
36
|
+
attr_accessor :filter_styles
|
37
|
+
|
38
|
+
# Do not output any raw HTML included in the source text.
|
39
|
+
attr_accessor :filter_html
|
40
|
+
|
41
|
+
# RedCloth compatible line folding -- not used for Markdown but
|
42
|
+
# included for compatibility.
|
43
|
+
attr_accessor :fold_lines
|
44
|
+
|
45
|
+
# Enable Table Of Contents generation
|
46
|
+
attr_accessor :generate_toc
|
47
|
+
|
48
|
+
# Do not process <tt>![]</tt> and remove <tt><img></tt> tags from the output.
|
49
|
+
attr_accessor :no_image
|
50
|
+
|
51
|
+
# Do not process <tt>[]</tt> and remove <tt><a></tt> tags from the output.
|
52
|
+
attr_accessor :no_links
|
53
|
+
|
54
|
+
# Do not process tables
|
55
|
+
attr_accessor :no_tables
|
56
|
+
|
57
|
+
# Disable superscript and relaxed emphasis processing.
|
58
|
+
attr_accessor :strict
|
59
|
+
|
60
|
+
# Convert URL in links, even if they aren't encased in <tt><></tt>
|
61
|
+
attr_accessor :autolink
|
62
|
+
|
63
|
+
# Don't make hyperlinks from <tt>[][]</tt> links that have unknown URL types.
|
64
|
+
attr_accessor :safelink
|
65
|
+
|
66
|
+
# Do not process pseudo-protocols like <tt>[](id:name)</tt>
|
67
|
+
attr_accessor :no_pseudo_protocols
|
68
|
+
|
69
|
+
# Protect text enclosed in dollar signs from being scrambled by smartypants
|
70
|
+
# and/or markdown.
|
71
|
+
attr_accessor :protect_math
|
72
|
+
|
73
|
+
# Create a RDiscount Markdown processor. The +text+ argument
|
74
|
+
# should be a string containing Markdown text. Additional arguments may be
|
75
|
+
# supplied to set various processing options:
|
76
|
+
#
|
77
|
+
# * <tt>:smart</tt> - Enable SmartyPants processing.
|
78
|
+
# * <tt>:filter_styles</tt> - Do not output <tt><style></tt> tags.
|
79
|
+
# * <tt>:filter_html</tt> - Do not output any raw HTML tags included in
|
80
|
+
# the source text.
|
81
|
+
# * <tt>:fold_lines</tt> - RedCloth compatible line folding (not used).
|
82
|
+
# * <tt>:generate_toc</tt> - Enable Table Of Contents generation
|
83
|
+
# * <tt>:no_image</tt> - Do not output any <tt><img></tt> tags.
|
84
|
+
# * <tt>:no_links</tt> - Do not output any <tt><a></tt> tags.
|
85
|
+
# * <tt>:no_tables</tt> - Do not output any tables.
|
86
|
+
# * <tt>:strict</tt> - Disable superscript and relaxed emphasis processing.
|
87
|
+
# * <tt>:autolink</tt> - Greedily urlify links.
|
88
|
+
# * <tt>:safelink</tt> - Do not make links for unknown URL types.
|
89
|
+
# * <tt>:no_pseudo_protocols</tt> - Do not process pseudo-protocols.
|
90
|
+
# * <tt>:protect_math</tt> - Do not modify text enclosed in dollar signs.
|
91
|
+
#
|
92
|
+
def initialize(text, *extensions)
|
93
|
+
@text = text
|
94
|
+
extensions.each { |e| send("#{e}=", true) }
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
Markdown = RDiscount unless defined? Markdown
|
100
|
+
|
101
|
+
require 'rdiscount.so'
|