wikitext 1.8 → 1.9

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/ext/parser.c CHANGED
@@ -1042,12 +1042,15 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
1042
1042
  // process options hash
1043
1043
  int base_indent = 0;
1044
1044
  int base_heading_level = NUM2INT(rb_iv_get(self, "@base_heading_level"));
1045
+ VALUE link_proc = Qnil;
1045
1046
  if (!NIL_P(options) && TYPE(options) == T_HASH)
1046
1047
  {
1047
1048
  // :indent => 0 (or more)
1048
- if (rb_funcall(options, rb_intern("has_key?"), 1, ID2SYM(rb_intern("indent"))) == Qtrue)
1049
+ ID has_key = rb_intern("has_key?");
1050
+ ID id = ID2SYM(rb_intern("indent"));
1051
+ if (rb_funcall(options, has_key, 1, id) == Qtrue)
1049
1052
  {
1050
- VALUE indent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
1053
+ VALUE indent = rb_hash_aref(options, id);
1051
1054
  if (indent == Qfalse)
1052
1055
  base_indent = -1; // indentation disabled
1053
1056
  else
@@ -1059,8 +1062,14 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
1059
1062
  }
1060
1063
 
1061
1064
  // :base_heading_level => 0/1/2/3/4/5/6
1062
- if (rb_funcall(options, rb_intern("has_key?"), 1, ID2SYM(rb_intern("base_heading_level"))) == Qtrue)
1063
- base_heading_level = NUM2INT(rb_hash_aref(options, ID2SYM(rb_intern("base_heading_level"))));
1065
+ id = ID2SYM(rb_intern("base_heading_level"));
1066
+ if (rb_funcall(options, has_key, 1, id) == Qtrue)
1067
+ base_heading_level = NUM2INT(rb_hash_aref(options, id));
1068
+
1069
+ // :link_proc => lambda { |link_target| ... }
1070
+ id = ID2SYM(rb_intern("link_proc"));
1071
+ if (rb_funcall(options, has_key, 1, id) == Qtrue)
1072
+ link_proc = rb_hash_aref(options, id);
1064
1073
  }
1065
1074
 
1066
1075
  // normalize, regardless of whether this came from instance variable or override
@@ -2144,10 +2153,23 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
2144
2153
  }
2145
2154
  else
2146
2155
  wiki_trim_link_text(parser);
2156
+
2157
+ // perform "redlink" check before manipulating link_target
2158
+ if (NIL_P(link_proc))
2159
+ j = Qnil;
2160
+ else
2161
+ {
2162
+ j = rb_funcall(link_proc, rb_intern("call"), 1, string_from_str(parser->link_target));
2163
+ if (!NIL_P(j))
2164
+ {
2165
+ VALUE l = j; // can't cast inside StringValue macro
2166
+ j = StringValue(l);
2167
+ }
2168
+ }
2147
2169
  wiki_encode_link_target(parser);
2148
2170
  wiki_pop_from_stack_up_to(parser, output, LINK_START, true);
2149
2171
  parser->capture = NULL;
2150
- wiki_append_hyperlink(parser, prefix, parser->link_target, parser->link_text, Qnil, false);
2172
+ wiki_append_hyperlink(parser, prefix, parser->link_target, parser->link_text, j, false);
2151
2173
  str_clear(parser->link_target);
2152
2174
  str_clear(parser->link_text);
2153
2175
  }
@@ -25,7 +25,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'ext',
25
25
  'wikitext'))
26
26
 
27
27
  class NilClass
28
- def to_wikitext
28
+ def to_wikitext options = {}
29
29
  ''
30
30
  end
31
31
  alias :w :to_wikitext
@@ -22,5 +22,5 @@
22
22
  # POSSIBILITY OF SUCH DAMAGE.
23
23
 
24
24
  module Wikitext
25
- VERSION = '1.8'
25
+ VERSION = '1.9'
26
26
  end # module Wikitext
@@ -114,6 +114,119 @@ describe Wikitext::Parser, 'internal links (space to underscore off)' do
114
114
  @parser.parse('foo [[bar]] baz').should == expected # was a bug
115
115
  end
116
116
 
117
+ describe '"red link" support' do
118
+ it 'should accept a Proc object via the optional "link_proc" parameter' do
119
+ @parser.parse('foo', :link_proc => Proc.new { }).should == %Q{<p>foo</p>\n}
120
+ end
121
+
122
+ it 'should accept a lambda via the optional "link_proc" parameter' do
123
+ @parser.parse('foo', :link_proc => lambda { }).should == %Q{<p>foo</p>\n}
124
+ end
125
+
126
+ it 'should apply custom link CSS when supplied (Proc object version)' do
127
+ link_proc = Proc.new { |target| target == 'bar' ? 'redlink' : nil }
128
+ expected = %Q{<p><a href="/wiki/foo">foo</a> <a href="/wiki/bar" class="redlink">bar</a></p>\n}
129
+ @parser.parse('[[foo]] [[bar]]', :link_proc => link_proc).should == expected
130
+ end
131
+
132
+ it 'should apply custom link CSS when supplied (lambda version)' do
133
+ link_proc = lambda { |target| target == 'bar' ? 'redlink' : nil }
134
+ expected = %Q{<p><a href="/wiki/foo">foo</a> <a href="/wiki/bar" class="redlink">bar</a></p>\n}
135
+ @parser.parse('[[foo]] [[bar]]', :link_proc => link_proc).should == expected
136
+ end
137
+
138
+ it 'should apply no custom link CSS when supplied nil (Proc object version)' do
139
+ expected = %Q{<p><a href="/wiki/foo">foo</a></p>\n}
140
+ @parser.parse('[[foo]]', :link_proc => Proc.new { |target| nil }).should == expected
141
+ end
142
+
143
+ it 'should apply no custom link CSS when supplied nil (lambda version)' do
144
+ expected = %Q{<p><a href="/wiki/foo">foo</a></p>\n}
145
+ @parser.parse('[[foo]]', :link_proc => lambda { |target| nil }).should == expected
146
+ end
147
+
148
+ it 'should let exceptions bubble up from the link proc (Proc object version)' do
149
+ lambda { @parser.parse('[[foo]]', :link_proc => Proc.new { |target| raise 'bar' }) }.should raise_error(RuntimeError, /bar/)
150
+ end
151
+
152
+ it 'should let exceptions bubble up from the link proc (lambda version)' do
153
+ lambda { @parser.parse('[[foo]]', :link_proc => lambda { |target| raise 'bar' }) }.should raise_error(RuntimeError, /bar/)
154
+ end
155
+
156
+ it 'should complain if the link proc returns a non-stringy object (Proc object version)' do
157
+ lambda {
158
+ @parser.parse '[[foo]]', :link_proc => Proc.new { 1 }
159
+ }.should raise_error(TypeError, /can't convert/)
160
+ end
161
+
162
+ it 'should complain if the link proc returns a non-stringy object (lambda version)' do
163
+ lambda {
164
+ @parser.parse '[[foo]]', :link_proc => lambda { 1 }
165
+ }.should raise_error(TypeError, /can't convert/)
166
+ end
167
+
168
+ # a couple of Ruby's idiosynchrasies: different behaviour of lambdas and Procs
169
+ it 'should not complain if the Proc object accepts too many arguments' do
170
+ lambda {
171
+ @parser.parse '[[foo]]', :link_proc => Proc.new { |a,b| }
172
+ }.should_not raise_error(ArgumentError, /wrong number/)
173
+ end
174
+
175
+ it 'should complain if the lambda accepts too many arguments' do
176
+ lambda {
177
+ @parser.parse '[[foo]]', :link_proc => lambda { |a,b| }
178
+ }.should raise_error(ArgumentError, /wrong number/)
179
+ end
180
+
181
+ it 'should complain when "return" is used inside a "Proc.new" block' do
182
+ lambda {
183
+ @parser.parse '[[foo]]', :link_proc => Proc.new { return 'bar' }
184
+ }.should raise_error(LocalJumpError)
185
+ end
186
+
187
+ it 'should not complain when "return" is used inside a lambda' do
188
+ lambda {
189
+ @parser.parse '[[foo]]', :link_proc => lambda { return 'bar' }
190
+ }.should_not raise_error(LocalJumpError)
191
+ end
192
+
193
+ it 'should interact correctly with spaces in link targets (Proc object version)' do
194
+ link_proc = Proc.new { |target| target == 'bar b' ? 'redlink' : nil }
195
+ expected = %Q{<p><a href="/wiki/foo%20a">foo a</a> <a href="/wiki/bar%20b" class="redlink">bar b</a></p>\n}
196
+ @parser.parse('[[foo a]] [[bar b]]', :link_proc => link_proc).should == expected
197
+ end
198
+
199
+ it 'should interact correctly with spaces in link targets (lambda version)' do
200
+ link_proc = lambda { |target| target == 'bar b' ? 'redlink' : nil }
201
+ expected = %Q{<p><a href="/wiki/foo%20a">foo a</a> <a href="/wiki/bar%20b" class="redlink">bar b</a></p>\n}
202
+ @parser.parse('[[foo a]] [[bar b]]', :link_proc => link_proc).should == expected
203
+ end
204
+
205
+ it 'should interact correctly with explicit link text (Proc object version)' do
206
+ link_proc = Proc.new { |target| target == 'bar b' ? 'redlink' : nil }
207
+ expected = %Q{<p><a href="/wiki/foo%20a">hello</a> <a href="/wiki/bar%20b" class="redlink">world</a></p>\n}
208
+ @parser.parse('[[foo a|hello]] [[bar b|world]]', :link_proc => link_proc).should == expected
209
+ end
210
+
211
+ it 'should interact correctly with explicit link text (lambda version)' do
212
+ link_proc = lambda { |target| target == 'bar b' ? 'redlink' : nil }
213
+ expected = %Q{<p><a href="/wiki/foo%20a">hello</a> <a href="/wiki/bar%20b" class="redlink">world</a></p>\n}
214
+ @parser.parse('[[foo a|hello]] [[bar b|world]]', :link_proc => link_proc).should == expected
215
+ end
216
+
217
+ it 'should handle link targets with encoded parts (Proc object version)' do
218
+ link_proc = Proc.new { |target| target == 'información' ? 'redlink' : nil }
219
+ expected = %Q{<p><a href="/wiki/informaci%c3%b3n" class="redlink">informaci&#x00f3;n</a> <a href="/wiki/bar">bar</a></p>\n}
220
+ @parser.parse('[[información]] [[bar]]', :link_proc => link_proc).should == expected
221
+ end
222
+
223
+ it 'should handle link targets with encoded parts (lambda version)' do
224
+ link_proc = lambda { |target| target == 'información' ? 'redlink' : nil }
225
+ expected = %Q{<p><a href="/wiki/informaci%c3%b3n" class="redlink">informaci&#x00f3;n</a> <a href="/wiki/bar">bar</a></p>\n}
226
+ @parser.parse('[[información]] [[bar]]', :link_proc => link_proc).should == expected
227
+ end
228
+ end
229
+
117
230
  describe 'custom link text' do
118
231
  it 'should recognize link text placed after the separator' do
119
232
  @parser.parse('[[foo|bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
@@ -541,6 +654,119 @@ describe Wikitext::Parser, 'internal links (space to underscore on)' do
541
654
  @parser.parse('foo [[bar]] baz').should == expected # was a bug
542
655
  end
543
656
 
657
+ describe '"red link" support' do
658
+ it 'should accept a Proc object via the optional "link_proc" parameter' do
659
+ @parser.parse('foo', :link_proc => Proc.new { }).should == %Q{<p>foo</p>\n}
660
+ end
661
+
662
+ it 'should accept a lambda via the optional "link_proc" parameter' do
663
+ @parser.parse('foo', :link_proc => lambda { }).should == %Q{<p>foo</p>\n}
664
+ end
665
+
666
+ it 'should apply custom link CSS when supplied (Proc object version)' do
667
+ link_proc = Proc.new { |target| target == 'bar' ? 'redlink' : nil }
668
+ expected = %Q{<p><a href="/wiki/foo">foo</a> <a href="/wiki/bar" class="redlink">bar</a></p>\n}
669
+ @parser.parse('[[foo]] [[bar]]', :link_proc => link_proc).should == expected
670
+ end
671
+
672
+ it 'should apply custom link CSS when supplied (lambda version)' do
673
+ link_proc = lambda { |target| target == 'bar' ? 'redlink' : nil }
674
+ expected = %Q{<p><a href="/wiki/foo">foo</a> <a href="/wiki/bar" class="redlink">bar</a></p>\n}
675
+ @parser.parse('[[foo]] [[bar]]', :link_proc => link_proc).should == expected
676
+ end
677
+
678
+ it 'should apply no custom link CSS when supplied nil (Proc object version)' do
679
+ expected = %Q{<p><a href="/wiki/foo">foo</a></p>\n}
680
+ @parser.parse('[[foo]]', :link_proc => Proc.new { |target| nil }).should == expected
681
+ end
682
+
683
+ it 'should apply no custom link CSS when supplied nil (lambda version)' do
684
+ expected = %Q{<p><a href="/wiki/foo">foo</a></p>\n}
685
+ @parser.parse('[[foo]]', :link_proc => lambda { |target| nil }).should == expected
686
+ end
687
+
688
+ it 'should let exceptions bubble up from the link proc (Proc object version)' do
689
+ lambda { @parser.parse('[[foo]]', :link_proc => Proc.new { |target| raise 'bar' }) }.should raise_error(RuntimeError, /bar/)
690
+ end
691
+
692
+ it 'should let exceptions bubble up from the link proc (lambda version)' do
693
+ lambda { @parser.parse('[[foo]]', :link_proc => lambda { |target| raise 'bar' }) }.should raise_error(RuntimeError, /bar/)
694
+ end
695
+
696
+ it 'should complain if the link proc returns a non-stringy object (Proc object version)' do
697
+ lambda {
698
+ @parser.parse '[[foo]]', :link_proc => Proc.new { 1 }
699
+ }.should raise_error(TypeError, /can't convert/)
700
+ end
701
+
702
+ it 'should complain if the link proc returns a non-stringy object (lambda version)' do
703
+ lambda {
704
+ @parser.parse '[[foo]]', :link_proc => lambda { 1 }
705
+ }.should raise_error(TypeError, /can't convert/)
706
+ end
707
+
708
+ # a couple of Ruby's idiosynchrasies: different behaviour of lambdas and Procs
709
+ it 'should not complain if the Proc object accepts too many arguments' do
710
+ lambda {
711
+ @parser.parse '[[foo]]', :link_proc => Proc.new { |a,b| }
712
+ }.should_not raise_error(ArgumentError, /wrong number/)
713
+ end
714
+
715
+ it 'should complain if the lambda accepts too many arguments' do
716
+ lambda {
717
+ @parser.parse '[[foo]]', :link_proc => lambda { |a,b| }
718
+ }.should raise_error(ArgumentError, /wrong number/)
719
+ end
720
+
721
+ it 'should complain when "return" is used inside a "Proc.new" block' do
722
+ lambda {
723
+ @parser.parse '[[foo]]', :link_proc => Proc.new { return 'bar' }
724
+ }.should raise_error(LocalJumpError)
725
+ end
726
+
727
+ it 'should not complain when "return" is used inside a lambda' do
728
+ lambda {
729
+ @parser.parse '[[foo]]', :link_proc => lambda { return 'bar' }
730
+ }.should_not raise_error(LocalJumpError)
731
+ end
732
+
733
+ it 'should interact correctly with spaces in link targets (Proc object version)' do
734
+ link_proc = Proc.new { |target| target == 'bar b' ? 'redlink' : nil }
735
+ expected = %Q{<p><a href="/wiki/foo_a">foo a</a> <a href="/wiki/bar_b" class="redlink">bar b</a></p>\n}
736
+ @parser.parse('[[foo a]] [[bar b]]', :link_proc => link_proc).should == expected
737
+ end
738
+
739
+ it 'should interact correctly with spaces in link targets (lambda version)' do
740
+ link_proc = lambda { |target| target == 'bar b' ? 'redlink' : nil }
741
+ expected = %Q{<p><a href="/wiki/foo_a">foo a</a> <a href="/wiki/bar_b" class="redlink">bar b</a></p>\n}
742
+ @parser.parse('[[foo a]] [[bar b]]', :link_proc => link_proc).should == expected
743
+ end
744
+
745
+ it 'should interact correctly with explicit link text (Proc object version)' do
746
+ link_proc = Proc.new { |target| target == 'bar b' ? 'redlink' : nil }
747
+ expected = %Q{<p><a href="/wiki/foo_a">hello</a> <a href="/wiki/bar_b" class="redlink">world</a></p>\n}
748
+ @parser.parse('[[foo a|hello]] [[bar b|world]]', :link_proc => link_proc).should == expected
749
+ end
750
+
751
+ it 'should interact correctly with explicit link text (lambda version)' do
752
+ link_proc = lambda { |target| target == 'bar b' ? 'redlink' : nil }
753
+ expected = %Q{<p><a href="/wiki/foo_a">hello</a> <a href="/wiki/bar_b" class="redlink">world</a></p>\n}
754
+ @parser.parse('[[foo a|hello]] [[bar b|world]]', :link_proc => link_proc).should == expected
755
+ end
756
+
757
+ it 'should handle link targets with encoded parts (Proc object version)' do
758
+ link_proc = Proc.new { |target| target == 'información' ? 'redlink' : nil }
759
+ expected = %Q{<p><a href="/wiki/informaci%c3%b3n" class="redlink">informaci&#x00f3;n</a> <a href="/wiki/bar">bar</a></p>\n}
760
+ @parser.parse('[[información]] [[bar]]', :link_proc => link_proc).should == expected
761
+ end
762
+
763
+ it 'should handle link targets with encoded parts (lambda version)' do
764
+ link_proc = lambda { |target| target == 'información' ? 'redlink' : nil }
765
+ expected = %Q{<p><a href="/wiki/informaci%c3%b3n" class="redlink">informaci&#x00f3;n</a> <a href="/wiki/bar">bar</a></p>\n}
766
+ @parser.parse('[[información]] [[bar]]', :link_proc => link_proc).should == expected
767
+ end
768
+ end
769
+
544
770
  describe 'custom link text' do
545
771
  it 'should recognize link text placed after the separator' do
546
772
  @parser.parse('[[foo|bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
@@ -33,4 +33,8 @@ describe NilClass, 'wikitext extensions' do
33
33
  it 'should provide a w method on the nil singleton' do
34
34
  nil.w.should == ''
35
35
  end
36
+
37
+ it 'should accept and ignore an optional options hash' do
38
+ lambda { nil.w :base_heading_level => 3 }.should_not raise_error
39
+ end
36
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wikitext
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.8"
4
+ version: "1.9"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wincent Colaiuta
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-27 00:00:00 +02:00
12
+ date: 2009-08-06 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15