aboutsummaryrefslogtreecommitdiff
path: root/doc/todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion.mdwn
blob: 8bc75420dff06992cd02304574e5c5747084142f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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]].

Updated to use fix noted in [[bugs/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](http://pivot.cs.unb.ca/git/?p=ikiplugins.git;a=blob_plain;f=IkiWiki/Plugin/sourcecode.pm;hb=21fc57091edb9))

> 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"]]

    - [[!format cc """
    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.
>>> 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