moredown 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,169 @@
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 footnotes.
59
+ */
60
+ void
61
+ ___mkd_freefootnotes(MMIOT *f)
62
+ {
63
+ int i;
64
+
65
+ if ( f->footnotes ) {
66
+ for (i=0; i < S(*f->footnotes); i++) {
67
+ DELETE(T(*f->footnotes)[i].tag);
68
+ DELETE(T(*f->footnotes)[i].link);
69
+ DELETE(T(*f->footnotes)[i].title);
70
+ }
71
+ DELETE(*f->footnotes);
72
+ free(f->footnotes);
73
+ }
74
+ }
75
+
76
+
77
+ /* initialize a new MMIOT
78
+ */
79
+ void
80
+ ___mkd_initmmiot(MMIOT *f, void *footnotes)
81
+ {
82
+ if ( f ) {
83
+ memset(f, 0, sizeof *f);
84
+ CREATE(f->in);
85
+ CREATE(f->out);
86
+ CREATE(f->Q);
87
+ if ( footnotes )
88
+ f->footnotes = footnotes;
89
+ else {
90
+ f->footnotes = malloc(sizeof f->footnotes[0]);
91
+ CREATE(*f->footnotes);
92
+ }
93
+ }
94
+ }
95
+
96
+
97
+ /* free the contents of a MMIOT, but leave the object alone.
98
+ */
99
+ void
100
+ ___mkd_freemmiot(MMIOT *f, void *footnotes)
101
+ {
102
+ if ( f ) {
103
+ DELETE(f->in);
104
+ DELETE(f->out);
105
+ DELETE(f->Q);
106
+ if ( f->footnotes != footnotes )
107
+ ___mkd_freefootnotes(f);
108
+ memset(f, 0, sizeof *f);
109
+ }
110
+ }
111
+
112
+
113
+ /* free lines up to an barrier.
114
+ */
115
+ void
116
+ ___mkd_freeLineRange(Line *anchor, Line *stop)
117
+ {
118
+ Line *r = anchor->next;
119
+
120
+ if ( r != stop ) {
121
+ while ( r && (r->next != stop) )
122
+ r = r->next;
123
+ if ( r ) r->next = 0;
124
+ ___mkd_freeLines(anchor->next);
125
+ }
126
+ anchor->next = 0;
127
+ }
128
+
129
+
130
+ /* clean up everything allocated in __mkd_compile()
131
+ */
132
+ void
133
+ mkd_cleanup(Document *doc)
134
+ {
135
+ if ( doc ) {
136
+ if ( doc->ctx ) {
137
+ ___mkd_freemmiot(doc->ctx, 0);
138
+ free(doc->ctx);
139
+ }
140
+
141
+ if ( doc->code) ___mkd_freeParagraph(doc->code);
142
+ if ( doc->headers ) ___mkd_freeLines(doc->headers);
143
+ if ( T(doc->content) ) ___mkd_freeLines(T(doc->content));
144
+ memset(doc, 0, sizeof doc[0]);
145
+ free(doc);
146
+ }
147
+ }
148
+
149
+
150
+ /* write output in XML format
151
+ */
152
+ void
153
+ ___mkd_xml(char *p, int size, FILE *out)
154
+ {
155
+ char c;
156
+
157
+ while ( size-- > 0 ) {
158
+ if ( !isascii(c = *p++) )
159
+ continue;
160
+ switch (c) {
161
+ case '<': fputs("&lt;", out); break;
162
+ case '>': fputs("&gt;", out); break;
163
+ case '&': fputs("&amp;", out); break;
164
+ case '"': fputs("&quot;", out); break;
165
+ case '\'':fputs("&apos;", out); break;
166
+ default: putc(c,out); break;
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,86 @@
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 *pp;
23
+ int last_hnumber = 0;
24
+ Cstring res;
25
+
26
+ CREATE(res);
27
+ RESERVE(res, 100);
28
+
29
+ *doc = 0;
30
+
31
+ if ( !(p && p->ctx) ) return -1;
32
+ if ( ! (p->ctx->flags & TOC) ) return 0;
33
+
34
+ for ( pp = p->code; pp ; pp = pp->next ) {
35
+ if ( pp->typ == HDR && pp->text ) {
36
+
37
+ if ( last_hnumber == pp->hnumber )
38
+ Csprintf(&res, "%*s</li>\n", pp->hnumber, "");
39
+ else while ( last_hnumber > pp->hnumber ) {
40
+ Csprintf(&res, "%*s</li>\n%*s</ul>\n",
41
+ last_hnumber, "",
42
+ last_hnumber-1,"");
43
+ --last_hnumber;
44
+ }
45
+
46
+ while ( pp->hnumber > last_hnumber ) {
47
+ Csprintf(&res, "\n%*s<ul>\n", pp->hnumber, "");
48
+ ++last_hnumber;
49
+ }
50
+ Csprintf(&res, "%*s<li><a href=\"#", pp->hnumber, "");
51
+ mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Csputc, &res);
52
+ Csprintf(&res, "\">");
53
+ Csreparse(&res, T(pp->text->text), S(pp->text->text), 0);
54
+ Csprintf(&res, "</a>");
55
+ }
56
+ }
57
+
58
+ while ( last_hnumber > 0 ) {
59
+ Csprintf(&res, "%*s</li>\n%*s</ul>\n",
60
+ last_hnumber, "", last_hnumber, "");
61
+ --last_hnumber;
62
+ }
63
+ /* HACK ALERT! HACK ALERT! HACK ALERT! */
64
+ *doc = T(res); /* we know that a T(Cstring) is a character pointer */
65
+ /* so we can simply pick it up and carry it away, */
66
+ return S(res); /* leaving the husk of the Ctring on the stack */
67
+ /* END HACK ALERT */
68
+ }
69
+
70
+
71
+ /* write an header index
72
+ */
73
+ int
74
+ mkd_generatetoc(Document *p, FILE *out)
75
+ {
76
+ char *buf = 0;
77
+ int sz = mkd_toc(p, &buf);
78
+ int ret = EOF;
79
+
80
+ if ( sz > 0 )
81
+ ret = fwrite(buf, sz, 1, out);
82
+
83
+ if ( buf ) free(buf);
84
+
85
+ return ret;
86
+ }
@@ -0,0 +1 @@
1
+ require 'rdiscount'
@@ -0,0 +1,153 @@
1
+ require 'rdiscount'
2
+
3
+ class Moredown < RDiscount
4
+ VERSION = '1.0.4'
5
+
6
+ # Don't use inline CSS for styling
7
+ attr_accessor :has_stylesheet
8
+
9
+ # Process emoticons
10
+ attr_accessor :emotes
11
+
12
+ # Map any relative URLs in the text to absolute URLs
13
+ attr_accessor :base_url
14
+
15
+ # Map headings down a few ranks (eg. :map_headings => 2 would convert h1 to h3)
16
+ attr_accessor :map_headings
17
+
18
+ # Use SwfObject2 if available (eg. :swfobject => { :src => 'swfobject.js', :version => '10', :fallback => 'No Flash' })
19
+ attr_accessor :swfobject
20
+
21
+ # Create a Moredown Markdown processor. The +text+ argument
22
+ # should be a string containing Markdown text. Additional arguments may be
23
+ # supplied to set various processing options:
24
+ #
25
+ # * <tt>:extensions</tt> - Any of the following RDiscount Extensions:
26
+ # * <tt>:smart</tt> - Enable SmartyPants processing.
27
+ # * <tt>:filter_styles</tt> - Do not output <tt><style></tt> tags.
28
+ # * <tt>:filter_html</tt> - Do not output any raw HTML tags included in
29
+ # the source text.
30
+ # * <tt>:fold_lines</tt> - RedCloth compatible line folding (not used).
31
+ # * <tt>:has_stylesheet</tt> - Don't use inline CSS for styling.
32
+ # * <tt>:emotes</tt> - Process emoticons.
33
+ # * <tt>:base_url</tt> - Map any relative URLs in the text to absolute URLs.
34
+ # * <tt>:map_headings</tt> - Map any headings down a few ranks (eg. h1 => h3).
35
+ # * <tt>:swfobject</tt> - Use SwfObject2 if available (eg. :swfobject => { :src => 'swfobject.js', :version => '10', :fallback => 'No Flash' })
36
+ #
37
+ # NOTE: The <tt>:filter_styles</tt> extension is not yet implemented.
38
+ def initialize text, args = {}
39
+ @has_stylesheet = args[:has_stylesheet]
40
+ @emotes = args[:emotes]
41
+ @base_url = args[:base_url]
42
+ @map_headings = args[:map_headings] || 0
43
+ @swfobject = args[:swfobject]
44
+
45
+ # each swfobject needs a unique id
46
+ @next_flash_id = 0
47
+
48
+ if args[:extensions]
49
+ super(text, args[:extensions])
50
+ else
51
+ super(text)
52
+ end
53
+ end
54
+
55
+ def to_html
56
+ html = super
57
+
58
+ # flash movies (including youtube)
59
+ html.gsub!(/<img src="(flash|youtube):(.*?)"\s?(?:title="(.*?)")? alt="(.*)" \/>/) do |match|
60
+ # grab width and height
61
+ if $3
62
+ sizes = $3.split(' ')
63
+ sizes = { :width => sizes[0], :height => sizes[1] }
64
+ else
65
+ sizes = {}
66
+ end
67
+
68
+ # check the source
69
+ if $1.downcase == "youtube"
70
+ url = "http://www.youtube.com/v/#{$2}"
71
+ sizes = { :width => 425, :height => 350 }.merge sizes
72
+ else
73
+ url = $2
74
+ end
75
+
76
+ flash_tag url, sizes
77
+ end
78
+
79
+ # image alignments
80
+ if @has_stylesheet
81
+ html.gsub!(/<img (.*?) \/>:(left|right|center)/) { |match| "<img class=\"#{$2}\" #{$1} />" }
82
+ else
83
+ html.gsub!(/<img (.*?) \/>:left/) { |match| "<img style=\"float: left; margin: 0 10px 10px 0;\" #{$1} />" }
84
+ html.gsub!(/<img (.*?) \/>:right/) { |match| "<img style=\"float: right; margin: 0 0 10px 10px;\" #{$1} />" }
85
+ html.gsub!(/<img (.*?) \/>:center/) { |match| "<img style=\"display: block; margin: auto;\" #{$1} />" }
86
+ end
87
+
88
+ # code
89
+ html.gsub!('<pre>', '<pre class="prettyprint">')
90
+
91
+ # emoticons
92
+ if @emotes
93
+ html.gsub!(':-)', '<img src="/images/emote-smile.png" alt=":-)" width="16" height="16" />')
94
+ html.gsub!(':-P', '<img src="/images/emote-tongue.png" alt=":-P" width="16" height="16" />')
95
+ html.gsub!(':-D', '<img src="/images/emote-grin.png" alt=":-D" width="16" height="16" />')
96
+ html.gsub!(':-(', '<img src="/images/emote-sad.png" alt=":-(" width="16" height="16" />')
97
+ html.gsub!(':-@', '<img src="/images/emote-angry.png" alt=":-@" width="16" height="16" />')
98
+ html.gsub!(';-)', '<img src="/images/emote-wink.png" alt=";-)" width="16" height="16" />')
99
+ end
100
+
101
+ # remap relative urls
102
+ if @base_url
103
+ html.gsub!('"/images/', "\"#{@base_url}/images/")
104
+ html.gsub!('<a href="/', "<a href=\"#{@base_url}/")
105
+ end
106
+
107
+ # remap headings down a few notches
108
+ if @map_headings > 0
109
+ html.gsub!(/<(\/)?h(\d)>/) { |match| "<#{$1}h#{$2.to_i + @map_headings}>" }
110
+ end
111
+
112
+ # add the js for swfobject
113
+ if @swfobject
114
+ swfobjects = []
115
+ 1.upto(@next_flash_id).each do |n|
116
+ swfobjects << "swfobject.registerObject(\"swf-#{n}\", \"#{@swfobject[:version]}\");\n"
117
+ end
118
+
119
+ # html seems to need to go after the swfobject javascript
120
+ html = "<script type=\"text/javascript\" src=\"#{@swfobject[:src]}\"></script><script type=\"text/javascript\">\n/*<![CDATA[*/\n#{swfobjects}/*]]>*/\n</script>\n#{html}"
121
+ end
122
+
123
+ html
124
+ end
125
+
126
+ # Process some text in Markdown format
127
+ def self.text_to_html text, args = {}
128
+ Moredown.new(text, args).to_html
129
+ end
130
+
131
+
132
+ protected
133
+ def flash_tag url, args = {}
134
+ args = {:width => 400, :height => 300, :fallback => 'Flash is not available.'}.merge args
135
+
136
+ if url.include? 'youtube.com'
137
+ fallback = "<a href=\"#{url}\"><img src=\"http://img.youtube.com/vi/#{url.split('/').last}/default.jpg\" alt=\"\" /></a>"
138
+ elsif @swfobject
139
+ fallback = @swfobject[:fallback]
140
+ else
141
+ fallback = args[:fallback]
142
+ end
143
+
144
+ return "<object id=\"swf-#{@next_flash_id += 1}\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\"#{args[:width]}\" height=\"#{args[:height]}\">" \
145
+ +"<param name=\"movie\" value=\"#{url}\" />" \
146
+ +"<!--[if !IE]>-->" \
147
+ +"<object type=\"application/x-shockwave-flash\" data=\"#{url}\" width=\"#{args[:width]}\" height=\"#{args[:height]}\">" \
148
+ +"<!--<![endif]-->#{fallback}<!--[if !IE]>-->" \
149
+ +"</object>" \
150
+ +"<!--<![endif]-->" \
151
+ +"</object>"
152
+ end
153
+ end
@@ -0,0 +1,72 @@
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.3.5'
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 <style> 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
+ # Create a RDiscount Markdown processor. The +text+ argument
49
+ # should be a string containing Markdown text. Additional arguments may be
50
+ # supplied to set various processing options:
51
+ #
52
+ # * <tt>:smart</tt> - Enable SmartyPants processing.
53
+ # * <tt>:filter_styles</tt> - Do not output <tt><style></tt> tags.
54
+ # * <tt>:filter_html</tt> - Do not output any raw HTML tags included in
55
+ # the source text.
56
+ # * <tt>:fold_lines</tt> - RedCloth compatible line folding (not used).
57
+ #
58
+ # NOTE: The <tt>:filter_styles</tt> extension is not yet implemented.
59
+ def initialize(text, *extensions)
60
+ @text = text
61
+ @smart = nil
62
+ @filter_styles = nil
63
+ @filter_html = nil
64
+ @fold_lines = nil
65
+ extensions.each { |e| send("#{e}=", true) }
66
+ end
67
+
68
+ end
69
+
70
+ Markdown = RDiscount unless defined? Markdown
71
+
72
+ require 'rdiscount.so'