rdiscount 1.3.1 → 1.3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/rdiscount.c +45 -10
- data/ext/toc.c +62 -0
- data/lib/rdiscount.rb +4 -1
- data/rdiscount.gemspec +3 -2
- data/test/markdown_test.rb +8 -5
- data/test/rdiscount_test.rb +14 -1
- metadata +3 -2
data/ext/rdiscount.c
CHANGED
@@ -16,29 +16,64 @@ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
|
|
16
16
|
VALUE buf = rb_str_buf_new(4096);
|
17
17
|
FILE *stream = rb_str_io_new(buf);
|
18
18
|
|
19
|
-
|
20
|
-
int flags = MKD_TABSTOP | MKD_NOHEADER;
|
19
|
+
int flags = rb_rdiscount__get_flags(self);
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
flags = flags | MKD_NOPANTS;
|
21
|
+
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
22
|
+
markdown(doc, stream, flags);
|
25
23
|
|
26
|
-
|
27
|
-
if ( rb_funcall(self, rb_intern("filter_html"), 0) == Qtrue )
|
28
|
-
flags = flags | MKD_NOHTML;
|
24
|
+
fclose(stream);
|
29
25
|
|
30
|
-
|
31
|
-
|
26
|
+
return buf;
|
27
|
+
}
|
28
|
+
|
29
|
+
static VALUE
|
30
|
+
rb_rdiscount_toc_content(int argc, VALUE *argv, VALUE self)
|
31
|
+
{
|
32
|
+
int flags = rb_rdiscount__get_flags(self);
|
33
|
+
|
34
|
+
/* grab char pointer to markdown input text */
|
35
|
+
VALUE text = rb_funcall(self, rb_intern("text"), 0);
|
36
|
+
Check_Type(text, T_STRING);
|
37
|
+
|
38
|
+
/* allocate a ruby string buffer and wrap it in a stream */
|
39
|
+
VALUE buf = rb_str_buf_new(4096);
|
40
|
+
FILE *stream = rb_str_io_new(buf);
|
41
|
+
|
42
|
+
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
43
|
+
mkd_compile(doc, flags);
|
44
|
+
mkd_generatetoc(doc, stream);
|
32
45
|
|
33
46
|
fclose(stream);
|
34
47
|
|
35
48
|
return buf;
|
36
49
|
}
|
37
50
|
|
51
|
+
int rb_rdiscount__get_flags(VALUE ruby_obj)
|
52
|
+
{
|
53
|
+
/* compile flags */
|
54
|
+
int flags = MKD_TABSTOP | MKD_NOHEADER;
|
55
|
+
|
56
|
+
/* smart */
|
57
|
+
if ( rb_funcall(ruby_obj, rb_intern("smart"), 0) != Qtrue )
|
58
|
+
flags = flags | MKD_NOPANTS;
|
59
|
+
|
60
|
+
/* filter_html */
|
61
|
+
if ( rb_funcall(ruby_obj, rb_intern("filter_html"), 0) == Qtrue )
|
62
|
+
flags = flags | MKD_NOHTML;
|
63
|
+
|
64
|
+
/* generate_toc */
|
65
|
+
if ( rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
|
66
|
+
flags = flags | MKD_TOC;
|
67
|
+
|
68
|
+
return flags;
|
69
|
+
}
|
70
|
+
|
71
|
+
|
38
72
|
void Init_rdiscount()
|
39
73
|
{
|
40
74
|
rb_cRDiscount = rb_define_class("RDiscount", rb_cObject);
|
41
75
|
rb_define_method(rb_cRDiscount, "to_html", rb_rdiscount_to_html, -1);
|
76
|
+
rb_define_method(rb_cRDiscount, "toc_content", rb_rdiscount_toc_content, -1);
|
42
77
|
}
|
43
78
|
|
44
79
|
/* vim: set ts=4 sw=4: */
|
data/ext/toc.c
ADDED
@@ -0,0 +1,62 @@
|
|
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_generatetoc(Document *p, FILE *output)
|
21
|
+
{
|
22
|
+
Paragraph *pp;
|
23
|
+
|
24
|
+
int last_hnumber = 0,
|
25
|
+
first_hnumber = 0;
|
26
|
+
|
27
|
+
if ( !(p && p->ctx) ) return -1;
|
28
|
+
if ( ! (p->ctx->flags & TOC) ) return 0;
|
29
|
+
|
30
|
+
for ( pp = p->code; pp ; pp = pp->next ) {
|
31
|
+
if ( pp->typ == HDR && pp->text ) {
|
32
|
+
|
33
|
+
if ( last_hnumber == pp->hnumber )
|
34
|
+
fprintf(output, "%*s</li>\n", pp->hnumber, "");
|
35
|
+
else while ( last_hnumber > pp->hnumber ) {
|
36
|
+
fprintf(output, "%*s</li>\n%*s</ul>\n",
|
37
|
+
last_hnumber, "",
|
38
|
+
last_hnumber-1,"");
|
39
|
+
--last_hnumber;
|
40
|
+
}
|
41
|
+
|
42
|
+
while ( pp->hnumber > last_hnumber ) {
|
43
|
+
fprintf(output, "\n%*s<ul>\n", pp->hnumber, "");
|
44
|
+
++last_hnumber;
|
45
|
+
}
|
46
|
+
fprintf(output, "%*s<li><a href=\"#", pp->hnumber, "");
|
47
|
+
mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), putc, output);
|
48
|
+
fprintf(output, "\">");
|
49
|
+
mkd_text(T(pp->text->text), S(pp->text->text), output, 0);
|
50
|
+
fprintf(output, "</a>");
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
while ( last_hnumber > 0 ) {
|
55
|
+
fprintf(output, "%*s</li>\n%*s</ul>\n",
|
56
|
+
last_hnumber, "", last_hnumber, "");
|
57
|
+
--last_hnumber;
|
58
|
+
}
|
59
|
+
|
60
|
+
return 0;
|
61
|
+
}
|
62
|
+
|
data/lib/rdiscount.rb
CHANGED
@@ -24,7 +24,7 @@
|
|
24
24
|
# end
|
25
25
|
#
|
26
26
|
class RDiscount
|
27
|
-
VERSION = '1.3.1'
|
27
|
+
VERSION = '1.3.1.1'
|
28
28
|
|
29
29
|
# Original Markdown formatted text.
|
30
30
|
attr_reader :text
|
@@ -42,6 +42,9 @@ class RDiscount
|
|
42
42
|
# included for compatibility.
|
43
43
|
attr_accessor :fold_lines
|
44
44
|
|
45
|
+
# Enable Table Of Contents generation
|
46
|
+
attr_accessor :generate_toc
|
47
|
+
|
45
48
|
# Create a RDiscount Markdown processor. The +text+ argument
|
46
49
|
# should be a string containing Markdown text. Additional arguments may be
|
47
50
|
# supplied to set various processing options:
|
data/rdiscount.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rdiscount'
|
3
|
-
s.version = '1.3.1'
|
3
|
+
s.version = '1.3.1.1'
|
4
4
|
s.summary = "Fast Implementation of Gruber's Markdown in C"
|
5
|
-
s.date = '2009-01-
|
5
|
+
s.date = '2009-01-31'
|
6
6
|
s.email = 'r@tomayko.com'
|
7
7
|
s.homepage = 'http://github.com/rtomayko/rdiscount'
|
8
8
|
s.has_rdoc = true
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
ext/rbstrio.h
|
29
29
|
ext/rdiscount.c
|
30
30
|
ext/resource.c
|
31
|
+
ext/toc.c
|
31
32
|
lib/markdown.rb
|
32
33
|
lib/rdiscount.rb
|
33
34
|
rdiscount.gemspec
|
data/test/markdown_test.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
-
|
1
|
+
rootdir = File.dirname(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift "#{rootdir}/lib"
|
2
3
|
|
3
4
|
require 'test/unit'
|
4
5
|
require 'markdown'
|
5
6
|
|
6
|
-
MARKDOWN_TEST_DIR = "#{
|
7
|
+
MARKDOWN_TEST_DIR = "#{rootdir}/test/MarkdownTest_1.0.3"
|
7
8
|
|
8
9
|
class MarkdownTest < Test::Unit::TestCase
|
9
10
|
|
10
11
|
def test_that_extension_methods_are_present_on_markdown_class
|
11
|
-
|
12
|
-
|
12
|
+
assert Markdown.instance_methods.map{|m| m.to_s }.include?('to_html'),
|
13
|
+
"Markdown class should respond to #to_html"
|
13
14
|
end
|
14
15
|
|
15
16
|
def test_that_simple_one_liner_goes_to_html
|
@@ -20,7 +21,6 @@ class MarkdownTest < Test::Unit::TestCase
|
|
20
21
|
|
21
22
|
def test_that_inline_markdown_goes_to_html
|
22
23
|
markdown = Markdown.new('_Hello World_!')
|
23
|
-
assert_respond_to markdown, :to_html
|
24
24
|
assert_equal "<p><em>Hello World</em>!</p>", markdown.to_html.strip
|
25
25
|
end
|
26
26
|
|
@@ -28,6 +28,9 @@ class MarkdownTest < Test::Unit::TestCase
|
|
28
28
|
markdown = Markdown.new('_start _ foo_bar bar_baz _ end_ *italic* **bold** <a>_blah_</a>')
|
29
29
|
assert_respond_to markdown, :to_html
|
30
30
|
assert_equal "<p><em>start _ foo_bar bar_baz _ end</em> <em>italic</em> <strong>bold</strong> <a><em>blah</em></a></p>", markdown.to_html.strip
|
31
|
+
|
32
|
+
markdown = Markdown.new("Run 'rake radiant:extensions:rbac_base:migrate'")
|
33
|
+
assert_equal "<p>Run 'rake radiant:extensions:rbac_base:migrate'</p>", markdown.to_html.strip
|
31
34
|
end
|
32
35
|
|
33
36
|
def test_that_filter_html_works
|
data/test/rdiscount_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
rootdir = File.dirname(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift "#{rootdir}/lib"
|
2
3
|
|
3
4
|
require 'test/unit'
|
4
5
|
require 'rdiscount'
|
@@ -27,4 +28,16 @@ class RDiscountTest < Test::Unit::TestCase
|
|
27
28
|
rd = RDiscount.new(%(# Heading\n\n"Quoted text"), :smart)
|
28
29
|
assert_equal %(<h1>Heading</h1>\n\n<p>“Quoted text”</p>\n), rd.to_html
|
29
30
|
end
|
31
|
+
|
32
|
+
def test_that_generate_toc_sets_toc_ids
|
33
|
+
rd = RDiscount.new("# Level 1\n\n## Level 2", :generate_toc)
|
34
|
+
assert rd.generate_toc
|
35
|
+
assert_equal %(<h1 id="Level+1\">Level 1</h1>\n\n<h2 id="Level+2\">Level 2</h2>\n), rd.to_html
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_get_the_generated_toc
|
39
|
+
rd = RDiscount.new("# Level 1\n\n## Level 2", :generate_toc)
|
40
|
+
exp = %(<ul>\n <li><a href="#Level+1">Level 1</a>\n <ul>\n <li><a href="#Level+2">Level 2</a> </li>\n </ul>\n </li>\n </ul>)
|
41
|
+
assert_equal exp, rd.toc_content.strip
|
42
|
+
end
|
30
43
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdiscount
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.1
|
4
|
+
version: 1.3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Tomayko
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-01-
|
13
|
+
date: 2009-01-31 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- ext/rbstrio.h
|
43
43
|
- ext/rdiscount.c
|
44
44
|
- ext/resource.c
|
45
|
+
- ext/toc.c
|
45
46
|
- lib/markdown.rb
|
46
47
|
- lib/rdiscount.rb
|
47
48
|
- rdiscount.gemspec
|