]> git.wincent.com - wikitext.git/commitdiff
Create "special links" from external rather than internal links
authorWincent Colaiuta <win@wincent.com>
Sun, 1 Feb 2009 21:03:47 +0000 (22:03 +0100)
committerWincent Colaiuta <win@wincent.com>
Sun, 1 Feb 2009 21:03:47 +0000 (22:03 +0100)
It was a clumsy design decision to offer detection of "special links"
inside internal links:

  [[/issues/20 | ticket #20]]

A much nicer syntax is to use external links instead:

  [/issues/20 ticket #20]

In this commit I rip out the old implementation as well as a
supporting instance variable (treat_slash_as_special), and a
couple of related low-level struct members used at the C
level (treat_slash_as_special and special_link) which were
themselves all probably evidence of "design smell".

In place of the old feature we move handling of "path"-style
links to inside of external links. Specs and docs are updated
accordingly.

See also:

  https://rails.wincent.com/issues/1208

Signed-off-by: Wincent Colaiuta <win@wincent.com>
12 files changed:
doc/README
doc/rdoc.rb
ext/parser.c
ext/token.c
ext/token.h
ext/wikitext.c
ext/wikitext_ragel.c
ext/wikitext_ragel.rl
spec/external_link_spec.rb
spec/internal_link_spec.rb
spec/link_encoding_spec.rb
spec/wikitext_spec.rb

index 20ad7fc6eb60815bef7b07ad1e74972fab1220c4..e71a8ff10bb86f4fe4eea58b597b3015ff11cc93 100644 (file)
@@ -237,6 +237,26 @@ Would become:
 See the Parser attributes documentation for information on overriding
 the default external link class (+external+ in this example).
 
+Note that in addition to providing a fully-qualified URL including a
+protocol (such as "http://" or "ftp://") you also have the option of
+using an unqualified "path"-style URL. This is useful for making
+links to other pages still on the same site, but outside of the wiki:
+
+  [/issues/1024 ticket #1024]
+
+Would become:
+
+  <a href="/issues/1024">ticket #1024</a>
+
+Note that no "external" class is included in the generated link.
+
+To avoid false positives, what constitutes a "path" is
+narrowly-defined as a string that begins with a slash, optionally
+followed by zero or more "path components" consisting of upper and
+lowercase letters, numbers, underscores, hyphens or periods. Path
+components are separated by a slash, and the trailing slash after
+the last path component is optional.
+
 == Images
 
   {{foo.png}}
index ad34d0306626a47365a8e30b21169b02dc636bc5..5c06082b3954de9a56c08f62c1941ca6a7660f9b 100644 (file)
@@ -81,26 +81,6 @@ module Wikitext
   # echoed literally:
   #     http://apple.com/
   #
-  # == +treat_slash_as_special+ (boolean)
-  #
-  # Whether "slash" in link text is treated specially. When true, any link
-  # containing a slash and matching <tt>\A[a-z]+\/\d+\z</tt> is considered to
-  # be a relative link _within_ the current site, but _outside_ the wiki. In
-  # other words, while:
-  #     [[interesting article]]
-  # is a wiki link (assuming the internal_link_prefix of "/wiki/"):
-  #     <a href="/wiki/interesting_article">interesting article</a>
-  # in contrast:
-  #     [[issue/400]]
-  # is interpreted as a link external to the wiki but internal to the site, and is converted into:
-  #     <a href="/issue/400">issue/400</a>
-  # this design is intended to work well with preprocessors, that can scan the input for things like:
-  #     issue #400
-  # and transform them before feeding them into the wikitext parser as:
-  #     [[issue/400|issue #400]]
-  # which in turn would be transformed into:
-  #     <a href="/issue/400">issue #400</a>
-  #
   # == +space_to_underscore+ (boolean)
   #
   # Whether spaces in link targets should be encoded normally or transformed
index 62a42fbb8cf770f1caca45c93c90aaf2a0efb1b4..fd586184ad49c5ab11d19159a9ec064866a6df38 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 Wincent Colaiuta
+// Copyright 2007-2009 Wincent Colaiuta
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
@@ -37,9 +37,7 @@ typedef struct
     ary_t   *line_buffer;           // stack for tracking raw tokens (not scope) on current line
     VALUE   pending_crlf;           // boolean (Qtrue or Qfalse)
     VALUE   autolink;               // boolean (Qtrue or Qfalse)
-    VALUE   treat_slash_as_special; // boolean (Qtrue or Qfalse)
     VALUE   space_to_underscore;    // boolean (Qtrue or Qfalse)
-    VALUE   special_link;           // boolean (Qtrue or Qfalse): is the current link_target a "special" link?
     str_t   *line_ending;
     int     base_indent;            // controlled by the :indent option to Wikitext::Parser#parse
     int     current_indent;         // fluctuates according to currently nested structures
@@ -398,6 +396,10 @@ void _Wikitext_pop_from_stack(parser_t *parser, VALUE target)
             // not an HTML tag; so nothing to emit
             break;
 
+        case PATH:
+            // not an HTML tag; so nothing to emit
+            break;
+
         case SPACE:
             // not an HTML tag (only used to separate an external link target from the link text); so nothing to emit
             break;
@@ -619,7 +621,7 @@ VALUE _Wikitext_parser_trim_link_target(VALUE string)
 // - non-printable (non-ASCII) characters converted to numeric entities
 // - QUOT and AMP characters converted to named entities
 // - if rollback is Qtrue, there is no special treatment of spaces
-// - if rollback is Qfalse, leading and trailing whitespace trimmed if trimmed
+// - if rollback is Qfalse, leading and trailing whitespace trimmed
 VALUE _Wikitext_parser_sanitize_link_target(parser_t *parser, VALUE rollback)
 {
     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)
 //         ...the [[foo]] is...
 // to be equivalent to:
 //         thing. [[Foo]] was...
-// this is also where we check treat_slash_as_special is true and act accordingly
-// basically any link target matching /\A[a-z]+\/\d+\z/ is flagged as special
 static void _Wikitext_parser_encode_link_target(parser_t *parser)
 {
     VALUE in                = StringValue(parser->link_target);
@@ -738,28 +738,6 @@ static void _Wikitext_parser_encode_link_target(parser_t *parser)
     char        *end        = input + len;
     static char hex[]       = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 
-    // this potential shortcut requires an (admittedly cheap) prescan, so only do it when treat_slash_as_special is true
-    parser->special_link = Qfalse;
-    if (parser->treat_slash_as_special == Qtrue)
-    {
-        char *c = input;                                    // \A
-        while (c < end && *c >= 'a' && *c <= 'z')           // [a-z]
-            c++;                                            // +
-        if (c > start && c < end && *c++ == '/')            // \/
-        {
-            while (c < end && *c >= '0' && *c <= '9')       // \d
-            {
-                c++;                                        // +
-                if (c == end)                               // \z
-                {
-                    // matches /\A[a-z]+\/\d+\z/ so no transformation required
-                    parser->special_link = Qtrue;
-                    return;
-                }
-            }
-        }
-    }
-
     // to avoid most reallocations start with a destination buffer twice the size of the source
     // this handles the most common case (where most chars are in the ASCII range and don't require more storage, but there are
     // 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)
 {
     parser_t parser;
     parser.link_target              = in;
-    parser.treat_slash_as_special   = Qfalse;
     parser.space_to_underscore      = Qfalse;
     _Wikitext_parser_encode_link_target(&parser);
     return parser.link_target;
@@ -838,7 +815,6 @@ VALUE Wikitext_parser_encode_special_link_target(VALUE self, VALUE in)
 {
     parser_t parser;
     parser.link_target              = in;
-    parser.treat_slash_as_special   = Qtrue;
     parser.space_to_underscore      = Qfalse;
     _Wikitext_parser_encode_link_target(&parser);
     return parser.link_target;
@@ -906,7 +882,6 @@ VALUE Wikitext_parser_initialize(int argc, VALUE *argv, VALUE self)
     VALUE internal_link_prefix          = rb_str_new2("/wiki/");
     VALUE img_prefix                    = rb_str_new2("/images/");
     VALUE space_to_underscore           = Qtrue;
-    VALUE treat_slash_as_special        = Qtrue;
     VALUE minimum_fulltext_token_length = INT2NUM(3);
 
     // process options hash (override defaults)
@@ -921,7 +896,6 @@ VALUE Wikitext_parser_initialize(int argc, VALUE *argv, VALUE self)
         internal_link_prefix            = OVERRIDE_IF_SET(internal_link_prefix);
         img_prefix                      = OVERRIDE_IF_SET(img_prefix);
         space_to_underscore             = OVERRIDE_IF_SET(space_to_underscore);
-        treat_slash_as_special          = OVERRIDE_IF_SET(treat_slash_as_special);
         minimum_fulltext_token_length   = OVERRIDE_IF_SET(minimum_fulltext_token_length);
     }
 
@@ -933,7 +907,6 @@ VALUE Wikitext_parser_initialize(int argc, VALUE *argv, VALUE self)
     rb_iv_set(self, "@internal_link_prefix",            internal_link_prefix);
     rb_iv_set(self, "@img_prefix",                      img_prefix);
     rb_iv_set(self, "@space_to_underscore",             space_to_underscore);
-    rb_iv_set(self, "@treat_slash_as_special",          treat_slash_as_special);
     rb_iv_set(self, "@minimum_fulltext_token_length",   minimum_fulltext_token_length);
     return self;
 }
@@ -1001,9 +974,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
     GC_WRAP_ARY(parser->line_buffer, line_buffer_gc);
     parser->pending_crlf            = Qfalse;
     parser->autolink                = rb_iv_get(self, "@autolink");
-    parser->treat_slash_as_special  = rb_iv_get(self, "@treat_slash_as_special");
     parser->space_to_underscore     = rb_iv_get(self, "@space_to_underscore");
-    parser->special_link            = Qfalse;
     parser->line_ending             = str_new_from_string(line_ending);
     GC_WRAP_STR(parser->line_ending, line_ending_gc);
     parser->base_indent             = base_indent;
@@ -1011,6 +982,12 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
     parser->tabulation              = str_new();
     GC_WRAP_STR(parser->tabulation, tabulation_gc);
 
+    // this simple looping design leads to a single enormous function,
+    // but it's faster than doing actual recursive descent and also secure in the face of
+    // malicious input that seeks to overflow the stack
+    // (with "<blockquote><blockquote><blockquote>..." times by 10,000, for example)
+    // given that we expect to deal with a lot of malformed input, a recursive descent design is less appropriate
+    // than a straightforward looping translator like this one anyway
     token_t _token;
     _token.type = NO_TOKEN;
     token_t *token = NULL;
@@ -1945,13 +1922,58 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                 }
                 break;
 
+            case PATH:
+                if (IN(NO_WIKI_START) || IN(PRE) || IN(PRE_START))
+                    rb_str_cat(parser->output, token->start, TOKEN_LEN(token));
+                else if (IN(EXT_LINK_START))
+                {
+                    if (NIL_P(parser->link_target))
+                    {
+                        // this must be our link target: look ahead to make sure we see the space we're expecting to see
+                        i = TOKEN_TEXT(token);
+                        NEXT_TOKEN();
+                        if (token->type == SPACE)
+                        {
+                            ary_push(parser->scope, PATH);
+                            ary_push(parser->scope, SPACE);
+                            parser->link_target = i;
+                            parser->link_text   = rb_str_new2("");
+                            parser->capture     = parser->link_text;
+                            token               = NULL; // silently consume space
+                        }
+                        else
+                        {
+                            // didn't see the space! this must be an error
+                            _Wikitext_pop_from_stack(parser, Qnil);
+                            _Wikitext_pop_excess_elements(parser);
+                            _Wikitext_start_para_if_necessary(parser);
+                            rb_str_cat(parser->output, ext_link_start, sizeof(ext_link_start) - 1);
+                            rb_str_append(parser->output, i);
+                        }
+                    }
+                    else
+                    {
+                        if (NIL_P(parser->link_text))
+                            // this must be the first part of our link text
+                            parser->link_text = TOKEN_TEXT(token);
+                        else
+                            // add to existing link text
+                            rb_str_cat(parser->link_text, token->start, TOKEN_LEN(token));
+                    }
+                }
+                else
+                {
+                    i = NIL_P(parser->capture) ? parser->output : parser->capture;
+                    _Wikitext_pop_excess_elements(parser);
+                    _Wikitext_start_para_if_necessary(parser);
+                    rb_str_cat(i, token->start, TOKEN_LEN(token));
+                }
+                break;
+
             // internal links (links to other wiki articles) look like this:
             //      [[another article]] (would point at, for example, "/wiki/another_article")
             //      [[the other article|the link text we'll use for it]]
             //      [[the other article | the link text we'll use for it]]
-            // note that the forward slash is a reserved character which changes the meaning of an internal link;
-            // this is a link that is external to the wiki but internal to the site as a whole:
-            //      [[bug/12]] (a relative link to "/bug/12")
             // MediaWiki has strict requirements about what it will accept as a link target:
             //      all wikitext markup is disallowed:
             //          example [[foo ''bar'' baz]]
@@ -1968,7 +1990,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
             //          example [[foo €]]
             //          renders <a href="/wiki/Foo_%E2%82%AC">foo €</a>
             // we'll impose similar restrictions here for the link target; allowed tokens will be:
-            //      SPACE, SPECIAL_URI_CHARS, PRINTABLE, ALNUM, DEFAULT, QUOT and AMP
+            //      SPACE, SPECIAL_URI_CHARS, PRINTABLE, PATH, ALNUM, DEFAULT, QUOT and AMP
             // everything else will be rejected
             case LINK_START:
                 i = NIL_P(parser->capture) ? parser->output : parser->capture;
@@ -2002,6 +2024,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                     {
                         if (type == SPACE               ||
                             type == SPECIAL_URI_CHARS   ||
+                            type == PATH                ||
                             type == PRINTABLE           ||
                             type == ALNUM               ||
                             type == DEFAULT             ||
@@ -2072,10 +2095,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                     _Wikitext_parser_encode_link_target(parser);
                     _Wikitext_pop_from_stack_up_to(parser, i, LINK_START, Qtrue);
                     parser->capture     = Qnil;
-                    if (parser->special_link)
-                        i = _Wikitext_hyperlink(rb_str_new2("/"), parser->link_target, parser->link_text, Qnil);
-                    else
-                        i = _Wikitext_hyperlink(prefix, parser->link_target, parser->link_text, Qnil);
+                    i = _Wikitext_hyperlink(prefix, parser->link_target, parser->link_text, Qnil);
                     rb_str_append(parser->output, i);
                     parser->link_target = Qnil;
                     parser->link_text   = Qnil;
@@ -2090,6 +2110,7 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
 
             // external links look like this:
             //      [http://google.com/ the link text]
+            //      [/other/page/on/site see this page]
             // strings in square brackets which don't match this syntax get passed through literally; eg:
             //      he was very angery [sic] about the turn of events
             case EXT_LINK_START:
@@ -2129,9 +2150,9 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                     _Wikitext_pop_excess_elements(parser);
                     _Wikitext_start_para_if_necessary(parser);
 
-                    // look ahead: expect a URI
+                    // look ahead: expect an absolute URI (with protocol) or "relative" (path) URI
                     NEXT_TOKEN();
-                    if (token->type == URI)
+                    if (token->type == URI || token->type == PATH)
                         ary_push(parser->scope, EXT_LINK_START);    // so far so good, jump back to the top of the loop
                     else
                         // 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)
                     else
                     {
                         // success!
+                        j = IN(PATH) ? Qnil : parser->external_link_class;
                         _Wikitext_pop_from_stack_up_to(parser, i, EXT_LINK_START, Qtrue);
                         parser->capture = Qnil;
-                        i = _Wikitext_hyperlink(Qnil, parser->link_target, parser->link_text, parser->external_link_class);
+                        i = _Wikitext_hyperlink(Qnil, parser->link_target, parser->link_text, j);
                         rb_str_append(parser->output, i);
                     }
                     parser->link_target = Qnil;
@@ -2275,13 +2297,13 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                     _Wikitext_pop_excess_elements(parser);
                     _Wikitext_start_para_if_necessary(parser);
 
-                    // scan ahead consuming PRINTABLE, ALNUM and SPECIAL_URI_CHARS tokens
+                    // scan ahead consuming PATH, PRINTABLE, ALNUM and SPECIAL_URI_CHARS tokens
                     // will cheat here and abuse the link_target capture buffer to accumulate text
                     if (NIL_P(parser->link_target))
                         parser->link_target = rb_str_new2("");
                     while (NEXT_TOKEN(), (type = token->type))
                     {
-                        if (type == PRINTABLE || type == ALNUM || type == SPECIAL_URI_CHARS)
+                        if (type == PATH || type == PRINTABLE || type == ALNUM || type == SPECIAL_URI_CHARS)
                             rb_str_cat(parser->link_target, token->start, TOKEN_LEN(token));
                         else if (type == IMG_END)
                         {
index 48cc04bcc29664455497ff4a53b650d311e8e1b3..d6986f6dcd80b371601e1c7f23dbf456c4e5a09f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2008 Wincent Colaiuta
+// Copyright 2008-2009 Wincent Colaiuta
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
@@ -63,6 +63,7 @@ VALUE Wikitext_parser_token_types(VALUE self)
     SET_TOKEN_TYPE(H1_END);
     SET_TOKEN_TYPE(URI);
     SET_TOKEN_TYPE(MAIL);
+    SET_TOKEN_TYPE(PATH);
     SET_TOKEN_TYPE(LINK_START);
     SET_TOKEN_TYPE(LINK_END);
     SET_TOKEN_TYPE(EXT_LINK_START);
index 19387d706105ba7c2a1a53d4783084d6445dffbb..8cc277ef35eef038d34807e54f76fd0455204a15 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2008 Wincent Colaiuta
+// Copyright 2008-2009 Wincent Colaiuta
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
@@ -69,6 +69,7 @@ enum token_types {
     H1_END,
     URI,
     MAIL,
+    PATH,
     LINK_START,
     LINK_END,
     EXT_LINK_START,
index b7136f311a788d271f1adde1c4acefc939379e0d..7a26942a3a867e6fb420e318a02f98e6ad474b28 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2008 Wincent Colaiuta
+// Copyright 2008-2009 Wincent Colaiuta
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
@@ -42,7 +42,6 @@ void Init_wikitext()
     rb_define_attr(cWikitextParser, "external_link_class", Qtrue, Qtrue);
     rb_define_attr(cWikitextParser, "mailto_class", Qtrue, Qtrue);
     rb_define_attr(cWikitextParser, "autolink", Qtrue, Qtrue);
-    rb_define_attr(cWikitextParser, "treat_slash_as_special", Qtrue, Qtrue);
     rb_define_attr(cWikitextParser, "space_to_underscore", Qtrue, Qtrue);
     rb_define_attr(cWikitextParser, "minimum_fulltext_token_length", Qtrue, Qtrue);
 
index 4bcc8cd08ab0a58377500d2d167def2c6b586935..760d590f66e6db5b02fd6774013bb24e7b048ff0 100644 (file)
@@ -1,5 +1,5 @@
 #line 1 "wikitext_ragel.rl"
-// Copyright 2008 Wincent Colaiuta
+// Copyright 2008-2009 Wincent Colaiuta
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
@@ -38,7 +38,7 @@ static const int wikitext_error = 0;
 
 static const int wikitext_en_main = 94;
 
-#line 461 "wikitext_ragel.rl"
+#line 468 "wikitext_ragel.rl"
 
 
 // for now we use the scanner as a tokenizer that returns one token at a time, just like ANTLR
@@ -88,7 +88,7 @@ void next_token(token_t *out, token_t *last_token, char *p, char *pe)
        te = 0;
        act = 0;
        }
-#line 503 "wikitext_ragel.rl"
+#line 510 "wikitext_ragel.rl"
     
 #line 94 "wikitext_ragel.c"
        {
@@ -102,7 +102,7 @@ tr0:
         out->code_point = ((uint32_t)(*(p - 1)) & 0x1f) << 6 |
             (*p & 0x3f);
     }
-#line 452 "wikitext_ragel.rl"
+#line 459 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(DEFAULT);
             out->column_stop = out->column_start + 1;
@@ -116,7 +116,7 @@ tr3:
             ((uint32_t)(*(p - 1)) & 0x3f) << 6 |
             (*p & 0x3f);
     }
-#line 452 "wikitext_ragel.rl"
+#line 459 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(DEFAULT);
             out->column_stop = out->column_start + 1;
@@ -131,7 +131,7 @@ tr6:
             ((uint32_t)(*(p - 1)) & 0x3f) << 6 |
             (*p & 0x3f);
     }
-#line 452 "wikitext_ragel.rl"
+#line 459 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(DEFAULT);
             out->column_stop = out->column_start + 1;
@@ -139,42 +139,42 @@ tr6:
         }}
        goto st94;
 tr7:
-#line 359 "wikitext_ragel.rl"
+#line 366 "wikitext_ragel.rl"
        {{p = ((te))-1;}{
             EMIT(AMP);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr10:
-#line 347 "wikitext_ragel.rl"
+#line 354 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(DECIMAL_ENTITY);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr12:
-#line 341 "wikitext_ragel.rl"
+#line 348 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(HEX_ENTITY);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr14:
-#line 335 "wikitext_ragel.rl"
+#line 342 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(NAMED_ENTITY);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr18:
-#line 329 "wikitext_ragel.rl"
+#line 336 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(AMP_ENTITY);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr22:
-#line 323 "wikitext_ragel.rl"
+#line 330 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(QUOT_ENTITY);
             {p++; cs = 94; goto _out;}
@@ -195,19 +195,19 @@ tr23:
             {p++; cs = 94; goto _out;}
         }
        break;
-       case 41:
+       case 42:
        {{p = ((te))-1;}
             EMIT(SPECIAL_URI_CHARS);
             {p++; cs = 94; goto _out;}
         }
        break;
-       case 42:
+       case 43:
        {{p = ((te))-1;}
             EMIT(ALNUM);
             {p++; cs = 94; goto _out;}
         }
        break;
-       case 43:
+       case 44:
        {{p = ((te))-1;}
             EMIT(PRINTABLE);
             {p++; cs = 94; goto _out;}
@@ -218,105 +218,105 @@ tr23:
        }
        goto st94;
 tr30:
-#line 365 "wikitext_ragel.rl"
+#line 372 "wikitext_ragel.rl"
        {{p = ((te))-1;}{
             EMIT(LESS);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr46:
-#line 110 "wikitext_ragel.rl"
+#line 111 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(BLOCKQUOTE_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr48:
-#line 152 "wikitext_ragel.rl"
+#line 153 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(EM_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr54:
-#line 86 "wikitext_ragel.rl"
+#line 87 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(NO_WIKI_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr57:
-#line 98 "wikitext_ragel.rl"
+#line 99 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(PRE_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr63:
-#line 140 "wikitext_ragel.rl"
+#line 141 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(STRONG_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr65:
-#line 170 "wikitext_ragel.rl"
+#line 171 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(TT_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr75:
-#line 104 "wikitext_ragel.rl"
+#line 105 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(BLOCKQUOTE_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr77:
-#line 146 "wikitext_ragel.rl"
+#line 147 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(EM_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr83:
-#line 80 "wikitext_ragel.rl"
+#line 81 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(NO_WIKI_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr86:
-#line 92 "wikitext_ragel.rl"
+#line 93 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(PRE_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr92:
-#line 134 "wikitext_ragel.rl"
+#line 135 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(STRONG_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr94:
-#line 164 "wikitext_ragel.rl"
+#line 165 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(TT_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr95:
-#line 420 "wikitext_ragel.rl"
+#line 427 "wikitext_ragel.rl"
        {{p = ((te))-1;}{
             EMIT(ALNUM);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr99:
-#line 281 "wikitext_ragel.rl"
+#line 282 "wikitext_ragel.rl"
        {{p = ((te))-1;}{
             EMIT(URI);
             {p++; cs = 94; goto _out;}
@@ -327,7 +327,7 @@ tr110:
        {
         out->code_point = *p & 0x7f;
     }
-#line 452 "wikitext_ragel.rl"
+#line 459 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(DEFAULT);
             out->column_stop = out->column_start + 1;
@@ -335,7 +335,7 @@ tr110:
         }}
        goto st94;
 tr111:
-#line 401 "wikitext_ragel.rl"
+#line 408 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(CRLF);
             out->column_stop = 1;
@@ -348,14 +348,14 @@ tr111:
     }
        goto st94;
 tr115:
-#line 353 "wikitext_ragel.rl"
+#line 360 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(QUOT);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
 tr116:
-#line 202 "wikitext_ragel.rl"
+#line 203 "wikitext_ragel.rl"
        {te = p+1;{
             if (out->column_start == 1              ||
                 last_token_type == OL               ||
@@ -369,7 +369,7 @@ tr116:
         }}
        goto st94;
 tr120:
-#line 215 "wikitext_ragel.rl"
+#line 216 "wikitext_ragel.rl"
        {te = p+1;{
             if (out->column_start == 1              ||
                 last_token_type == OL               ||
@@ -382,22 +382,22 @@ tr120:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr133:
-#line 158 "wikitext_ragel.rl"
+tr134:
+#line 159 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(TT);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr135:
-#line 305 "wikitext_ragel.rl"
+tr136:
+#line 312 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(SEPARATOR);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr137:
-#line 401 "wikitext_ragel.rl"
+tr138:
+#line 408 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(CRLF);
             out->column_stop = 1;
@@ -405,8 +405,8 @@ tr137:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr138:
-#line 401 "wikitext_ragel.rl"
+tr139:
+#line 408 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(CRLF);
             out->column_stop = 1;
@@ -414,8 +414,8 @@ tr138:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr139:
-#line 190 "wikitext_ragel.rl"
+tr140:
+#line 191 "wikitext_ragel.rl"
        {te = p;p--;{
             if (out->column_start == 1 || last_token_type == BLOCKQUOTE)
             {
@@ -427,29 +427,29 @@ tr139:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr141:
-#line 414 "wikitext_ragel.rl"
+tr142:
+#line 421 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(SPECIAL_URI_CHARS);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr142:
-#line 432 "wikitext_ragel.rl"
+tr143:
+#line 439 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(PRINTABLE);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr143:
-#line 359 "wikitext_ragel.rl"
+tr144:
+#line 366 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(AMP);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr147:
-#line 116 "wikitext_ragel.rl"
+tr148:
+#line 117 "wikitext_ragel.rl"
        {te = p;p--;{
             if (DISTANCE() == 5)
                 EMIT(STRONG_EM);
@@ -467,8 +467,8 @@ tr147:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr151:
-#line 116 "wikitext_ragel.rl"
+tr152:
+#line 117 "wikitext_ragel.rl"
        {te = p+1;{
             if (DISTANCE() == 5)
                 EMIT(STRONG_EM);
@@ -486,29 +486,36 @@ tr151:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr153:
-#line 287 "wikitext_ragel.rl"
+tr154:
+#line 288 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(MAIL);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr157:
-#line 420 "wikitext_ragel.rl"
+tr158:
+#line 294 "wikitext_ragel.rl"
+       {te = p;p--;{
+            EMIT(PATH);
+            {p++; cs = 94; goto _out;}
+        }}
+       goto st94;
+tr162:
+#line 427 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(ALNUM);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr158:
-#line 365 "wikitext_ragel.rl"
+tr163:
+#line 372 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(LESS);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr166:
-#line 228 "wikitext_ragel.rl"
+tr171:
+#line 229 "wikitext_ragel.rl"
        {te = p;p--;{
             if (out->column_start == 1 || last_token_type == BLOCKQUOTE || last_token_type == BLOCKQUOTE_START)
             {
@@ -561,8 +568,8 @@ tr166:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr168:
-#line 177 "wikitext_ragel.rl"
+tr173:
+#line 178 "wikitext_ragel.rl"
        {te = p;p--;{
             if (out->column_start == 1 || last_token_type == BLOCKQUOTE)
                 EMIT(BLOCKQUOTE);
@@ -574,8 +581,8 @@ tr168:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr169:
-#line 177 "wikitext_ragel.rl"
+tr174:
+#line 178 "wikitext_ragel.rl"
        {te = p+1;{
             if (out->column_start == 1 || last_token_type == BLOCKQUOTE)
                 EMIT(BLOCKQUOTE);
@@ -587,64 +594,64 @@ tr169:
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr173:
-#line 281 "wikitext_ragel.rl"
+tr178:
+#line 282 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(URI);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr187:
-#line 311 "wikitext_ragel.rl"
+tr192:
+#line 318 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(EXT_LINK_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr188:
-#line 293 "wikitext_ragel.rl"
+tr193:
+#line 300 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(LINK_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr189:
-#line 317 "wikitext_ragel.rl"
+tr194:
+#line 324 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(EXT_LINK_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr190:
-#line 299 "wikitext_ragel.rl"
+tr195:
+#line 306 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(LINK_END);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr191:
-#line 389 "wikitext_ragel.rl"
+tr196:
+#line 396 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(LEFT_CURLY);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr192:
-#line 377 "wikitext_ragel.rl"
+tr197:
+#line 384 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(IMG_START);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr193:
-#line 395 "wikitext_ragel.rl"
+tr198:
+#line 402 "wikitext_ragel.rl"
        {te = p;p--;{
             EMIT(RIGHT_CURLY);
             {p++; cs = 94; goto _out;}
         }}
        goto st94;
-tr194:
-#line 383 "wikitext_ragel.rl"
+tr199:
+#line 390 "wikitext_ragel.rl"
        {te = p+1;{
             EMIT(IMG_END);
             {p++; cs = 94; goto _out;}
@@ -658,7 +665,7 @@ st94:
 case 94:
 #line 1 "wikitext_ragel.rl"
        {ts = p;}
-#line 662 "wikitext_ragel.c"
+#line 669 "wikitext_ragel.c"
        switch( (*p) ) {
                case 10: goto tr111;
                case 13: goto tr112;
@@ -672,28 +679,28 @@ case 94:
                case 43: goto st98;
                case 45: goto tr121;
                case 46: goto tr122;
-               case 47: goto st98;
-               case 60: goto tr124;
-               case 61: goto tr125;
-               case 62: goto tr126;
+               case 47: goto st111;
+               case 60: goto tr125;
+               case 61: goto tr126;
+               case 62: goto tr127;
                case 64: goto st98;
-               case 70: goto tr127;
-               case 72: goto tr128;
-               case 77: goto tr129;
-               case 83: goto tr130;
-               case 91: goto st136;
+               case 70: goto tr128;
+               case 72: goto tr129;
+               case 77: goto tr130;
+               case 83: goto tr131;
+               case 91: goto st140;
                case 92: goto st98;
-               case 93: goto st137;
+               case 93: goto st141;
                case 94: goto st98;
                case 95: goto tr121;
-               case 96: goto tr133;
-               case 102: goto tr127;
-               case 104: goto tr128;
-               case 109: goto tr129;
-               case 115: goto tr130;
-               case 123: goto st138;
-               case 124: goto tr135;
-               case 125: goto st139;
+               case 96: goto tr134;
+               case 102: goto tr128;
+               case 104: goto tr129;
+               case 109: goto tr130;
+               case 115: goto tr131;
+               case 123: goto st142;
+               case 124: goto tr136;
+               case 125: goto st143;
                case 126: goto st98;
                case 127: goto tr110;
        }
@@ -716,11 +723,11 @@ case 94:
                } else if ( (*p) > 57 ) {
                        if ( (*p) > 63 ) {
                                if ( 65 <= (*p) && (*p) <= 122 )
-                                       goto tr123;
+                                       goto tr124;
                        } else if ( (*p) >= 58 )
                                goto st97;
                } else
-                       goto tr123;
+                       goto tr124;
        } else
                goto st98;
        goto st0;
@@ -779,10 +786,10 @@ st95:
        if ( ++p == pe )
                goto _test_eof95;
 case 95:
-#line 783 "wikitext_ragel.c"
+#line 790 "wikitext_ragel.c"
        if ( (*p) == 10 )
-               goto tr138;
-       goto tr137;
+               goto tr139;
+       goto tr138;
 tr113:
 #line 36 "wikitext_ragel.rl"
        {
@@ -793,10 +800,10 @@ st96:
        if ( ++p == pe )
                goto _test_eof96;
 case 96:
-#line 797 "wikitext_ragel.c"
+#line 804 "wikitext_ragel.c"
        if ( (*p) == 32 )
                goto st96;
-       goto tr139;
+       goto tr140;
 st97:
        if ( ++p == pe )
                goto _test_eof97;
@@ -812,7 +819,7 @@ case 97:
                        goto st97;
        } else if ( (*p) >= 40 )
                goto st97;
-       goto tr141;
+       goto tr142;
 st98:
        if ( ++p == pe )
                goto _test_eof98;
@@ -830,7 +837,7 @@ case 98:
                        goto st98;
        } else if ( (*p) >= 36 )
                goto st98;
-       goto tr142;
+       goto tr143;
 tr118:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
@@ -839,7 +846,7 @@ st99:
        if ( ++p == pe )
                goto _test_eof99;
 case 99:
-#line 843 "wikitext_ragel.c"
+#line 850 "wikitext_ragel.c"
        switch( (*p) ) {
                case 35: goto st7;
                case 97: goto st13;
@@ -850,7 +857,7 @@ case 99:
                        goto st11;
        } else if ( (*p) >= 65 )
                goto st11;
-       goto tr143;
+       goto tr144;
 st7:
        if ( ++p == pe )
                goto _test_eof7;
@@ -1044,44 +1051,44 @@ st100:
 case 100:
        if ( (*p) == 39 )
                goto st101;
-       goto tr147;
+       goto tr148;
 st101:
        if ( ++p == pe )
                goto _test_eof101;
 case 101:
        if ( (*p) == 39 )
                goto st102;
-       goto tr147;
+       goto tr148;
 st102:
        if ( ++p == pe )
                goto _test_eof102;
 case 102:
        if ( (*p) == 39 )
                goto st103;
-       goto tr147;
+       goto tr148;
 st103:
        if ( ++p == pe )
                goto _test_eof103;
 case 103:
        if ( (*p) == 39 )
-               goto tr151;
-       goto tr147;
+               goto tr152;
+       goto tr148;
 tr121:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 432 "wikitext_ragel.rl"
-       {act = 43;}
+#line 439 "wikitext_ragel.rl"
+       {act = 44;}
        goto st104;
 st104:
        if ( ++p == pe )
                goto _test_eof104;
 case 104:
-#line 1080 "wikitext_ragel.c"
+#line 1087 "wikitext_ragel.c"
        switch( (*p) ) {
                case 43: goto st98;
                case 45: goto tr121;
                case 47: goto st98;
-               case 64: goto tr152;
+               case 64: goto tr153;
                case 92: goto st98;
                case 94: goto st98;
                case 95: goto tr121;
@@ -1098,7 +1105,7 @@ case 104:
                        goto st20;
        } else
                goto st20;
-       goto tr142;
+       goto tr143;
 st20:
        if ( ++p == pe )
                goto _test_eof20;
@@ -1178,14 +1185,14 @@ case 24:
 tr29:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 287 "wikitext_ragel.rl"
+#line 288 "wikitext_ragel.rl"
        {act = 21;}
        goto st105;
 st105:
        if ( ++p == pe )
                goto _test_eof105;
 case 105:
-#line 1189 "wikitext_ragel.c"
+#line 1196 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st23;
        if ( (*p) < 65 ) {
@@ -1193,21 +1200,21 @@ case 105:
                        goto st22;
        } else if ( (*p) > 90 ) {
                if ( 97 <= (*p) && (*p) <= 122 )
-                       goto tr154;
+                       goto tr155;
        } else
-               goto tr154;
-       goto tr153;
-tr154:
+               goto tr155;
+       goto tr154;
+tr155:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 287 "wikitext_ragel.rl"
+#line 288 "wikitext_ragel.rl"
        {act = 21;}
        goto st106;
 st106:
        if ( ++p == pe )
                goto _test_eof106;
 case 106:
-#line 1211 "wikitext_ragel.c"
+#line 1218 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st23;
        if ( (*p) < 65 ) {
@@ -1215,21 +1222,21 @@ case 106:
                        goto st22;
        } else if ( (*p) > 90 ) {
                if ( 97 <= (*p) && (*p) <= 122 )
-                       goto tr155;
+                       goto tr156;
        } else
-               goto tr155;
-       goto tr153;
-tr155:
+               goto tr156;
+       goto tr154;
+tr156:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 287 "wikitext_ragel.rl"
+#line 288 "wikitext_ragel.rl"
        {act = 21;}
        goto st107;
 st107:
        if ( ++p == pe )
                goto _test_eof107;
 case 107:
-#line 1233 "wikitext_ragel.c"
+#line 1240 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st23;
        if ( (*p) < 65 ) {
@@ -1237,21 +1244,21 @@ case 107:
                        goto st22;
        } else if ( (*p) > 90 ) {
                if ( 97 <= (*p) && (*p) <= 122 )
-                       goto tr156;
+                       goto tr157;
        } else
-               goto tr156;
-       goto tr153;
-tr156:
+               goto tr157;
+       goto tr154;
+tr157:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 287 "wikitext_ragel.rl"
+#line 288 "wikitext_ragel.rl"
        {act = 21;}
        goto st108;
 st108:
        if ( ++p == pe )
                goto _test_eof108;
 case 108:
-#line 1255 "wikitext_ragel.c"
+#line 1262 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st23;
        if ( (*p) < 65 ) {
@@ -1262,18 +1269,18 @@ case 108:
                        goto st22;
        } else
                goto st22;
-       goto tr153;
-tr152:
+       goto tr154;
+tr153:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 432 "wikitext_ragel.rl"
-       {act = 43;}
+#line 439 "wikitext_ragel.rl"
+       {act = 44;}
        goto st109;
 st109:
        if ( ++p == pe )
                goto _test_eof109;
 case 109:
-#line 1277 "wikitext_ragel.c"
+#line 1284 "wikitext_ragel.c"
        switch( (*p) ) {
                case 43: goto st98;
                case 45: goto st98;
@@ -1296,18 +1303,18 @@ case 109:
                        goto st98;
        } else
                goto st22;
-       goto tr142;
+       goto tr143;
 tr122:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 414 "wikitext_ragel.rl"
-       {act = 41;}
+#line 421 "wikitext_ragel.rl"
+       {act = 42;}
        goto st110;
 st110:
        if ( ++p == pe )
                goto _test_eof110;
 case 110:
-#line 1311 "wikitext_ragel.c"
+#line 1318 "wikitext_ragel.c"
        switch( (*p) ) {
                case 33: goto st97;
                case 44: goto st97;
@@ -1331,18 +1338,105 @@ case 110:
                        goto st20;
        } else
                goto st97;
-       goto tr141;
-tr123:
-#line 1 "wikitext_ragel.rl"
-       {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st111;
+       goto tr142;
 st111:
        if ( ++p == pe )
                goto _test_eof111;
 case 111:
-#line 1346 "wikitext_ragel.c"
+       switch( (*p) ) {
+               case 43: goto st98;
+               case 45: goto st112;
+               case 47: goto st98;
+               case 64: goto st98;
+               case 92: goto st98;
+               case 94: goto st98;
+               case 95: goto st112;
+               case 126: goto st98;
+       }
+       if ( (*p) < 46 ) {
+               if ( 36 <= (*p) && (*p) <= 37 )
+                       goto st98;
+       } else if ( (*p) > 57 ) {
+               if ( (*p) > 90 ) {
+                       if ( 97 <= (*p) && (*p) <= 122 )
+                               goto st113;
+               } else if ( (*p) >= 65 )
+                       goto st113;
+       } else
+               goto st113;
+       goto tr158;
+st112:
+       if ( ++p == pe )
+               goto _test_eof112;
+case 112:
+       switch( (*p) ) {
+               case 43: goto st98;
+               case 45: goto st112;
+               case 47: goto st111;
+               case 64: goto st98;
+               case 92: goto st98;
+               case 94: goto st98;
+               case 95: goto st112;
+               case 126: goto st98;
+       }
+       if ( (*p) < 46 ) {
+               if ( 36 <= (*p) && (*p) <= 37 )
+                       goto st98;
+       } else if ( (*p) > 57 ) {
+               if ( (*p) > 90 ) {
+                       if ( 97 <= (*p) && (*p) <= 122 )
+                               goto st113;
+               } else if ( (*p) >= 65 )
+                       goto st113;
+       } else
+               goto st113;
+       goto tr158;
+st113:
+       if ( ++p == pe )
+               goto _test_eof113;
+case 113:
+       switch( (*p) ) {
+               case 47: goto st114;
+               case 95: goto st113;
+       }
+       if ( (*p) < 65 ) {
+               if ( 45 <= (*p) && (*p) <= 57 )
+                       goto st113;
+       } else if ( (*p) > 90 ) {
+               if ( 97 <= (*p) && (*p) <= 122 )
+                       goto st113;
+       } else
+               goto st113;
+       goto tr158;
+st114:
+       if ( ++p == pe )
+               goto _test_eof114;
+case 114:
+       if ( (*p) == 95 )
+               goto st113;
+       if ( (*p) < 48 ) {
+               if ( 45 <= (*p) && (*p) <= 46 )
+                       goto st113;
+       } else if ( (*p) > 57 ) {
+               if ( (*p) > 90 ) {
+                       if ( 97 <= (*p) && (*p) <= 122 )
+                               goto st113;
+               } else if ( (*p) >= 65 )
+                       goto st113;
+       } else
+               goto st113;
+       goto tr158;
+tr124:
+#line 1 "wikitext_ragel.rl"
+       {te = p+1;}
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st115;
+st115:
+       if ( ++p == pe )
+               goto _test_eof115;
+case 115:
+#line 1440 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
                case 95: goto st20;
@@ -1353,21 +1447,21 @@ case 111:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr124:
+               goto tr124;
+       goto tr162;
+tr125:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-       goto st112;
-st112:
+       goto st116;
+st116:
        if ( ++p == pe )
-               goto _test_eof112;
-case 112:
-#line 1371 "wikitext_ragel.c"
+               goto _test_eof116;
+case 116:
+#line 1465 "wikitext_ragel.c"
        switch( (*p) ) {
                case 47: goto st25;
                case 66: goto st55;
@@ -1383,7 +1477,7 @@ case 112:
                case 115: goto st76;
                case 116: goto st82;
        }
-       goto tr158;
+       goto tr163;
 st25:
        if ( ++p == pe )
                goto _test_eof25;
@@ -1901,59 +1995,59 @@ case 83:
        if ( (*p) == 62 )
                goto tr94;
        goto tr30;
-tr125:
+tr126:
 #line 36 "wikitext_ragel.rl"
        {
         MARK();
     }
-       goto st113;
-st113:
+       goto st117;
+st117:
        if ( ++p == pe )
-               goto _test_eof113;
-case 113:
-#line 1915 "wikitext_ragel.c"
+               goto _test_eof117;
+case 117:
+#line 2009 "wikitext_ragel.c"
        switch( (*p) ) {
-               case 32: goto st114;
-               case 61: goto tr125;
+               case 32: goto st118;
+               case 61: goto tr126;
        }
-       goto tr166;
-st114:
+       goto tr171;
+st118:
        if ( ++p == pe )
-               goto _test_eof114;
-case 114:
+               goto _test_eof118;
+case 118:
        if ( (*p) == 32 )
-               goto st114;
-       goto tr166;
-tr126:
+               goto st118;
+       goto tr171;
+tr127:
 #line 36 "wikitext_ragel.rl"
        {
         MARK();
     }
-       goto st115;
-st115:
+       goto st119;
+st119:
        if ( ++p == pe )
-               goto _test_eof115;
-case 115:
-#line 1938 "wikitext_ragel.c"
+               goto _test_eof119;
+case 119:
+#line 2032 "wikitext_ragel.c"
        if ( (*p) == 32 )
-               goto tr169;
-       goto tr168;
-tr127:
+               goto tr174;
+       goto tr173;
+tr128:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st116;
-st116:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st120;
+st120:
        if ( ++p == pe )
-               goto _test_eof116;
-case 116:
-#line 1952 "wikitext_ragel.c"
+               goto _test_eof120;
+case 120:
+#line 2046 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 84: goto tr170;
+               case 84: goto tr175;
                case 95: goto st20;
-               case 116: goto tr170;
+               case 116: goto tr175;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -1961,28 +2055,28 @@ case 116:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr170:
+               goto tr124;
+       goto tr162;
+tr175:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st117;
-st117:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st121;
+st121:
        if ( ++p == pe )
-               goto _test_eof117;
-case 117:
-#line 1981 "wikitext_ragel.c"
+               goto _test_eof121;
+case 121:
+#line 2075 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 80: goto tr171;
+               case 80: goto tr176;
                case 95: goto st20;
-               case 112: goto tr171;
+               case 112: goto tr176;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -1990,23 +2084,23 @@ case 117:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr171:
+               goto tr124;
+       goto tr162;
+tr176:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st118;
-st118:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st122;
+st122:
        if ( ++p == pe )
-               goto _test_eof118;
-case 118:
-#line 2010 "wikitext_ragel.c"
+               goto _test_eof122;
+case 122:
+#line 2104 "wikitext_ragel.c"
        switch( (*p) ) {
                case 58: goto st84;
                case 64: goto st21;
@@ -2018,12 +2112,12 @@ case 118:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
+               goto tr124;
+       goto tr162;
 st84:
        if ( ++p == pe )
                goto _test_eof84;
@@ -2066,12 +2160,12 @@ case 86:
 tr98:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-       goto st119;
-st119:
+       goto st123;
+st123:
        if ( ++p == pe )
-               goto _test_eof119;
-case 119:
-#line 2075 "wikitext_ragel.c"
+               goto _test_eof123;
+case 123:
+#line 2169 "wikitext_ragel.c"
        switch( (*p) ) {
                case 33: goto st87;
                case 41: goto st87;
@@ -2093,7 +2187,7 @@ case 119:
                        goto tr98;
        } else
                goto st87;
-       goto tr173;
+       goto tr178;
 st87:
        if ( ++p == pe )
                goto _test_eof87;
@@ -2120,22 +2214,22 @@ case 87:
        } else
                goto st87;
        goto tr99;
-tr128:
+tr129:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st120;
-st120:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st124;
+st124:
        if ( ++p == pe )
-               goto _test_eof120;
-case 120:
-#line 2134 "wikitext_ragel.c"
+               goto _test_eof124;
+case 124:
+#line 2228 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 84: goto tr174;
+               case 84: goto tr179;
                case 95: goto st20;
-               case 116: goto tr174;
+               case 116: goto tr179;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2143,28 +2237,28 @@ case 120:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr174:
+               goto tr124;
+       goto tr162;
+tr179:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st121;
-st121:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st125;
+st125:
        if ( ++p == pe )
-               goto _test_eof121;
-case 121:
-#line 2163 "wikitext_ragel.c"
+               goto _test_eof125;
+case 125:
+#line 2257 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 84: goto tr175;
+               case 84: goto tr180;
                case 95: goto st20;
-               case 116: goto tr175;
+               case 116: goto tr180;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2172,28 +2266,28 @@ case 121:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr175:
+               goto tr124;
+       goto tr162;
+tr180:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st122;
-st122:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st126;
+st126:
        if ( ++p == pe )
-               goto _test_eof122;
-case 122:
-#line 2192 "wikitext_ragel.c"
+               goto _test_eof126;
+case 126:
+#line 2286 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 80: goto tr176;
+               case 80: goto tr181;
                case 95: goto st20;
-               case 112: goto tr176;
+               case 112: goto tr181;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2201,29 +2295,29 @@ case 122:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr176:
+               goto tr124;
+       goto tr162;
+tr181:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st123;
-st123:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st127;
+st127:
        if ( ++p == pe )
-               goto _test_eof123;
-case 123:
-#line 2221 "wikitext_ragel.c"
+               goto _test_eof127;
+case 127:
+#line 2315 "wikitext_ragel.c"
        switch( (*p) ) {
                case 58: goto st84;
                case 64: goto st21;
-               case 83: goto tr171;
+               case 83: goto tr176;
                case 95: goto st20;
-               case 115: goto tr171;
+               case 115: goto tr176;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2231,28 +2325,28 @@ case 123:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr129:
+               goto tr124;
+       goto tr162;
+tr130:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st124;
-st124:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st128;
+st128:
        if ( ++p == pe )
-               goto _test_eof124;
-case 124:
-#line 2251 "wikitext_ragel.c"
+               goto _test_eof128;
+case 128:
+#line 2345 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 65: goto tr177;
+               case 65: goto tr182;
                case 95: goto st20;
-               case 97: goto tr177;
+               case 97: goto tr182;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2260,28 +2354,28 @@ case 124:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 98 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 66 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr177:
+               goto tr124;
+       goto tr162;
+tr182:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st125;
-st125:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st129;
+st129:
        if ( ++p == pe )
-               goto _test_eof125;
-case 125:
-#line 2280 "wikitext_ragel.c"
+               goto _test_eof129;
+case 129:
+#line 2374 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 73: goto tr178;
+               case 73: goto tr183;
                case 95: goto st20;
-               case 105: goto tr178;
+               case 105: goto tr183;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2289,28 +2383,28 @@ case 125:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr178:
+               goto tr124;
+       goto tr162;
+tr183:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st126;
-st126:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st130;
+st130:
        if ( ++p == pe )
-               goto _test_eof126;
-case 126:
-#line 2309 "wikitext_ragel.c"
+               goto _test_eof130;
+case 130:
+#line 2403 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 76: goto tr179;
+               case 76: goto tr184;
                case 95: goto st20;
-               case 108: goto tr179;
+               case 108: goto tr184;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2318,28 +2412,28 @@ case 126:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr179:
+               goto tr124;
+       goto tr162;
+tr184:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st127;
-st127:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st131;
+st131:
        if ( ++p == pe )
-               goto _test_eof127;
-case 127:
-#line 2338 "wikitext_ragel.c"
+               goto _test_eof131;
+case 131:
+#line 2432 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 84: goto tr180;
+               case 84: goto tr185;
                case 95: goto st20;
-               case 116: goto tr180;
+               case 116: goto tr185;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2347,28 +2441,28 @@ case 127:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr180:
+               goto tr124;
+       goto tr162;
+tr185:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st128;
-st128:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st132;
+st132:
        if ( ++p == pe )
-               goto _test_eof128;
-case 128:
-#line 2367 "wikitext_ragel.c"
+               goto _test_eof132;
+case 132:
+#line 2461 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 79: goto tr181;
+               case 79: goto tr186;
                case 95: goto st20;
-               case 111: goto tr181;
+               case 111: goto tr186;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2376,23 +2470,23 @@ case 128:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr181:
+               goto tr124;
+       goto tr162;
+tr186:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st129;
-st129:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st133;
+st133:
        if ( ++p == pe )
-               goto _test_eof129;
-case 129:
-#line 2396 "wikitext_ragel.c"
+               goto _test_eof133;
+case 133:
+#line 2490 "wikitext_ragel.c"
        switch( (*p) ) {
                case 58: goto st88;
                case 64: goto st21;
@@ -2404,12 +2498,12 @@ case 129:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
+               goto tr124;
+       goto tr162;
 st88:
        if ( ++p == pe )
                goto _test_eof88;
@@ -2507,14 +2601,14 @@ case 93:
 tr106:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 281 "wikitext_ragel.rl"
+#line 282 "wikitext_ragel.rl"
        {act = 20;}
-       goto st130;
-st130:
+       goto st134;
+st134:
        if ( ++p == pe )
-               goto _test_eof130;
-case 130:
-#line 2518 "wikitext_ragel.c"
+               goto _test_eof134;
+case 134:
+#line 2612 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st92;
        if ( (*p) < 65 ) {
@@ -2522,21 +2616,21 @@ case 130:
                        goto st91;
        } else if ( (*p) > 90 ) {
                if ( 97 <= (*p) && (*p) <= 122 )
-                       goto tr183;
+                       goto tr188;
        } else
-               goto tr183;
-       goto tr173;
-tr183:
+               goto tr188;
+       goto tr178;
+tr188:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 281 "wikitext_ragel.rl"
+#line 282 "wikitext_ragel.rl"
        {act = 20;}
-       goto st131;
-st131:
+       goto st135;
+st135:
        if ( ++p == pe )
-               goto _test_eof131;
-case 131:
-#line 2540 "wikitext_ragel.c"
+               goto _test_eof135;
+case 135:
+#line 2634 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st92;
        if ( (*p) < 65 ) {
@@ -2544,21 +2638,21 @@ case 131:
                        goto st91;
        } else if ( (*p) > 90 ) {
                if ( 97 <= (*p) && (*p) <= 122 )
-                       goto tr184;
+                       goto tr189;
        } else
-               goto tr184;
-       goto tr173;
-tr184:
+               goto tr189;
+       goto tr178;
+tr189:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 281 "wikitext_ragel.rl"
+#line 282 "wikitext_ragel.rl"
        {act = 20;}
-       goto st132;
-st132:
+       goto st136;
+st136:
        if ( ++p == pe )
-               goto _test_eof132;
-case 132:
-#line 2562 "wikitext_ragel.c"
+               goto _test_eof136;
+case 136:
+#line 2656 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st92;
        if ( (*p) < 65 ) {
@@ -2566,21 +2660,21 @@ case 132:
                        goto st91;
        } else if ( (*p) > 90 ) {
                if ( 97 <= (*p) && (*p) <= 122 )
-                       goto tr185;
+                       goto tr190;
        } else
-               goto tr185;
-       goto tr173;
-tr185:
+               goto tr190;
+       goto tr178;
+tr190:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 281 "wikitext_ragel.rl"
+#line 282 "wikitext_ragel.rl"
        {act = 20;}
-       goto st133;
-st133:
+       goto st137;
+st137:
        if ( ++p == pe )
-               goto _test_eof133;
-case 133:
-#line 2584 "wikitext_ragel.c"
+               goto _test_eof137;
+case 137:
+#line 2678 "wikitext_ragel.c"
        if ( (*p) == 46 )
                goto st92;
        if ( (*p) < 65 ) {
@@ -2591,23 +2685,23 @@ case 133:
                        goto st91;
        } else
                goto st91;
-       goto tr173;
-tr130:
+       goto tr178;
+tr131:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st134;
-st134:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st138;
+st138:
        if ( ++p == pe )
-               goto _test_eof134;
-case 134:
-#line 2606 "wikitext_ragel.c"
+               goto _test_eof138;
+case 138:
+#line 2700 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 86: goto tr186;
+               case 86: goto tr191;
                case 95: goto st20;
-               case 118: goto tr186;
+               case 118: goto tr191;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2615,28 +2709,28 @@ case 134:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-tr186:
+               goto tr124;
+       goto tr162;
+tr191:
 #line 1 "wikitext_ragel.rl"
        {te = p+1;}
-#line 420 "wikitext_ragel.rl"
-       {act = 42;}
-       goto st135;
-st135:
+#line 427 "wikitext_ragel.rl"
+       {act = 43;}
+       goto st139;
+st139:
        if ( ++p == pe )
-               goto _test_eof135;
-case 135:
-#line 2635 "wikitext_ragel.c"
+               goto _test_eof139;
+case 139:
+#line 2729 "wikitext_ragel.c"
        switch( (*p) ) {
                case 64: goto st21;
-               case 78: goto tr171;
+               case 78: goto tr176;
                case 95: goto st20;
-               case 110: goto tr171;
+               case 110: goto tr176;
        }
        if ( (*p) < 48 ) {
                if ( 45 <= (*p) && (*p) <= 46 )
@@ -2644,40 +2738,40 @@ case 135:
        } else if ( (*p) > 57 ) {
                if ( (*p) > 90 ) {
                        if ( 97 <= (*p) && (*p) <= 122 )
-                               goto tr123;
+                               goto tr124;
                } else if ( (*p) >= 65 )
-                       goto tr123;
+                       goto tr124;
        } else
-               goto tr123;
-       goto tr157;
-st136:
+               goto tr124;
+       goto tr162;
+st140:
        if ( ++p == pe )
-               goto _test_eof136;
-case 136:
+               goto _test_eof140;
+case 140:
        if ( (*p) == 91 )
-               goto tr188;
-       goto tr187;
-st137:
+               goto tr193;
+       goto tr192;
+st141:
        if ( ++p == pe )
-               goto _test_eof137;
-case 137:
+               goto _test_eof141;
+case 141:
        if ( (*p) == 93 )
-               goto tr190;
-       goto tr189;
-st138:
+               goto tr195;
+       goto tr194;
+st142:
        if ( ++p == pe )
-               goto _test_eof138;
-case 138:
+               goto _test_eof142;
+case 142:
        if ( (*p) == 123 )
-               goto tr192;
-       goto tr191;
-st139:
+               goto tr197;
+       goto tr196;
+st143:
        if ( ++p == pe )
-               goto _test_eof139;
-case 139:
+               goto _test_eof143;
+case 143:
        if ( (*p) == 125 )
-               goto tr194;
-       goto tr193;
+               goto tr199;
+       goto tr198;
        }
        _test_eof94: cs = 94; goto _test_eof; 
        _test_eof1: cs = 1; goto _test_eof; 
@@ -2722,6 +2816,10 @@ case 139:
        _test_eof110: cs = 110; goto _test_eof; 
        _test_eof111: cs = 111; goto _test_eof; 
        _test_eof112: cs = 112; goto _test_eof; 
+       _test_eof113: cs = 113; goto _test_eof; 
+       _test_eof114: cs = 114; goto _test_eof; 
+       _test_eof115: cs = 115; goto _test_eof; 
+       _test_eof116: cs = 116; goto _test_eof; 
        _test_eof25: cs = 25; goto _test_eof; 
        _test_eof26: cs = 26; goto _test_eof; 
        _test_eof27: cs = 27; goto _test_eof; 
@@ -2781,53 +2879,53 @@ case 139:
        _test_eof81: cs = 81; goto _test_eof; 
        _test_eof82: cs = 82; goto _test_eof; 
        _test_eof83: cs = 83; goto _test_eof; 
-       _test_eof113: cs = 113; goto _test_eof; 
-       _test_eof114: cs = 114; goto _test_eof; 
-       _test_eof115: cs = 115; goto _test_eof; 
-       _test_eof116: cs = 116; goto _test_eof; 
        _test_eof117: cs = 117; goto _test_eof; 
        _test_eof118: cs = 118; goto _test_eof; 
-       _test_eof84: cs = 84; goto _test_eof; 
-       _test_eof85: cs = 85; goto _test_eof; 
-       _test_eof86: cs = 86; goto _test_eof; 
        _test_eof119: cs = 119; goto _test_eof; 
-       _test_eof87: cs = 87; goto _test_eof; 
        _test_eof120: cs = 120; goto _test_eof; 
        _test_eof121: cs = 121; goto _test_eof; 
        _test_eof122: cs = 122; goto _test_eof; 
+       _test_eof84: cs = 84; goto _test_eof; 
+       _test_eof85: cs = 85; goto _test_eof; 
+       _test_eof86: cs = 86; goto _test_eof; 
        _test_eof123: cs = 123; goto _test_eof; 
+       _test_eof87: cs = 87; goto _test_eof; 
        _test_eof124: cs = 124; goto _test_eof; 
        _test_eof125: cs = 125; goto _test_eof; 
        _test_eof126: cs = 126; goto _test_eof; 
        _test_eof127: cs = 127; goto _test_eof; 
        _test_eof128: cs = 128; goto _test_eof; 
        _test_eof129: cs = 129; goto _test_eof; 
+       _test_eof130: cs = 130; goto _test_eof; 
+       _test_eof131: cs = 131; goto _test_eof; 
+       _test_eof132: cs = 132; goto _test_eof; 
+       _test_eof133: cs = 133; goto _test_eof; 
        _test_eof88: cs = 88; goto _test_eof; 
        _test_eof89: cs = 89; goto _test_eof; 
        _test_eof90: cs = 90; goto _test_eof; 
        _test_eof91: cs = 91; goto _test_eof; 
        _test_eof92: cs = 92; goto _test_eof; 
        _test_eof93: cs = 93; goto _test_eof; 
-       _test_eof130: cs = 130; goto _test_eof; 
-       _test_eof131: cs = 131; goto _test_eof; 
-       _test_eof132: cs = 132; goto _test_eof; 
-       _test_eof133: cs = 133; goto _test_eof; 
        _test_eof134: cs = 134; goto _test_eof; 
        _test_eof135: cs = 135; goto _test_eof; 
        _test_eof136: cs = 136; goto _test_eof; 
        _test_eof137: cs = 137; goto _test_eof; 
        _test_eof138: cs = 138; goto _test_eof; 
        _test_eof139: cs = 139; goto _test_eof; 
+       _test_eof140: cs = 140; goto _test_eof; 
+       _test_eof141: cs = 141; goto _test_eof; 
+       _test_eof142: cs = 142; goto _test_eof; 
+       _test_eof143: cs = 143; goto _test_eof; 
 
        _test_eof: {}
        if ( p == eof )
        {
        switch ( cs ) {
-       case 95: goto tr137;
-       case 96: goto tr139;
-       case 97: goto tr141;
-       case 98: goto tr142;
-       case 99: goto tr143;
+       case 95: goto tr138;
+       case 96: goto tr140;
+       case 97: goto tr142;
+       case 98: goto tr143;
+       case 99: goto tr144;
        case 7: goto tr7;
        case 8: goto tr7;
        case 9: goto tr7;
@@ -2841,24 +2939,28 @@ case 139:
        case 17: goto tr7;
        case 18: goto tr7;
        case 19: goto tr7;
-       case 100: goto tr147;
-       case 101: goto tr147;
-       case 102: goto tr147;
-       case 103: goto tr147;
-       case 104: goto tr142;
+       case 100: goto tr148;
+       case 101: goto tr148;
+       case 102: goto tr148;
+       case 103: goto tr148;
+       case 104: goto tr143;
        case 20: goto tr23;
        case 21: goto tr23;
        case 22: goto tr23;
        case 23: goto tr23;
        case 24: goto tr23;
-       case 105: goto tr153;
-       case 106: goto tr153;
-       case 107: goto tr153;
-       case 108: goto tr153;
-       case 109: goto tr142;
-       case 110: goto tr141;
-       case 111: goto tr157;
+       case 105: goto tr154;
+       case 106: goto tr154;
+       case 107: goto tr154;
+       case 108: goto tr154;
+       case 109: goto tr143;
+       case 110: goto tr142;
+       case 111: goto tr158;
        case 112: goto tr158;
+       case 113: goto tr158;
+       case 114: goto tr158;
+       case 115: goto tr162;
+       case 116: goto tr163;
        case 25: goto tr30;
        case 26: goto tr30;
        case 27: goto tr30;
@@ -2918,49 +3020,49 @@ case 139:
        case 81: goto tr30;
        case 82: goto tr30;
        case 83: goto tr30;
-       case 113: goto tr166;
-       case 114: goto tr166;
-       case 115: goto tr168;
-       case 116: goto tr157;
-       case 117: goto tr157;
-       case 118: goto tr157;
+       case 117: goto tr171;
+       case 118: goto tr171;
+       case 119: goto tr173;
+       case 120: goto tr162;
+       case 121: goto tr162;
+       case 122: goto tr162;
        case 84: goto tr95;
        case 85: goto tr95;
        case 86: goto tr95;
-       case 119: goto tr173;
+       case 123: goto tr178;
        case 87: goto tr99;
-       case 120: goto tr157;
-       case 121: goto tr157;
-       case 122: goto tr157;
-       case 123: goto tr157;
-       case 124: goto tr157;
-       case 125: goto tr157;
-       case 126: goto tr157;
-       case 127: goto tr157;
-       case 128: goto tr157;
-       case 129: goto tr157;
+       case 124: goto tr162;
+       case 125: goto tr162;
+       case 126: goto tr162;
+       case 127: goto tr162;
+       case 128: goto tr162;
+       case 129: goto tr162;
+       case 130: goto tr162;
+       case 131: goto tr162;
+       case 132: goto tr162;
+       case 133: goto tr162;
        case 88: goto tr95;
        case 89: goto tr95;
        case 90: goto tr95;
        case 91: goto tr23;
        case 92: goto tr23;
        case 93: goto tr23;
-       case 130: goto tr173;
-       case 131: goto tr173;
-       case 132: goto tr173;
-       case 133: goto tr173;
-       case 134: goto tr157;
-       case 135: goto tr157;
-       case 136: goto tr187;
-       case 137: goto tr189;
-       case 138: goto tr191;
-       case 139: goto tr193;
+       case 134: goto tr178;
+       case 135: goto tr178;
+       case 136: goto tr178;
+       case 137: goto tr178;
+       case 138: goto tr162;
+       case 139: goto tr162;
+       case 140: goto tr192;
+       case 141: goto tr194;
+       case 142: goto tr196;
+       case 143: goto tr198;
        }
        }
 
        _out: {}
        }
-#line 504 "wikitext_ragel.rl"
+#line 511 "wikitext_ragel.rl"
     if (cs == wikitext_error)
         rb_raise(eWikitextParserError, "failed before finding a token");
     else if (out->type == NO_TOKEN)
index 7227171c28667287d7be45390158c59c33260984..4d949429d68a8aaa5844433eef50c29504916585 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2008 Wincent Colaiuta
+// Copyright 2008-2009 Wincent Colaiuta
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
@@ -73,6 +73,7 @@
     special_uri_chars   = ([:!\(\),;\.\?])+ ;
     uri                 = ('mailto:'i mail) |
                           (('http'i [sS]? '://' | 'ftp://'i | 'svn://'i) uri_chars (special_uri_chars uri_chars)*) ;
+    path                = '/' ([a-zA-Z0-9_\-.]+ '/'?)* ;
 
     main := |*
 
             fbreak;
         };
 
+        path
+        {
+            EMIT(PATH);
+            fbreak;
+        };
+
         '[['
         {
             EMIT(LINK_START);
index ccad56900fdf5311fed0f8b464c4ae00c33be022..f0fea486cb2287b3a6e130060aca7d1c487b3a0e 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env ruby
-# Copyright 2007-2008 Wincent Colaiuta
+# Copyright 2007-2009 Wincent Colaiuta
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
@@ -48,6 +48,33 @@ describe Wikitext::Parser, 'external links' do
     @parser.parse('[mailto:user@example.com john]').should == expected
   end
 
+  it 'should format absolute path links' do
+    expected = %Q{<p><a href="/foo/bar">fb</a></p>\n} # note no "external" class
+    @parser.parse('[/foo/bar fb]').should == expected
+  end
+
+  it 'should format deeply nested absolute path links' do
+    expected = %Q{<p><a href="/foo/bar/baz/bing">fb</a></p>\n} # note no "external" class
+    @parser.parse('[/foo/bar/baz/bing fb]').should == expected
+  end
+
+  it 'should format minimal absolute path links' do
+    expected = %Q{<p><a href="/">fb</a></p>\n} # note no "external" class
+    @parser.parse('[/ fb]').should == expected
+  end
+
+  it 'should format absolute path links with trailing slashes' do
+    expected = %Q{<p><a href="/foo/bar/">fb</a></p>\n} # note no "external" class
+    @parser.parse('[/foo/bar/ fb]').should == expected
+  end
+
+  it 'should not format relative path links' do
+    # relative paths don't make sense in wikitext because
+    # they could be displayed anywhere (eg. /wiki/article, /dashboard/ etc)
+    expected = %Q{<p>[foo/bar fb]</p>\n}
+    @parser.parse('[foo/bar fb]').should == expected
+  end
+
   it 'should treat runs of spaces after the link target as a single space' do
     expected = %Q{<p><a href="http://google.com/" class="external">Google</a></p>\n}
     @parser.parse('[http://google.com/                  Google]').should == expected
index 5fcea432f91ac8a695b68bd1e5401c441a9155a8..41c9018ce57cd8b885f02da17ba1f230a452e7e3 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env ruby
-# Copyright 2007-2008 Wincent Colaiuta
+# Copyright 2007-2009 Wincent Colaiuta
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # 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
     @parser.parse('[[foo, "bar" & baz €]]').should == expected
   end
 
+  it 'should handle embedded paths' do
+    expected = %Q{<p><a href="/wiki/foo%2fbar">foo/bar</a></p>\n}
+    @parser.parse('[[foo/bar]]').should == expected
+  end
+
   it 'should handle links in paragraph flows' do
     expected = %Q{<p>foo <a href="/wiki/bar">bar</a> baz</p>\n}
     @parser.parse('foo [[bar]] baz').should == expected # was a bug
@@ -252,6 +257,11 @@ describe Wikitext::Parser, 'internal links (space to underscore off)' do
       expected = %Q{<p><a href="/wiki/foo">bar ]</a></p>\n}
       @parser.parse("[[foo|bar <nowiki>]</nowiki>]]").should == expected
     end
+
+    it 'should handle paths in custom link text' do
+      expected = %Q{<p><a href="/wiki/hello%2fworld">foo/bar</a></p>\n}
+      @parser.parse('[[hello/world|foo/bar]]').should == expected
+    end
   end
 
   describe 'overriding the link prefix' do
@@ -266,36 +276,30 @@ describe Wikitext::Parser, 'internal links (space to underscore off)' do
     end
   end
 
+  # "special links" existed in internal links up to and including wikitext version 1.3.2
+  # from version 1.4.0 onwards this feature was changed to instead work with external links
+  # as such, all of these specs have been updated to make sure that the old behaviour was removed
   describe 'special links' do
-    it 'should recognize links of the form "bug/10" as special links' do
-      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
-      @parser.parse('[[issue/25]]').should == %Q{<p><a href="/issue/25">issue/25</a></p>\n}
-      @parser.parse('[[post/7]]').should == %Q{<p><a href="/post/7">post/7</a></p>\n}
+    it 'should no longer recognize links of the form "bug/10" as special links' do
+      @parser.parse('[[bug/10]]').should    == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
+      @parser.parse('[[issue/25]]').should  == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
+      @parser.parse('[[post/7]]').should    == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
     end
 
-    it 'should not recognize special links when "treat_slash_as_special" is set to false' do
-      @parser.treat_slash_as_special = false
-      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
-      @parser.parse('[[issue/25]]').should == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
-      @parser.parse('[[post/7]]').should == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
+    it 'should no longer accept custom link text in conjunction with special links' do
+      @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug #10</a></p>\n}
     end
 
-    it 'should accept custom link text in conjunction with special links' do
-      @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/bug/10">bug #10</a></p>\n}
-    end
-
-    it 'should ignore link prefix overrides when emitting special links' do
+    it 'should not emit special links regardless of custom internal link prefix overrides' do
       @parser.internal_link_prefix = '/custom/'
-      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
+      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/custom/bug%2f10">bug/10</a></p>\n}
     end
 
-    it 'should not classify links as special merely because of the presence of a slash' do
-      # we want the syntax to be tight to minimize false positives
+    it 'should (still) not classify links as special merely because of the presence of a slash' do
       @parser.parse('[[foo/bar]]').should == %Q{<p><a href="/wiki/foo%2fbar">foo/bar</a></p>\n}
     end
 
-    it 'should not accept special links which have a leading forward slash' do
-      # this is a syntax error
+    it 'should (still) not accept special links which have a leading forward slash' do
       @parser.parse('[[/bug/10]]').should == %Q{<p><a href="/wiki/%2fbug%2f10">/bug/10</a></p>\n}
     end
   end
@@ -694,36 +698,28 @@ describe Wikitext::Parser, 'internal links (space to underscore on)' do
     end
   end
 
+  # see note above about "special links" being removed from internal links from 1.4.0 onwards
   describe 'special links' do
-    it 'should recognize links of the form "bug/10" as special links' do
-      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
-      @parser.parse('[[issue/25]]').should == %Q{<p><a href="/issue/25">issue/25</a></p>\n}
-      @parser.parse('[[post/7]]').should == %Q{<p><a href="/post/7">post/7</a></p>\n}
-    end
-
-    it 'should not recognize special links when "treat_slash_as_special" is set to false' do
-      @parser.treat_slash_as_special = false
-      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
-      @parser.parse('[[issue/25]]').should == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
-      @parser.parse('[[post/7]]').should == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
+    it 'should no longer recognize links of the form "bug/10" as special links' do
+      @parser.parse('[[bug/10]]').should    == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
+      @parser.parse('[[issue/25]]').should  == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
+      @parser.parse('[[post/7]]').should    == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
     end
 
-    it 'should accept custom link text in conjunction with special links' do
-      @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/bug/10">bug #10</a></p>\n}
+    it 'should no longer accept custom link text in conjunction with special links' do
+      @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug #10</a></p>\n}
     end
 
-    it 'should ignore link prefix overrides when emitting special links' do
+    it 'should not emit special links regardless of custom internal link prefix overrides' do
       @parser.internal_link_prefix = '/custom/'
-      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
+      @parser.parse('[[bug/10]]').should == %Q{<p><a href="/custom/bug%2f10">bug/10</a></p>\n}
     end
 
-    it 'should not classify links as special merely because of the presence of a slash' do
-      # we want the syntax to be tight to minimize false positives
+    it 'should (still) not classify links as special merely because of the presence of a slash' do
       @parser.parse('[[foo/bar]]').should == %Q{<p><a href="/wiki/foo%2fbar">foo/bar</a></p>\n}
     end
 
-    it 'should not accept special links which have a leading forward slash' do
-      # this is a syntax error
+    it 'should (still) not accept special links which have a leading forward slash' do
       @parser.parse('[[/bug/10]]').should == %Q{<p><a href="/wiki/%2fbug%2f10">/bug/10</a></p>\n}
     end
   end
index ab689bf8e383d06e255486d4fa88ccbac71981c0..17838d90066c2a1b0190333e13f6ea2d8649361c 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env ruby
-# Copyright 2007-2008 Wincent Colaiuta
+# Copyright 2007-2009 Wincent Colaiuta
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
@@ -87,10 +87,12 @@ describe Wikitext, 'encoding a link target' do
 
   # "special" links don't get transformed in any way
   describe 'special links' do
-    it 'should recognize links which match /\A[a-z]+\/\d+\z/ as being special' do
+
+    # as of version 1.4.0 the encode_link_target function no longer handles special links
+    it 'should (no longer) recognize links which match /\A[a-z]+\/\d+\z/ as being special' do
       string = 'foo/10'
-      Wikitext::Parser.encode_special_link_target(string).should == string
-      Wikitext::Parser.encode_link_target(string).should_not == string
+      Wikitext::Parser.encode_special_link_target(string).should == 'foo%2f10'
+      Wikitext::Parser.encode_link_target(string).should == 'foo%2f10'
     end
 
     it "should not recognize links which don't match at /\A/ as being special" do
index 942d5d3cc4f68559d6f4d72e9bdee3660af0d7ea..ae39c755409239243abe5ce268c5baa9831834b9 100755 (executable)
@@ -49,10 +49,6 @@ describe Wikitext::Parser do
     @parser.space_to_underscore.should == true
   end
 
-  it 'should treat slash as special by default' do
-    @parser.treat_slash_as_special.should == true
-  end
-
   describe 'overriding defaults at initialization time' do
     it 'should allow overriding of autolink' do
       Wikitext::Parser.new(:autolink => false).autolink.should == false
@@ -83,10 +79,6 @@ describe Wikitext::Parser do
     it 'should allow overriding of space-to-underscore' do
       Wikitext::Parser.new(:space_to_underscore => false).space_to_underscore.should == false
     end
-
-    it 'should allow overriding of treat slash as special' do
-      Wikitext::Parser.new(:treat_slash_as_special => false).treat_slash_as_special.should == false
-    end
   end
 
   describe 'overriding defaults at parse time' do