2 package IkiWiki::Plugin::highlight;
10 hook(type => "getsetup", id => "highlight", call => \&getsetup);
11 hook(type => "checkconfig", id => "highlight", call => \&checkconfig);
12 # this hook is used by the format plugin
13 hook(type => "htmlizeformat", id => "highlight",
14 call => \&htmlizeformat, last => 1);
21 rebuild => 1, # format plugin
26 example => ".c .h .cpp .pl .py Makefile:make",
27 description => "types of source files to syntax highlight",
33 example => "/etc/highlight/filetypes.conf",
34 description => "location of highlight's filetypes.conf",
40 example => "/usr/share/highlight/langDefs",
41 description => "location of highlight's langDefs directory",
48 if (! exists $config{filetypes_conf}) {
49 $config{filetypes_conf}="/etc/highlight/filetypes.conf";
51 if (! exists $config{langdefdir}) {
52 $config{langdefdir}="/usr/share/highlight/langDefs";
54 if (exists $config{tohighlight}) {
55 foreach my $file (split ' ', $config{tohighlight}) {
56 my @opts = $file=~s/^\.// ?
57 (keepextension => 1) :
59 my $ext = $file=~s/:(.*)// ? $1 : $file;
61 my $langfile=ext2langfile($ext);
62 if (! defined $langfile) {
63 error(sprintf(gettext(
64 "tohighlight contains unknown file type '%s'"),
73 highlight($langfile, $params{content});
75 longname => sprintf(gettext("Source code: %s"), $file),
84 my $langfile=ext2langfile($format);
86 if (! defined $langfile) {
90 return Encode::decode_utf8(highlight($langfile, shift));
97 # Parse highlight's config file to get extension => language mappings.
98 sub read_filetypes () {
99 open (my $f, $config{filetypes_conf}) || error("$config{filetypes_conf}: $!");
104 # highlight >= 3.2 format (bind-style)
105 while ($config=~m/Lang\s*=\s*\"([^"]+)\"[,\s]+Extensions\s*=\s*{([^}]+)}/sg) {
107 foreach my $bit (split ',', $2) {
108 $bit=~s/.*"(.*)".*/$1/s;
109 $ext2lang{$bit}=$lang;
113 # highlight < 3.2 format
114 if (! keys %ext2lang) {
115 foreach (split("\n", $config)) {
116 if (/^\$ext\((.*)\)=(.*)$/) {
117 $ext2lang{$_}=$1 foreach $1, split ' ', $2;
126 # Given a filename extension, determines the language definition to
127 # use to highlight it.
128 sub ext2langfile ($) {
131 my $langfile="$config{langdefdir}/$ext.lang";
132 return $langfile if exists $highlighters{$langfile};
134 read_filetypes() unless $filetypes_read;
135 if (exists $ext2lang{$ext}) {
136 return "$config{langdefdir}/$ext2lang{$ext}.lang";
138 # If a language only has one common extension, it will not
139 # be listed in filetypes, so check the langfile.
140 elsif (-e $langfile) {
148 # Interface to the highlight C library.
153 eval q{use highlight};
155 print STDERR gettext("warning: highlight perl module not available; falling back to pass through");
160 if (! exists $highlighters{$langfile}) {
161 $gen = highlightc::CodeGenerator_getInstance($highlightc::XHTML);
162 $gen->setFragmentCode(1); # generate html fragment
163 $gen->setHTMLEnclosePreTag(1); # include stylish <pre>
164 $gen->initTheme("/dev/null"); # theme is not needed because CSS is not emitted
165 $gen->initLanguage($langfile); # must come after initTheme
166 $gen->setEncoding("utf-8");
167 $highlighters{$langfile}=$gen;
170 $gen=$highlighters{$langfile};
173 return $gen->generateString($input);