X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/8c2c8c6bea57e4d9119500b866f6bd286533d4ea..06cf6e7cf64ba97a17e4f9d70e3bb31407664b94:/IkiWiki.pm?ds=inline diff --git a/IkiWiki.pm b/IkiWiki.pm index a5dc66516..8da2ddde4 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -33,7 +33,21 @@ sub defaultconfig () { #{{{ qr/\.x?html?$/, qr/\.ikiwiki-new$/, qr/(^|\/).svn\//, qr/.arch-ids\//, qr/{arch}\//, qr/\.dpkg-tmp$/], - wiki_link_regexp => qr/\[\[(?:([^\]\|]+)\|)?([^\s\]#]+)(?:#([^\s\]]+))?\]\]/, + wiki_link_regexp => qr{ + \[\[ # beginning of link + (?: + ([^\]\|]+) # 1: link text + \| # followed by '|' + )? # optional + + ([^\s\]#]+) # 2: page to link to + (?: + \# # '#', beginning of anchor + ([^\s\]]+) # 3: anchor text + )? # optional + + \]\] # end of link + }x, wiki_file_regexp => qr/(^[-[:alnum:]_.:\/+]+$)/, web_commit_regexp => qr/^web commit (by (.*?(?=: |$))|from (\d+\.\d+\.\d+\.\d+)):?(.*)/, verbose => 0, @@ -112,7 +126,7 @@ sub checkconfig () { #{{{ unless exists $config{wikistatedir}; if ($config{rcs}) { - eval qq{require IkiWiki::Rcs::$config{rcs}}; + eval qq{use IkiWiki::Rcs::$config{rcs}}; if ($@) { error("Failed to load RCS module IkiWiki::Rcs::$config{rcs}: $@"); } @@ -192,7 +206,7 @@ sub log_message ($$) { #{{{ sub possibly_foolish_untaint ($) { #{{{ my $tainted=shift; - my ($untainted)=$tainted=~/(.*)/; + my ($untainted)=$tainted=~/(.*)/s; return $untainted; } #}}} @@ -599,7 +613,17 @@ sub preprocess ($$$;$$) { #{{{ # Note: preserve order of params, some plugins may # consider it significant. my @params; - while ($params =~ /(?:(\w+)=)?(?:"""(.*?)"""|"([^"]+)"|(\S+))(?:\s+|$)/sg) { + while ($params =~ m{ + (?:(\w+)=)? # 1: named parameter key? + (?: + """(.*?)""" # 2: triple-quoted value + | + "([^"]+)" # 3: single-quoted value + | + (\S+) # 4: unquoted value + ) + (?:\s+|$) # delimiter to next param + }sgx) { my $key=$1; my $val; if (defined $2) { @@ -643,11 +667,31 @@ sub preprocess ($$$;$$) { #{{{ return $ret; } else { - return "[[$command $params]]"; + return "\\[[$command $params]]"; } }; - $content =~ s{(\\?)\[\[(\w+)\s+((?:(?:\w+=)?(?:""".*?"""|"[^"]+"|[^\s\]]+)\s*)*)\]\]}{$handle->($1, $2, $3)}seg; + $content =~ s{ + (\\?) # 1: escape? + \[\[ # directive open + (\w+) # 2: command + \s+ + ( # 3: the parameters.. + (?: + (?:\w+=)? # named parameter key? + (?: + """.*?""" # triple-quoted value + | + "[^"]+" # single-quoted value + | + [^\s\]]+ # unquoted value + ) + \s* # whitespace or end + # of directive + ) + *) # 0 or more parameters + \]\] # directive closed + }{$handle->($1, $2, $3)}sexg; return $content; } #}}} @@ -798,7 +842,6 @@ sub template_params (@) { #{{{ return ""; } - require HTML::Template; my @ret=( filter => sub { my $text_ref = shift; @@ -813,6 +856,7 @@ sub template_params (@) { #{{{ } #}}} sub template ($;@) { #{{{ + require HTML::Template; HTML::Template->new(template_params(@_)); } #}}} @@ -977,7 +1021,21 @@ sub pagespec_translate ($) { #{{{ # Convert spec to perl code. my $code=""; - while ($spec=~m/\s*(\!|\(|\)|\w+\([^\)]+\)|[^\s()]+)\s*/ig) { + while ($spec=~m{ + \s* # ignore whitespace + ( # 1: match a single word + \! # ! + | + \( # ( + | + \) # ) + | + \w+\([^\)]+\) # command(params) + | + [^\s()]+ # any other text + ) + \s* # ignore whitespace + }igx) { my $word=$1; if (lc $word eq "and") { $code.=" &&"; @@ -1056,8 +1114,8 @@ sub match_glob ($$;@) { #{{{ # relative matching if ($glob =~ m!^\./!) { - $from=~s!/?[^/]+$!!; - $glob=~s!^\./!!; + $from=~s#/?[^/]+$##; + $glob=~s#^\./##; $glob="$from/$glob" if length $from; } @@ -1083,18 +1141,23 @@ sub match_link ($$;@) { #{{{ # relative matching if ($link =~ m!^\.! && defined $from) { - $from=~s!/?[^/]+$!!; - $link=~s!^\./!!; + $from=~s#/?[^/]+$##; + $link=~s#^\./##; $link="$from/$link" if length $from; } my $links = $IkiWiki::links{$page} or return undef; return IkiWiki::FailReason->new("$page has no links") unless @$links; my $bestlink = IkiWiki::bestlink($from, $link); - return IkiWiki::FailReason->new("no such link") unless length $bestlink; foreach my $p (@$links) { - return IkiWiki::SuccessReason->new("$page links to $link") - if $bestlink eq IkiWiki::bestlink($page, $p); + if (length $bestlink) { + return IkiWiki::SuccessReason->new("$page links to $link") + if $bestlink eq IkiWiki::bestlink($page, $p); + } + else { + return IkiWiki::SuccessReason->new("$page links to page matching $link") + if match_glob($p, $link, %params); + } } return IkiWiki::FailReason->new("$page does not link to $link"); } #}}}