diff options
Diffstat (limited to 'IkiWiki')
-rw-r--r-- | IkiWiki/Plugin/smiley.pm | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/IkiWiki/Plugin/smiley.pm b/IkiWiki/Plugin/smiley.pm index 932c2c4fe..7e0b54499 100644 --- a/IkiWiki/Plugin/smiley.pm +++ b/IkiWiki/Plugin/smiley.pm @@ -34,13 +34,47 @@ sub build_regexp () { #{{{ sub filter (@) { #{{{ my %params=@_; - + build_regexp() unless defined $smiley_regexp; - $params{content} =~ s{(?:^|(?<=\s))(\\?)$smiley_regexp(?:(?=\s)|$)}{ - $1 ? $2 : htmllink($params{page}, $params{destpage}, $smileys{$2}, linktext => $2) - }egs if length $smiley_regexp; + + $_=$params{content}; + return $_ unless length $smiley_regexp; + +MATCH: while (m{(?:^|(?<=\s))(\\?)$smiley_regexp(?:(?=\s)|$)}g) { + # Smilies are not allowed inside <pre> or <code>. + # For each tag in turn, match forward to find <tag> or + # </tag>. If it's </tag>, then the smiley is inside the + # tag, and is not expanded. If it's <tag>, the smiley is + # outside the block. + my $pos=pos; + foreach my $tag ("pre", "code") { + if (m/.*?<(\/)?\s*$tag\s*>/isg) { + if (defined $1) { + # Inside tag, so do nothing. + # (Smiley hunting will continue after + # the tag.) + next MATCH; + } + else { + # Reset pos back to where it was before + # this test. + pos=$pos; + } + } + } + + if ($1) { + # Remove escape. + substr($_, $-[1], 1)=""; + } + else { + # Replace the smiley with its expanded value. + substr($_, $-[2], length($2))= + htmllink($params{page}, $params{destpage}, $smileys{$2}, linktext => $2); + } + } - return $params{content}; + return $_; } # }}} 1 |