rdiscount 1.5.5 → 1.5.8

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