Perl: HTML :: PrettyPrinter - Обработка самозакрывающихся тегов - PullRequest
3 голосов
/ 18 января 2012

Я новичок в Perl (Strawberry Perl v5.12.3 в Windows 7), пытаюсь написать скрипт, который поможет мне с повторяющейся задачей форматирования HTML. В будущем файлы должны быть отредактированы вручную, и я хочу, чтобы они были удобны для человека, поэтому после обработки с использованием пакета HTML (HTML :: TreeBuilder и т. Д.) Я записываю результат в файл, используя HTML: : PrettyPrinter . Все это работает хорошо, и вывод от PrettyPrinter очень приятный и понятный для человека. Однако PrettyPrinter плохо обрабатывает самозакрывающиеся теги; в основном это выглядит как косая черта как атрибут HTML. С вводом как:

<img />

PrettyPrinter возвращает:

<img /="/" >

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

Не уверен, что это будет полезно, но вот моя настройка для красивой печати:

my $hpp = HTML::PrettyPrinter->new('linelength' => 120, 'quote_attr' => 1);
$hpp->allow_forced_nl(1);

my $output = new FileHandle ">output.html";
if (defined $output) {
    $hpp->select($output);
    my $linearray_ref = $hpp->format($internal);
    undef $output;
    $hpp->select(undef),
}

1 Ответ

1 голос
/ 19 января 2012

Вы можете распечатать отформатированный html, читаемый человеком, с помощью метода TreeBuilder:

$h = HTML::TreeBuilder->new_from_content($html);
print $h->as_HTML('',"\t");

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

$h = HTML::TreeBuilder->new_from_content($html);
while(my $n = $h->look_down(_tag=>img,'src'=>undef)) { $n->delete }

UPD:

хорошо ... тогда мы можем исправить PrettyPrinter. Это чистый Perl модуль, так что давайте посмотрим ... Не знаю, где на Windows Perl модули для меня это / usr / local / share / perl / 5.10.1 / HTML / PrettyPrinter.pm

возможно, не элегантное решение, но, надеюсь, будет работать. это пара атрибут / значение sub parse, небольшое исправление, и он добавит один '/' в конце

~ строка 756 в PrettyPrinter.pm Я пометил строки, которые я добавил, с помощью ### <<<<<< </strong> в конце

#
# format the attributes
#
sub _attributes {
  my ($self, $e) = @_;
  my @result = (); # list of ATTR="value" strings to return

  my $self_closing = 0; ###<<<<<<
  my @attrs = $e->all_external_attr();  # list (name0, val0, name1, val1, ...)

  while (@attrs) {
    my ($a,$v) = (shift @attrs,shift @attrs);  # get current name, value pair
    if($a eq '/') {     ###<<<<<<
      $self_closing=1;  ###<<<<<<
      next;             ###<<<<<<
    }                   ###<<<<<<

    # string for output: 1. attribute name
    my $s = $self->uppercase? "\U$a" : $a;.

    # value part, skip for boolean attributes if desired
    unless ($a eq lc($v) &&
      $self->min_bool_attr &&.
      exists($HTML::Tagset::boolean_attr{$e->tag}) &&
      (ref($HTML::Tagset::boolean_attr{$e->tag}).
        ? $HTML::Tagset::boolean_attr{$e->tag}{$a}.
        : $HTML::Tagset::boolean_attr{$e->tag} eq $a)) {
      my $q = '';
      # quote value?
      if ($self->quote_attr || $v =~ tr/a-zA-Z0-9.-//c) {
        # use single quote if value contains double quotes but no single quotes
        $q = ($v =~ tr/"//  && $v !~ tr/'//) ? "'" : '"'; # catch emacs ");
      }
      # add value part
      $s .= '='.$q.(encode_entities($v,$q.$self->entities)).$q;
   }
   # add string to resulting list
   push @result, $s;
  }

  push @result,'/' if $self_closing;  ###<<<<<<
  return @result;  # return list ('attr="val"','attr="val"',...);
}
...