File Coverage

blib/lib/Statocles/Plugin/Highlight.pm
Criterion Covered Total %
statement 32 34 94.1
branch 9 12 75.0
condition 4 6 66.6
subroutine 5 5 100.0
pod 2 2 100.0
total 52 59 88.1


line stmt bran cond sub pod time code
1             package Statocles::Plugin::Highlight;
2             our $VERSION = '0.086';
3             # ABSTRACT: Highlight code and configuration syntax
4              
5             #pod =head1 SYNOPSIS
6             #pod
7             #pod # --- Configuration
8             #pod # site.yml
9             #pod ---
10             #pod site:
11             #pod class: Statocles::Site
12             #pod args:
13             #pod plugins:
14             #pod highlight:
15             #pod $class: Statocles::Plugin::Highlight
16             #pod $args:
17             #pod style: default
18             #pod
19             #pod # --- Usage
20             #pod <%= highlight perl => begin %>
21             #pod print "Hello, World!\n";
22             #pod <% end %>
23             #pod
24             #pod =head1 DESCRIPTION
25             #pod
26             #pod This plugin adds the C<highlight> helper function to all templates and
27             #pod content documents, allowing for syntax highlighting of source code and
28             #pod configuration blocks.
29             #pod
30             #pod =cut
31              
32 1     1   7751 use Statocles::Base 'Class';
  1         2  
  1         7  
33             with 'Statocles::Plugin';
34             BEGIN {
35 1 50   1   6454 eval { require Syntax::Highlight::Engine::Kate; 1 }
  1         8  
  1         494  
36             or die "Error loading Statocles::Plugin::Highlight. To use this plugin, install Syntax::Highlight::Engine::Kate";
37             };
38              
39             #pod =attr style
40             #pod
41             #pod The style to use, which corresponds to a stylesheet file in your theme's
42             #pod C</plugin/highlight> directory without the trailing C<.css>. Defaults to
43             #pod C<"default">, which refers to the C<default.css> file.
44             #pod
45             #pod The styles included by default are:
46             #pod
47             #pod =over 4
48             #pod
49             #pod =item *
50             #pod
51             #pod default
52             #pod
53             #pod =item *
54             #pod
55             #pod solarized-light
56             #pod
57             #pod =item *
58             #pod
59             #pod solarized-dark
60             #pod
61             #pod =back
62             #pod
63             #pod =cut
64              
65             has style => (
66             is => 'ro',
67             isa => Str,
68             default => "default",
69             );
70              
71             #pod =method highlight
72             #pod
73             #pod %= highlight $type => $content
74             #pod
75             #pod Highlight the given C<$content> using the given C<$type> syntax.
76             #pod
77             #pod The list of supported syntaxes are in the L<SUPPORTED SYNTAX|/SUPPORTED
78             #pod SYNTAX> section, below.
79             #pod
80             #pod To highlight a block of code, use C<begin>/C<end>:
81             #pod
82             #pod %= highlight Perl => begin
83             #pod use strict;
84             #pod use warnings;
85             #pod print "Hello, World!\n";
86             #pod % end
87             #pod
88             #pod To highlight an included file, use the L<include helper|Statocles::Template/include>:
89             #pod
90             #pod %= highlight Perl => include 'test.pl'
91             #pod
92             #pod The highlight function adds both C<pre> and C<code> tags.
93             #pod
94             #pod <p>This example Perl code prints the string "Hello, World" to the screen:</p>
95             #pod %= highlight Perl => 'print "Hello, World\n"'
96             #pod
97             #pod We can override the style we want by passing in a C<-style> option:
98             #pod
99             #pod %= highlight -style => 'solarized-dark', Perl => begin
100             #pod print "Hello, World!\n";
101             #pod % end
102             #pod
103             #pod =cut
104              
105             my $hl = Syntax::Highlight::Engine::Kate->new(
106             substitutions => {
107             "<" => "&lt;",
108             ">" => "&gt;",
109             "&" => "&amp;",
110             },
111             format_table => {
112             Alert => [ '', '' ],
113             BaseN => [ '<span class="hljs-number">', '</span>' ],
114             BString => [ '', '' ],
115             Char => [ '<span class="hljs-string">', '</span>' ],
116             Comment => [ '<span class="hljs-comment">', '</span>' ],
117             DataType => [ '<span class="hljs-type">', '</span>' ],
118             DecVal => [ '<span class="hljs-number">', '</span>' ],
119             Error => [ '', '' ],
120             Float => [ '<span class="hljs-number">', '</span>' ],
121             Function => [ '<span class="hljs-function">', '</span>' ],
122             IString => [ '', '' ],
123             Keyword => [ '<span class="hljs-keyword">', '</span>' ],
124             Normal => [ '', '' ],
125             Operator => [ '', '' ],
126             Others => [ '', '' ],
127             RegionMarker => [ '', '' ],
128             Reserved => [ '<span class="hljs-built-in">', '</span>' ],
129             String => [ '<span class="hljs-string">', '</span>' ],
130             Variable => [ '<span class="hljs-variable">', '</span>' ],
131             Warning => [ '', '' ],
132             },
133             );
134              
135             sub highlight {
136 6     6 1 3528 my ( $self, $args, @args ) = @_;
137              
138             # Last two args are always type and text and are required
139 6         19 my ( $text, $type ) = ( pop @args, pop @args );
140              
141             # Other args are options
142 6         14 my %opt = @args;
143              
144 6   66     39 my $style = $opt{ -style } || $self->style;
145              
146             # Handle Mojolicious begin/end
147 6 100       18 if ( ref $text eq 'CODE' ) {
148 1         3 $text = $text->();
149             # begin/end starts with a newline, so remove it to prevent too
150             # much top space
151 1         48 $text =~ s/^\n//;
152             }
153              
154             # XXX We need to normalize this so that the current page is always
155             # `$args->{page}`
156 6   66     45 my $page = $args->{page} || $args->{self};
157 6 100       23 if ( $page ) {
158             # Add the appropriate stylesheet to the page
159 2         33 my $style_url = $page->site->theme->url( '/plugin/highlight/' . $style . '.css' );
160 2 50       11 if ( !grep { $_->href eq $style_url } $page->links( 'stylesheet' ) ) {
  0         0  
161 2         6 $page->links( stylesheet => $style_url );
162             }
163             }
164              
165             # Find the right language
166             # We can't use languagePlug for this because it will always write
167             # a warning to the screen.
168             # See https://rt.cpan.org/Ticket/Display.html?id=110836
169 6         12 my $found_lang;
170 6         36 for my $lang ( $hl->languageList ) {
171 454 100       5160 if ( lc $lang eq lc $type ) {
172 6         11 $found_lang = $lang;
173 6         11 last;
174             }
175             }
176 6 50       54 if ( !$found_lang ) {
177 0         0 die sprintf qq{Could not find language "%s"\n}, $type;
178             }
179              
180 6         30 $hl->language( $found_lang );
181              
182             # Wrap the output in <pre> and <code> to ensure the right background is set
183 6         9566 my $wrap_start = '<pre><code class="hljs">';
184 6         10 my $wrap_end = '</code></pre>';
185 6         26 my $output = $wrap_start . $hl->highlightText( $text ) . $wrap_end;
186              
187 6         307775 return $output;
188             }
189              
190             #pod =method register
191             #pod
192             #pod Register this plugin with the site. Called automatically.
193             #pod
194             #pod =cut
195              
196             sub register {
197 3     3 1 11 my ( $self, $site ) = @_;
198 3     3   27 $site->theme->helper( highlight => sub { $self->highlight( @_ ) } );
  3         11  
199             }
200              
201             1;
202              
203             =pod
204              
205             =encoding UTF-8
206              
207             =head1 NAME
208              
209             Statocles::Plugin::Highlight - Highlight code and configuration syntax
210              
211             =head1 VERSION
212              
213             version 0.086
214              
215             =head1 SYNOPSIS
216              
217             # --- Configuration
218             # site.yml
219             ---
220             site:
221             class: Statocles::Site
222             args:
223             plugins:
224             highlight:
225             $class: Statocles::Plugin::Highlight
226             $args:
227             style: default
228              
229             # --- Usage
230             <%= highlight perl => begin %>
231             print "Hello, World!\n";
232             <% end %>
233              
234             =head1 DESCRIPTION
235              
236             This plugin adds the C<highlight> helper function to all templates and
237             content documents, allowing for syntax highlighting of source code and
238             configuration blocks.
239              
240             =head1 ATTRIBUTES
241              
242             =head2 style
243              
244             The style to use, which corresponds to a stylesheet file in your theme's
245             C</plugin/highlight> directory without the trailing C<.css>. Defaults to
246             C<"default">, which refers to the C<default.css> file.
247              
248             The styles included by default are:
249              
250             =over 4
251              
252             =item *
253              
254             default
255              
256             =item *
257              
258             solarized-light
259              
260             =item *
261              
262             solarized-dark
263              
264             =back
265              
266             =head1 METHODS
267              
268             =head2 highlight
269              
270             %= highlight $type => $content
271              
272             Highlight the given C<$content> using the given C<$type> syntax.
273              
274             The list of supported syntaxes are in the L<SUPPORTED SYNTAX|/SUPPORTED
275             SYNTAX> section, below.
276              
277             To highlight a block of code, use C<begin>/C<end>:
278              
279             %= highlight Perl => begin
280             use strict;
281             use warnings;
282             print "Hello, World!\n";
283             % end
284              
285             To highlight an included file, use the L<include helper|Statocles::Template/include>:
286              
287             %= highlight Perl => include 'test.pl'
288              
289             The highlight function adds both C<pre> and C<code> tags.
290              
291             <p>This example Perl code prints the string "Hello, World" to the screen:</p>
292             %= highlight Perl => 'print "Hello, World\n"'
293              
294             We can override the style we want by passing in a C<-style> option:
295              
296             %= highlight -style => 'solarized-dark', Perl => begin
297             print "Hello, World!\n";
298             % end
299              
300             =head2 register
301              
302             Register this plugin with the site. Called automatically.
303              
304             =head1 SUPPORTED SYNTAX
305              
306             All of the syntax types supported by the L<Syntax::Highlight::Engine::Kate> Perl module
307             are supported by this module:
308              
309             .desktop ferite PHP/PHP
310             4GL Fortran PicAsm
311             4GL-PER FreeBASIC Pike
312             ABC GDL PostScript
313             Ada GLSL POV-Ray
314             AHDL GNU Assembler progress
315             Alerts GNU Gettext Prolog
316             ANSI C89 Haskell PureBasic
317             Ansys HTML Python
318             Apache Configuration IDL Quake Script
319             Asm6502 ILERPG R Script
320             ASP Inform RenderMan RIB
321             AVR Assembler INI Files REXX
322             AWK Intel x86 (NASM) RPM Spec
323             BaseTest Java RSI IDL
324             BaseTestchild Javadoc Ruby
325             Bash JavaScript Sather
326             BibTeX JavaScript/PHP Scheme
327             C JSP scilab
328             C# Kate File Template SGML
329             C++ KBasic Sieve
330             Cg LaTeX SML
331             CGiS LDIF Spice
332             ChangeLog Lex/Flex SQL
333             Cisco LilyPond SQL (MySQL)
334             Clipper Literate Haskell SQL (PostgreSQL)
335             CMake Logtalk Stata
336             ColdFusion LPC TaskJuggler
337             Common Lisp Lua Tcl/Tk
338             Component-Pascal M3U TI Basic
339             CSS MAB-DB txt2tags
340             CSS/PHP Makefile UnrealScript
341             CUE Sheet Mason Velocity
342             D Matlab Verilog
343             Debian Changelog MIPS Assembler VHDL
344             Debian Control Modula-2 VRML
345             de_DE Music Publisher Wikimedia
346             Diff nl WINE Config
347             Doxygen Objective Caml x.org Configuration
348             E Language Objective-C xHarbour
349             Eiffel Octave XML
350             Email Pascal xslt
351             en_US Perl yacas
352             Euphoria PHP (HTML) Yacc/Bison
353              
354             =head1 ATTRIBUTION
355              
356             The C<default>, C<solarized-light>, and C<solarized-dark> styles are taken from
357             the L<Highlight.js project|https://highlightjs.org>, and are licensed under the
358             BSD license.
359              
360             =head1 SEE ALSO
361              
362             =over 4
363              
364             =item L<Syntax::Highlight::Engine::Kate>
365              
366             The underlying syntax highlighter powering this plugin
367              
368             =back
369              
370             =head1 AUTHOR
371              
372             Doug Bell <preaction@cpan.org>
373              
374             =head1 COPYRIGHT AND LICENSE
375              
376             This software is copyright (c) 2016 by Doug Bell.
377              
378             This is free software; you can redistribute it and/or modify it under
379             the same terms as the Perl 5 programming language system itself.
380              
381             =cut
382              
383             __END__
384              
385             # Generate the list of languages supported with:
386             # perl -MSyntax::Highlight::Engine::Kate -E'say for Syntax::Highlight::Engine::Kate->new->languageList' | fmtcol -w72
387             # fmtcol comes from Term::FormatColumns
388              
389