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 sourcehighlight.

Updated to use fix noted in multiple pages with same name.

-- Will


I was trying to replace sourcehighlight with sourcecode. I had to modify the htmlize call slightly so that it would work in a format directive. (modified version)

I haven't tested them, but those changes look sensible to me. -- Will

I hit a wall the following example (the last commit in the above repo).

[[!meta  title="Solutions to assignment 1"]]

- <div class="highlight-cc"><pre class="hl">    test

I haven't actually tested this to see what the problem is. How does this fail? Does source-highlight barf on the non-c++ content? Is there a wiki URL that shows the failure? -- Will

Here is the content div from the output page DavidBremner

 <div id="content">
 <p><ul>
 <li><div id="sourcecode"></li>
 </ul>
 2beb4fd7289998159f61976143f66bb6</p>

 <p></div></p>

 </div>

That is quite strange. I tested your version of the plugin. I had to revert one your changes to get it to work: the linenumber argument should not have a space at the end of it. Once I made that change, everything worked as expected. The output I get for your example is below:

<div id="content">
<ul>
<li><div id="sourcecode"></li>
</ul>

<pre><tt><span class="linenum">00001:</span> <span class="normal">test</span></tt></pre>

<p></div></p>

</div>

I don't know what is going wrong for you... source-highlight, Markdown or something else.

It's a well-known bug in old versions of markdown. --Joey I do find it interesting the way the sourcecode div and the list get interleaved. That just looks like a Markdown thing though. In any case, I've updated the patch below to include most of your changes. -- Will


#!/usr/bin/perl
# markup source files
# Originally by Will Uther
# With modifications by David Bremner
package IkiWiki::Plugin::sourcecode;

use warnings;
use strict;
use IkiWiki 2.00;
use open qw{:utf8 :std};

my %metaheaders;

sub import {
    hook(type => "getsetup", id => "sourcecode", call => \&getsetup);
    hook(type => "checkconfig", id => "sourcecode", call => \&checkconfig);
    hook(type => "pagetemplate", id => "sourcecode", call => \&pagetemplate);
}

sub getsetup () {
    return 
        plugin => {
            safe => 1,
            rebuild => 1, # format plugin
        },
        sourcecode_command => {
            type => "string",
            example => "/usr/bin/source-highlight",
            description => "The command to execute to run source-highlight",
            safe => 0,
            rebuild => 1,
        },
        sourcecode_lang => {
            type => "string",
            example => "c,cpp,h,java",
            description => "Comma separated list of suffixes to recognise as source code",
            safe => 1,
            rebuild => 1,
        },
        sourcecode_linenumbers => {
            type => "boolean",
            example => 1,
            description => "Should we add line numbers to the source code",
            safe => 1,
            rebuild => 1,
        },
        sourcecode_css => {
            type => "string",
            example => "sourcecode_style",
            description => "page to use as css file for source",
            safe => 1,
            rebuild => 1,
        },
}

sub checkconfig () {
    if (! $config{sourcecode_lang}) {
        error("The sourcecode plugin requires a list of suffixes in the 'sourcecode_lang' config option");
    }

    if (! $config{sourcecode_command}) {
        $config{sourcecode_command} = "source-highlight";
    }

    if (! length `which $config{sourcecode_command} 2>/dev/null`) {
        error("The sourcecode plugin is unable to find the $config{sourcecode_command} command");
    }

    if (! $config{sourcecode_css}) {
        $config{sourcecode_css} = "sourcecode_style";
    }

    if (! defined $config{sourcecode_linenumbers}) {
        $config{sourcecode_linenumbers} = 1;
    }

    my %langs = ();

    open(LANGS, "$config{sourcecode_command} --lang-list|");
    while (<LANGS>) {
        if ($_ =~ /(\w+) = .+\.lang/) {
            $langs{$1} = 1;
        }
    }
    close(LANGS);

    foreach my $lang (split(/[, ]+/, $config{sourcecode_lang})) {
        if ($langs{$lang}) {
            hook(type => "htmlize", id => $lang, no_override=>1,
         call => sub { htmlize(lang=>$lang, @_) }, 
         keepextension => 1);
        } else {
            error("Your installation of source-highlight cannot handle sourcecode language $lang!");
        }
    }
}

sub htmlize (@) {
    my %params=@_;

    my $page = $params{page};

    eval q{use FileHandle};
    error($@) if $@;
    eval q{use IPC::Open2};
    error($@) if $@;

    local(*SPS_IN, *SPS_OUT);  # Create local handles

    my @args;

    if ($config{sourcecode_linenumbers}) {
        push @args, '--line-number';
    }

    my $pid = open2(*SPS_IN, *SPS_OUT, $config{sourcecode_command},
                    '-s', $params{lang},
                    '-c', $config{sourcecode_css}, '--no-doc',
                    '-f', 'xhtml',
                    @args);

    error("Unable to open $config{sourcecode_command}") unless $pid;

    print SPS_OUT $params{content};
    close SPS_OUT;

    my @html = <SPS_IN>;
    close SPS_IN;

    waitpid $pid, 0;

    my $stylesheet=bestlink($page, $config{sourcecode_css}.".css");
    if (length $stylesheet) {
        push @{$metaheaders{$page}}, '<link href="'.urlto($stylesheet, $page).'"'.
            ' rel="stylesheet"'.
            ' type="text/css" />';
    }

    return '<div id="sourcecode">'."\r\n".join("",@html)."\r\n</div>\r\n";
}

sub pagetemplate (@) {
    my %params=@_;

    my $page=$params{page};
    my $template=$params{template};

    if (exists $metaheaders{$page} && $template->query(name => "meta")) {
        # avoid duplicate meta lines
        my %seen;
        $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
    }
}

1