summaryrefslogtreecommitdiffstats
path: root/lib/IkiWiki/Plugin/highlight.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IkiWiki/Plugin/highlight.pm')
-rw-r--r--lib/IkiWiki/Plugin/highlight.pm93
1 files changed, 93 insertions, 0 deletions
diff --git a/lib/IkiWiki/Plugin/highlight.pm b/lib/IkiWiki/Plugin/highlight.pm
new file mode 100644
index 0000000..f2de12d
--- /dev/null
+++ b/lib/IkiWiki/Plugin/highlight.pm
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+package IkiWiki::Plugin::highlight;
+use IkiWiki '3.00';
+use Syntax::Highlight::Engine::Kate;
+
+# variables {{{
+my %hl_args = (
+ substitutions => { },
+ format_table => {
+ Alert => ["<span class='synAlert'>", "</span>"],
+ BaseN => ["<span class='synBaseN'>", "</span>"],
+ BString => ["<span class='synBString'>", "</span>"],
+ Char => ["<span class='synChar'>", "</span>"],
+ Comment => ["<span class='synComment'>", "</span>"],
+ DataType => ["<span class='synDataType'>", "</span>"],
+ DecVal => ["<span class='synDecVal'>", "</span>"],
+ Error => ["<span class='synError'>", "</span>"],
+ Float => ["<span class='synFloat'>", "</span>"],
+ Function => ["<span class='synFunction'>", "</span>"],
+ IString => ["<span class='synIString'>", "</span>"],
+ Keyword => ["<span class='synKeyword'>", "</span>"],
+ Normal => ["", "" ],
+ Operator => ["<span class='synOperator'>", "</span>"],
+ Others => ["<span class='synOthers'>", "</span>"],
+ RegionMarker => ["<span class='synRegionMarker'>", "</span>"],
+ Reserved => ["<span class='synReserved'>", "</span>"],
+ String => ["<span class='synString'>", "</span>"],
+ Variable => ["<span class='synVariable'>", "</span>"],
+ Warning => ["<span class='synWarning'>", "</span>"],
+ },
+);
+my %syntaxes;
+# }}}
+
+sub import { # {{{
+ hook(type => 'sanitize', id => __PACKAGE__, call => \&sanitize, first => 1);
+} # }}}
+
+sub sanitize { # {{{
+ my %args = @_;
+ my $content = '';
+ my $in_code = 0;
+ for my $line (split /^/m, $args{content}) {
+ if ($in_code) {
+ if ($line =~ s{(</code></pre>.*)}{}s) {
+ my $rest_line = $1;
+ $code_block .= $line;
+ $content .= highlight($code_block) . $rest_line;
+ $code_block = '';
+ $in_code = 0;
+ }
+ else {
+ $code_block .= $line;
+ }
+ }
+ else {
+ if ($line =~ s{(.*<pre><code>)}{}s) {
+ $content .= $1;
+ $code_block .= $line;
+ $in_code = 1;
+ }
+ else {
+ $content .= $line;
+ }
+ }
+ }
+ $content .= $code_block;
+ return $content;
+} # }}}
+
+sub highlight { # {{{
+ my ($code_block) = @_;
+ my $filetype = guess_filetype($code_block);
+ return unless $filetype;
+ my $hl = Syntax::Highlight::Engine::Kate->new(
+ language => $filetype, %hl_args
+ );
+ %syntaxes ||= map { lc($_) => $hl->syntaxes->{$_} } keys %$hl->syntaxes;
+ return $hl->highlightText($code_block);
+} # }}}
+
+sub guess_filetype { # {{{
+ my ($code_block) = @_;
+ my ($first_line) = split /\n/, $code_block;
+ if ($first_line =~ /^#!(\w+)/) {
+ return $syntaxes{$1};
+ }
+ return;
+} # }}}
+
+1;