]> sipb.mit.edu Git - ikiwiki.git/blob - doc/todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion.mdwn
59c1a245b4595565bfc20b9233a24aef728424dd
[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 I hit a wall the following example (the last commit in the above repo).
12
13     \[[!meta title="Solutions to assignment 1"]]
14
15     - [[!format cc """
16     test
17     """]]
18
19
20 ----
21
22     #!/usr/bin/perl
23     # markup source files
24     package IkiWiki::Plugin::sourcecode;
25     
26     use warnings;
27     use strict;
28     use IkiWiki 2.00;
29     use open qw{:utf8 :std};
30     
31     my %metaheaders;
32     
33     sub import {
34         hook(type => "getsetup", id => "sourcecode", call => \&getsetup);
35         hook(type => "checkconfig", id => "sourcecode", call => \&checkconfig);
36         hook(type => "pagetemplate", id => "sourcecode", call => \&pagetemplate);
37     }
38     
39     sub getsetup () {
40         return 
41                 plugin => {
42                         safe => 1,
43                         rebuild => 1, # format plugin
44                 },
45                 sourcecode_command => {
46                         type => "string",
47                         example => "/usr/bin/source-highlight",
48                         description => "The command to execute to run source-highlight",
49                         safe => 0,
50                         rebuild => 1,
51                 },
52                 sourcecode_lang => {
53                         type => "string",
54                         example => "c,cpp,h,java",
55                         description => "Comma separated list of suffixes to recognise as source code",
56                         safe => 1,
57                         rebuild => 1,
58                 },
59                 sourcecode_linenumbers => {
60                         type => "boolean",
61                         example => 1,
62                         description => "Should we add line numbers to the source code",
63                         safe => 1,
64                         rebuild => 1,
65                 },
66                 sourcecode_css => {
67                         type => "string",
68                         example => "sourcecode_style",
69                         description => "page to use as css file for source",
70                         safe => 1,
71                         rebuild => 1,
72                 },
73     }
74     
75     sub checkconfig () {
76         if (! $config{sourcecode_lang}) {
77                 error("The sourcecode plugin requires a list of suffixes in the 'sourcecode_lang' config option");
78         }
79         
80         if (! $config{sourcecode_command}) {
81                 $config{sourcecode_command} = "source-highlight";
82         }
83         
84         if (! length `which $config{sourcecode_command} 2>/dev/null`) {
85                 error("The sourcecode plugin is unable to find the $config{sourcecode_command} command");
86         }
87     
88         if (! $config{sourcecode_css}) {
89                 $config{sourcecode_css} = "sourcecode_style";
90         }
91         
92         if (! defined $config{sourcecode_linenumbers}) {
93                 $config{sourcecode_linenumbers} = 1;
94         }
95         
96         my %langs = ();
97         
98         open(LANGS, "$config{sourcecode_command} --lang-list|");
99         while (<LANGS>) {
100                 if ($_ =~ /(\w+) = .+\.lang/) {
101                         $langs{$1} = 1;
102                 }
103         }
104         close(LANGS);
105         
106         foreach my $lang (split(/[, ]+/, $config{sourcecode_lang})) {
107                 if ($langs{$lang}) {
108                         hook(type => "htmlize", id => $lang, call => \&htmlize, keepextension => 1);
109                 } else {
110                         error("Your installation of source-highlight cannot handle sourcecode language $lang!");
111                 }
112         }
113     }
114     
115     sub htmlize (@) {
116         my %params=@_;
117     
118         my $page = $params{page};
119     
120         eval q{use FileHandle};
121         error($@) if $@;
122         eval q{use IPC::Open2};
123         error($@) if $@;
124     
125         local(*SPS_IN, *SPS_OUT);  # Create local handles
126     
127         my @args;
128     
129         if ($config{sourcecode_linenumbers}) {
130                 push @args, '--line-number= ';
131         }
132     
133         my $pid = open2(*SPS_IN, *SPS_OUT, $config{sourcecode_command},
134                                         '-s', IkiWiki::pagetype($pagesources{$page}),
135                                         '-c', $config{sourcecode_css}, '--no-doc',
136                                         '-f', 'xhtml',
137                                         @args);
138     
139         error("Unable to open $config{sourcecode_command}") unless $pid;
140     
141         print SPS_OUT $params{content};
142         close SPS_OUT;
143     
144         my @html = <SPS_IN>;
145         close SPS_IN;
146         
147         waitpid $pid, 0;
148     
149         my $stylesheet=bestlink($page, $config{sourcecode_css}.".css");
150         if (length $stylesheet) {
151                 push @{$metaheaders{$page}}, '<link href="'.urlto($stylesheet, $page).'"'.
152                         ' rel="stylesheet"'.
153                         ' type="text/css" />';
154         }
155     
156         return '<div id="sourcecode">'."\r\n".join("\r\n",@html)."\r\n</div>\n";
157     }
158     
159     sub pagetemplate (@) {
160         my %params=@_;
161     
162         my $page=$params{page};
163         my $template=$params{template};
164     
165         if (exists $metaheaders{$page} && $template->query(name => "meta")) {
166                 # avoid duplicate meta lines
167                 my %seen;
168                 $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
169         }
170     }
171     
172     1