rdiscount-dsc 1.6.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ /*
2
+ * mkdio -- markdown front end input functions
3
+ *
4
+ * Copyright (C) 2007 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 "mkdio.h"
14
+ #include "cstring.h"
15
+ #include "amalloc.h"
16
+
17
+ static char *
18
+ e_basename(const char *string, const int size, void *context)
19
+ {
20
+ char *ret;
21
+ char *base = (char*)context;
22
+
23
+ if ( base && string && (*string == '/') && (ret=malloc(strlen(base)+size+2)) ) {
24
+ strcpy(ret, base);
25
+ strncat(ret, string, size);
26
+ return ret;
27
+ }
28
+ return 0;
29
+ }
30
+
31
+ static void
32
+ e_free(char *string, void *context)
33
+ {
34
+ if ( string ) free(string);
35
+ }
36
+
37
+ void
38
+ mkd_basename(MMIOT *document, char *base)
39
+ {
40
+ mkd_e_url(document, e_basename);
41
+ mkd_e_data(document, base);
42
+ mkd_e_free(document, e_free);
43
+ }
@@ -0,0 +1,23 @@
1
+ /*
2
+ * rdiscount extension discount configuration
3
+ */
4
+ #ifndef __MARKDOWN_D
5
+ #define __MARKDOWN_D 1
6
+
7
+ /* tabs are four spaces */
8
+ #define TABSTOP 4
9
+
10
+ /* these are setup by extconf.rb */
11
+ #if HAVE_RANDOM
12
+ #define COINTOSS() (random()&1)
13
+ #elif HAVE_RAND
14
+ #define COINTOSS() (rand()&1)
15
+ #endif
16
+
17
+ #if HAVE_SRANDOM
18
+ #define INITRNG(x) srandom((unsigned int)x)
19
+ #elif HAVE_SRAND
20
+ #define INITRNG(x) srand((unsigned int)x)
21
+ #endif
22
+
23
+ #endif/* __MARKDOWN_D */
@@ -0,0 +1,85 @@
1
+ /* markdown: a C implementation of John Gruber's Markdown markup language.
2
+ *
3
+ * Copyright (C) 2009 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
+
21
+ /*
22
+ * dump out stylesheet sections.
23
+ */
24
+ static void
25
+ stylesheets(Paragraph *p, Cstring *f)
26
+ {
27
+ Line* q;
28
+
29
+ for ( ; p ; p = p->next ) {
30
+ if ( p->typ == STYLE ) {
31
+ for ( q = p->text; q ; q = q->next ) {
32
+ Cswrite(f, T(q->text), S(q->text));
33
+ Csputc('\n', f);
34
+ }
35
+ }
36
+ if ( p->down )
37
+ stylesheets(p->down, f);
38
+ }
39
+ }
40
+
41
+
42
+ /* dump any embedded styles to a string
43
+ */
44
+ int
45
+ mkd_css(Document *d, char **res)
46
+ {
47
+ Cstring f;
48
+ int size;
49
+
50
+ if ( res && d && d->compiled ) {
51
+ *res = 0;
52
+ CREATE(f);
53
+ RESERVE(f, 100);
54
+ stylesheets(d->code, &f);
55
+
56
+ if ( (size = S(f)) > 0 ) {
57
+ EXPAND(f) = 0;
58
+ /* HACK ALERT! HACK ALERT! HACK ALERT! */
59
+ *res = T(f);/* we know that a T(Cstring) is a character pointer */
60
+ /* so we can simply pick it up and carry it away, */
61
+ /* leaving the husk of the Ctring on the stack */
62
+ /* END HACK ALERT */
63
+ }
64
+ else
65
+ DELETE(f);
66
+ return size;
67
+ }
68
+ return EOF;
69
+ }
70
+
71
+
72
+ /* dump any embedded styles to a file
73
+ */
74
+ int
75
+ mkd_generatecss(Document *d, FILE *f)
76
+ {
77
+ char *res;
78
+ int written = EOF, size = mkd_css(d, &res);
79
+
80
+ if ( size > 0 )
81
+ written = fwrite(res, 1, size, f);
82
+ if ( res )
83
+ free(res);
84
+ return (written == size) ? size : EOF;
85
+ }
@@ -0,0 +1,77 @@
1
+ /* two template types: STRING(t) which defines a pascal-style string
2
+ * of element (t) [STRING(char) is the closest to the pascal string],
3
+ * and ANCHOR(t) which defines a baseplate that a linked list can be
4
+ * built up from. [The linked list /must/ contain a ->next pointer
5
+ * for linking the list together with.]
6
+ */
7
+ #ifndef _CSTRING_D
8
+ #define _CSTRING_D
9
+
10
+ #include <string.h>
11
+ #include <stdlib.h>
12
+
13
+ #ifndef __WITHOUT_AMALLOC
14
+ # include "amalloc.h"
15
+ #endif
16
+
17
+ /* expandable Pascal-style string.
18
+ */
19
+ #define STRING(type) struct { type *text; int size, alloc; }
20
+
21
+ #define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) )
22
+ #define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
23
+ ? (T(x)) \
24
+ : (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
25
+ : malloc(sizeof T(x)[0] * ((x).alloc += 100)) )]
26
+
27
+ #define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
28
+ : ( S(x) = 0 )
29
+ #define CLIP(t,i,sz) \
30
+ ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
31
+ (memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
32
+ S(t) -= (sz)) : -1
33
+
34
+ #define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \
35
+ ? T(x) \
36
+ : T(x) \
37
+ ? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \
38
+ : malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))))
39
+ #define SUFFIX(t,p,sz) \
40
+ memcpy(((S(t) += (sz)) - (sz)) + \
41
+ (T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \
42
+ : malloc(sizeof T(t)[0] * ((t).alloc += sz))), \
43
+ (p), sizeof(T(t)[0])*(sz))
44
+
45
+ #define PREFIX(t,p,sz) \
46
+ RESERVE( (t), (sz) ); \
47
+ if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \
48
+ memcpy( T(t), (p), (sz) ); \
49
+ S(t) += (sz)
50
+
51
+ /* reference-style links (and images) are stored in an array
52
+ */
53
+ #define T(x) (x).text
54
+ #define S(x) (x).size
55
+ #define ALLOCATED(x) (x).alloc
56
+
57
+ /* abstract anchor type that defines a list base
58
+ * with a function that attaches an element to
59
+ * the end of the list.
60
+ *
61
+ * the list base field is named .text so that the T()
62
+ * macro will work with it.
63
+ */
64
+ #define ANCHOR(t) struct { t *text, *end; }
65
+ #define E(t) ((t).end)
66
+
67
+ #define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \
68
+ : ( (T(t) = E(t) = (p)) ) )
69
+
70
+ typedef STRING(char) Cstring;
71
+
72
+ extern void Csputc(int, Cstring *);
73
+ extern int Csprintf(Cstring *, char *, ...);
74
+ extern int Cswrite(Cstring *, char *, int);
75
+ extern void Csreparse(Cstring *, char *, int, int);
76
+
77
+ #endif/*_CSTRING_D*/
@@ -0,0 +1,49 @@
1
+ /*
2
+ * docheader -- get values from the document header
3
+ *
4
+ * Copyright (C) 2007 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
+ static char *
18
+ onlyifset(Line *l)
19
+ {
20
+ char *ret = T(l->text) + l->dle;
21
+
22
+ return ret[0] ? ret : 0;
23
+ }
24
+
25
+ char *
26
+ mkd_doc_title(Document *doc)
27
+ {
28
+ if ( doc && doc->title )
29
+ return onlyifset(doc->title);
30
+ return 0;
31
+ }
32
+
33
+
34
+ char *
35
+ mkd_doc_author(Document *doc)
36
+ {
37
+ if ( doc && doc->author )
38
+ return onlyifset(doc->author);
39
+ return 0;
40
+ }
41
+
42
+
43
+ char *
44
+ mkd_doc_date(Document *doc)
45
+ {
46
+ if ( doc && doc->date )
47
+ return onlyifset(doc->date);
48
+ return 0;
49
+ }
@@ -0,0 +1,152 @@
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 "markdown.h"
9
+ #include "cstring.h"
10
+ #include "amalloc.h"
11
+
12
+ struct frame {
13
+ int indent;
14
+ char c;
15
+ };
16
+
17
+ typedef STRING(struct frame) Stack;
18
+
19
+ static char *
20
+ Pptype(int typ)
21
+ {
22
+ switch (typ) {
23
+ case WHITESPACE: return "whitespace";
24
+ case CODE : return "code";
25
+ case QUOTE : return "quote";
26
+ case MARKUP : return "markup";
27
+ case HTML : return "html";
28
+ case DL : return "dl";
29
+ case UL : return "ul";
30
+ case OL : return "ol";
31
+ case LISTITEM : return "item";
32
+ case HDR : return "header";
33
+ case HR : return "hr";
34
+ case TABLE : return "table";
35
+ case SOURCE : return "source";
36
+ case STYLE : return "style";
37
+ default : return "mystery node!";
38
+ }
39
+ }
40
+
41
+ static void
42
+ pushpfx(int indent, char c, Stack *sp)
43
+ {
44
+ struct frame *q = &EXPAND(*sp);
45
+
46
+ q->indent = indent;
47
+ q->c = c;
48
+ }
49
+
50
+
51
+ static void
52
+ poppfx(Stack *sp)
53
+ {
54
+ S(*sp)--;
55
+ }
56
+
57
+
58
+ static void
59
+ changepfx(Stack *sp, char c)
60
+ {
61
+ char ch;
62
+
63
+ if ( !S(*sp) ) return;
64
+
65
+ ch = T(*sp)[S(*sp)-1].c;
66
+
67
+ if ( ch == '+' || ch == '|' )
68
+ T(*sp)[S(*sp)-1].c = c;
69
+ }
70
+
71
+
72
+ static void
73
+ printpfx(Stack *sp, FILE *f)
74
+ {
75
+ int i;
76
+ char c;
77
+
78
+ if ( !S(*sp) ) return;
79
+
80
+ c = T(*sp)[S(*sp)-1].c;
81
+
82
+ if ( c == '+' || c == '-' ) {
83
+ fprintf(f, "--%c", c);
84
+ T(*sp)[S(*sp)-1].c = (c == '-') ? ' ' : '|';
85
+ }
86
+ else
87
+ for ( i=0; i < S(*sp); i++ ) {
88
+ if ( i )
89
+ fprintf(f, " ");
90
+ fprintf(f, "%*s%c", T(*sp)[i].indent + 2, " ", T(*sp)[i].c);
91
+ if ( T(*sp)[i].c == '`' )
92
+ T(*sp)[i].c = ' ';
93
+ }
94
+ fprintf(f, "--");
95
+ }
96
+
97
+
98
+ static void
99
+ dumptree(Paragraph *pp, Stack *sp, FILE *f)
100
+ {
101
+ int count;
102
+ Line *p;
103
+ int d;
104
+ static char *Begin[] = { 0, "P", "center" };
105
+
106
+ while ( pp ) {
107
+ if ( !pp->next )
108
+ changepfx(sp, '`');
109
+ printpfx(sp, f);
110
+
111
+ d = fprintf(f, "[%s", Pptype(pp->typ));
112
+ if ( pp->ident )
113
+ d += fprintf(f, " %s", pp->ident);
114
+ if ( pp->align )
115
+ d += fprintf(f, ", <%s>", Begin[pp->align]);
116
+
117
+ for (count=0, p=pp->text; p; ++count, (p = p->next) )
118
+ ;
119
+
120
+ if ( count )
121
+ d += fprintf(f, ", %d line%s", count, (count==1)?"":"s");
122
+
123
+ d += fprintf(f, "]");
124
+
125
+ if ( pp->down ) {
126
+ pushpfx(d, pp->down->next ? '+' : '-', sp);
127
+ dumptree(pp->down, sp, f);
128
+ poppfx(sp);
129
+ }
130
+ else fputc('\n', f);
131
+ pp = pp->next;
132
+ }
133
+ }
134
+
135
+
136
+ int
137
+ mkd_dump(Document *doc, FILE *out, int flags, char *title)
138
+ {
139
+ Stack stack;
140
+
141
+ if (mkd_compile(doc, flags) ) {
142
+
143
+ CREATE(stack);
144
+ pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack);
145
+ dumptree(doc->code, &stack, out);
146
+ DELETE(stack);
147
+
148
+ mkd_cleanup(doc);
149
+ return 0;
150
+ }
151
+ return -1;
152
+ }
@@ -0,0 +1,188 @@
1
+ /* markdown: a C implementation of John Gruber's Markdown markup language.
2
+ *
3
+ * Copyright (C) 2010 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
+
21
+ /* emmatch: the emphasis mangler that's run after a block
22
+ * of html has been generated.
23
+ *
24
+ * It should create MarkdownTest_1.0 (and _1.0.3)
25
+ * compatable emphasis for non-pathological cases
26
+ * and it should fail in a standards-compliant way
27
+ * when someone attempts to feed it junk.
28
+ *
29
+ * Emmatching is done after the input has been
30
+ * processed into a STRING (f->Q) of text and
31
+ * emphasis blocks. After ___mkd_emblock() finishes,
32
+ * it truncates f->Q and leaves the rendered paragraph
33
+ * if f->out.
34
+ */
35
+
36
+
37
+ /* empair() -- find the NEAREST matching emphasis token (or
38
+ * subtoken of a 3+ long emphasis token.
39
+ */
40
+ static int
41
+ empair(MMIOT *f, int first, int last, int match)
42
+ {
43
+
44
+ int i;
45
+ block *begin, *p;
46
+
47
+ begin = &T(f->Q)[first];
48
+
49
+ for (i=first+1; i <= last; i++) {
50
+ p = &T(f->Q)[i];
51
+
52
+ if ( (p->b_type != bTEXT) && (p->b_count <= 0) )
53
+ continue; /* break? */
54
+
55
+ if ( p->b_type == begin->b_type ) {
56
+ if ( p->b_count == match ) /* exact match */
57
+ return i;
58
+
59
+ if ( p->b_count > 2 ) /* fuzzy match */
60
+ return i;
61
+ }
62
+ }
63
+ return 0;
64
+ } /* empair */
65
+
66
+
67
+ /* emfill() -- if an emphasis token has leftover stars or underscores,
68
+ * convert them back into character and append them to b_text.
69
+ */
70
+ static void
71
+ emfill(block *p)
72
+ {
73
+ int j;
74
+
75
+ if ( p->b_type == bTEXT )
76
+ return;
77
+
78
+ for (j=0; j < p->b_count; j++)
79
+ EXPAND(p->b_text) = p->b_char;
80
+ p->b_count = 0;
81
+ } /* emfill */
82
+
83
+
84
+ static void
85
+ emclose(MMIOT *f, int first, int last)
86
+ {
87
+ int j;
88
+
89
+ for (j=first+1; j<last-1; j++)
90
+ emfill(&T(f->Q)[j]);
91
+ }
92
+
93
+
94
+ static struct emtags {
95
+ char open[10];
96
+ char close[10];
97
+ int size;
98
+ } emtags[] = { { "<em>" , "</em>", 5 }, { "<strong>", "</strong>", 9 } };
99
+
100
+
101
+ static void emblock(MMIOT*,int,int);
102
+
103
+
104
+ /* emmatch() -- match emphasis for a single emphasis token.
105
+ */
106
+ static void
107
+ emmatch(MMIOT *f, int first, int last)
108
+ {
109
+ block *start = &T(f->Q)[first];
110
+ int e, e2, match;
111
+
112
+ switch (start->b_count) {
113
+ case 2: if ( e = empair(f,first,last,match=2) )
114
+ break;
115
+ case 1: e = empair(f,first,last,match=1);
116
+ break;
117
+ case 0: return;
118
+ default:
119
+ e = empair(f,first,last,1);
120
+ e2= empair(f,first,last,2);
121
+
122
+ if ( e2 >= e ) {
123
+ e = e2;
124
+ match = 2;
125
+ }
126
+ else
127
+ match = 1;
128
+ break;
129
+ }
130
+
131
+ if ( e ) {
132
+ /* if we found emphasis to match, match it, recursively call
133
+ * emblock to match emphasis inside the new html block, add
134
+ * the emphasis markers for the block, then (tail) recursively
135
+ * call ourself to match any remaining emphasis on this token.
136
+ */
137
+ block *end = &T(f->Q)[e];
138
+
139
+ end->b_count -= match;
140
+ start->b_count -= match;
141
+
142
+ emblock(f, first, e);
143
+
144
+ PREFIX(start->b_text, emtags[match-1].open, emtags[match-1].size-1);
145
+ SUFFIX(end->b_post, emtags[match-1].close, emtags[match-1].size);
146
+
147
+ emmatch(f, first, last);
148
+ }
149
+ } /* emmatch */
150
+
151
+
152
+ /* emblock() -- walk a blocklist, attempting to match emphasis
153
+ */
154
+ static void
155
+ emblock(MMIOT *f, int first, int last)
156
+ {
157
+ int i;
158
+
159
+ for ( i = first; i <= last; i++ )
160
+ if ( T(f->Q)[i].b_type != bTEXT )
161
+ emmatch(f, i, last);
162
+ emclose(f, first, last);
163
+ } /* emblock */
164
+
165
+
166
+ /* ___mkd_emblock() -- emblock a string of blocks, then concatenate the
167
+ * resulting text onto f->out.
168
+ */
169
+ void
170
+ ___mkd_emblock(MMIOT *f)
171
+ {
172
+ int i;
173
+ block *p;
174
+
175
+ emblock(f, 0, S(f->Q)-1);
176
+
177
+ for (i=0; i < S(f->Q); i++) {
178
+ p = &T(f->Q)[i];
179
+ emfill(p);
180
+
181
+ if ( S(p->b_post) ) { SUFFIX(f->out, T(p->b_post), S(p->b_post));
182
+ DELETE(p->b_post); }
183
+ if ( S(p->b_text) ) { SUFFIX(f->out, T(p->b_text), S(p->b_text));
184
+ DELETE(p->b_text); }
185
+ }
186
+
187
+ S(f->Q) = 0;
188
+ } /* ___mkd_emblock */