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

标签 html css perl parsing

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

  • 错误:<link rel=stylesheet type="text/css" href="/style.css">
  • 错误:<style type="text/css">...</style>
  • 作品:<h1 style="margin: 0">...</h1>

但是,这种内联样式属性方法管理起来很痛苦。

我找到了适用于 Ruby 和 PHP 的工具,它们会将 CSS 文件和一些单独的标记作为输入,并返回合并后的结果 - 一个标记文件,其中所有 CSS 都已转换为样式属性。

我正在寻找解决此问题的 Perl 解决方案,但我没有在 CPAN 上或通过搜索 Google 找到一个解决方案。任何指针?或者,是否可以组合 CPAN 模块来达到相同的结果?

最佳答案

我不知道有完整的预打包解决方案。

CSS::DOMcompute_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)$/;
}

关于html - 如何使用 Perl 将文件中的 CSS 定义合并到内联样式属性中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1271438/

相关文章:

html - 具有背景颜色的 Css 过渡

javascript - 仅在移动设备上向下滚动时隐藏 div

javascript - 地理定位 API 错误处理

html - 在另一个 div 中左右定位 div

javascript - 浏览器中的 CSS 错误 : 'Unknown property name' when using pseudo :after

regex - 在已编译的正则表达式中禁用捕获? (例如,Perl 5.22+,/n 修饰符)

arrays - perl 打开文件名中带有变量的文件

javascript - 修改文本javascript

Perl `defined' 和 `undef' 子程序范围

css - 如何在 python3 中替换非标准标签的属性?