许多电子邮件客户端不喜欢链接的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>
我找到了Ruby和PHP的工具,它们将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)$/; }