]> sipb.mit.edu Git - ikiwiki.git/blob - doc/todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion.mdwn
Update patch and reply to bug report.
[ikiwiki.git] / doc / todo / automatic_use_of_syntax_plugin_on_source_code_files / discussion.mdwn
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]].
2
3 Updated to use fix noted in [[bugs/multiple_pages_with_same_name]].
4
5 -- [[Will]]
6
7 ----
8 I was trying to replace sourcehighlight with sourcecode. I had to modify the 
9 htmlize call slightly so that it would work in a format directive.
10 ([modified version](http://pivot.cs.unb.ca/git/?p=ikiplugins.git;a=blob_plain;f=IkiWiki/Plugin/sourcecode.pm;hb=21fc57091edb9))
11
12 > I haven't tested them, but those changes look sensible to me. -- [[Will]]
13
14 I hit a wall the following example (the last commit in the above repo).
15
16     \[[!meta title="Solutions to assignment 1"]]
17
18     - [[!format cc """
19     test
20     """]]
21
22
23 > I haven't actually tested this to see what the problem is.  How does this fail?
24 > Does source-highlight barf on the non-c++ content?  Is there a wiki URL that shows the failure?  -- [[Will]]
25 >> Here is the content div from the output page
26 >> [[DavidBremner]]
27
28      <div id="content">
29      <p><ul>
30      <li><div id="sourcecode"></li>
31      </ul>
32      2beb4fd7289998159f61976143f66bb6</p>
33
34      <p></div></p>
35
36      </div>
37
38 >>> That is quite strange.  I tested your version of the plugin.  I had to revert one your changes to get it to
39 >>> work: the linenumber argument should not have a space at the end of it.  Once I made that change,
40 >>> everything worked as expected.  The output I get for your example is below:
41
42     <div id="content">
43     <ul>
44     <li><div id="sourcecode"></li>
45     </ul>
46     
47     <pre><tt><span class="linenum">00001:</span> <span class="normal">test</span></tt></pre>
48     
49     <p></div></p>
50     
51     </div>
52
53 >>> I don't know what is going wrong for you... source-highlight, Markdown or something else.
54 >>> I do find it interesting the way the sourcecode `div` and the list get interleaved.  That
55 >>> just looks like a Markdown thing though.
56 >>> In any case, I've updated the patch below to include most of your changes.  -- [[Will]]
57
58 ----
59
60     #!/usr/bin/perl
61     # markup source files
62     # Originally by Will Uther
63     # With modifications by David Bremner
64     package IkiWiki::Plugin::sourcecode;
65     
66     use warnings;
67     use strict;
68     use IkiWiki 2.00;
69     use open qw{:utf8 :std};
70     
71     my %metaheaders;
72     
73     sub import {
74         hook(type => "getsetup", id => "sourcecode", call => \&getsetup);
75         hook(type => "checkconfig", id => "sourcecode", call => \&checkconfig);
76         hook(type => "pagetemplate", id => "sourcecode", call => \&pagetemplate);
77     }
78     
79     sub getsetup () {
80         return 
81             plugin => {
82                 safe => 1,
83                 rebuild => 1, # format plugin
84             },
85             sourcecode_command => {
86                 type => "string",
87                 example => "/usr/bin/source-highlight",
88                 description => "The command to execute to run source-highlight",
89                 safe => 0,
90                 rebuild => 1,
91             },
92             sourcecode_lang => {
93                 type => "string",
94                 example => "c,cpp,h,java",
95                 description => "Comma separated list of suffixes to recognise as source code",
96                 safe => 1,
97                 rebuild => 1,
98             },
99             sourcecode_linenumbers => {
100                 type => "boolean",
101                 example => 1,
102                 description => "Should we add line numbers to the source code",
103                 safe => 1,
104                 rebuild => 1,
105             },
106             sourcecode_css => {
107                 type => "string",
108                 example => "sourcecode_style",
109                 description => "page to use as css file for source",
110                 safe => 1,
111                 rebuild => 1,
112             },
113     }
114     
115     sub checkconfig () {
116         if (! $config{sourcecode_lang}) {
117             error("The sourcecode plugin requires a list of suffixes in the 'sourcecode_lang' config option");
118         }
119     
120         if (! $config{sourcecode_command}) {
121             $config{sourcecode_command} = "source-highlight";
122         }
123     
124         if (! length `which $config{sourcecode_command} 2>/dev/null`) {
125             error("The sourcecode plugin is unable to find the $config{sourcecode_command} command");
126         }
127     
128         if (! $config{sourcecode_css}) {
129             $config{sourcecode_css} = "sourcecode_style";
130         }
131     
132         if (! defined $config{sourcecode_linenumbers}) {
133             $config{sourcecode_linenumbers} = 1;
134         }
135     
136         my %langs = ();
137     
138         open(LANGS, "$config{sourcecode_command} --lang-list|");
139         while (<LANGS>) {
140             if ($_ =~ /(\w+) = .+\.lang/) {
141                 $langs{$1} = 1;
142             }
143         }
144         close(LANGS);
145     
146         foreach my $lang (split(/[, ]+/, $config{sourcecode_lang})) {
147             if ($langs{$lang}) {
148                 hook(type => "htmlize", id => $lang, no_override=>1,
149                  call => sub { htmlize(lang=>$lang, @_) }, 
150                  keepextension => 1);
151             } else {
152                 error("Your installation of source-highlight cannot handle sourcecode language $lang!");
153             }
154         }
155     }
156     
157     sub htmlize (@) {
158         my %params=@_;
159     
160         my $page = $params{page};
161     
162         eval q{use FileHandle};
163         error($@) if $@;
164         eval q{use IPC::Open2};
165         error($@) if $@;
166     
167         local(*SPS_IN, *SPS_OUT);  # Create local handles
168     
169         my @args;
170     
171         if ($config{sourcecode_linenumbers}) {
172             push @args, '--line-number';
173         }
174     
175         my $pid = open2(*SPS_IN, *SPS_OUT, $config{sourcecode_command},
176                         '-s', $params{lang},
177                         '-c', $config{sourcecode_css}, '--no-doc',
178                         '-f', 'xhtml',
179                         @args);
180     
181         error("Unable to open $config{sourcecode_command}") unless $pid;
182     
183         print SPS_OUT $params{content};
184         close SPS_OUT;
185     
186         my @html = <SPS_IN>;
187         close SPS_IN;
188     
189         waitpid $pid, 0;
190     
191         my $stylesheet=bestlink($page, $config{sourcecode_css}.".css");
192         if (length $stylesheet) {
193             push @{$metaheaders{$page}}, '<link href="'.urlto($stylesheet, $page).'"'.
194                 ' rel="stylesheet"'.
195                 ' type="text/css" />';
196         }
197     
198         return '<div id="sourcecode">'."\r\n".join("",@html)."\r\n</div>\r\n";
199     }
200     
201     sub pagetemplate (@) {
202         my %params=@_;
203     
204         my $page=$params{page};
205         my $template=$params{template};
206     
207         if (exists $metaheaders{$page} && $template->query(name => "meta")) {
208             # avoid duplicate meta lines
209             my %seen;
210             $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
211         }
212     }
213     
214     1