在HTML中显示美观的Perl代码而不使用JavaScript
您想在网页上显示美观的语法高亮Perl代码,而不使用JavaScript吗?也许您想使用现有的CSS主题,而不必在Perl代码中编写内联CSS?如果是这样,请看看PPI::Prettify。
背景
prettify.js库在为网页显示代码时,对大量不同的语言进行语法着色做得非常出色。它被用于blogs.perl.org;我们在PerlTricks.com上使用它。但由于Perl是一种模糊的语言,prettify.js通常无法正确标记所有代码。更糟糕的是,如果用户禁用了JavaScript,代码将根本不会高亮显示。这就是我编写PPI::Prettify的原因。它使用PPI::Document在后台运行,因此比prettify.js更快更准确,但输出的HTML代码与prettify.js相同,这使得您可以使用任何现有的CSS主题(例如这里,这里和这里)。
需求
您将需要PPI::Prettify,并且可以在终端通过CPAN安装它。
$ cpan PPI::Prettify
在操作系统兼容性方面,PPI::Prettify是纯Perl编写的,因此您应该在安装了Perl的任何平台上运行它。
标记内联Perl代码
PPI::Prettify导出了一个prettify()方法,它接受一个Perl代码字符串,并返回用标签标记的标记化代码。为了安全起见,PPI::Prettify对所有标记内容进行HTML编码。让我们快速编写一个脚本以演示prettify()。
use warnings;
use strict;
use PPI::Prettify;
read(main::DATA, my $code, 500);
print prettify({ code => $code });
__DATA__
# a simple OO class
package Shape;
sub new {
my ($class, $args) = @_;
my $self = {
color => $args->{color} || 'black',
length => $args->{length} || 1,
width => $args->{width} || 1,
};
return bless $self, $class;
}
sub get_area {
my $self = shift;
return $self->{length} * $self->{width};
}
sub get_color {
my $self = shift;
return $self->{color};
}
sub set_color {
my ($self, $color) = @_;
$self->{color} = $color;
}
1;
该脚本使用__DATA__标记来创建一个文件句柄以指向一些内联Perl代码(该代码是从我们文章Old School Object Oriented Perl中取出的简单面向对象示例)。读取函数将文件句柄内容吸入$code。然后我们使用prettify()函数标记和标记Perl代码。
运行该脚本将返回用标签包围的Perl代码。这是prettify()产生的标记的总结。
<pre class="prettyprint"><span class="com"># a simple OO class
</span><span class="pln">
</span><span class="kwd">package</span><span class="pln"> </span><span class="atn">Shape</span><span class="pln">;</span>
...
</pre>
下面的示例显示了使用desert CSS主题时标记的外观。
# a simple OO class
package Shape;
sub new {
my ($class, $args) = @_;
my $self = {
color => $args->{color} || 'black',
length => $args->{length} || 1,
width => $args->{width} || 1,
};
return bless $self, $class;
}
sub get_area {
my $self = shift;
return $self->{length} * $self->{width};
}
sub get_color {
my $self = shift;
return $self->{color};
}
sub set_color {
my ($self, $color) = @_;
$self->{color} = $color;
}
1;
这里有两点需要注意:禁用JavaScript不会影响上面的语法高亮,因为它是在后台使用PPI::Prettify生成的。其次,代码正确显示了多行注释(从__DATA__之后的内容),这与prettify.js不同。
标记存储在文件中的Perl代码
很容易从文件中美化现有的Perl代码。您可以在终端用一行Perl完成此操作。
$ perl -MPPI::Prettify -MFile::Slurp -e '$code=read_file("output");print prettify({code=>$code})'
高级功能1:调试模式
prettify()方法还接受一个可选的调试参数。
my $html = prettify({ code => $code, debug => 1 });
调试模式将提供相同的输出,但是每个标签都将有一个“title”属性,其值是原始PPI::Token类。这可以帮助您通过将光标悬停在文本上理解原始PPI::Token类如何映射到标记。以下是启用调试模式打印的代码。试试悬停!
# a simple OO class
package Shape;
sub new {
my ($class, $args) = @_;
my $self = {
color => $args->{color} || 'black',
length => $args->{length} || 1,
width => $args->{width} || 1,
};
return bless $self, $class;
}
sub get_area {
my $self = shift;
return $self->{length} * $self->{width};
}
sub get_color {
my $self = shift;
return $self->{color};
}
sub set_color {
my ($self, $color) = @_;
$self->{color} = $color;
}
1;
高级功能2:覆盖映射
您可能希望更改Perl代码中某些标记的token。PPI::Prettify导出映射到名为$MARKUP_RULES的哈希引用中。每个PPI::Token类都是键,其值是prettify.js使用的CSS类名(以及prettify CSS主题预期的)。例如,PPI::Token::Comment映射到“com”
'PPI::Token::Comment' => 'com'
结合调试模式,应可直接更改特定PPI::Token类到所需prettify类的映射。
替代方案
如果您愿意在Perl代码中编写内联CSS,或者需要比PPI::Prettify提供的约10个类更详细的标记,请考虑使用Adam Kennedy的PPI::HTML。这是一个更成熟的模块,还可以进行行编号。
本文最初发布在PerlTricks.com。
标签
反馈
这篇文章有什么问题吗?请在GitHub上打开一个问题或拉取请求,帮助我们。