rdiscountwl 1.0.0.1

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/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