wikitext 1.8 → 1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/parser.c +27 -5
- data/lib/wikitext/nil_class.rb +1 -1
- data/lib/wikitext/version.rb +1 -1
- data/spec/internal_link_spec.rb +226 -0
- data/spec/nil_class_spec.rb +4 -0
- metadata +2 -2
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
|
-
|
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,
|
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
|
-
|
1063
|
-
|
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,
|
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
|
}
|
data/lib/wikitext/nil_class.rb
CHANGED
data/lib/wikitext/version.rb
CHANGED
data/spec/internal_link_spec.rb
CHANGED
@@ -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ó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ó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ó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ó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}
|
data/spec/nil_class_spec.rb
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2009-08-06 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|