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 +70 -48
- data/ext/token.c +2 -1
- data/ext/token.h +2 -1
- data/ext/wikitext.c +1 -2
- data/lib/wikitext/string.rb +1 -1
- data/lib/wikitext/version.rb +1 -1
- data/spec/external_link_spec.rb +28 -1
- data/spec/internal_link_spec.rb +35 -39
- data/spec/link_encoding_spec.rb +6 -4
- data/spec/vim_formatter.rb +41 -0
- data/spec/wikitext_spec.rb +0 -8
- metadata +3 -4
- data/ext/wikitext_ragel.c +0 -2968
- data/spec/#spec_helper.rb# +0 -78
data/ext/parser.c
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
// Copyright 2007-
|
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
|
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
|
-
|
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
|
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,
|
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
|
|
data/lib/wikitext/string.rb
CHANGED
@@ -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, '[
|
29
|
+
gsub /\b(bug|issue|request|ticket) #(\d+)/i, '[/issues/\2 \1 #\2]'
|
30
30
|
end
|
31
31
|
end
|
data/lib/wikitext/version.rb
CHANGED
data/spec/external_link_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright 2007-
|
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
|
data/spec/internal_link_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright 2007-
|
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
|
272
|
-
@parser.parse('[[issue/25]]').should
|
273
|
-
@parser.parse('[[post/7]]').should
|
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
|
277
|
-
@parser.
|
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
|
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
|
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
|
700
|
-
@parser.parse('[[issue/25]]').should
|
701
|
-
@parser.parse('[[post/7]]').should
|
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
|
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
|
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
|
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
|
data/spec/link_encoding_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright 2007-
|
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
|
-
|
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 ==
|
93
|
-
Wikitext::Parser.encode_link_target(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
|
data/spec/wikitext_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|