File Coverage

lib/IkiWiki/Plugin/syntax.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package IkiWiki::Plugin::syntax;
2              
3 1     1   5 use warnings;
  1         2  
  1         29  
4 1     1   4 use strict;
  1         2  
  1         27  
5 1     1   4 use Carp;
  1         1  
  1         65  
6 1     1   760 use utf8;
  1         9  
  1         4  
7 1     1   784 use Data::Dumper;
  1         9269  
  1         79  
8              
9 1     1   426 use IkiWiki 2.00;
  0            
  0            
10              
11             use IkiWiki::Plugin::syntax::gettext; # fake gettext for the IkiWiki old version
12             use IkiWiki::Plugin::syntax::Simple; # the last option
13             use IkiWiki::Plugin::syntax::X;
14              
15             our $VERSION = '0.25';
16             our $_syntax = undef;
17              
18             my %engine_parameters = (
19             'Simple' => undef,
20             'Kate' => undef,
21             'Vim' => undef,
22             );
23             my $use_template = 0;
24              
25             # Module implementation here
26             sub import { #{{{
27             ### Define the hooks into ikiwiki ...
28             hook(type => 'checkconfig', id => 'syntax', call => \&checkconfig);
29             hook(type => "preprocess", id => "syntax", call => \&preprocess);
30             } # }}}
31              
32             sub checkconfig {
33            
34             ### select an engine from the global ikiwiki configuration
35             #
36             my $engine = $IkiWiki::config{syntax_engine} || q(Simple);
37              
38             ### Read global parameters ...
39             $use_template = $IkiWiki::config{syntax_use_template} || 0;
40              
41             # search for special parameters (unused)
42             foreach my $engine_name (keys %engine_parameters) {
43             my $key = "syntax_" . lc($engine_name);
44             if (exists $IkiWiki::config{$key}) {
45             $engine_parameters{$engine_name} = $config{$key};
46             }
47             }
48              
49             _change_engine( $engine, %{ $engine_parameters{$engine} } );
50              
51             return;
52             }
53              
54             sub _change_engine {
55             my ($engine_name, %engine_params) = @_;
56              
57             # close the old engine
58             if (defined $_syntax) {
59             undef $_syntax;
60             }
61              
62             ## create a reusable object
63             $_syntax = _new_engine( $engine_name );
64              
65             if ($_syntax) {
66             $_syntax->logging( sprintf 'using the engine %s', $engine_name );
67             }
68             else {
69             error 'could not create a IkiWiki::Plugin::syntax object';
70             }
71            
72             return $_syntax;
73             }
74              
75             sub _new_engine {
76             my $name = shift;
77             my $engine = sprintf 'IkiWiki::Plugin::syntax::%s', $name;
78             my $object = undef;
79              
80             eval "use ${engine}";
81              
82             if (not @_) {
83             if (not $object = $engine->new( )) {
84             $object = IkiWiki::Plugin::syntax::Simple->new();
85             }
86             }
87              
88             return $object;
89             }
90              
91             sub preprocess (@) { #{{{
92             my %params = (
93             language => undef, ### plugin parameters
94             description => undef, #
95             text => undef, #
96             file => undef, #
97             linenumbers => 0, #
98             formatcomments => 0, ###
99             force_subpage => 0, ### Ikiwiki parameters
100             page => undef, #
101             destpage => undef, ###
102             @_
103             );
104              
105             # engine change ?
106             if (defined( $params{engine} )) {
107             _change_engine( $params{engine} );
108             }
109              
110             # check parameters
111             eval {
112             _clean_up_parameters( \%params );
113             };
114              
115             if ($@) {
116             if (my $ex = Syntax::X::Parameters::None->caught()) {
117             # show the plugin info
118             return _info_response();
119             } else {
120             return $_syntax->fail_response( $ex );
121             }
122             }
123              
124             $_syntax->logging( sprintf 'set language to %s', $params{language} );
125              
126             ### getting syntax highlight in html format ...
127             eval {
128             $_syntax->syntax_highlight( %params );
129             };
130              
131             if (my $ex = $@) {
132             return $_syntax->fail_response( $ex );
133             }
134              
135             ### decode to utf-8 ...
136             # utf8::decode( $syntax_html );
137              
138             ### build the final text with a template named "syntax" or joining html
139             # blocks
140             return _build_output( \%params, $_syntax->output() );
141             } # }}}
142              
143             sub _build_output {
144             my $params_ref = shift;
145             my $html_text = shift;
146             my %params = (
147             language => $_syntax->language(),
148             title => $params_ref->{title},
149             description => $params_ref->{description},
150             text => $html_text,
151             url => defined $params_ref->{file}
152             ? IkiWiki::urlto( $params_ref->{file},
153             $params_ref->{page} )
154             : undef,
155             );
156              
157             if ($use_template) {
158             # take a template reference
159             my $tmpl = template('syntax.tmpl', default_escape => 0);
160            
161             # set substitutions variables
162             $tmpl->param( %params );
163              
164             # and process ..
165             return $tmpl->output();
166             }
167             else {
168             return _manual_output( %params );
169             }
170             }
171              
172             sub _manual_output {
173             my %params = @_;
174             my @html = ();
175              
176             if (defined $params{title}) {
177             push(@html, $_syntax->css('title', $params{title}));
178             }
179              
180             if (defined $params{url}) {
181             push(@html, $params{url});
182             }
183              
184             if (defined $params{text}) {
185             push(@html, $_syntax->css('syntax', $params{text} ) );
186             }
187              
188             if (defined $params{description}) {
189             push(@html, $_syntax->css('description', $params{description}) );
190             }
191              
192             return join("\n", @html);
193             }
194              
195             sub _clean_up_parameters {
196             my $params_ref = shift;
197              
198             # check for the object availability
199             if (not $_syntax) {
200             Syntax::X->throw( 'syntax plugin not available' );
201             }
202             else {
203             $_syntax->reset_engine();
204             }
205              
206             ## save a selected group of parameters in the engine object
207             $_syntax->page( $params_ref->{page} );
208             if ($params_ref->{linenumbers}) {
209             $_syntax->linenumbers( 1 );
210             $_syntax->first_line_number( $params_ref->{linenumbers} );
211             }
212             if ($params_ref->{bars}) {
213             $_syntax->bars( $params_ref->{bars} );
214             }
215              
216             # if defined a external source file ...
217             if (defined($params_ref->{file})) {
218             ### load file content: $params_ref->{file}
219             $_syntax->source( readfile(srcfile($params_ref->{file})) );
220              
221             ### add depend from file ...
222             add_depends($params_ref->{page}, $params_ref->{file});
223             }
224             elsif (defined($params_ref->{text})) {
225             $_syntax->source( $params_ref->{text} );
226             }
227             else {
228             Syntax::X::Parameters::None->throw( gettext(q(missing text or file parameters)) );
229             }
230              
231             ## check the source language
232             if (not $_syntax->detect_language(
233             proposed => $params_ref->{language},
234             filename => $params_ref->{file},
235             content => $_syntax->source() )) {
236             Syntax::X::Parameters::Wrong->throw(
237             gettext( q(could not determine or manage the source language) ));
238             }
239             else {
240             # save the language
241             $params_ref->{language} = $_syntax->language();
242             }
243              
244             return;
245             }
246              
247             sub _info_response {
248             my %info = $_syntax->plugin_info();
249             my $tmpl = template('syntax_info.tmpl');
250              
251             $tmpl->param( %info );
252              
253             return $tmpl->output();
254             }
255              
256             1;
257              
258             __END__