Заменить определенный встроенный CSS с HTML-аналогом в Perl - PullRequest
3 голосов
/ 10 ноября 2009

Я впервые использую переполнение стека, поэтому, если я что-то сделал не так, дайте мне знать.

В настоящее время я пытаюсь написать «скребок», из-за отсутствия лучшего термина, который будет извлекать html и заменять определенные встроенные стили CSS аналогами HTML. Например, у меня есть этот HTML:

<p style="text-align:center"><span style="font-weight:bold;font-style:italic;">Some random text here. What's here doesn't matter so much as what needs to happen around it.</span></p>

Я хочу иметь возможность заменить font-weight:bold на <b>, font-style:italic на <i>, text-align:center на <center>. После этого я буду использовать регулярные выражения для удаления всех неосновных тегов HTML и любых атрибутов. Поцелуй определенно применяется здесь.

Я прочитал этот вопрос: Преобразование атрибутов стиля CSS в атрибуты HTML с использованием Perl и некоторых других, касающихся использования HTML :: TreeBuilder и других модулей (например, HTML :: TokeParser), но до сих пор я наткнулся на себя.

Я новичок в Perl, но не новичок в кодировании в целом. Логика этого та же.

Вот что у меня есть:

#!/usr/bin/perl
use warnings;
use strict;

use HTML::TreeBuilder;

my $newcont = ""; #Has to be set to something? I've seen other scripts where it doesn't...this is confusing.
my $html = <<HTML;
<p style="text-align:center"><span style="font-weight:bold;font-style:italic;">Some random text here. What's here doesn't matter so much as what needs to happen around it.</span> And sometimes not all the text is styled the same.</p>
HTML

my $tb = HTML::TreeBuilder->new_from_content($html);
my @spans = $tb->look_down(_tag => q{span}) or die qq{look_down for tag failed: $!\n};

for my $span (@spans){
    #What next?? A print gives HASH, not really workable. Split doesn't seem to work...I've never felt like such a noobie coder before.
}

print $tb->as_HTML;

Надеюсь, кто-нибудь может мне помочь, показать, что я, возможно, сделал неправильно, и т. Д. Мне искренне любопытно, какие еще возможные способы сделать это. Или если это когда-либо было сделано раньше.

Кроме того, если бы кто-то мог помочь, предложив, какие теги я должен был использовать, это было бы здорово. Единственное, что я точно знаю, это perl.

Ответы [ 3 ]

3 голосов
/ 10 ноября 2009

Из документов HTML :: Element кажется, что look_down () возвращает список объектов HTML :: Element. Объекты Perl обычно являются ссылками на хэши (хотя они не должны быть), что Вот почему вы получаете HASH при печати $span.

Во всяком случае, внутри вашего цикла for вы сможете звонить

 $span->method()

, где method - любой метод HTML :: Element. Для ваших целей методы all_attr(), as_text() и replace_with() выглядят довольно многообещающе.

Я пытался ссылаться на каждый из методов, но SO не понравились грубые привязанные ссылки CPAN, поэтому для удобства вот одна быстрая ссылка на главную страницу документа:

https://metacpan.org/pod/HTML::Element

2 голосов
/ 10 ноября 2009

Mike
Проблема в том, что в Perl вы, к сожалению, не можете видеть тип элементов в отладчике, поскольку объектная система является просто оболочкой для стандартных типов. Таким образом, невозможно найти соответствующие атрибуты / методы, глядя на документацию и / или код. Об объектах дает более подробную информацию об этом.
Каждый $ span будет объектом HTML :: Element - ответ Бена охватывает эту часть. Я полагаю, вы просто измените некоторые атрибуты внутри дерева и сохраните дерево в новом файле.

1 голос
/ 10 ноября 2009

Используя HTML :: TreeBuilder , вы определенно на правильном пути; для разбора CSS я только что нашел CSS :: DOM . Это действительно интересный модуль, который позволяет вам получить доступ к свойствам без особых усилий.

#!/usr/bin/perl
use warnings;
use strict;

use HTML::TreeBuilder;
use CSS::DOM::Style;

my $html = <<HTML;
<p style="text-align:center"><span style="font-weight:bold;font-style:italic;">Some random text here. What's here doesn't matter so much as what needs to ha>
HTML

my $tb = HTML::TreeBuilder->new_from_content($html);


my @replacements = (
    { property => 'font-style', value => 'italic', replacement => 'em' },
    { property => 'font-weight', value => 'bold', replacement => 'strong' },
    { property => 'text-align', value => 'center', replacement => 'center' },
);

# build a sensible list of tag names (or just use sub { 1 })
my @nodes = $tb->look_down(sub { $_[0]->tag =~ /^(p|span)$/ });

for my $el (@nodes) {
    if ($el->attr('style')) {
        my $st = CSS::DOM::Style::parse($el->attr('style'));
        if ($st) {
            foreach my $h (@replacements) {
                if ($st->getPropertyValue($h->{property}) eq $h->{value}) {
                    $st->removeProperty($h->{property});
                    my $new = HTML::Element->new($h->{replacement});
                    foreach my $inner ($el->detach_content) {
                        $new->push_content($inner);
                    }
                    $el->push_content($new);
                }
            }
            $el->attr('style', $st->cssText ? $st->cssText : undef);
        }
    }
}

print $tb->as_HTML(undef, "\t");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...