2 package IkiWiki::Plugin::smiley;
12 add_underlay("smiley");
13 hook(type => "getsetup", id => "smiley", call => \&getsetup);
14 hook(type => "sanitize", id => "smiley", call => \&sanitize);
21 # force a rebuild because turning it off
22 # removes the smileys, which would break links
28 my $srcfile = srcfile("smileys.mdwn", 1);
29 if (! defined $srcfile) {
30 print STDERR sprintf(gettext("smiley plugin will not work without %s"),
35 my $list=readfile($srcfile);
36 while ($list =~ m/^\s*\*\s+\\\\([^\s]+)\s+\[\[([^]]+)\]\]/mg) {
40 $smileys{$smiley}=$file;
42 # Add a version with < and > escaped, since they probably
43 # will be (by markdown) by the time the sanitize hook runs.
46 $smileys{$smiley}=$file;
50 debug(gettext("failed to parse any smileys"));
55 # sort and reverse so that substrings come after longer strings
56 # that contain them, in most cases.
57 $smiley_regexp='('.join('|', map { quotemeta }
58 reverse sort keys %smileys).')';
59 #debug($smiley_regexp);
65 build_regexp() unless defined $smiley_regexp;
68 return $_ unless length $smiley_regexp;
70 MATCH: while (m{(?:^|(?<=\s|>))(\\?)$smiley_regexp(?:(?=\s|<)|$)}g) {
76 # Smilies are not allowed inside <pre> or <code>.
77 # For each tag in turn, match forward to find the next <tag>
78 # or </tag> after the smiley.
80 foreach my $tag ("pre", "code") {
81 if (m/<(\/)?\s*$tag\s*>/isg && defined $1) {
82 # </tag> found first, so the smiley is
83 # inside the tag, so do not expand it.
86 # Reset pos back to where it was before this test.
92 substr($_, $epos, 1)="";
96 # Replace the smiley with its expanded value.
97 my $link=htmllink($params{page}, $params{destpage},
98 $smileys{$smiley}, linktext => $smiley);
99 substr($_, $spos, length($smiley))=$link;
100 pos=$epos+length($link);