2009-08-13 7 views
8

Birçok e-posta istemcisi, bağlı CSS stil sayfalarını ve hatta gömülü <style> etiketini sevmez, bunun yerine CSS'nin tüm biçimlendirmede stil öznitelikleri olarak satır içi görünmesini istemez.Dosyalardaki CSS tanımlarını Perl kullanarak satır içi stil özniteliklerine nasıl birleştirebilirim?

  • KÖTÜ: <link rel=stylesheet type="text/css" href="/style.css">
  • KÖTÜ: <style type="text/css">...</style>
  • İŞLER: <h1 style="margin: 0">...</h1>

Ancak bu satır içi stil nitelik yaklaşımı yönetmek için doğru acıdır.

Ruby ve PHP için bir CSS dosyası ve giriş olarak ayrı bir işaretleme alacağınız ve birleştirilen sonucu size döndüren araçları buldum. Bu, tüm CSS stil özelliklerine dönüştürülmüş tek bir işaretleme dosyası.

Bu soruna bir Perl çözümü arıyorum, ancak CPAN'da veya Google'da arama yapamadım. Herhangi bir işaretçi? Alternatif olarak, aynı sonucu elde etmek için bir araya getirilebilecek CPAN modülleri var mı?

+0

kullanabilirsiniz, geçerli üretti Geçerli HTML'den HTML ve geçerli CSS'den geçerli CSS görünüyor. Bunu denediniz mi? Bazı geri bildirim almak harika olurdu. –

+0

@Sinan Ünür: evet - kesinlikle çalışır ve oldukça yakın alır, ama ben oldukça Cevabınız hakkında yorum yaparak doğru alamayacak şey kaydetti - CSS :: DOM sorun değil, senin tho bu. Ve yorumlarda önizleme eksikliği meants yorum karıştı, ama bence bu vızıltı bulmak mümkün olmalıdır. CSS :: DOM ile bir oyun geçireceğim, Yardımlarınız için çok teşekkür ederim ama ben karmaşıklığı bana burada ötesinde olabilir korkuyorlar. – mintywalker

+0

HTML :: TreeBuilder' ve 'CSS' için daha kolay olabilir. Biraz deneme yapıyorum. –

cevap

10

Tam, önceden paketlenmiş bir çözüm bilmiyorum.

CSS::DOM 'ın compute_style hemen hemen aynı uyarılar emogrifier yukarıdaki tabidir. Bu modül, HTML::TokeParser ile birlikte bir şeyler pişirmek için kullanılabilir olmalıdır. Güncelleme

: İşte şeylerin bir arabası miş-püre geçerli:

#!/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)$/; 
} 
+0

Teşekkür ederim - bu oldukça şaşırtıcı, her ne kadar CSS :: Dom ile bir hata/todo olduğunu düşünmeme rağmen (ki bu hala biraz kırılgan görünüyor!) O şeyleri küçük bir #foo {border-width: 2px} div {border: 1px yeşil kesik} html < div id ile = foo > ... </div > olsun gerektiğini style = 'border: 1px yeşil kesik; kenarlık genişliği: 2px; ' ancak şu anda biçeminde = 'kenarlık genişliği: 2px; kenarlık: 1px kesik yeşil ' – mintywalker

+0

@mintywalker Bu bir sorun. "Compute_style" kaynağına baktım ve şu an bunu düzelteceğime emin değilim. Bir kludgy düzeltmesi CSS dosyasındaki sırayı değiştirmek: div {border: 1px kesikli yeşil} #foo {border-width: 8px} ancak bu genel durumda pratik değildir. –

+0

CSS :: DOM ile bir oyuna sahip olacağım - amaçlarım için bir istisna tespit etmek ve bir istisna atmak yanlış olan bir şey yaymaktan daha iyi olurdu, bu yüzden bu yönde compute_style'i değiştirip değiştiremeyeceğimi merak ediyorum en azından. Eğer herhangi bir yere ulaşırsam (burada hiç garanti edilmez!) Rapor edeceğim. Tekrar - çok teşekkürler, çok faydalı bir başlangıç. – mintywalker

4

Biliyorsun vardı dosyaların bir demet üzerinde çalıştı posted kod @mintywalker CSS::Inlinerhttp://search.cpan.org/dist/CSS-Inliner/

+0

Son zamanlarda bu soruna da girdim. CSS :: Inliner benim için tam olarak bir araç gibi görünüyor. Şablonları CSS kurallarını kullanarak tutmak istiyorum, ancak e-postayı göndermeden önce stilleri satır içi satır içi. Link için teşekkürler! –

İlgili konular