wikitext 1.3.2 → 1.4.0

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