aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/highlight.pm
diff options
context:
space:
mode:
authorJoey Hess <joey@gnu.kitenet.net>2009-05-22 22:57:03 -0400
committerJoey Hess <joey@gnu.kitenet.net>2009-05-22 22:57:03 -0400
commit8ae260015fa6ecd5aa39a84898f42837935c9953 (patch)
tree7fb1a89e05ce78611db7026bf1887bfe32592758 /IkiWiki/Plugin/highlight.pm
parent6c8dd33b7886641407d4036105c7a12c7e8e1dc0 (diff)
downloadikiwiki-8ae260015fa6ecd5aa39a84898f42837935c9953.tar
ikiwiki-8ae260015fa6ecd5aa39a84898f42837935c9953.tar.gz
highlight: New plugin supporting syntax highlighting of pretty much anything.
* debian/control: Add suggests for libhighlight-perl, although that package is not yet created by Debian's highlight source package. (See #529869)
Diffstat (limited to 'IkiWiki/Plugin/highlight.pm')
-rw-r--r--IkiWiki/Plugin/highlight.pm118
1 files changed, 118 insertions, 0 deletions
diff --git a/IkiWiki/Plugin/highlight.pm b/IkiWiki/Plugin/highlight.pm
new file mode 100644
index 000000000..f43f18628
--- /dev/null
+++ b/IkiWiki/Plugin/highlight.pm
@@ -0,0 +1,118 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::highlight;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+use highlight;
+
+# locations of highlight's files
+my $filetypes="/etc/highlight/filetypes.conf";
+my $langdefdir="/usr/share/highlight/langDefs";
+
+sub import {
+ hook(type => "getsetup", id => "highlight", call => \&getsetup);
+ hook(type => "checkconfig", id => "highlight", call => \&checkconfig);
+}
+
+sub getsetup () {
+ return
+ plugin => {
+ safe => 1,
+ rebuild => 1, # format plugin
+ },
+ tohighlight => {
+ type => "string",
+ example => ".c, .h, .cpp, .pl, .py, Makefile:make",
+ description => "source files to syntax highlight",
+ safe => 1,
+ rebuild => 1,
+ },
+}
+
+sub checkconfig () {
+ if (exists $config{tohighlight}) {
+ foreach my $file (split /, /, $config{tohighlight}) {
+ my @opts = $file=~s/^\.// ?
+ (keepextension => 1) :
+ (noextension => 1);
+ my $ext = $file=~s/:(.*)// ? $1 : $file;
+
+ my $langfile=ext2langfile($ext);
+ if (! defined $langfile) {
+ error(sprintf(gettext(
+ "tohighlight contains unknown file type '%s'"),
+ $ext));
+ }
+
+ hook(
+ type => "htmlize",
+ id => $file,
+ call => sub {
+ my %params=@_;
+ highlight($langfile, $params{content});
+ },
+ longname => sprintf(gettext("Source code: %s"), $file),
+ @opts,
+ );
+ }
+ }
+}
+
+my %ext2lang;
+my $filetypes_read=0;
+
+# Parse highlight's config file to get extension => language mappings.
+sub read_filetypes () {
+ open (IN, $filetypes);
+ while (<IN>) {
+ chomp;
+ if (/^\$ext\((.*)\)=(.*)$/) {
+ $ext2lang{$_}=$1 foreach $1, split ' ', $2;
+ }
+ }
+ close IN;
+ $filetypes_read=1;
+}
+
+sub langfile ($) {
+ return "$langdefdir/$_[0].lang";
+}
+
+# Given a filename extension, determines the language definition to
+# use to highlight it.
+sub ext2langfile ($) {
+ my $ext=shift;
+
+ read_filetypes() unless $filetypes_read;
+ if (exists $ext2lang{$ext}) {
+ return langfile($ext2lang{$ext});
+ }
+ # If a language only has one common extension, it will not
+ # be listed in filetypes, so check the langfile.
+ elsif (-e langfile($ext)) {
+ return langfile($ext);
+ }
+ else {
+ return undef;
+ }
+}
+
+# Interface to the highlight C library.
+sub highlight ($$) {
+ my $langfile=shift;
+ my $input=shift;
+
+ my $gen = highlightc::CodeGenerator_getInstance($highlightc::XHTML);
+ $gen->setFragmentCode(1); # generate html fragment
+ $gen->setHTMLEnclosePreTag(1); # include stylish <pre>
+ $gen->initLanguage($langfile);
+ $gen->initTheme("/dev/null"); # theme is not needed because CSS is not emitted
+ $gen->setEncoding("utf-8");
+
+ my $output=$gen->generateString($input);
+ highlightc::CodeGenerator_deleteInstance($gen);
+ return $output;
+}
+
+1