rdiscount 1.2.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/ext/rbstrio.h ADDED
@@ -0,0 +1,4 @@
1
+ #include <stdio.h>
2
+ #include "ruby.h"
3
+
4
+ FILE *rb_str_io_new(VALUE buf);
data/ext/rdiscount.c ADDED
@@ -0,0 +1,48 @@
1
+ #include <stdio.h>
2
+ #include "ruby.h"
3
+ #include "mkdio.h"
4
+ #include "rbstrio.h"
5
+
6
+ static VALUE rb_cRDiscount;
7
+
8
+ static ID id_text;
9
+ static ID id_smart;
10
+ static ID id_notes;
11
+
12
+
13
+ static VALUE
14
+ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
15
+ {
16
+ /* grab char pointer to markdown input text */
17
+ VALUE text = rb_funcall(self, id_text, 0);
18
+ Check_Type(text, T_STRING);
19
+
20
+ /* allocate a ruby string buffer and wrap it in a stream */
21
+ VALUE buf = rb_str_buf_new(4096);
22
+ FILE *stream = rb_str_io_new(buf);
23
+
24
+ /* compile flags */
25
+ int flags = MKD_TABSTOP | MKD_NOHEADER;
26
+ if (rb_funcall(self, id_smart, 0) != Qtrue )
27
+ flags = flags | MKD_NOPANTS;
28
+
29
+ MMIOT *doc = mkd_string(RSTRING(text)->ptr, RSTRING(text)->len, flags);
30
+ markdown(doc, stream, flags);
31
+
32
+ fclose(stream);
33
+
34
+ return buf;
35
+ }
36
+
37
+ void Init_rdiscount()
38
+ {
39
+ /* Initialize frequently used Symbols */
40
+ id_text = rb_intern("text");
41
+ id_smart = rb_intern("smart");
42
+ id_notes = rb_intern("notes");
43
+
44
+ rb_cRDiscount = rb_define_class("RDiscount", rb_cObject);
45
+ rb_define_method(rb_cRDiscount, "to_html", rb_rdiscount_to_html, -1);
46
+ }
47
+
48
+ /* vim: set ts=4 sw=4: */
data/ext/resource.c ADDED
@@ -0,0 +1,167 @@
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
+ free(p);
53
+ }
54
+
55
+
56
+ /* bye bye footnotes.
57
+ */
58
+ void
59
+ ___mkd_freefootnotes(MMIOT *f)
60
+ {
61
+ int i;
62
+
63
+ if ( f->footnotes ) {
64
+ for (i=0; i < S(*f->footnotes); i++) {
65
+ DELETE(T(*f->footnotes)[i].tag);
66
+ DELETE(T(*f->footnotes)[i].link);
67
+ DELETE(T(*f->footnotes)[i].title);
68
+ }
69
+ DELETE(*f->footnotes);
70
+ free(f->footnotes);
71
+ }
72
+ }
73
+
74
+
75
+ /* initialize a new MMIOT
76
+ */
77
+ void
78
+ ___mkd_initmmiot(MMIOT *f, void *footnotes)
79
+ {
80
+ if ( f ) {
81
+ memset(f, 0, sizeof *f);
82
+ CREATE(f->in);
83
+ CREATE(f->out);
84
+ CREATE(f->Q);
85
+ if ( footnotes )
86
+ f->footnotes = footnotes;
87
+ else {
88
+ f->footnotes = malloc(sizeof f->footnotes[0]);
89
+ CREATE(*f->footnotes);
90
+ }
91
+ }
92
+ }
93
+
94
+
95
+ /* free the contents of a MMIOT, but leave the object alone.
96
+ */
97
+ void
98
+ ___mkd_freemmiot(MMIOT *f, void *footnotes)
99
+ {
100
+ if ( f ) {
101
+ DELETE(f->in);
102
+ DELETE(f->out);
103
+ DELETE(f->Q);
104
+ if ( f->footnotes != footnotes )
105
+ ___mkd_freefootnotes(f);
106
+ memset(f, 0, sizeof *f);
107
+ }
108
+ }
109
+
110
+
111
+ /* free lines up to an barrier.
112
+ */
113
+ void
114
+ ___mkd_freeLineRange(Line *anchor, Line *stop)
115
+ {
116
+ Line *r = anchor->next;
117
+
118
+ if ( r != stop ) {
119
+ while ( r && (r->next != stop) )
120
+ r = r->next;
121
+ if ( r ) r->next = 0;
122
+ ___mkd_freeLines(anchor->next);
123
+ }
124
+ anchor->next = 0;
125
+ }
126
+
127
+
128
+ /* clean up everything allocated in __mkd_compile()
129
+ */
130
+ void
131
+ mkd_cleanup(Document *doc)
132
+ {
133
+ if ( doc ) {
134
+ if ( doc->ctx ) {
135
+ ___mkd_freemmiot(doc->ctx, 0);
136
+ free(doc->ctx);
137
+ }
138
+
139
+ if ( doc->code) ___mkd_freeParagraph(doc->code);
140
+ if ( doc->headers ) ___mkd_freeLines(doc->headers);
141
+ if ( T(doc->content) ) ___mkd_freeLines(T(doc->content));
142
+ memset(doc, 0, sizeof doc[0]);
143
+ free(doc);
144
+ }
145
+ }
146
+
147
+
148
+ /* write output in XML format
149
+ */
150
+ void
151
+ ___mkd_xml(char *p, int size, FILE *out)
152
+ {
153
+ char c;
154
+
155
+ while ( size-- > 0 ) {
156
+ if ( !isascii(c = *p++) )
157
+ continue;
158
+ switch (c) {
159
+ case '<': fputs("&lt;", out); break;
160
+ case '>': fputs("&gt;", out); break;
161
+ case '&': fputs("&amp;", out); break;
162
+ case '"': fputs("&quot;", out); break;
163
+ case '\'':fputs("&apos;", out); break;
164
+ default: putc(c,out); break;
165
+ }
166
+ }
167
+ }
data/lib/rdiscount.rb ADDED
@@ -0,0 +1,73 @@
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
+
28
+ # Original Markdown formatted text.
29
+ attr_reader :text
30
+
31
+ # Set true to have smarty-like quote translation performed.
32
+ attr_accessor :smart
33
+
34
+ # BlueCloth compatible output filtering.
35
+ attr_accessor :filter_styles, :filter_html
36
+
37
+ # RedCloth compatible line folding -- not used for Markdown but
38
+ # included for compatibility.
39
+ attr_accessor :fold_lines
40
+
41
+ # Create a RDiscount Markdown processor. The +text+ argument
42
+ # should be a string containing Markdown text. Additional arguments may be
43
+ # supplied to set various processing options:
44
+ #
45
+ # * <tt>:smart</tt> - Enable SmartyPants processing.
46
+ # * <tt>:filter_styles</tt> - Do not output <tt><style></tt> tags.
47
+ # * <tt>:filter_html</tt> - Do not output any raw HTML tags included in
48
+ # the source text.
49
+ # * <tt>:fold_lines</tt> - RedCloth compatible line folding (not used).
50
+ #
51
+ # NOTE: The <tt>:filter_styles</tt> and <tt>:filter_html</tt> extensions
52
+ # are not yet implemented.
53
+ def initialize(text, *extensions)
54
+ @text = text
55
+ @smart = nil
56
+ @filter_styles = nil
57
+ @filter_html = nil
58
+ @fold_lines = nil
59
+ extensions.each { |e| send("#{e}=", true) }
60
+ end
61
+
62
+ # Convert the Markdown #text to HTML.
63
+ #--
64
+ # This is method is replaced when the C extension is loaded.
65
+ def to_html
66
+ raise NotImplemented
67
+ end
68
+
69
+ end
70
+
71
+ # Load the extension library. This replaces RDiscount#to_html with a real
72
+ # implementation.
73
+ require 'rdiscount.so'
data/test/benchmark.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+
3
+ iterations = 100
4
+ test_file = "#{File.dirname(__FILE__)}/benchmark.txt"
5
+ implementations = %w[BlueCloth RDiscount Maruku Markdown]
6
+
7
+ # Attempt to require each implementation and remove any that are not
8
+ # installed.
9
+ implementations.reject! do |class_name|
10
+ begin
11
+ require class_name.downcase
12
+ false
13
+ rescue LoadError => boom
14
+ puts "#{class_name} excluded from benchmark. (Try: gem install #{class_name.downcase})"
15
+ true
16
+ end
17
+ end
18
+
19
+ # Grab actual class objects.
20
+ implementations.map! { |class_name| Object.const_get(class_name) }
21
+
22
+ # The actual benchmark.
23
+ def benchmark(implementation, text, iterations)
24
+ start = Time.now
25
+ iterations.times do |i|
26
+ implementation.new(text).to_html
27
+ end
28
+ Time.now - start
29
+ end
30
+
31
+ # Read test file
32
+ test_data = File.read(test_file)
33
+
34
+ # Prime the pump
35
+ puts "Spinning up ..."
36
+ implementations.each { |impl| benchmark(impl, test_data, 1) }
37
+
38
+ # Run benchmarks; gather results.
39
+ puts "Running benchmarks ..."
40
+ results =
41
+ implementations.inject([]) do |r,impl|
42
+ GC.start
43
+ r << [ impl, benchmark(impl, test_data, iterations) ]
44
+ end
45
+
46
+ puts "Results for #{iterations} iterations:"
47
+ results.each do |impl,time|
48
+ printf " %10s %09.06fs total time, %09.06fs average\n", "#{impl}:", time, time / iterations
49
+ end
@@ -0,0 +1,306 @@
1
+ Markdown: Basics
2
+ ================
3
+
4
+ <ul id="ProjectSubmenu">
5
+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
6
+ <li><a class="selected" title="Markdown Basics">Basics</a></li>
7
+ <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
8
+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
9
+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
10
+ </ul>
11
+
12
+
13
+ Getting the Gist of Markdown's Formatting Syntax
14
+ ------------------------------------------------
15
+
16
+ This page offers a brief overview of what it's like to use Markdown.
17
+ The [syntax page] [s] provides complete, detailed documentation for
18
+ every feature, but Markdown should be very easy to pick up simply by
19
+ looking at a few examples of it in action. The examples on this page
20
+ are written in a before/after style, showing example syntax and the
21
+ HTML output produced by Markdown.
22
+
23
+ It's also helpful to simply try Markdown out; the [Dingus] [d] is a
24
+ web application that allows you type your own Markdown-formatted text
25
+ and translate it to XHTML.
26
+
27
+ **Note:** This document is itself written using Markdown; you
28
+ can [see the source for it by adding '.text' to the URL] [src].
29
+
30
+ [s]: /projects/markdown/syntax "Markdown Syntax"
31
+ [d]: /projects/markdown/dingus "Markdown Dingus"
32
+ [src]: /projects/markdown/basics.text
33
+
34
+
35
+ ## Paragraphs, Headers, Blockquotes ##
36
+
37
+ A paragraph is simply one or more consecutive lines of text, separated
38
+ by one or more blank lines. (A blank line is any line that looks like a
39
+ blank line -- a line containing nothing spaces or tabs is considered
40
+ blank.) Normal paragraphs should not be intended with spaces or tabs.
41
+
42
+ Markdown offers two styles of headers: *Setext* and *atx*.
43
+ Setext-style headers for `<h1>` and `<h2>` are created by
44
+ "underlining" with equal signs (`=`) and hyphens (`-`), respectively.
45
+ To create an atx-style header, you put 1-6 hash marks (`#`) at the
46
+ beginning of the line -- the number of hashes equals the resulting
47
+ HTML header level.
48
+
49
+ Blockquotes are indicated using email-style '`>`' angle brackets.
50
+
51
+ Markdown:
52
+
53
+ A First Level Header
54
+ ====================
55
+
56
+ A Second Level Header
57
+ ---------------------
58
+
59
+ Now is the time for all good men to come to
60
+ the aid of their country. This is just a
61
+ regular paragraph.
62
+
63
+ The quick brown fox jumped over the lazy
64
+ dog's back.
65
+
66
+ ### Header 3
67
+
68
+ > This is a blockquote.
69
+ >
70
+ > This is the second paragraph in the blockquote.
71
+ >
72
+ > ## This is an H2 in a blockquote
73
+
74
+
75
+ Output:
76
+
77
+ <h1>A First Level Header</h1>
78
+
79
+ <h2>A Second Level Header</h2>
80
+
81
+ <p>Now is the time for all good men to come to
82
+ the aid of their country. This is just a
83
+ regular paragraph.</p>
84
+
85
+ <p>The quick brown fox jumped over the lazy
86
+ dog's back.</p>
87
+
88
+ <h3>Header 3</h3>
89
+
90
+ <blockquote>
91
+ <p>This is a blockquote.</p>
92
+
93
+ <p>This is the second paragraph in the blockquote.</p>
94
+
95
+ <h2>This is an H2 in a blockquote</h2>
96
+ </blockquote>
97
+
98
+
99
+
100
+ ### Phrase Emphasis ###
101
+
102
+ Markdown uses asterisks and underscores to indicate spans of emphasis.
103
+
104
+ Markdown:
105
+
106
+ Some of these words *are emphasized*.
107
+ Some of these words _are emphasized also_.
108
+
109
+ Use two asterisks for **strong emphasis**.
110
+ Or, if you prefer, __use two underscores instead__.
111
+
112
+ Output:
113
+
114
+ <p>Some of these words <em>are emphasized</em>.
115
+ Some of these words <em>are emphasized also</em>.</p>
116
+
117
+ <p>Use two asterisks for <strong>strong emphasis</strong>.
118
+ Or, if you prefer, <strong>use two underscores instead</strong>.</p>
119
+
120
+
121
+
122
+ ## Lists ##
123
+
124
+ Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
125
+ `+`, and `-`) as list markers. These three markers are
126
+ interchangable; this:
127
+
128
+ * Candy.
129
+ * Gum.
130
+ * Booze.
131
+
132
+ this:
133
+
134
+ + Candy.
135
+ + Gum.
136
+ + Booze.
137
+
138
+ and this:
139
+
140
+ - Candy.
141
+ - Gum.
142
+ - Booze.
143
+
144
+ all produce the same output:
145
+
146
+ <ul>
147
+ <li>Candy.</li>
148
+ <li>Gum.</li>
149
+ <li>Booze.</li>
150
+ </ul>
151
+
152
+ Ordered (numbered) lists use regular numbers, followed by periods, as
153
+ list markers:
154
+
155
+ 1. Red
156
+ 2. Green
157
+ 3. Blue
158
+
159
+ Output:
160
+
161
+ <ol>
162
+ <li>Red</li>
163
+ <li>Green</li>
164
+ <li>Blue</li>
165
+ </ol>
166
+
167
+ If you put blank lines between items, you'll get `<p>` tags for the
168
+ list item text. You can create multi-paragraph list items by indenting
169
+ the paragraphs by 4 spaces or 1 tab:
170
+
171
+ * A list item.
172
+
173
+ With multiple paragraphs.
174
+
175
+ * Another item in the list.
176
+
177
+ Output:
178
+
179
+ <ul>
180
+ <li><p>A list item.</p>
181
+ <p>With multiple paragraphs.</p></li>
182
+ <li><p>Another item in the list.</p></li>
183
+ </ul>
184
+
185
+
186
+
187
+ ### Links ###
188
+
189
+ Markdown supports two styles for creating links: *inline* and
190
+ *reference*. With both styles, you use square brackets to delimit the
191
+ text you want to turn into a link.
192
+
193
+ Inline-style links use parentheses immediately after the link text.
194
+ For example:
195
+
196
+ This is an [example link](http://example.com/).
197
+
198
+ Output:
199
+
200
+ <p>This is an <a href="http://example.com/">
201
+ example link</a>.</p>
202
+
203
+ Optionally, you may include a title attribute in the parentheses:
204
+
205
+ This is an [example link](http://example.com/ "With a Title").
206
+
207
+ Output:
208
+
209
+ <p>This is an <a href="http://example.com/" title="With a Title">
210
+ example link</a>.</p>
211
+
212
+ Reference-style links allow you to refer to your links by names, which
213
+ you define elsewhere in your document:
214
+
215
+ I get 10 times more traffic from [Google][1] than from
216
+ [Yahoo][2] or [MSN][3].
217
+
218
+ [1]: http://google.com/ "Google"
219
+ [2]: http://search.yahoo.com/ "Yahoo Search"
220
+ [3]: http://search.msn.com/ "MSN Search"
221
+
222
+ Output:
223
+
224
+ <p>I get 10 times more traffic from <a href="http://google.com/"
225
+ title="Google">Google</a> than from <a href="http://search.yahoo.com/"
226
+ title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
227
+ title="MSN Search">MSN</a>.</p>
228
+
229
+ The title attribute is optional. Link names may contain letters,
230
+ numbers and spaces, but are *not* case sensitive:
231
+
232
+ I start my morning with a cup of coffee and
233
+ [The New York Times][NY Times].
234
+
235
+ [ny times]: http://www.nytimes.com/
236
+
237
+ Output:
238
+
239
+ <p>I start my morning with a cup of coffee and
240
+ <a href="http://www.nytimes.com/">The New York Times</a>.</p>
241
+
242
+
243
+ ### Images ###
244
+
245
+ Image syntax is very much like link syntax.
246
+
247
+ Inline (titles are optional):
248
+
249
+ ![alt text](/path/to/img.jpg "Title")
250
+
251
+ Reference-style:
252
+
253
+ ![alt text][id]
254
+
255
+ [id]: /path/to/img.jpg "Title"
256
+
257
+ Both of the above examples produce the same output:
258
+
259
+ <img src="/path/to/img.jpg" alt="alt text" title="Title" />
260
+
261
+
262
+
263
+ ### Code ###
264
+
265
+ In a regular paragraph, you can create code span by wrapping text in
266
+ backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
267
+ `>`) will automatically be translated into HTML entities. This makes
268
+ it easy to use Markdown to write about HTML example code:
269
+
270
+ I strongly recommend against using any `<blink>` tags.
271
+
272
+ I wish SmartyPants used named entities like `&mdash;`
273
+ instead of decimal-encoded entites like `&#8212;`.
274
+
275
+ Output:
276
+
277
+ <p>I strongly recommend against using any
278
+ <code>&lt;blink&gt;</code> tags.</p>
279
+
280
+ <p>I wish SmartyPants used named entities like
281
+ <code>&amp;mdash;</code> instead of decimal-encoded
282
+ entites like <code>&amp;#8212;</code>.</p>
283
+
284
+
285
+ To specify an entire block of pre-formatted code, indent every line of
286
+ the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
287
+ and `>` characters will be escaped automatically.
288
+
289
+ Markdown:
290
+
291
+ If you want your page to validate under XHTML 1.0 Strict,
292
+ you've got to put paragraph tags in your blockquotes:
293
+
294
+ <blockquote>
295
+ <p>For example.</p>
296
+ </blockquote>
297
+
298
+ Output:
299
+
300
+ <p>If you want your page to validate under XHTML 1.0 Strict,
301
+ you've got to put paragraph tags in your blockquotes:</p>
302
+
303
+ <pre><code>&lt;blockquote&gt;
304
+ &lt;p&gt;For example.&lt;/p&gt;
305
+ &lt;/blockquote&gt;
306
+ </code></pre>