html – 如何使用Perl将文件中的CSS定义合并到内联样式属性中?

许多电子邮件客户端不喜欢链接的CSS样式表,甚至不喜欢嵌入的< style> tag,而是希望CSS在所有标记显示为内联样式属性.

> BAD:< link rel = stylesheet type =“text / css”href =“/ style.css”>
> BAD:< style type =“text / css”> …< / style>
> WORKS:< h1 style =“margin:0”> …< / h1>

然而,这种内联样式属性方法是一种正确的管理方法.

我找到了RubyPHP的工具,它们将CSS文件和一些单独的标记作为输入,并返回合并结果 – 一个标记文件,所有CSS转换为样式属性.

我正在寻找Perl解决方案来解决这个问题,但我没有在CPAN上找到一个解决方案,也没有在Google上找到解决方案.有什么指针吗?或者,是否有CPAN模块可以组合以实现相同的结果?

> Ruby http://code.dunae.ca/premailer.web/
> PHP http://www.pelagodesign.com/sidecar/emogrifier/
> Perl?

解决方法

我不知道一个完整的,预先打包的解决方案.

CSS::DOM的compute_style与上面的emogrifier几乎相同.该模块与HTML::TokeParser一起应该可以用来烹饪一些东西.

更新:这是一个错误的混合物:

#!/usr/bin/perl

use strict;
use warnings;

use CSS::DOM;
use File::Slurp;
use HTML::DOM;
use HTML::TokeParser;

die "convert html_file css_file" unless @ARGV == 2;
my ($html_file,$css_file) = @ARGV;

my $html_parser = HTML::TokeParser->new($html_file)
    or die "Cannot open '$html_file': $!";

my $sheet = CSS::DOM::parse( scalar read_file $css_file );

while ( my $token = $html_parser->get_token ) {
    my $type = $token->[0];
    my $text = $type eq 'T' ? $token->[1] : $token->[-1];
    if ( $type eq 'S' ) {
        unless ( skip( $token->[1] ) ) {
            $text = insert_computed_style($sheet,$token);
        }
    }
    print $text;
}

sub insert_computed_style {
    my ($sheet,$token) = @_;
    my ($tag,$attr,$attrseq) = @$token[1 .. 3];
    my $doc = HTML::DOM->new;

    my $element = $doc->createElement($tag);

    for my $attr_name ( @$attrseq ) {
        $element->setAttribute($attr_name,$attr->{$attr_name});
    }

    my $style = CSS::DOM::compute_style(
        element => $element,user_sheet => $sheet
    );

    my @attrseq = (style => grep { lc $_ ne 'style' } @$attrseq );
    $attr->{style} = $style->csstext;

    my $text .= join(" ","<$tag",map{ qq/$_='$attr->{$_}'/ } @attrseq );
    $text .= '>';

    return $text;
}

sub skip {
    my ($tag) = @_;
    $tag = lc $tag;
    return 1 if $tag =~ /^(?:h(?:ead|tml)|link|Meta|script|title)$/;
}

相关文章

vue阻止冒泡事件 阻止点击事件的执行 &lt;div @click=&a...
尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用...
后台我拿的数据是这样的格式: [ {id:1 , parentId: 0, name:...
JAVA下载文件防重复点击,防止多次下载请求,Cookie方式快速简...
Mip是什么意思以及作用有哪些