rdiscount 1.6.8 → 2.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,6 +12,10 @@ typedef struct footnote {
12
12
  Cstring title; /* what it's called (TITLE= attribute) */
13
13
  int height, width; /* dimensions (for image link) */
14
14
  int dealloc; /* deallocation needed? */
15
+ int refnumber;
16
+ int flags;
17
+ #define EXTRA_BOOKMARK 0x01
18
+ #define REFERENCED 0x02
15
19
  } Footnote;
16
20
 
17
21
  /* each input line is read into a Line, which contains the line,
@@ -75,24 +79,36 @@ typedef struct mmiot {
75
79
  Cstring in;
76
80
  Qblock Q;
77
81
  int isp;
82
+ int reference;
83
+ char *ref_prefix;
78
84
  STRING(Footnote) *footnotes;
79
- int flags;
80
- #define DENY_A 0x0001
81
- #define DENY_IMG 0x0002
82
- #define DENY_SMARTY 0x0004
83
- #define DENY_HTML 0x0008
84
- #define STRICT 0x0010
85
- #define INSIDE_TAG 0x0020
86
- #define NO_PSEUDO_PROTO 0x0040
87
- #define CDATA_OUTPUT 0x0080
88
- #define NOTABLES 0x0400
89
- #define NOSTRIKETHROUGH 0x0800
90
- #define TOC 0x1000
91
- #define MKD_1_COMPAT 0x2000
92
- #define AUTOLINK 0x4000
93
- #define SAFELINK 0x8000
94
- #define USER_FLAGS 0xFCFF
95
- #define EMBEDDED DENY_A|DENY_IMG|NO_PSEUDO_PROTO|CDATA_OUTPUT
85
+ DWORD flags;
86
+ #define MKD_NOLINKS 0x00000001
87
+ #define MKD_NOIMAGE 0x00000002
88
+ #define MKD_NOPANTS 0x00000004
89
+ #define MKD_NOHTML 0x00000008
90
+ #define MKD_STRICT 0x00000010
91
+ #define MKD_TAGTEXT 0x00000020
92
+ #define MKD_NO_EXT 0x00000040
93
+ #define MKD_CDATA 0x00000080
94
+ #define MKD_NOSUPERSCRIPT 0x00000100
95
+ #define MKD_NORELAXED 0x00000200
96
+ #define MKD_NOTABLES 0x00000400
97
+ #define MKD_NOSTRIKETHROUGH 0x00000800
98
+ #define MKD_TOC 0x00001000
99
+ #define MKD_1_COMPAT 0x00002000
100
+ #define MKD_AUTOLINK 0x00004000
101
+ #define MKD_SAFELINK 0x00008000
102
+ #define MKD_NOHEADER 0x00010000
103
+ #define MKD_TABSTOP 0x00020000
104
+ #define MKD_NODIVQUOTE 0x00040000
105
+ #define MKD_NOALPHALIST 0x00080000
106
+ #define MKD_NODLIST 0x00100000
107
+ #define MKD_EXTRA_FOOTNOTE 0x00200000
108
+ #define IS_LABEL 0x08000000
109
+ #define USER_FLAGS 0x0FFFFFFF
110
+ #define INPUT_MASK (MKD_NOHEADER|MKD_TABSTOP)
111
+
96
112
  Callback_data *cb;
97
113
  } MMIOT;
98
114
 
@@ -107,19 +123,22 @@ typedef struct mmiot {
107
123
  typedef struct document {
108
124
  int magic; /* "I AM VALID" magic number */
109
125
  #define VALID_DOCUMENT 0x19600731
110
- Line *headers; /* title -> author(s) -> date */
126
+ Line *title;
127
+ Line *author;
128
+ Line *date;
111
129
  ANCHOR(Line) content; /* uncompiled text, not valid after compile() */
112
130
  Paragraph *code; /* intermediate code generated by compile() */
113
131
  int compiled; /* set after mkd_compile() */
114
132
  int html; /* set after (internal) htmlify() */
115
133
  int tabstop; /* for properly expanding tabs (ick) */
134
+ char *ref_prefix;
116
135
  MMIOT *ctx; /* backend buffers, flags, and structures */
117
136
  Callback_data cb; /* callback functions & private data */
118
137
  } Document;
119
138
 
120
139
 
121
140
  extern int mkd_firstnonblank(Line *);
122
- extern int mkd_compile(Document *, int);
141
+ extern int mkd_compile(Document *, DWORD);
123
142
  extern int mkd_document(Document *, char **);
124
143
  extern int mkd_generatehtml(Document *, FILE *);
125
144
  extern int mkd_css(Document *, char **);
@@ -128,19 +147,21 @@ extern int mkd_generatecss(Document *, FILE *);
128
147
  extern int mkd_xml(char *, int , char **);
129
148
  extern int mkd_generatexml(char *, int, FILE *);
130
149
  extern void mkd_cleanup(Document *);
131
- extern int mkd_line(char *, int, char **, int);
132
- extern int mkd_generateline(char *, int, FILE*, int);
150
+ extern int mkd_line(char *, int, char **, DWORD);
151
+ extern int mkd_generateline(char *, int, FILE*, DWORD);
133
152
  #define mkd_text mkd_generateline
134
153
  extern void mkd_basename(Document*, char *);
135
- extern void mkd_string_to_anchor(char*,int, void(*)(int,void*), void*);
136
154
 
137
- extern Document *mkd_in(FILE *, int);
138
- extern Document *mkd_string(char*,int, int);
155
+ typedef int (*mkd_sta_function_t)(const int,const void*);
156
+ extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int);
157
+
158
+ extern Document *mkd_in(FILE *, DWORD);
159
+ extern Document *mkd_string(char*,int, DWORD);
139
160
 
140
- #define NO_HEADER 0x0100
141
- #define STD_TABSTOP 0x0200
142
- #define INPUT_MASK (NO_HEADER|STD_TABSTOP)
161
+ extern void mkd_initialize();
162
+ extern void mkd_shlib_destructor();
143
163
 
164
+ extern void mkd_ref_prefix(Document*, char*);
144
165
 
145
166
  /* internal resource handling functions.
146
167
  */
@@ -70,16 +70,14 @@ queue(Document* a, Cstring *line)
70
70
  }
71
71
 
72
72
 
73
- #ifdef PANDOC_HEADER
74
73
  /* trim leading blanks from a header line
75
74
  */
76
75
  static void
77
- snip(Line *p)
76
+ header_dle(Line *p)
78
77
  {
79
78
  CLIP(p->text, 0, 1);
80
79
  p->dle = mkd_firstnonblank(p);
81
80
  }
82
- #endif
83
81
 
84
82
 
85
83
  /* build a Document from any old input.
@@ -92,26 +90,22 @@ populate(getc_func getc, void* ctx, int flags)
92
90
  Cstring line;
93
91
  Document *a = new_Document();
94
92
  int c;
95
- #ifdef PANDOC_HEADER
96
93
  int pandoc = 0;
97
- #endif
98
94
 
99
95
  if ( !a ) return 0;
100
96
 
101
- a->tabstop = (flags & STD_TABSTOP) ? 4 : TABSTOP;
97
+ a->tabstop = (flags & MKD_TABSTOP) ? 4 : TABSTOP;
102
98
 
103
99
  CREATE(line);
104
100
 
105
101
  while ( (c = (*getc)(ctx)) != EOF ) {
106
102
  if ( c == '\n' ) {
107
- #ifdef PANDOC_HEADER
108
103
  if ( pandoc != EOF && pandoc < 3 ) {
109
104
  if ( S(line) && (T(line)[0] == '%') )
110
105
  pandoc++;
111
106
  else
112
107
  pandoc = EOF;
113
108
  }
114
- #endif
115
109
  queue(a, &line);
116
110
  S(line) = 0;
117
111
  }
@@ -124,20 +118,19 @@ populate(getc_func getc, void* ctx, int flags)
124
118
 
125
119
  DELETE(line);
126
120
 
127
- #ifdef PANDOC_HEADER
128
- if ( (pandoc == 3) && !(flags & NO_HEADER) ) {
121
+ if ( (pandoc == 3) && !(flags & (MKD_NOHEADER|MKD_STRICT)) ) {
129
122
  /* the first three lines started with %, so we have a header.
130
123
  * clip the first three lines out of content and hang them
131
124
  * off header.
132
125
  */
133
- a->headers = T(a->content);
134
- T(a->content) = a->headers->next->next->next;
135
- a->headers->next->next->next = 0;
136
- snip(a->headers);
137
- snip(a->headers->next);
138
- snip(a->headers->next->next);
126
+ Line *headers = T(a->content);
127
+
128
+ a->title = headers; header_dle(a->title);
129
+ a->author= headers->next; header_dle(a->author);
130
+ a->date = headers->next->next; header_dle(a->date);
131
+
132
+ T(a->content) = headers->next->next->next;
139
133
  }
140
- #endif
141
134
 
142
135
  return a;
143
136
  }
@@ -146,7 +139,7 @@ populate(getc_func getc, void* ctx, int flags)
146
139
  /* convert a file into a linked list
147
140
  */
148
141
  Document *
149
- mkd_in(FILE *f, int flags)
142
+ mkd_in(FILE *f, DWORD flags)
150
143
  {
151
144
  return populate((getc_func)fgetc, f, flags & INPUT_MASK);
152
145
  }
@@ -174,7 +167,7 @@ strget(struct string_ctx *in)
174
167
  /* convert a block of text into a linked list
175
168
  */
176
169
  Document *
177
- mkd_string(char *buf, int len, int flags)
170
+ mkd_string(char *buf, int len, DWORD flags)
178
171
  {
179
172
  struct string_ctx about;
180
173
 
@@ -194,7 +187,7 @@ mkd_generatehtml(Document *p, FILE *output)
194
187
  int szdoc;
195
188
 
196
189
  if ( (szdoc = mkd_document(p, &doc)) != EOF ) {
197
- if ( p->ctx->flags & CDATA_OUTPUT )
190
+ if ( p->ctx->flags & MKD_CDATA )
198
191
  mkd_generatexml(doc, szdoc, output);
199
192
  else
200
193
  fwrite(doc, szdoc, 1, output);
@@ -222,19 +215,32 @@ markdown(Document *document, FILE *out, int flags)
222
215
  /* write out a Cstring, mangled into a form suitable for `<a href=` or `<a id=`
223
216
  */
224
217
  void
225
- mkd_string_to_anchor(char *s, int len, void(*outchar)(int,void*), void *out)
218
+ mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
219
+ void *out, int labelformat)
226
220
  {
227
221
  unsigned char c;
222
+
223
+ int i, size;
224
+ char *line;
225
+
226
+ size = mkd_line(s, len, &line, IS_LABEL);
228
227
 
229
- for ( ; len-- > 0; ) {
230
- c = *s++;
231
- if ( c == ' ' || c == '&' || c == '<' || c == '"' )
232
- (*outchar)('+', out);
233
- else if ( isalnum(c) || ispunct(c) || (c & 0x80) )
234
- (*outchar)(c, out);
228
+ if ( labelformat && size && !isalpha(line[0]) )
229
+ (*outchar)('L',out);
230
+ for ( i=0; i < size ; i++ ) {
231
+ c = line[i];
232
+ if ( labelformat ) {
233
+ if ( isalnum(c) || (c == '_') || (c == ':') || (c == '-') || (c == '.' ) )
234
+ (*outchar)(c, out);
235
+ else
236
+ (*outchar)('.',out);
237
+ }
235
238
  else
236
- (*outchar)('~',out);
239
+ (*outchar)(c,out);
237
240
  }
241
+
242
+ if (line)
243
+ free(line);
238
244
  }
239
245
 
240
246
 
@@ -253,7 +259,7 @@ mkd_parse_line(char *bfr, int size, MMIOT *f, int flags)
253
259
  /* ___mkd_reparse() a line, returning it in malloc()ed memory
254
260
  */
255
261
  int
256
- mkd_line(char *bfr, int size, char **res, int flags)
262
+ mkd_line(char *bfr, int size, char **res, DWORD flags)
257
263
  {
258
264
  MMIOT f;
259
265
  int len;
@@ -266,9 +272,10 @@ mkd_line(char *bfr, int size, char **res, int flags)
266
272
  * should be an opaque method that transparently moves
267
273
  * the pointer out of the embedded Cstring.
268
274
  */
275
+ EXPAND(f.out) = 0;
269
276
  *res = T(f.out);
270
277
  T(f.out) = 0;
271
- S(f.out) = 0;
278
+ S(f.out) = ALLOCATED(f.out) = 0;
272
279
  }
273
280
  else {
274
281
  *res = 0;
@@ -282,12 +289,12 @@ mkd_line(char *bfr, int size, char **res, int flags)
282
289
  /* ___mkd_reparse() a line, writing it to a FILE
283
290
  */
284
291
  int
285
- mkd_generateline(char *bfr, int size, FILE *output, int flags)
292
+ mkd_generateline(char *bfr, int size, FILE *output, DWORD flags)
286
293
  {
287
294
  MMIOT f;
288
295
 
289
296
  mkd_parse_line(bfr, size, &f, flags);
290
- if ( flags & CDATA_OUTPUT )
297
+ if ( flags & MKD_CDATA )
291
298
  mkd_generatexml(T(f.out), S(f.out), output);
292
299
  else
293
300
  fwrite(T(f.out), S(f.out), 1, output);
@@ -335,3 +342,13 @@ mkd_e_data(Document *f, void *data)
335
342
  if ( f )
336
343
  f->cb.e_data = data;
337
344
  }
345
+
346
+
347
+ /* set the href prefix for markdown extra style footnotes
348
+ */
349
+ void
350
+ mkd_ref_prefix(Document *f, char *data)
351
+ {
352
+ if ( f )
353
+ f->ref_prefix = data;
354
+ }
@@ -5,24 +5,31 @@
5
5
 
6
6
  typedef void MMIOT;
7
7
 
8
+ typedef unsigned int mkd_flag_t;
9
+
8
10
  /* line builder for markdown()
9
11
  */
10
- MMIOT *mkd_in(FILE*,int); /* assemble input from a file */
11
- MMIOT *mkd_string(char*,int,int); /* assemble input from a buffer */
12
+ MMIOT *mkd_in(FILE*,mkd_flag_t); /* assemble input from a file */
13
+ MMIOT *mkd_string(char*,int,mkd_flag_t); /* assemble input from a buffer */
12
14
 
13
15
  void mkd_basename(MMIOT*,char*);
14
16
 
17
+ void mkd_initialize();
18
+ void mkd_with_html5_tags();
19
+ void mkd_shlib_destructor();
20
+
15
21
  /* compilation, debugging, cleanup
16
22
  */
17
- int mkd_compile(MMIOT*, int);
23
+ int mkd_compile(MMIOT*, mkd_flag_t);
18
24
  int mkd_cleanup(MMIOT*);
19
25
 
20
26
  /* markup functions
21
27
  */
22
28
  int mkd_dump(MMIOT*, FILE*, int, char*);
23
- int markdown(MMIOT*, FILE*, int);
24
- int mkd_line(char *, int, char **, int);
25
- void mkd_string_to_anchor(char *, int, int (*)(int,void*), void*);
29
+ int markdown(MMIOT*, FILE*, mkd_flag_t);
30
+ int mkd_line(char *, int, char **, mkd_flag_t);
31
+ typedef int (*mkd_sta_function_t)(const int,const void*);
32
+ void mkd_string_to_anchor(char *, int, mkd_sta_function_t, void*, int);
26
33
  int mkd_xhtmlpage(MMIOT*,int,FILE*);
27
34
 
28
35
  /* header block access
@@ -45,7 +52,7 @@ int mkd_generatetoc(MMIOT*,FILE*);
45
52
  int mkd_generatexml(char *, int,FILE*);
46
53
  int mkd_generatecss(MMIOT*,FILE*);
47
54
  #define mkd_style mkd_generatecss
48
- int mkd_generateline(char *, int, FILE*, int);
55
+ int mkd_generateline(char *, int, FILE*, mkd_flag_t);
49
56
  #define mkd_text mkd_generateline
50
57
 
51
58
  /* url generator callbacks
@@ -61,30 +68,41 @@ void mkd_e_data(void *, void *);
61
68
  /* version#.
62
69
  */
63
70
  extern char markdown_version[];
71
+ void mkd_mmiot_flags(FILE *, MMIOT *, int);
72
+ void mkd_flags_are(FILE*, mkd_flag_t, int);
73
+
74
+ void mkd_ref_prefix(MMIOT*, char*);
75
+
64
76
 
65
77
  /* special flags for markdown() and mkd_text()
66
78
  */
67
- #define MKD_NOLINKS 0x0001 /* don't do link processing, block <a> tags */
68
- #define MKD_NOIMAGE 0x0002 /* don't do image processing, block <img> */
69
- #define MKD_NOPANTS 0x0004 /* don't run smartypants() */
70
- #define MKD_NOHTML 0x0008 /* don't allow raw html through AT ALL */
71
- #define MKD_STRICT 0x0010 /* disable SUPERSCRIPT, RELAXED_EMPHASIS */
72
- #define MKD_TAGTEXT 0x0020 /* process text inside an html tag; no
73
- * <em>, no <bold>, no html or [] expansion */
74
- #define MKD_NO_EXT 0x0040 /* don't allow pseudo-protocols */
75
- #define MKD_CDATA 0x0080 /* generate code for xml ![CDATA[...]] */
76
- #define MKD_NOTABLES 0x0400 /* disallow tables */
77
- #define MKD_NOSTRIKETHROUGH 0x0800/* forbid ~~strikethrough~~ */
78
- #define MKD_TOC 0x1000 /* do table-of-contents processing */
79
- #define MKD_1_COMPAT 0x2000 /* compatability with MarkdownTest_1.0 */
80
- #define MKD_AUTOLINK 0x4000 /* make http://foo.com link even without <>s */
81
- #define MKD_SAFELINK 0x8000 /* paranoid check for link protocol */
79
+ #define MKD_NOLINKS 0x00000001 /* don't do link processing, block <a> tags */
80
+ #define MKD_NOIMAGE 0x00000002 /* don't do image processing, block <img> */
81
+ #define MKD_NOPANTS 0x00000004 /* don't run smartypants() */
82
+ #define MKD_NOHTML 0x00000008 /* don't allow raw html through AT ALL */
83
+ #define MKD_STRICT 0x00000010 /* disable SUPERSCRIPT, RELAXED_EMPHASIS */
84
+ #define MKD_TAGTEXT 0x00000020 /* process text inside an html tag; no
85
+ * <em>, no <bold>, no html or [] expansion */
86
+ #define MKD_NO_EXT 0x00000040 /* don't allow pseudo-protocols */
87
+ #define MKD_CDATA 0x00000080 /* generate code for xml ![CDATA[...]] */
88
+ #define MKD_NOSUPERSCRIPT 0x00000100 /* no A^B */
89
+ #define MKD_NORELAXED 0x00000200 /* emphasis happens /everywhere/ */
90
+ #define MKD_NOTABLES 0x00000400 /* disallow tables */
91
+ #define MKD_NOSTRIKETHROUGH 0x00000800 /* forbid ~~strikethrough~~ */
92
+ #define MKD_TOC 0x00001000 /* do table-of-contents processing */
93
+ #define MKD_1_COMPAT 0x00002000 /* compatibility with MarkdownTest_1.0 */
94
+ #define MKD_AUTOLINK 0x00004000 /* make http://foo.com link even without <>s */
95
+ #define MKD_SAFELINK 0x00008000 /* paranoid check for link protocol */
96
+ #define MKD_NOHEADER 0x00010000 /* don't process header blocks */
97
+ #define MKD_TABSTOP 0x00020000 /* expand tabs to 4 spaces */
98
+ #define MKD_NODIVQUOTE 0x00040000 /* forbid >%class% blocks */
99
+ #define MKD_NOALPHALIST 0x00080000 /* forbid alphabetic lists */
100
+ #define MKD_NODLIST 0x00100000 /* forbid definition lists */
101
+ #define MKD_EXTRA_FOOTNOTE 0x00200000 /* enable markdown extra-style footnotes */
82
102
  #define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
83
103
 
84
104
  /* special flags for mkd_in() and mkd_string()
85
105
  */
86
- #define MKD_NOHEADER 0x0100 /* don't process header blocks */
87
- #define MKD_TABSTOP 0x0200 /* expand tabs to 4 spaces */
88
106
 
89
107
 
90
108
  #endif/*_MKDIO_D*/
@@ -82,6 +82,10 @@ int rb_rdiscount__get_flags(VALUE ruby_obj)
82
82
  if ( rb_funcall(ruby_obj, rb_intern("filter_html"), 0) == Qtrue )
83
83
  flags = flags | MKD_NOHTML;
84
84
 
85
+ /* footnotes */
86
+ if ( rb_funcall(ruby_obj, rb_intern("footnotes"), 0) == Qtrue )
87
+ flags = flags | MKD_EXTRA_FOOTNOTE;
88
+
85
89
  /* generate_toc */
86
90
  if ( rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
87
91
  flags = flags | MKD_TOC;
@@ -147,7 +147,9 @@ mkd_cleanup(Document *doc)
147
147
  }
148
148
 
149
149
  if ( doc->code) ___mkd_freeParagraph(doc->code);
150
- if ( doc->headers ) ___mkd_freeLines(doc->headers);
150
+ if ( doc->title) ___mkd_freeLine(doc->title);
151
+ if ( doc->author) ___mkd_freeLine(doc->author);
152
+ if ( doc->date) ___mkd_freeLine(doc->date);
151
153
  if ( T(doc->content) ) ___mkd_freeLines(T(doc->content));
152
154
  memset(doc, 0, sizeof doc[0]);
153
155
  free(doc);
@@ -0,0 +1,47 @@
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 "config.h"
8
+
9
+ #include <stdio.h>
10
+ #include <string.h>
11
+ #include <stdarg.h>
12
+ #include <stdlib.h>
13
+ #include <time.h>
14
+ #include <ctype.h>
15
+
16
+ #include "cstring.h"
17
+ #include "markdown.h"
18
+ #include "amalloc.h"
19
+ #include "tags.h"
20
+
21
+ static int need_to_setup = 1;
22
+ static int need_to_initrng = 1;
23
+
24
+ void
25
+ mkd_initialize()
26
+ {
27
+
28
+ if ( need_to_initrng ) {
29
+ need_to_initrng = 0;
30
+ INITRNG(time(0));
31
+ }
32
+ if ( need_to_setup ) {
33
+ need_to_setup = 0;
34
+ mkd_prepare_tags();
35
+ }
36
+ }
37
+
38
+
39
+ void
40
+ mkd_shlib_destructor()
41
+ {
42
+ if ( !need_to_setup ) {
43
+ need_to_setup = 1;
44
+ mkd_deallocate_tags();
45
+ }
46
+ }
47
+