wikitext 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/parser.c CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2007-2008 Wincent Colaiuta
1
+ // Copyright 2007-2009 Wincent Colaiuta
2
2
  // This program is free software: you can redistribute it and/or modify
3
3
  // it under the terms of the GNU General Public License as published by
4
4
  // the Free Software Foundation, either version 3 of the License, or
@@ -37,9 +37,7 @@ typedef struct
37
37
  ary_t *line_buffer; // stack for tracking raw tokens (not scope) on current line
38
38
  VALUE pending_crlf; // boolean (Qtrue or Qfalse)
39
39
  VALUE autolink; // boolean (Qtrue or Qfalse)
40
- VALUE treat_slash_as_special; // boolean (Qtrue or Qfalse)
41
40
  VALUE space_to_underscore; // boolean (Qtrue or Qfalse)
42
- VALUE special_link; // boolean (Qtrue or Qfalse): is the current link_target a "special" link?
43
41
  str_t *line_ending;
44
42
  int base_indent; // controlled by the :indent option to Wikitext::Parser#parse
45
43
  int current_indent; // fluctuates according to currently nested structures
@@ -398,6 +396,10 @@ void _Wikitext_pop_from_stack(parser_t *parser, VALUE target)
398
396
  // not an HTML tag; so nothing to emit
399
397
  break;
400
398
 
399
+ case PATH:
400
+ // not an HTML tag; so nothing to emit
401
+ break;
402
+
401
403
  case SPACE:
402
404
  // not an HTML tag (only used to separate an external link target from the link text); so nothing to emit
403
405
  break;
@@ -619,7 +621,7 @@ VALUE _Wikitext_parser_trim_link_target(VALUE string)
619
621
  // - non-printable (non-ASCII) characters converted to numeric entities
620
622
  // - QUOT and AMP characters converted to named entities
621
623
  // - if rollback is Qtrue, there is no special treatment of spaces
622
- // - if rollback is Qfalse, leading and trailing whitespace trimmed if trimmed
624
+ // - if rollback is Qfalse, leading and trailing whitespace trimmed
623
625
  VALUE _Wikitext_parser_sanitize_link_target(parser_t *parser, VALUE rollback)
624
626
  {
625
627
  VALUE string = StringValue(parser->link_target); // raises if string is nil or doesn't quack like a string
@@ -725,8 +727,6 @@ VALUE Wikitext_parser_sanitize_link_target(VALUE self, VALUE string)
725
727
  // ...the [[foo]] is...
726
728
  // to be equivalent to:
727
729
  // thing. [[Foo]] was...
728
- // this is also where we check treat_slash_as_special is true and act accordingly
729
- // basically any link target matching /\A[a-z]+\/\d+\z/ is flagged as special
730
730
  static void _Wikitext_parser_encode_link_target(parser_t *parser)
731
731
  {
732
732
  VALUE in = StringValue(parser->link_target);
@@ -738,28 +738,6 @@ static void _Wikitext_parser_encode_link_target(parser_t *parser)
738
738
  char *end = input + len;
739
739
  static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
740
740
 
741
- // this potential shortcut requires an (admittedly cheap) prescan, so only do it when treat_slash_as_special is true
742
- parser->special_link = Qfalse;
743
- if (parser->treat_slash_as_special == Qtrue)
744
- {
745
- char *c = input; // \A
746
- while (c < end && *c >= 'a' && *c <= 'z') // [a-z]
747
- c++; // +
748
- if (c > start && c < end && *c++ == '/') // \/
749
- {
750
- while (c < end && *c >= '0' && *c <= '9') // \d
751
- {
752
- c++; // +
753
- if (c == end) // \z
754
- {
755
- // matches /\A[a-z]+\/\d+\z/ so no transformation required
756
- parser->special_link = Qtrue;
757
- return;
758
- }
759
- }
760
- }
761
- }
762
-
763
741
  // to avoid most reallocations start with a destination buffer twice the size of the source
764
742
  // this handles the most common case (where most chars are in the ASCII range and don't require more storage, but there are
765
743
  // often quite a few spaces, which are encoded as "%20" and occupy 3 bytes)
@@ -827,7 +805,6 @@ VALUE Wikitext_parser_encode_link_target(VALUE self, VALUE in)
827
805
  {
828
806
  parser_t parser;
829
807
  parser.link_target = in;
830
- parser.treat_slash_as_special = Qfalse;
831
808
  parser.space_to_underscore = Qfalse;
832
809
  _Wikitext_parser_encode_link_target(&parser);
833
810
  return parser.link_target;
@@ -838,7 +815,6 @@ VALUE Wikitext_parser_encode_special_link_target(VALUE self, VALUE in)
838
815
  {
839
816
  parser_t parser;
840
817
  parser.link_target = in;
841
- parser.treat_slash_as_special = Qtrue;
842
818
  parser.space_to_underscore = Qfalse;
843
819
  _Wikitext_parser_encode_link_target(&parser);
844
820
  return parser.link_target;
@@ -906,7 +882,6 @@ VALUE Wikitext_parser_initialize(int argc, VALUE *argv, VALUE self)
906
882
  VALUE internal_link_prefix = rb_str_new2("/wiki/");
907
883
  VALUE img_prefix = rb_str_new2("/images/");
908
884
  VALUE space_to_underscore = Qtrue;
909
- VALUE treat_slash_as_special = Qtrue;
910
885
  VALUE minimum_fulltext_token_length = INT2NUM(3);
911
886
 
912
887
  // process options hash (override defaults)
@@ -921,7 +896,6 @@ VALUE Wikitext_parser_initialize(int argc, VALUE *argv, VALUE self)
921
896
  internal_link_prefix = OVERRIDE_IF_SET(internal_link_prefix);
922
897
  img_prefix = OVERRIDE_IF_SET(img_prefix);
923
898
  space_to_underscore = OVERRIDE_IF_SET(space_to_underscore);
924
- treat_slash_as_special = OVERRIDE_IF_SET(treat_slash_as_special);
925
899
  minimum_fulltext_token_length = OVERRIDE_IF_SET(minimum_fulltext_token_length);
926
900
  }
927
901
 
@@ -933,7 +907,6 @@ VALUE Wikitext_parser_initialize(int argc, VALUE *argv, VALUE self)
933
907
  rb_iv_set(self, "@internal_link_prefix", internal_link_prefix);
934
908
  rb_iv_set(self, "@img_prefix", img_prefix);
935
909
  rb_iv_set(self, "@space_to_underscore", space_to_underscore);
936
- rb_iv_set(self, "@treat_slash_as_special", treat_slash_as_special);
937
910
  rb_iv_set(self, "@minimum_fulltext_token_length", minimum_fulltext_token_length);
938
911
  return self;
939
912
  }
@@ -1001,9 +974,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
1001
974
  GC_WRAP_ARY(parser->line_buffer, line_buffer_gc);
1002
975
  parser->pending_crlf = Qfalse;
1003
976
  parser->autolink = rb_iv_get(self, "@autolink");
1004
- parser->treat_slash_as_special = rb_iv_get(self, "@treat_slash_as_special");
1005
977
  parser->space_to_underscore = rb_iv_get(self, "@space_to_underscore");
1006
- parser->special_link = Qfalse;
1007
978
  parser->line_ending = str_new_from_string(line_ending);
1008
979
  GC_WRAP_STR(parser->line_ending, line_ending_gc);
1009
980
  parser->base_indent = base_indent;
@@ -1011,6 +982,12 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
1011
982
  parser->tabulation = str_new();
1012
983
  GC_WRAP_STR(parser->tabulation, tabulation_gc);
1013
984
 
985
+ // this simple looping design leads to a single enormous function,
986
+ // but it's faster than doing actual recursive descent and also secure in the face of
987
+ // malicious input that seeks to overflow the stack
988
+ // (with "<blockquote><blockquote><blockquote>..." times by 10,000, for example)
989
+ // given that we expect to deal with a lot of malformed input, a recursive descent design is less appropriate
990
+ // than a straightforward looping translator like this one anyway
1014
991
  token_t _token;
1015
992
  _token.type = NO_TOKEN;
1016
993
  token_t *token = NULL;
@@ -1945,13 +1922,58 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
1945
1922
  }
1946
1923
  break;
1947
1924
 
1925
+ case PATH:
1926
+ if (IN(NO_WIKI_START) || IN(PRE) || IN(PRE_START))
1927
+ rb_str_cat(parser->output, token->start, TOKEN_LEN(token));
1928
+ else if (IN(EXT_LINK_START))
1929
+ {
1930
+ if (NIL_P(parser->link_target))
1931
+ {
1932
+ // this must be our link target: look ahead to make sure we see the space we're expecting to see
1933
+ i = TOKEN_TEXT(token);
1934
+ NEXT_TOKEN();
1935
+ if (token->type == SPACE)
1936
+ {
1937
+ ary_push(parser->scope, PATH);
1938
+ ary_push(parser->scope, SPACE);
1939
+ parser->link_target = i;
1940
+ parser->link_text = rb_str_new2("");
1941
+ parser->capture = parser->link_text;
1942
+ token = NULL; // silently consume space
1943
+ }
1944
+ else
1945
+ {
1946
+ // didn't see the space! this must be an error
1947
+ _Wikitext_pop_from_stack(parser, Qnil);
1948
+ _Wikitext_pop_excess_elements(parser);
1949
+ _Wikitext_start_para_if_necessary(parser);
1950
+ rb_str_cat(parser->output, ext_link_start, sizeof(ext_link_start) - 1);
1951
+ rb_str_append(parser->output, i);
1952
+ }
1953
+ }
1954
+ else
1955
+ {
1956
+ if (NIL_P(parser->link_text))
1957
+ // this must be the first part of our link text
1958
+ parser->link_text = TOKEN_TEXT(token);
1959
+ else
1960
+ // add to existing link text
1961
+ rb_str_cat(parser->link_text, token->start, TOKEN_LEN(token));
1962
+ }
1963
+ }
1964
+ else
1965
+ {
1966
+ i = NIL_P(parser->capture) ? parser->output : parser->capture;
1967
+ _Wikitext_pop_excess_elements(parser);
1968
+ _Wikitext_start_para_if_necessary(parser);
1969
+ rb_str_cat(i, token->start, TOKEN_LEN(token));
1970
+ }
1971
+ break;
1972
+
1948
1973
  // internal links (links to other wiki articles) look like this:
1949
1974
  // [[another article]] (would point at, for example, "/wiki/another_article")
1950
1975
  // [[the other article|the link text we'll use for it]]
1951
1976
  // [[the other article | the link text we'll use for it]]
1952
- // note that the forward slash is a reserved character which changes the meaning of an internal link;
1953
- // this is a link that is external to the wiki but internal to the site as a whole:
1954
- // [[bug/12]] (a relative link to "/bug/12")
1955
1977
  // MediaWiki has strict requirements about what it will accept as a link target:
1956
1978
  // all wikitext markup is disallowed:
1957
1979
  // example [[foo ''bar'' baz]]
@@ -1968,7 +1990,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
1968
1990
  // example [[foo €]]
1969
1991
  // renders <a href="/wiki/Foo_%E2%82%AC">foo €</a>
1970
1992
  // we'll impose similar restrictions here for the link target; allowed tokens will be:
1971
- // SPACE, SPECIAL_URI_CHARS, PRINTABLE, ALNUM, DEFAULT, QUOT and AMP
1993
+ // SPACE, SPECIAL_URI_CHARS, PRINTABLE, PATH, ALNUM, DEFAULT, QUOT and AMP
1972
1994
  // everything else will be rejected
1973
1995
  case LINK_START:
1974
1996
  i = NIL_P(parser->capture) ? parser->output : parser->capture;
@@ -2002,6 +2024,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
2002
2024
  {
2003
2025
  if (type == SPACE ||
2004
2026
  type == SPECIAL_URI_CHARS ||
2027
+ type == PATH ||
2005
2028
  type == PRINTABLE ||
2006
2029
  type == ALNUM ||
2007
2030
  type == DEFAULT ||
@@ -2072,10 +2095,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
2072
2095
  _Wikitext_parser_encode_link_target(parser);
2073
2096
  _Wikitext_pop_from_stack_up_to(parser, i, LINK_START, Qtrue);
2074
2097
  parser->capture = Qnil;
2075
- if (parser->special_link)
2076
- i = _Wikitext_hyperlink(rb_str_new2("/"), parser->link_target, parser->link_text, Qnil);
2077
- else
2078
- i = _Wikitext_hyperlink(prefix, parser->link_target, parser->link_text, Qnil);
2098
+ i = _Wikitext_hyperlink(prefix, parser->link_target, parser->link_text, Qnil);
2079
2099
  rb_str_append(parser->output, i);
2080
2100
  parser->link_target = Qnil;
2081
2101
  parser->link_text = Qnil;
@@ -2090,6 +2110,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
2090
2110
 
2091
2111
  // external links look like this:
2092
2112
  // [http://google.com/ the link text]
2113
+ // [/other/page/on/site see this page]
2093
2114
  // strings in square brackets which don't match this syntax get passed through literally; eg:
2094
2115
  // he was very angery [sic] about the turn of events
2095
2116
  case EXT_LINK_START:
@@ -2129,9 +2150,9 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
2129
2150
  _Wikitext_pop_excess_elements(parser);
2130
2151
  _Wikitext_start_para_if_necessary(parser);
2131
2152
 
2132
- // look ahead: expect a URI
2153
+ // look ahead: expect an absolute URI (with protocol) or "relative" (path) URI
2133
2154
  NEXT_TOKEN();
2134
- if (token->type == URI)
2155
+ if (token->type == URI || token->type == PATH)
2135
2156
  ary_push(parser->scope, EXT_LINK_START); // so far so good, jump back to the top of the loop
2136
2157
  else
2137
2158
  // only get here if there was a syntax error (missing URI)
@@ -2155,9 +2176,10 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
2155
2176
  else
2156
2177
  {
2157
2178
  // success!
2179
+ j = IN(PATH) ? Qnil : parser->external_link_class;
2158
2180
  _Wikitext_pop_from_stack_up_to(parser, i, EXT_LINK_START, Qtrue);
2159
2181
  parser->capture = Qnil;
2160
- i = _Wikitext_hyperlink(Qnil, parser->link_target, parser->link_text, parser->external_link_class);
2182
+ i = _Wikitext_hyperlink(Qnil, parser->link_target, parser->link_text, j);
2161
2183
  rb_str_append(parser->output, i);
2162
2184
  }
2163
2185
  parser->link_target = Qnil;
@@ -2275,13 +2297,13 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
2275
2297
  _Wikitext_pop_excess_elements(parser);
2276
2298
  _Wikitext_start_para_if_necessary(parser);
2277
2299
 
2278
- // scan ahead consuming PRINTABLE, ALNUM and SPECIAL_URI_CHARS tokens
2300
+ // scan ahead consuming PATH, PRINTABLE, ALNUM and SPECIAL_URI_CHARS tokens
2279
2301
  // will cheat here and abuse the link_target capture buffer to accumulate text
2280
2302
  if (NIL_P(parser->link_target))
2281
2303
  parser->link_target = rb_str_new2("");
2282
2304
  while (NEXT_TOKEN(), (type = token->type))
2283
2305
  {
2284
- if (type == PRINTABLE || type == ALNUM || type == SPECIAL_URI_CHARS)
2306
+ if (type == PATH || type == PRINTABLE || type == ALNUM || type == SPECIAL_URI_CHARS)
2285
2307
  rb_str_cat(parser->link_target, token->start, TOKEN_LEN(token));
2286
2308
  else if (type == IMG_END)
2287
2309
  {
data/ext/token.c CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2008 Wincent Colaiuta
1
+ // Copyright 2008-2009 Wincent Colaiuta
2
2
  // This program is free software: you can redistribute it and/or modify
3
3
  // it under the terms of the GNU General Public License as published by
4
4
  // the Free Software Foundation, either version 3 of the License, or
@@ -63,6 +63,7 @@ VALUE Wikitext_parser_token_types(VALUE self)
63
63
  SET_TOKEN_TYPE(H1_END);
64
64
  SET_TOKEN_TYPE(URI);
65
65
  SET_TOKEN_TYPE(MAIL);
66
+ SET_TOKEN_TYPE(PATH);
66
67
  SET_TOKEN_TYPE(LINK_START);
67
68
  SET_TOKEN_TYPE(LINK_END);
68
69
  SET_TOKEN_TYPE(EXT_LINK_START);
data/ext/token.h CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2008 Wincent Colaiuta
1
+ // Copyright 2008-2009 Wincent Colaiuta
2
2
  // This program is free software: you can redistribute it and/or modify
3
3
  // it under the terms of the GNU General Public License as published by
4
4
  // the Free Software Foundation, either version 3 of the License, or
@@ -69,6 +69,7 @@ enum token_types {
69
69
  H1_END,
70
70
  URI,
71
71
  MAIL,
72
+ PATH,
72
73
  LINK_START,
73
74
  LINK_END,
74
75
  EXT_LINK_START,
data/ext/wikitext.c CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2008 Wincent Colaiuta
1
+ // Copyright 2008-2009 Wincent Colaiuta
2
2
  // This program is free software: you can redistribute it and/or modify
3
3
  // it under the terms of the GNU General Public License as published by
4
4
  // the Free Software Foundation, either version 3 of the License, or
@@ -42,7 +42,6 @@ void Init_wikitext()
42
42
  rb_define_attr(cWikitextParser, "external_link_class", Qtrue, Qtrue);
43
43
  rb_define_attr(cWikitextParser, "mailto_class", Qtrue, Qtrue);
44
44
  rb_define_attr(cWikitextParser, "autolink", Qtrue, Qtrue);
45
- rb_define_attr(cWikitextParser, "treat_slash_as_special", Qtrue, Qtrue);
46
45
  rb_define_attr(cWikitextParser, "space_to_underscore", Qtrue, Qtrue);
47
46
  rb_define_attr(cWikitextParser, "minimum_fulltext_token_length", Qtrue, Qtrue);
48
47
 
@@ -26,6 +26,6 @@ private
26
26
  # if speed later becomes a concern can whip up a Ragel C extension to do it
27
27
  # TODO: make this customizable (accept a lambda that performs preprocessing)
28
28
  def wikitext_preprocess
29
- gsub /\b(bug|issue|request|ticket) #(\d+)/i, '[[issues/\2|\1 #\2]]'
29
+ gsub /\b(bug|issue|request|ticket) #(\d+)/i, '[/issues/\2 \1 #\2]'
30
30
  end
31
31
  end
@@ -13,5 +13,5 @@
13
13
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
14
 
15
15
  module Wikitext
16
- VERSION = '1.3.2'
16
+ VERSION = '1.4.0'
17
17
  end # module Wikitext
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright 2007-2008 Wincent Colaiuta
2
+ # Copyright 2007-2009 Wincent Colaiuta
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
5
5
  # the Free Software Foundation, either version 3 of the License, or
@@ -48,6 +48,33 @@ describe Wikitext::Parser, 'external links' do
48
48
  @parser.parse('[mailto:user@example.com john]').should == expected
49
49
  end
50
50
 
51
+ it 'should format absolute path links' do
52
+ expected = %Q{<p><a href="/foo/bar">fb</a></p>\n} # note no "external" class
53
+ @parser.parse('[/foo/bar fb]').should == expected
54
+ end
55
+
56
+ it 'should format deeply nested absolute path links' do
57
+ expected = %Q{<p><a href="/foo/bar/baz/bing">fb</a></p>\n} # note no "external" class
58
+ @parser.parse('[/foo/bar/baz/bing fb]').should == expected
59
+ end
60
+
61
+ it 'should format minimal absolute path links' do
62
+ expected = %Q{<p><a href="/">fb</a></p>\n} # note no "external" class
63
+ @parser.parse('[/ fb]').should == expected
64
+ end
65
+
66
+ it 'should format absolute path links with trailing slashes' do
67
+ expected = %Q{<p><a href="/foo/bar/">fb</a></p>\n} # note no "external" class
68
+ @parser.parse('[/foo/bar/ fb]').should == expected
69
+ end
70
+
71
+ it 'should not format relative path links' do
72
+ # relative paths don't make sense in wikitext because
73
+ # they could be displayed anywhere (eg. /wiki/article, /dashboard/ etc)
74
+ expected = %Q{<p>[foo/bar fb]</p>\n}
75
+ @parser.parse('[foo/bar fb]').should == expected
76
+ end
77
+
51
78
  it 'should treat runs of spaces after the link target as a single space' do
52
79
  expected = %Q{<p><a href="http://google.com/" class="external">Google</a></p>\n}
53
80
  @parser.parse('[http://google.com/ Google]').should == expected
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright 2007-2008 Wincent Colaiuta
2
+ # Copyright 2007-2009 Wincent Colaiuta
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
5
5
  # the Free Software Foundation, either version 3 of the License, or
@@ -94,6 +94,11 @@ describe Wikitext::Parser, 'internal links (space to underscore off)' do
94
94
  @parser.parse('[[foo, "bar" & baz €]]').should == expected
95
95
  end
96
96
 
97
+ it 'should handle embedded paths' do
98
+ expected = %Q{<p><a href="/wiki/foo%2fbar">foo/bar</a></p>\n}
99
+ @parser.parse('[[foo/bar]]').should == expected
100
+ end
101
+
97
102
  it 'should handle links in paragraph flows' do
98
103
  expected = %Q{<p>foo <a href="/wiki/bar">bar</a> baz</p>\n}
99
104
  @parser.parse('foo [[bar]] baz').should == expected # was a bug
@@ -252,6 +257,11 @@ describe Wikitext::Parser, 'internal links (space to underscore off)' do
252
257
  expected = %Q{<p><a href="/wiki/foo">bar ]</a></p>\n}
253
258
  @parser.parse("[[foo|bar <nowiki>]</nowiki>]]").should == expected
254
259
  end
260
+
261
+ it 'should handle paths in custom link text' do
262
+ expected = %Q{<p><a href="/wiki/hello%2fworld">foo/bar</a></p>\n}
263
+ @parser.parse('[[hello/world|foo/bar]]').should == expected
264
+ end
255
265
  end
256
266
 
257
267
  describe 'overriding the link prefix' do
@@ -266,36 +276,30 @@ describe Wikitext::Parser, 'internal links (space to underscore off)' do
266
276
  end
267
277
  end
268
278
 
279
+ # "special links" existed in internal links up to and including wikitext version 1.3.2
280
+ # from version 1.4.0 onwards this feature was changed to instead work with external links
281
+ # as such, all of these specs have been updated to make sure that the old behaviour was removed
269
282
  describe 'special links' do
270
- it 'should recognize links of the form "bug/10" as special links' do
271
- @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
272
- @parser.parse('[[issue/25]]').should == %Q{<p><a href="/issue/25">issue/25</a></p>\n}
273
- @parser.parse('[[post/7]]').should == %Q{<p><a href="/post/7">post/7</a></p>\n}
283
+ it 'should no longer recognize links of the form "bug/10" as special links' do
284
+ @parser.parse('[[bug/10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
285
+ @parser.parse('[[issue/25]]').should == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
286
+ @parser.parse('[[post/7]]').should == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
274
287
  end
275
288
 
276
- it 'should not recognize special links when "treat_slash_as_special" is set to false' do
277
- @parser.treat_slash_as_special = false
278
- @parser.parse('[[bug/10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
279
- @parser.parse('[[issue/25]]').should == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
280
- @parser.parse('[[post/7]]').should == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
289
+ it 'should no longer accept custom link text in conjunction with special links' do
290
+ @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug #10</a></p>\n}
281
291
  end
282
292
 
283
- it 'should accept custom link text in conjunction with special links' do
284
- @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/bug/10">bug #10</a></p>\n}
285
- end
286
-
287
- it 'should ignore link prefix overrides when emitting special links' do
293
+ it 'should not emit special links regardless of custom internal link prefix overrides' do
288
294
  @parser.internal_link_prefix = '/custom/'
289
- @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
295
+ @parser.parse('[[bug/10]]').should == %Q{<p><a href="/custom/bug%2f10">bug/10</a></p>\n}
290
296
  end
291
297
 
292
- it 'should not classify links as special merely because of the presence of a slash' do
293
- # we want the syntax to be tight to minimize false positives
298
+ it 'should (still) not classify links as special merely because of the presence of a slash' do
294
299
  @parser.parse('[[foo/bar]]').should == %Q{<p><a href="/wiki/foo%2fbar">foo/bar</a></p>\n}
295
300
  end
296
301
 
297
- it 'should not accept special links which have a leading forward slash' do
298
- # this is a syntax error
302
+ it 'should (still) not accept special links which have a leading forward slash' do
299
303
  @parser.parse('[[/bug/10]]').should == %Q{<p><a href="/wiki/%2fbug%2f10">/bug/10</a></p>\n}
300
304
  end
301
305
  end
@@ -694,36 +698,28 @@ describe Wikitext::Parser, 'internal links (space to underscore on)' do
694
698
  end
695
699
  end
696
700
 
701
+ # see note above about "special links" being removed from internal links from 1.4.0 onwards
697
702
  describe 'special links' do
698
- it 'should recognize links of the form "bug/10" as special links' do
699
- @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
700
- @parser.parse('[[issue/25]]').should == %Q{<p><a href="/issue/25">issue/25</a></p>\n}
701
- @parser.parse('[[post/7]]').should == %Q{<p><a href="/post/7">post/7</a></p>\n}
702
- end
703
-
704
- it 'should not recognize special links when "treat_slash_as_special" is set to false' do
705
- @parser.treat_slash_as_special = false
706
- @parser.parse('[[bug/10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
707
- @parser.parse('[[issue/25]]').should == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
708
- @parser.parse('[[post/7]]').should == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
703
+ it 'should no longer recognize links of the form "bug/10" as special links' do
704
+ @parser.parse('[[bug/10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
705
+ @parser.parse('[[issue/25]]').should == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
706
+ @parser.parse('[[post/7]]').should == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
709
707
  end
710
708
 
711
- it 'should accept custom link text in conjunction with special links' do
712
- @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/bug/10">bug #10</a></p>\n}
709
+ it 'should no longer accept custom link text in conjunction with special links' do
710
+ @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug #10</a></p>\n}
713
711
  end
714
712
 
715
- it 'should ignore link prefix overrides when emitting special links' do
713
+ it 'should not emit special links regardless of custom internal link prefix overrides' do
716
714
  @parser.internal_link_prefix = '/custom/'
717
- @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
715
+ @parser.parse('[[bug/10]]').should == %Q{<p><a href="/custom/bug%2f10">bug/10</a></p>\n}
718
716
  end
719
717
 
720
- it 'should not classify links as special merely because of the presence of a slash' do
721
- # we want the syntax to be tight to minimize false positives
718
+ it 'should (still) not classify links as special merely because of the presence of a slash' do
722
719
  @parser.parse('[[foo/bar]]').should == %Q{<p><a href="/wiki/foo%2fbar">foo/bar</a></p>\n}
723
720
  end
724
721
 
725
- it 'should not accept special links which have a leading forward slash' do
726
- # this is a syntax error
722
+ it 'should (still) not accept special links which have a leading forward slash' do
727
723
  @parser.parse('[[/bug/10]]').should == %Q{<p><a href="/wiki/%2fbug%2f10">/bug/10</a></p>\n}
728
724
  end
729
725
  end
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright 2007-2008 Wincent Colaiuta
2
+ # Copyright 2007-2009 Wincent Colaiuta
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
5
5
  # the Free Software Foundation, either version 3 of the License, or
@@ -87,10 +87,12 @@ describe Wikitext, 'encoding a link target' do
87
87
 
88
88
  # "special" links don't get transformed in any way
89
89
  describe 'special links' do
90
- it 'should recognize links which match /\A[a-z]+\/\d+\z/ as being special' do
90
+
91
+ # as of version 1.4.0 the encode_link_target function no longer handles special links
92
+ it 'should (no longer) recognize links which match /\A[a-z]+\/\d+\z/ as being special' do
91
93
  string = 'foo/10'
92
- Wikitext::Parser.encode_special_link_target(string).should == string
93
- Wikitext::Parser.encode_link_target(string).should_not == string
94
+ Wikitext::Parser.encode_special_link_target(string).should == 'foo%2f10'
95
+ Wikitext::Parser.encode_link_target(string).should == 'foo%2f10'
94
96
  end
95
97
 
96
98
  it "should not recognize links which don't match at /\A/ as being special" do
@@ -0,0 +1,41 @@
1
+ require 'spec/runner/formatter/base_text_formatter'
2
+ require 'pathname'
3
+
4
+ # Format spec results for display in the Vim quickfix window
5
+ # Use this custom formatter like this:
6
+ # spec -r spec/vim_formatter.rb -f Spec::Runner::Formatter::VimFormatter spec
7
+ module Spec
8
+ module Runner
9
+ module Formatter
10
+ class VimFormatter < BaseTextFormatter
11
+
12
+ # TODO: handle pending issues
13
+ # TODO: vim-side function for printing progress
14
+ def dump_failure counter, failure
15
+ path = failure.exception.backtrace.find do |frame|
16
+ frame =~ %r{\bspec/.*_spec\.rb:\d+\z}
17
+ end
18
+ message = failure.exception.message.gsub("\n", ' ')
19
+ @output.puts "#{relativize_path(path)}: #{message}" if path
20
+ end
21
+
22
+ def dump_pending; end
23
+
24
+ def dump_summary duration, example_count, failure_count, pending_count
25
+ end
26
+
27
+ private
28
+
29
+ def relativize_path path
30
+ @wd ||= Pathname.new Dir.getwd
31
+ begin
32
+ return Pathname.new(path).relative_path_from(@wd)
33
+ rescue ArgumentError
34
+ # raised unless both paths relative, or both absolute
35
+ return path
36
+ end
37
+ end
38
+ end # class VimFormatter
39
+ end # module Formatter
40
+ end # module Runner
41
+ end # module Spec
@@ -49,10 +49,6 @@ describe Wikitext::Parser do
49
49
  @parser.space_to_underscore.should == true
50
50
  end
51
51
 
52
- it 'should treat slash as special by default' do
53
- @parser.treat_slash_as_special.should == true
54
- end
55
-
56
52
  describe 'overriding defaults at initialization time' do
57
53
  it 'should allow overriding of autolink' do
58
54
  Wikitext::Parser.new(:autolink => false).autolink.should == false
@@ -83,10 +79,6 @@ describe Wikitext::Parser do
83
79
  it 'should allow overriding of space-to-underscore' do
84
80
  Wikitext::Parser.new(:space_to_underscore => false).space_to_underscore.should == false
85
81
  end
86
-
87
- it 'should allow overriding of treat slash as special' do
88
- Wikitext::Parser.new(:treat_slash_as_special => false).treat_slash_as_special.should == false
89
- end
90
82
  end
91
83
 
92
84
  describe 'overriding defaults at parse time' do
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.3.2
4
+ version: 1.4.0
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-01-06 00:00:00 +01:00
12
+ date: 2009-02-02 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -22,7 +22,6 @@ extensions:
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
- - spec/#spec_helper.rb#
26
25
  - spec/autolinking_spec.rb
27
26
  - spec/blockquote_spec.rb
28
27
  - spec/em_spec.rb
@@ -59,6 +58,7 @@ files:
59
58
  - spec/tt_spec.rb
60
59
  - spec/ul_spec.rb
61
60
  - spec/version_spec.rb
61
+ - spec/vim_formatter.rb
62
62
  - spec/wikitext_spec.rb
63
63
  - ext/extconf.rb
64
64
  - ext/ary.c
@@ -66,7 +66,6 @@ files:
66
66
  - ext/str.c
67
67
  - ext/token.c
68
68
  - ext/wikitext.c
69
- - ext/wikitext_ragel.c
70
69
  - ext/ary.h
71
70
  - ext/parser.h
72
71
  - ext/ruby_compat.h