1 Here is another [[patch]] for this. It is more up to date than either of the patches linked on the previous page. It is most similar to [[plugins/contrib/sourcehighlight]].
3 Note that if this is being used with `c` or `c++` then you'll probably want to wait until [[bugs/multiple_pages_with_same_name]] is fixed.
11 package IkiWiki::Plugin::sourcecode;
16 use open qw{:utf8 :std};
21 hook(type => "getsetup", id => "sourcecode", call => \&getsetup);
22 hook(type => "checkconfig", id => "sourcecode", call => \&checkconfig);
23 hook(type => "pagetemplate", id => "sourcecode", call => \&pagetemplate);
26 sub getsetup () { #{{{
30 rebuild => 1, # format plugin
32 sourcecode_command => {
34 example => "/usr/bin/source-highlight",
35 description => "The command to execute to run source-highlight",
41 example => "c,cpp,h,java",
42 description => "Comma separated list of suffixes to recognise as source code",
46 sourcecode_linenumbers => {
49 description => "Should we add line numbers to the source code",
55 example => "sourcecode_style",
56 description => "page to use as css file for source",
62 sub checkconfig () { #{{{
63 if (! $config{sourcecode_lang}) {
64 error("The sourcecode plugin requires a list of suffixes in the 'sourcecode_lang' config option");
67 if (! $config{sourcecode_command}) {
68 $config{sourcecode_command} = "source-highlight";
71 if (! length `which $config{sourcecode_command} 2>/dev/null`) {
72 error("The sourcecode plugin is unable to find the $config{sourcecode_command} command");
75 if (! $config{sourcecode_css}) {
76 $config{sourcecode_css} = "sourcecode_style";
79 if (! defined $config{sourcecode_linenumbers}) {
80 $config{sourcecode_linenumbers} = 1;
85 open(LANGS, "$config{sourcecode_command} --lang-list|");
87 if ($_ =~ /(\w+) = .+\.lang/) {
93 foreach my $lang (split(/[, ]+/, $config{sourcecode_lang})) {
95 hook(type => "htmlize", id => $lang, call => \&htmlize);
97 error("Your installation of source-highlight cannot handle sourcecode language $lang!");
102 sub htmlize (@) { #{{{
105 my $page = $params{page};
107 eval q{use FileHandle};
109 eval q{use IPC::Open2};
112 local(*SPS_IN, *SPS_OUT); # Create local handles
116 if ($config{sourcecode_linenumbers}) {
117 push @args, '--line-number= ';
120 my $pid = open2(*SPS_IN, *SPS_OUT, $config{sourcecode_command},
121 '-s', IkiWiki::pagetype($pagesources{$page}),
122 '-c', $config{sourcecode_css}, '--no-doc',
126 error("Unable to open $config{sourcecode_command}") unless $pid;
128 print SPS_OUT $params{content};
136 my $stylesheet=bestlink($page, $config{sourcecode_css}.".css");
137 if (length $stylesheet) {
138 push @{$metaheaders{$page}}, '<link href="'.urlto($stylesheet, $page).'"'.
140 ' type="text/css" />';
143 return '<div id="sourcecode">'."\r\n".join("\r\n",@html)."\r\n</div>\n";
146 sub pagetemplate (@) { #{{{
149 my $page=$params{page};
150 my $template=$params{template};
152 if (exists $metaheaders{$page} && $template->query(name => "meta")) {
153 # avoid duplicate meta lines
155 $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));