remove commas in tohighlight list
[ikiwiki.git] / IkiWiki / Plugin / highlight.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::highlight;
3
4 use warnings;
5 use strict;
6 use IkiWiki 3.00;
7 use highlight;
8
9 # locations of highlight's files
10 my $filetypes="/etc/highlight/filetypes.conf";
11 my $langdefdir="/usr/share/highlight/langDefs";
12
13 sub import {
14         hook(type => "getsetup", id => "highlight",  call => \&getsetup);
15         hook(type => "checkconfig", id => "highlight", call => \&checkconfig);
16 }
17
18 sub getsetup () {
19         return
20                 plugin => {
21                         safe => 1,
22                         rebuild => 1, # format plugin
23                 },
24                 tohighlight => {
25                         type => "string",
26                         example => ".c .h .cpp .pl .py Makefile:make",
27                         description => "source files to syntax highlight",
28                         safe => 1,
29                         rebuild => 1,
30                 },
31 }
32
33 sub checkconfig () {
34         if (exists $config{tohighlight}) {
35                 foreach my $file (split ' ', $config{tohighlight}) {
36                         my @opts = $file=~s/^\.// ?
37                                 (keepextension => 1) :
38                                 (noextension => 1);
39                         my $ext = $file=~s/:(.*)// ? $1 : $file;
40                 
41                         my $langfile=ext2langfile($ext);
42                         if (! defined $langfile) {
43                                 error(sprintf(gettext(
44                                         "tohighlight contains unknown file type '%s'"),
45                                         $ext));
46                         }
47         
48                         hook(
49                                 type => "htmlize",
50                                 id => $file,
51                                 call => sub {
52                                         my %params=@_;
53                                         highlight($langfile, $params{content});
54                                 },
55                                 longname => sprintf(gettext("Source code: %s"), $file),
56                                 @opts,
57                         );
58                 }
59         }
60 }
61
62 my %ext2lang;
63 my $filetypes_read=0;
64
65 # Parse highlight's config file to get extension => language mappings.
66 sub read_filetypes () {
67         open (IN, $filetypes);
68         while (<IN>) {
69                 chomp;
70                 if (/^\$ext\((.*)\)=(.*)$/) {
71                         $ext2lang{$_}=$1 foreach $1, split ' ', $2;
72                 }
73         }
74         close IN;
75         $filetypes_read=1;
76 }
77
78 sub langfile ($) {
79         return "$langdefdir/$_[0].lang";
80 }
81
82 # Given a filename extension, determines the language definition to
83 # use to highlight it.
84 sub ext2langfile ($) {
85         my $ext=shift;
86
87         read_filetypes() unless $filetypes_read;
88         if (exists $ext2lang{$ext}) {
89                 return langfile($ext2lang{$ext});
90         }
91         # If a language only has one common extension, it will not
92         # be listed in filetypes, so check the langfile.
93         elsif (-e langfile($ext)) {
94                 return langfile($ext);
95         }
96         else {
97                 return undef;
98         }
99 }
100
101 # Interface to the highlight C library.
102 sub highlight ($$) {
103         my $langfile=shift;
104         my $input=shift;
105
106         my $gen = highlightc::CodeGenerator_getInstance($highlightc::XHTML);
107         $gen->setFragmentCode(1); # generate html fragment
108         $gen->setHTMLEnclosePreTag(1); # include stylish <pre>
109         $gen->initLanguage($langfile);
110         $gen->initTheme("/dev/null"); # theme is not needed because CSS is not emitted
111         $gen->setEncoding("utf-8");
112
113         my $output=$gen->generateString($input);
114         highlightc::CodeGenerator_deleteInstance($gen);
115         return $output;
116 }
117
118 1