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);
17 sub getsetup () { #{{{
21 # force a rebuild because turning it off
22 # removes the smileys, which would break links
27 sub build_regexp () { #{{{
28 my $list=readfile(srcfile("smileys.mdwn"));
29 while ($list =~ m/^\s*\*\s+\\\\([^\s]+)\s+\[\[([^]]+)\]\]/mg) {
33 $smileys{$smiley}=$file;
35 # Add a version with < and > escaped, since they probably
36 # will be (by markdown) by the time the sanitize hook runs.
39 $smileys{$smiley}=$file;
43 debug(gettext("failed to parse any smileys"));
48 # sort and reverse so that substrings come after longer strings
49 # that contain them, in most cases.
50 $smiley_regexp='('.join('|', map { quotemeta }
51 reverse sort keys %smileys).')';
52 #debug($smiley_regexp);
55 sub sanitize (@) { #{{{
58 build_regexp() unless defined $smiley_regexp;
61 return $_ unless length $smiley_regexp;
63 MATCH: while (m{(?:^|(?<=\s|>))(\\?)$smiley_regexp(?:(?=\s|<)|$)}g) {
69 # Smilies are not allowed inside <pre> or <code>.
70 # For each tag in turn, match forward to find the next <tag>
71 # or </tag> after the smiley.
73 foreach my $tag ("pre", "code") {
74 if (m/<(\/)?\s*$tag\s*>/isg && defined $1) {
75 # </tag> found first, so the smiley is
76 # inside the tag, so do not expand it.
79 # Reset pos back to where it was before this test.
85 substr($_, $epos, 1)="";
89 # Replace the smiley with its expanded value.
90 substr($_, $spos, length($smiley))=
91 htmllink($params{page}, $params{destpage},
92 $smileys{$smiley}, linktext => $smiley);
96 # Breaks out at end, otherwise it will scan through again,
97 # replacing de-escaped ones.
98 #last unless defined pos;