rdiscount 1.5.5 → 1.5.8

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,75 +1,28 @@
1
1
  require 'rake/clean'
2
+ require 'digest/md5'
2
3
 
3
4
  task :default => :test
4
5
 
5
- # PACKAGING =================================================================
6
-
7
- require 'rubygems/specification'
8
- $spec = eval(File.read('rdiscount.gemspec'))
9
-
10
- def package(ext='')
11
- "pkg/rdiscount-#{$spec.version}" + ext
12
- end
13
-
14
- desc 'Build packages'
15
- task :package => %w[.gem .tar.gz].map {|e| package(e)}
16
-
17
- desc 'Build and install as local gem'
18
- task :install => package('.gem') do
19
- sh "gem install #{package('.gem')}"
20
- end
21
-
22
- directory 'pkg/'
23
-
24
- file package('.gem') => %w[pkg/ rdiscount.gemspec] + $spec.files do |f|
25
- sh "gem build rdiscount.gemspec"
26
- mv File.basename(f.name), f.name
27
- end
28
-
29
- file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
30
- sh "git archive --format=tar HEAD | gzip > #{f.name}"
31
- end
32
-
33
- # GEMSPEC HELPERS ==========================================================
34
-
35
- def source_version
36
- line = File.read('lib/rdiscount.rb')[/^\s*VERSION = .*/]
37
- line.match(/.*VERSION = '(.*)'/)[1]
38
- end
39
-
40
- file 'rdiscount.gemspec' => FileList['Rakefile','lib/rdiscount.rb'] do |f|
41
- # read spec file and split out manifest section
42
- spec = File.read(f.name)
43
- head, manifest, tail = spec.split(" # = MANIFEST =\n")
44
- head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
45
- head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
46
- # determine file list from git ls-files
47
- files = `git ls-files`.
48
- split("\n").
49
- sort.
50
- reject{ |file| file =~ /^\./ || file =~ /^test\/MarkdownTest/ }.
51
- map{ |file| " #{file}" }.
52
- join("\n")
53
- # piece file back together and write...
54
- manifest = " s.files = %w[\n#{files}\n ]\n"
55
- spec = [head,manifest,tail].join(" # = MANIFEST =\n")
56
- File.open(f.name, 'w') { |io| io.write(spec) }
57
- puts "updated #{f.name}"
58
- end
59
-
60
6
  # ==========================================================
61
7
  # Ruby Extension
62
8
  # ==========================================================
63
9
 
64
10
  DLEXT = Config::CONFIG['DLEXT']
11
+ RUBYDIGEST = Digest::MD5.hexdigest(`#{RUBY} --version`)
65
12
 
66
- file 'ext/Makefile' => FileList['ext/{*.c,*.h,*.rb}'] do
13
+ file 'ext/Makefile' => FileList['ext/*.{c,h,rb}'] do
67
14
  chdir('ext') { ruby 'extconf.rb' }
68
15
  end
69
16
  CLEAN.include 'ext/Makefile', 'ext/mkmf.log'
70
17
 
71
- file "ext/rdiscount.#{DLEXT}" => FileList['ext/Makefile', 'ext/*.{c,h,rb}'] do |f|
72
- sh 'cd ext && make'
18
+ file "ext/ruby-#{RUBYDIGEST}" do |f|
19
+ rm_f FileList["ext/ruby-*"]
20
+ touch f.name
21
+ end
22
+ CLEAN.include "ext/ruby-*"
23
+
24
+ file "ext/rdiscount.#{DLEXT}" => FileList["ext/Makefile", "ext/ruby-#{RUBYDIGEST}"] do |f|
25
+ sh 'cd ext && make clean && make'
73
26
  end
74
27
  CLEAN.include 'ext/*.{o,bundle,so,dll}'
75
28
 
@@ -84,18 +37,12 @@ task :build => "lib/rdiscount.#{DLEXT}"
84
37
  # Testing
85
38
  # ==========================================================
86
39
 
87
- def runner
88
- if system("type turn 2>/dev/null 1>&2")
89
- "turn"
90
- else
91
- "testrb"
92
- end
93
- end
94
-
95
- desc 'Run unit tests'
96
- task 'test:unit' => [:build] do |t|
97
- sh "#{runner} test/markdown_test.rb test/rdiscount_test.rb"
40
+ require 'rake/testtask'
41
+ Rake::TestTask.new('test:unit') do |t|
42
+ t.test_files = FileList['test/*_test.rb']
43
+ t.ruby_opts += ['-rubygems'] if defined? Gem
98
44
  end
45
+ task 'test:unit' => [:build]
99
46
 
100
47
  desc 'Run conformance tests (MARKDOWN_TEST_VER=1.0)'
101
48
  task 'test:conformance' => [:build] do |t|
@@ -136,37 +83,14 @@ task :doc => 'doc/index.html'
136
83
 
137
84
  file 'doc/index.html' => FileList['lib/*.rb'] do |f|
138
85
  sh((<<-end).gsub(/\s+/, ' '))
139
- hanna --charset utf8 \
140
- --fmt html \
141
- --inline-source \
142
- --line-numbers \
143
- --main RDiscount \
144
- --op doc \
145
- --title 'RDiscount API Documentation' \
86
+ hanna --charset utf8 --fmt html --inline-source --line-numbers \
87
+ --main RDiscount --op doc --title 'RDiscount API Documentation' \
146
88
  #{f.prerequisites.join(' ')}
147
89
  end
148
90
  end
149
91
 
150
92
  CLEAN.include 'doc'
151
93
 
152
-
153
- # ==========================================================
154
- # Rubyforge
155
- # ==========================================================
156
-
157
- desc 'Publish new release to rubyforge'
158
- task :release => [package('.gem'), package('.tar.gz')] do |t|
159
- sh <<-end
160
- rubyforge add_release wink rdiscount #{$spec.version} #{package('.gem')} &&
161
- rubyforge add_file wink rdiscount #{$spec.version} #{package('.tar.gz')}
162
- end
163
- end
164
-
165
- desc 'Publish API docs to rubyforge'
166
- task :publish => :doc do |t|
167
- sh 'scp -rp doc/. rubyforge.org:/var/www/gforge-projects/wink/rdiscount'
168
- end
169
-
170
94
  # ==========================================================
171
95
  # Update package's Discount sources
172
96
  # ==========================================================
@@ -200,3 +124,59 @@ file 'discount' do |f|
200
124
  TEXT
201
125
  fail "discount sources required."
202
126
  end
127
+
128
+ # PACKAGING =================================================================
129
+
130
+ if defined?(Gem)
131
+ $spec = eval(File.read('rdiscount.gemspec'))
132
+
133
+ def package(ext='')
134
+ "pkg/rdiscount-#{$spec.version}" + ext
135
+ end
136
+
137
+ desc 'Build packages'
138
+ task :package => %w[.gem .tar.gz].map {|e| package(e)}
139
+
140
+ desc 'Build and install as local gem'
141
+ task :install => package('.gem') do
142
+ sh "gem install #{package('.gem')}"
143
+ end
144
+
145
+ directory 'pkg/'
146
+
147
+ file package('.gem') => %w[pkg/ rdiscount.gemspec] + $spec.files do |f|
148
+ sh "gem build rdiscount.gemspec"
149
+ mv File.basename(f.name), f.name
150
+ end
151
+
152
+ file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
153
+ sh "git archive --format=tar HEAD | gzip > #{f.name}"
154
+ end
155
+
156
+ # GEMSPEC HELPERS ==========================================================
157
+
158
+ def source_version
159
+ line = File.read('lib/rdiscount.rb')[/^\s*VERSION = .*/]
160
+ line.match(/.*VERSION = '(.*)'/)[1]
161
+ end
162
+
163
+ file 'rdiscount.gemspec' => FileList['Rakefile','lib/rdiscount.rb'] do |f|
164
+ # read spec file and split out manifest section
165
+ spec = File.read(f.name)
166
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
167
+ head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
168
+ head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
169
+ # determine file list from git ls-files
170
+ files = `git ls-files`.
171
+ split("\n").
172
+ sort.
173
+ reject{ |file| file =~ /^\./ || file =~ /^test\/MarkdownTest/ }.
174
+ map{ |file| " #{file}" }.
175
+ join("\n")
176
+ # piece file back together and write...
177
+ manifest = " s.files = %w[\n#{files}\n ]\n"
178
+ spec = [head,manifest,tail].join(" # = MANIFEST =\n")
179
+ File.open(f.name, 'w') { |io| io.write(spec) }
180
+ puts "updated #{f.name}"
181
+ end
182
+ end
data/ext/dumptree.c CHANGED
File without changes
data/ext/generate.c CHANGED
@@ -632,9 +632,9 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
632
632
 
633
633
  Qstring(tag->link_sfx, f);
634
634
 
635
- if ( tag->WxH && ref->height && ref->width ) {
636
- Qprintf(f," height=\"%d\"", ref->height);
637
- Qprintf(f, " width=\"%d\"", ref->width);
635
+ if ( tag->WxH) {
636
+ if ( ref->height) Qprintf(f," height=\"%d\"", ref->height);
637
+ if ( ref->width) Qprintf(f, " width=\"%d\"", ref->width);
638
638
  }
639
639
 
640
640
  if ( S(ref->title) ) {
@@ -667,7 +667,7 @@ linkylinky(int image, MMIOT *f)
667
667
  int status = 0;
668
668
 
669
669
  CREATE(name);
670
- bzero(&key, sizeof key);
670
+ memset(&key, 0, sizeof key);
671
671
 
672
672
  if ( linkylabel(f, &name) ) {
673
673
  if ( peek(f,1) == '(' ) {
@@ -869,9 +869,19 @@ maybe_tag_or_link(MMIOT *f)
869
869
 
870
870
  if ( size ) {
871
871
  if ( maybetag || (size >= 3 && strncmp(cursor(f), "!--", 3) == 0) ) {
872
+
873
+ /* It is not a html tag unless we find the closing '>' in
874
+ * the same block.
875
+ */
876
+ while ( (c = peek(f, size+1)) != '>' )
877
+ if ( c == EOF )
878
+ return 0;
879
+ else
880
+ size++;
881
+
872
882
  Qstring(forbidden_tag(f) ? "&lt;" : "<", f);
873
883
  while ( ((c = peek(f, 1)) != EOF) && (c != '>') )
874
- cputc(pull(f), f);
884
+ Qchar(pull(f), f);
875
885
  return 1;
876
886
  }
877
887
  else if ( !isspace(c) && process_possible_link(f, size) ) {
@@ -973,6 +983,9 @@ static struct smarties {
973
983
  { '\'', "'t>", "rsquo", 0 },
974
984
  { '\'', "'re>", "rsquo", 0 },
975
985
  { '\'', "'ll>", "rsquo", 0 },
986
+ { '\'', "'ve>", "rsquo", 0 },
987
+ { '\'', "'m>", "rsquo", 0 },
988
+ { '\'', "'d>", "rsquo", 0 },
976
989
  { '-', "--", "mdash", 1 },
977
990
  { '-', "<->", "ndash", 0 },
978
991
  { '.', "...", "hellip", 2 },
@@ -1331,7 +1344,7 @@ printtable(Paragraph *pp, MMIOT *f)
1331
1344
  int hcols;
1332
1345
  char *p;
1333
1346
 
1334
- if ( !(pp->text && pp->text->next && pp->text->next->next) )
1347
+ if ( !(pp->text && pp->text->next) )
1335
1348
  return 0;
1336
1349
 
1337
1350
  hdr = pp->text;
data/ext/markdown.c CHANGED
@@ -230,6 +230,8 @@ htmlblock(Paragraph *p, struct kw *tag)
230
230
  /* consume trailing gunk in close tag */
231
231
  c = flogetc(&f);
232
232
  }
233
+ if ( !f.t )
234
+ return 0;
233
235
  ret = f.t->next;
234
236
  f.t->next = 0;
235
237
  return ret;
@@ -269,17 +271,24 @@ istable(Line *t)
269
271
  {
270
272
  char *p;
271
273
  Line *dashes = t->next;
274
+ int contains = 0; /* found character bits; 0x01 is |, 0x02 is - */
272
275
 
273
276
  /* two lines, first must contain | */
274
277
  if ( !(dashes && memchr(T(t->text), '|', S(t->text))) )
275
278
  return 0;
276
279
 
277
- /* second line must be only whitespace, |, -, or - */
280
+ /* second line must contain - or | and nothing
281
+ * else except for whitespace or :
282
+ */
278
283
  for ( p = T(dashes->text)+S(dashes->text)-1; p >= T(dashes->text); --p)
279
- if ( ! ((*p == '|') || (*p == ':') || (*p == '-') || isspace(*p)) )
284
+ if ( *p == '|' )
285
+ contains |= 0x01;
286
+ else if ( *p == '-' )
287
+ contains |= 0x02;
288
+ else if ( ! ((*p == ':') || isspace(*p)) )
280
289
  return 0;
281
290
 
282
- return 1;
291
+ return (contains & 0x03);
283
292
  }
284
293
 
285
294
 
@@ -379,7 +388,11 @@ ishdr(Line *t, int *htyp)
379
388
  char *q = T(t->next->text);
380
389
 
381
390
  if ( (*q == '=') || (*q == '-') ) {
382
- for (i=1; i < S(t->next->text); i++)
391
+ /* find trailing space on === line */
392
+ int e = S(t->next->text) - 1;
393
+ while (e > 1 && q[e] == ' ') e--;
394
+
395
+ for (i=1; i <= e; i++)
383
396
  if ( q[0] != q[i] )
384
397
  return 0;
385
398
  *htyp = SETEXT;
data/ext/rdiscount.c CHANGED
@@ -10,6 +10,7 @@ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
10
10
  /* grab char pointer to markdown input text */
11
11
  char *res;
12
12
  int szres;
13
+ VALUE encoding;
13
14
  VALUE text = rb_funcall(self, rb_intern("text"), 0);
14
15
  VALUE buf = rb_str_buf_new(1024);
15
16
  Check_Type(text, T_STRING);
@@ -28,6 +29,13 @@ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
28
29
  }
29
30
  mkd_cleanup(doc);
30
31
 
32
+
33
+ /* force the input encoding */
34
+ if ( rb_respond_to(text, rb_intern("encoding")) ) {
35
+ encoding = rb_funcall(text, rb_intern("encoding"), 0);
36
+ rb_funcall(buf, rb_intern("force_encoding"), 1, encoding);
37
+ }
38
+
31
39
  return buf;
32
40
  }
33
41
 
data/lib/rdiscount.rb CHANGED
@@ -24,7 +24,7 @@
24
24
  # end
25
25
  #
26
26
  class RDiscount
27
- VERSION = '1.3.5'
27
+ VERSION = '1.5.8'
28
28
 
29
29
  # Original Markdown formatted text.
30
30
  attr_reader :text
data/rdiscount.gemspec CHANGED
@@ -1,12 +1,12 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rdiscount'
3
- s.version = '1.5.5'
3
+ s.version = '1.5.8'
4
4
  s.summary = "Fast Implementation of Gruber's Markdown in C"
5
- s.date = '2009-11-13'
5
+ s.date = '2010-02-03'
6
6
  s.email = 'r@tomayko.com'
7
7
  s.homepage = 'http://github.com/rtomayko/rdiscount'
8
8
  s.has_rdoc = true
9
- s.authors = ["Ryan Tomayko", "Andrew White"]
9
+ s.authors = ["Ryan Tomayko", "David Loren Parsons", "Andrew White"]
10
10
  # = MANIFEST =
11
11
  s.files = %w[
12
12
  COPYING
@@ -111,13 +111,35 @@ class MarkdownTest < Test::Unit::TestCase
111
111
  markdown.to_html
112
112
  end
113
113
 
114
+ def test_ul_with_zero_space_indent
115
+ markdown = Markdown.new("- foo\n\n- bar\n\n baz\n")
116
+ assert_equal "<ul><li><p>foo</p></li><li><p>bar</p><p>baz</p></li></ul>",
117
+ markdown.to_html.gsub("\n", "")
118
+ end
119
+
120
+ def test_ul_with_single_space_indent
121
+ markdown = Markdown.new(" - foo\n\n - bar\n\n baz\n")
122
+ assert_equal "<ul><li><p>foo</p></li><li><p>bar</p><p>baz</p></li></ul>",
123
+ markdown.to_html.gsub("\n", "")
124
+ end
125
+
126
+ # http://github.com/rtomayko/rdiscount/issues/#issue/13
127
+ def test_headings_with_trailing_space
128
+ text = "The Ant-Sugar Tales \n" +
129
+ "=================== \n\n" +
130
+ "By Candice Yellowflower \n"
131
+ markdown = Markdown.new(text)
132
+ assert_equal "<h1>The Ant-Sugar Tales </h1>\n\n<p>By Candice Yellowflower <br/>\n</p>\n",
133
+ markdown.to_html
134
+ end
135
+
114
136
  # Build tests for each file in the MarkdownTest test suite
115
137
 
116
138
  Dir["#{MARKDOWN_TEST_DIR}/Tests/*.text"].each do |text_file|
117
139
 
118
140
  basename = File.basename(text_file).sub(/\.text$/, '')
119
141
  html_file = text_file.sub(/text$/, 'html')
120
- method_name = basename.gsub(/[-,]/, '').gsub(/\s+/, '_').downcase
142
+ method_name = basename.gsub(/[-,()]/, '').gsub(/\s+/, '_').downcase
121
143
 
122
144
  define_method "test_#{method_name}" do
123
145
  markdown = Markdown.new(File.read(text_file))
@@ -125,7 +147,7 @@ class MarkdownTest < Test::Unit::TestCase
125
147
  assert_not_nil actual_html
126
148
  end
127
149
 
128
- define_method "test_#{method_name}_with_smarty_enabled" do
150
+ define_method "test_#{method_name}_smart" do
129
151
  markdown = Markdown.new(File.read(text_file), :smart)
130
152
  actual_html = markdown.to_html
131
153
  assert_not_nil actual_html
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  rootdir = File.dirname(File.dirname(__FILE__))
2
3
  $LOAD_PATH.unshift "#{rootdir}/lib"
3
4
 
@@ -29,6 +30,21 @@ class RDiscountTest < Test::Unit::TestCase
29
30
  assert_equal %(<h1>Heading</h1>\n\n<p>&ldquo;Quoted text&rdquo;</p>\n), rd.to_html
30
31
  end
31
32
 
33
+ def test_that_smart_gives_ve_suffix_a_rsquo
34
+ rd = RDiscount.new("I've been meaning to tell you ..", :smart)
35
+ assert_equal "<p>I&rsquo;ve been meaning to tell you ..</p>\n", rd.to_html
36
+ end
37
+
38
+ def test_that_smart_gives_m_suffix_a_rsquo
39
+ rd = RDiscount.new("I'm not kidding", :smart)
40
+ assert_equal "<p>I&rsquo;m not kidding</p>\n", rd.to_html
41
+ end
42
+
43
+ def test_that_smart_gives_d_suffix_a_rsquo
44
+ rd = RDiscount.new("what'd you say?", :smart)
45
+ assert_equal "<p>what&rsquo;d you say?</p>\n", rd.to_html
46
+ end
47
+
32
48
  def test_that_generate_toc_sets_toc_ids
33
49
  rd = RDiscount.new("# Level 1\n\n## Level 2", :generate_toc)
34
50
  assert rd.generate_toc
@@ -40,4 +56,12 @@ class RDiscountTest < Test::Unit::TestCase
40
56
  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
57
  assert_equal exp, rd.toc_content.strip
42
58
  end
59
+
60
+ if "".respond_to?(:encoding)
61
+ def test_should_return_string_in_same_encoding_as_input
62
+ input = "Yogācāra"
63
+ output = RDiscount.new(input).to_html
64
+ assert_equal input.encoding.name, output.encoding.name
65
+ end
66
+ end
43
67
  end
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdiscount
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.5
4
+ version: 1.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Tomayko
8
+ - David Loren Parsons
8
9
  - Andrew White
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
13
 
13
- date: 2009-11-13 00:00:00 -08:00
14
+ date: 2010-02-03 00:00:00 -08:00
14
15
  default_executable:
15
16
  dependencies: []
16
17