rdiscountwl 1.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/mktags.c ADDED
@@ -0,0 +1,89 @@
1
+ /* block-level tags for passing html blocks through the blender
2
+ */
3
+ #include <stdio.h>
4
+
5
+ #define __WITHOUT_AMALLOC 1
6
+ #include "cstring.h"
7
+ #include "tags.h"
8
+
9
+ STRING(struct kw) blocktags;
10
+
11
+
12
+ /* define a html block tag
13
+ */
14
+ static void
15
+ define_one_tag(char *id, int selfclose)
16
+ {
17
+ struct kw *p = &EXPAND(blocktags);
18
+
19
+ p->id = id;
20
+ p->size = strlen(id);
21
+ p->selfclose = selfclose;
22
+ }
23
+
24
+
25
+ /* case insensitive string sort (for qsort() and bsearch() of block tags)
26
+ */
27
+ static int
28
+ casort(struct kw *a, struct kw *b)
29
+ {
30
+ if ( a->size != b->size )
31
+ return a->size - b->size;
32
+ return strncasecmp(a->id, b->id, b->size);
33
+ }
34
+
35
+
36
+ /* stupid cast to make gcc shut up about the function types being
37
+ * passed into qsort() and bsearch()
38
+ */
39
+ typedef int (*stfu)(const void*,const void*);
40
+
41
+
42
+ /* load in the standard collection of html tags that markdown supports
43
+ */
44
+ main()
45
+ {
46
+ int i;
47
+
48
+ #define KW(x) define_one_tag(x, 0)
49
+ #define SC(x) define_one_tag(x, 1)
50
+
51
+ KW("STYLE");
52
+ KW("SCRIPT");
53
+ KW("ADDRESS");
54
+ KW("BDO");
55
+ KW("BLOCKQUOTE");
56
+ KW("CENTER");
57
+ KW("DFN");
58
+ KW("DIV");
59
+ KW("OBJECT");
60
+ KW("H1");
61
+ KW("H2");
62
+ KW("H3");
63
+ KW("H4");
64
+ KW("H5");
65
+ KW("H6");
66
+ KW("LISTING");
67
+ KW("NOBR");
68
+ KW("UL");
69
+ KW("P");
70
+ KW("OL");
71
+ KW("DL");
72
+ KW("PLAINTEXT");
73
+ KW("PRE");
74
+ KW("TABLE");
75
+ KW("WBR");
76
+ KW("XMP");
77
+ SC("HR");
78
+ KW("IFRAME");
79
+ KW("MAP");
80
+
81
+ qsort(T(blocktags), S(blocktags), sizeof(struct kw), (stfu)casort);
82
+
83
+ printf("static struct kw blocktags[] = {\n");
84
+ for (i=0; i < S(blocktags); i++)
85
+ printf(" { \"%s\", %d, %d },\n", T(blocktags)[i].id, T(blocktags)[i].size, T(blocktags)[i].selfclose );
86
+ printf("};\n\n");
87
+ printf("#define NR_blocktags %d\n", S(blocktags));
88
+ exit(0);
89
+ }
data/ext/pgm_options.c ADDED
@@ -0,0 +1,146 @@
1
+ /* markdown: a C implementation of John Gruber's Markdown markup language.
2
+ *
3
+ * Copyright (C) 2007-2011 David L Parsons.
4
+ * The redistribution terms are provided in the COPYRIGHT file that must
5
+ * be distributed with this source code.
6
+ */
7
+
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <limits.h>
11
+ #ifndef _MSC_VER
12
+ #include <unistd.h>
13
+ #endif
14
+ #include <mkdio.h>
15
+ #include <errno.h>
16
+ #include <string.h>
17
+ #include <stdarg.h>
18
+
19
+ #include "config.h"
20
+ #include "amalloc.h"
21
+
22
+ #if HAVE_LIBGEN_H
23
+ #include <libgen.h>
24
+ #endif
25
+
26
+ static struct _opt {
27
+ char *name;
28
+ char *desc;
29
+ int off;
30
+ int skip; /* this opt is a synonym */
31
+ int sayenable;
32
+ mkd_flag_t flag;
33
+ } opts[] = {
34
+ { "tabstop", "default (4-space) tabstops", 0, 0, 1, MKD_TABSTOP },
35
+ { "image", "images", 1, 0, 1, MKD_NOIMAGE },
36
+ { "links", "links", 1, 0, 1, MKD_NOLINKS },
37
+ { "relax", "emphasis inside words", 1, 1, 1, MKD_STRICT },
38
+ { "strict", "emphasis inside words", 0, 0, 1, MKD_STRICT },
39
+ { "tables", "tables", 1, 0, 1, MKD_NOTABLES },
40
+ { "header", "pandoc-style headers", 1, 0, 1, MKD_NOHEADER },
41
+ { "html", "raw html", 1, 0, 1, MKD_NOHTML },
42
+ { "ext", "extended protocols", 1, 0, 1, MKD_NO_EXT },
43
+ { "cdata", "generate cdata", 0, 0, 0, MKD_CDATA },
44
+ { "smarty", "smartypants", 1, 0, 1, MKD_NOPANTS },
45
+ { "pants", "smartypants", 1, 1, 1, MKD_NOPANTS },
46
+ { "toc", "tables of contents", 0, 0, 1, MKD_TOC },
47
+ { "autolink", "autolinking", 0, 0, 1, MKD_AUTOLINK },
48
+ { "safelink", "safe links", 0, 0, 1, MKD_SAFELINK },
49
+ { "strikethrough", "strikethrough", 1, 0, 1, MKD_NOSTRIKETHROUGH },
50
+ { "del", "strikethrough", 1, 1, 1, MKD_NOSTRIKETHROUGH },
51
+ { "superscript", "superscript", 1, 0, 1, MKD_NOSUPERSCRIPT },
52
+ { "emphasis", "emphasis inside words", 0, 0, 1, MKD_NORELAXED },
53
+ { "divquote", ">%class% blockquotes", 1, 0, 1, MKD_NODIVQUOTE },
54
+ { "alphalist", "alpha lists", 1, 0, 1, MKD_NOALPHALIST },
55
+ { "definitionlist","definition lists", 1, 0, 1, MKD_NODLIST },
56
+ { "1.0", "markdown 1.0 compatibility", 0, 0, 1, MKD_1_COMPAT },
57
+ { "footnotes", "markdown extra footnotes", 0, 0, 1, MKD_EXTRA_FOOTNOTE },
58
+ { "footnote", "markdown extra footnotes", 0, 1, 1, MKD_EXTRA_FOOTNOTE },
59
+ { "style", "extract style blocks", 1, 0, 1, MKD_NOSTYLE },
60
+ { "dldiscount", "discount-style definition lists", 1, 0, 1, MKD_NODLDISCOUNT },
61
+ { "dlextra", "extra-style definition lists", 0, 0, 1, MKD_DLEXTRA },
62
+ { "fencedcode", "fenced code blocks", 0, 0, 1, MKD_FENCEDCODE },
63
+ { "idanchor", "id= anchors in TOC", 0, 0, 1, MKD_IDANCHOR },
64
+ { "githubtags", "permit - and _ in element names", 0, 0, 0, MKD_GITHUBTAGS },
65
+ { "urlencodedanchor", "urlencode special chars in TOC links", 0, 0, 0, MKD_URLENCODEDANCHOR },
66
+ } ;
67
+
68
+ #define NR(x) (sizeof x / sizeof x[0])
69
+
70
+
71
+ typedef int (*stfu)(const void *, const void *);
72
+
73
+ int
74
+ sort_by_name(struct _opt *a, struct _opt *b)
75
+ {
76
+ return strcmp(a->name,b->name);
77
+ }
78
+
79
+ int
80
+ sort_by_flag(struct _opt *a, struct _opt *b)
81
+ {
82
+ return a->flag - b->flag;
83
+ }
84
+
85
+
86
+ void
87
+ show_flags(int byname)
88
+ {
89
+ int i;
90
+
91
+ if ( byname ) {
92
+ qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name);
93
+
94
+ for (i=0; i < NR(opts); i++)
95
+ if ( ! opts[i].skip )
96
+ fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc);
97
+ }
98
+ else {
99
+ qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag);
100
+
101
+ for (i=0; i < NR(opts); i++)
102
+ if ( ! opts[i].skip ) {
103
+ fprintf(stderr, "%08lx : ", (long)opts[i].flag);
104
+ if ( opts[i].sayenable )
105
+ fprintf(stderr, opts[i].off ? "disable " : "enable ");
106
+ fprintf(stderr, "%s\n", opts[i].desc);
107
+ }
108
+ }
109
+ }
110
+
111
+
112
+ int
113
+ set_flag(mkd_flag_t *flags, char *optionstring)
114
+ {
115
+ int i;
116
+ int enable;
117
+ char *arg;
118
+
119
+ for ( arg = strtok(optionstring, ","); arg; arg = strtok(NULL, ",") ) {
120
+ if ( *arg == '+' || *arg == '-' )
121
+ enable = (*arg++ == '+') ? 1 : 0;
122
+ else if ( strncasecmp(arg, "no", 2) == 0 ) {
123
+ arg += 2;
124
+ enable = 0;
125
+ }
126
+ else
127
+ enable = 1;
128
+
129
+ for ( i=0; i < NR(opts); i++ )
130
+ if ( strcasecmp(arg, opts[i].name) == 0 )
131
+ break;
132
+
133
+ if ( i < NR(opts) ) {
134
+ if ( opts[i].off )
135
+ enable = !enable;
136
+
137
+ if ( enable )
138
+ *flags |= opts[i].flag;
139
+ else
140
+ *flags &= ~opts[i].flag;
141
+ }
142
+ else
143
+ return 0;
144
+ }
145
+ return 1;
146
+ }
data/ext/pgm_options.h ADDED
@@ -0,0 +1,9 @@
1
+ #ifndef PGM_OPTIONS_D
2
+ #define PGM_OPTIONS_D
3
+
4
+ #include <mkdio.h>
5
+
6
+ int set_flag(mkd_flag_t *flags, char *optionstring);
7
+ void show_flags(int byname);
8
+
9
+ #endif/*PGM_OPTIONS_D*/
data/ext/rdiscount.c ADDED
@@ -0,0 +1,150 @@
1
+ #include <stdio.h>
2
+ #include <locale.h>
3
+ #include "ruby.h"
4
+ #include "mkdio.h"
5
+
6
+ typedef struct {
7
+ char *accessor_name;
8
+ int flag;
9
+ } AccessorFlagPair;
10
+
11
+ /*
12
+ * Maps accessor names on the RDiscount object to Discount flags.
13
+ *
14
+ * The following flags are handled specially:
15
+ * - MKD_TABSTOP: Always set.
16
+ * - MKD_NOHEADER: Always set.
17
+ * - MKD_DLEXTRA: Always set. (For compatibility with RDiscount 2.1.8 and earlier.)
18
+ * - MKD_FENCEDCODE: Always set. (For compatibility with RDiscount 2.1.8 and earlier.)
19
+ * - MKD_GITHUBTAGS: Always set. (For compatibility with RDiscount 2.1.8 and earlier.)
20
+ * - MKD_NOPANTS: Set unless the "smart" accessor returns true.
21
+ *
22
+ * See rb_rdiscount__get_flags() for the detailed implementation.
23
+ */
24
+ static AccessorFlagPair ACCESSOR_2_FLAG[] = {
25
+ { "filter_html", MKD_NOHTML },
26
+ { "footnotes", MKD_EXTRA_FOOTNOTE },
27
+ { "generate_toc", MKD_TOC },
28
+ { "no_image", MKD_NOIMAGE },
29
+ { "no_links", MKD_NOLINKS },
30
+ { "no_tables", MKD_NOTABLES },
31
+ { "strict", MKD_STRICT },
32
+ { "autolink", MKD_AUTOLINK },
33
+ { "safelink", MKD_SAFELINK },
34
+ { "no_pseudo_protocols", MKD_NO_EXT },
35
+ { "no_superscript", MKD_NOSUPERSCRIPT },
36
+ { "no_strikethrough", MKD_NOSTRIKETHROUGH },
37
+ { NULL, 0 } /* sentinel */
38
+ };
39
+
40
+ static VALUE rb_cRDiscount;
41
+
42
+ int rb_rdiscount__get_flags(VALUE ruby_obj)
43
+ {
44
+ AccessorFlagPair *entry;
45
+
46
+ /* compile flags */
47
+ int flags = MKD_TABSTOP | MKD_NOHEADER | MKD_DLEXTRA | MKD_FENCEDCODE | MKD_GITHUBTAGS;
48
+
49
+ /* The "smart" accessor turns OFF the MKD_NOPANTS flag. */
50
+ if ( rb_funcall(ruby_obj, rb_intern("smart"), 0) != Qtrue ) {
51
+ flags = flags | MKD_NOPANTS;
52
+ }
53
+
54
+ /* Handle standard flags declared in ACCESSOR_2_FLAG */
55
+ for ( entry = ACCESSOR_2_FLAG; entry->accessor_name; entry++ ) {
56
+ if ( rb_funcall(ruby_obj, rb_intern(entry->accessor_name), 0) == Qtrue ) {
57
+ flags = flags | entry->flag;
58
+ }
59
+ }
60
+
61
+ return flags;
62
+ }
63
+
64
+ static VALUE
65
+ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
66
+ {
67
+ /* grab char pointer to markdown input text */
68
+ char *res;
69
+ int szres;
70
+ VALUE encoding;
71
+ VALUE text = rb_funcall(self, rb_intern("text"), 0);
72
+ VALUE buf = rb_str_buf_new(1024);
73
+ Check_Type(text, T_STRING);
74
+
75
+ int flags = rb_rdiscount__get_flags(self);
76
+
77
+ /*
78
+ * Force Discount to use ASCII character encoding for isalnum(), isalpha(),
79
+ * and similar functions.
80
+ *
81
+ * Ruby tends to use UTF-8 encoding, which is ill-defined for these
82
+ * functions since they expect 8-bit codepoints (and UTF-8 has codepoints
83
+ * of at least 21 bits).
84
+ */
85
+ char *old_locale = strdup(setlocale(LC_CTYPE, NULL));
86
+ setlocale(LC_CTYPE, "C"); /* ASCII (and passthru characters > 127) */
87
+
88
+ MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
89
+
90
+ if ( mkd_compile(doc, flags) ) {
91
+ szres = mkd_document(doc, &res);
92
+
93
+ if ( szres != EOF ) {
94
+ rb_str_cat(buf, res, szres);
95
+ rb_str_cat(buf, "\n", 1);
96
+ }
97
+ }
98
+ mkd_cleanup(doc);
99
+
100
+ setlocale(LC_CTYPE, old_locale);
101
+ free(old_locale);
102
+
103
+ /* force the input encoding */
104
+ if ( rb_respond_to(text, rb_intern("encoding")) ) {
105
+ encoding = rb_funcall(text, rb_intern("encoding"), 0);
106
+ rb_funcall(buf, rb_intern("force_encoding"), 1, encoding);
107
+ }
108
+
109
+ return buf;
110
+ }
111
+
112
+ static VALUE
113
+ rb_rdiscount_toc_content(int argc, VALUE *argv, VALUE self)
114
+ {
115
+ char *res;
116
+ int szres;
117
+
118
+ int flags = rb_rdiscount__get_flags(self);
119
+
120
+ /* grab char pointer to markdown input text */
121
+ VALUE text = rb_funcall(self, rb_intern("text"), 0);
122
+ Check_Type(text, T_STRING);
123
+
124
+ /* allocate a ruby string buffer and wrap it in a stream */
125
+ VALUE buf = rb_str_buf_new(4096);
126
+
127
+ MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
128
+
129
+ if ( mkd_compile(doc, flags) ) {
130
+ szres = mkd_toc(doc, &res);
131
+
132
+ if ( szres != EOF ) {
133
+ rb_str_cat(buf, res, szres);
134
+ rb_str_cat(buf, "\n", 1);
135
+ }
136
+ }
137
+ mkd_cleanup(doc);
138
+
139
+ return buf;
140
+ }
141
+
142
+
143
+ void Init_rdiscount()
144
+ {
145
+ rb_cRDiscount = rb_define_class("RDiscount", rb_cObject);
146
+ rb_define_method(rb_cRDiscount, "to_html", rb_rdiscount_to_html, -1);
147
+ rb_define_method(rb_cRDiscount, "toc_content", rb_rdiscount_toc_content, -1);
148
+ }
149
+
150
+ /* vim: set ts=4 sw=4: */
data/ext/resource.c ADDED
@@ -0,0 +1,159 @@
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
+ if (p->lang)
55
+ free(p->lang);
56
+ free(p);
57
+ }
58
+
59
+
60
+ /* bye bye footnote.
61
+ */
62
+ void
63
+ ___mkd_freefootnote(Footnote *f)
64
+ {
65
+ DELETE(f->tag);
66
+ DELETE(f->link);
67
+ DELETE(f->title);
68
+ }
69
+
70
+
71
+ /* bye bye footnotes.
72
+ */
73
+ void
74
+ ___mkd_freefootnotes(MMIOT *f)
75
+ {
76
+ int i;
77
+
78
+ if ( f->footnotes ) {
79
+ for (i=0; i < S(f->footnotes->note); i++)
80
+ ___mkd_freefootnote( &T(f->footnotes->note)[i] );
81
+ DELETE(f->footnotes->note);
82
+ free(f->footnotes);
83
+ }
84
+ }
85
+
86
+
87
+ /* initialize a new MMIOT
88
+ */
89
+ void
90
+ ___mkd_initmmiot(MMIOT *f, void *footnotes)
91
+ {
92
+ if ( f ) {
93
+ memset(f, 0, sizeof *f);
94
+ CREATE(f->in);
95
+ CREATE(f->out);
96
+ CREATE(f->Q);
97
+ if ( footnotes )
98
+ f->footnotes = footnotes;
99
+ else {
100
+ f->footnotes = malloc(sizeof f->footnotes[0]);
101
+ CREATE(f->footnotes->note);
102
+ }
103
+ }
104
+ }
105
+
106
+
107
+ /* free the contents of a MMIOT, but leave the object alone.
108
+ */
109
+ void
110
+ ___mkd_freemmiot(MMIOT *f, void *footnotes)
111
+ {
112
+ if ( f ) {
113
+ DELETE(f->in);
114
+ DELETE(f->out);
115
+ DELETE(f->Q);
116
+ if ( f->footnotes != footnotes )
117
+ ___mkd_freefootnotes(f);
118
+ memset(f, 0, sizeof *f);
119
+ }
120
+ }
121
+
122
+
123
+ /* free lines up to an barrier.
124
+ */
125
+ void
126
+ ___mkd_freeLineRange(Line *anchor, Line *stop)
127
+ {
128
+ Line *r = anchor->next;
129
+
130
+ if ( r != stop ) {
131
+ while ( r && (r->next != stop) )
132
+ r = r->next;
133
+ if ( r ) r->next = 0;
134
+ ___mkd_freeLines(anchor->next);
135
+ }
136
+ anchor->next = 0;
137
+ }
138
+
139
+
140
+ /* clean up everything allocated in __mkd_compile()
141
+ */
142
+ void
143
+ mkd_cleanup(Document *doc)
144
+ {
145
+ if ( doc && (doc->magic == VALID_DOCUMENT) ) {
146
+ if ( doc->ctx ) {
147
+ ___mkd_freemmiot(doc->ctx, 0);
148
+ free(doc->ctx);
149
+ }
150
+
151
+ if ( doc->code) ___mkd_freeParagraph(doc->code);
152
+ if ( doc->title) ___mkd_freeLine(doc->title);
153
+ if ( doc->author) ___mkd_freeLine(doc->author);
154
+ if ( doc->date) ___mkd_freeLine(doc->date);
155
+ if ( T(doc->content) ) ___mkd_freeLines(T(doc->content));
156
+ memset(doc, 0, sizeof doc[0]);
157
+ free(doc);
158
+ }
159
+ }
data/ext/setup.c ADDED
@@ -0,0 +1,39 @@
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_initrng = 1;
22
+
23
+ void
24
+ mkd_initialize()
25
+ {
26
+
27
+ if ( need_to_initrng ) {
28
+ need_to_initrng = 0;
29
+ INITRNG(time(0));
30
+ }
31
+ }
32
+
33
+
34
+ void
35
+ mkd_shlib_destructor()
36
+ {
37
+ mkd_deallocate_tags();
38
+ }
39
+
data/ext/tags.c ADDED
@@ -0,0 +1,94 @@
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) extratags;
8
+
9
+ /* the standard collection of tags are built and sorted when
10
+ * discount is configured, so all we need to do is pull them
11
+ * in and use them.
12
+ *
13
+ * Additional tags still need to be allocated, sorted, and deallocated.
14
+ */
15
+ #include "blocktags"
16
+
17
+
18
+ /* define an additional html block tag
19
+ */
20
+ void
21
+ mkd_define_tag(char *id, int selfclose)
22
+ {
23
+ struct kw *p;
24
+
25
+ /* only add the new tag if it doesn't exist in
26
+ * either the standard or extra tag tables.
27
+ */
28
+ if ( !(p = mkd_search_tags(id, strlen(id))) ) {
29
+ /* extratags could be deallocated */
30
+ if ( S(extratags) == 0 )
31
+ CREATE(extratags);
32
+ p = &EXPAND(extratags);
33
+ p->id = id;
34
+ p->size = strlen(id);
35
+ p->selfclose = selfclose;
36
+ }
37
+ }
38
+
39
+
40
+ /* case insensitive string sort (for qsort() and bsearch() of block tags)
41
+ */
42
+ static int
43
+ casort(struct kw *a, struct kw *b)
44
+ {
45
+ if ( a->size != b->size )
46
+ return a->size - b->size;
47
+ return strncasecmp(a->id, b->id, b->size);
48
+ }
49
+
50
+
51
+ /* stupid cast to make gcc shut up about the function types being
52
+ * passed into qsort() and bsearch()
53
+ */
54
+ typedef int (*stfu)(const void*,const void*);
55
+
56
+
57
+ /* sort the list of extra html block tags for later searching
58
+ */
59
+ void
60
+ mkd_sort_tags()
61
+ {
62
+ qsort(T(extratags), S(extratags), sizeof(struct kw), (stfu)casort);
63
+ }
64
+
65
+
66
+ /* look for a token in the html block tag list
67
+ */
68
+ struct kw*
69
+ mkd_search_tags(char *pat, int len)
70
+ {
71
+ struct kw key;
72
+ struct kw *ret;
73
+
74
+ key.id = pat;
75
+ key.size = len;
76
+
77
+ if ( (ret=bsearch(&key,blocktags,NR_blocktags,sizeof key,(stfu)casort)) )
78
+ return ret;
79
+
80
+ if ( S(extratags) )
81
+ return bsearch(&key,T(extratags),S(extratags),sizeof key,(stfu)casort);
82
+
83
+ return 0;
84
+ }
85
+
86
+
87
+ /* destroy the extratags list (for shared libraries)
88
+ */
89
+ void
90
+ mkd_deallocate_tags()
91
+ {
92
+ if ( S(extratags) > 0 )
93
+ DELETE(extratags);
94
+ } /* 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