Aion-Format
view release on metacpan or search on metacpan
lib/Aion/Format/Html.pm view on Meta::CPAN
# ÐÑбÑаÑÑваем из ÑÑека пÑедÑдÑÑий Ñег
my @ret;
push @ret, pop @$S while @$S and
($TOP_NEW_TAG{ $S->[$#$S][0] })->{$tag};
push @$S, [$tag, $atag] unless exists $SINGLE_TAG{$tag};
@ret
}
# ÐÑбÑаÑÑÐ²Ð°ÐµÑ Ñег из ÑÑека. ÐозвÑаÑÐ°ÐµÑ Ð²ÑдавленнÑе им и вÑбÑаÑÑÐ²Ð°ÐµÑ Ð¸ÑклÑÑение, еÑли Ñакого в ÑÑеке неÑ
sub out_tag(\@$) {
my ($S, $tag) = @_;
# ÐÑо одиноÑнÑй Ñег - он не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð·Ð°ÐºÑÑваÑÑим
die "</$tag> is a single tag - it cannot be a closing tag" if exists $SINGLE_TAG{$tag};
# закÑÑваем пÑедÑдÑÑий, еÑли нÑжно
my @ret;
push @ret, pop @$S while @$S and
($TOP_CLOSE_TAG{$S->[$#$S][0]})->{$tag};
die "</$tag>, but stack is empty!" unless @$S;
# Ñег Ñавен закÑÑваÑÑемÑ
die "<$S->[$#$S][0]> in stack ne </$tag>!" if $S->[$#$S][0] ne $tag;
push @ret, pop @$S;
@ret
}
# Ð Ð°Ð·Ð±Ð¸Ð²Ð°ÐµÑ ÑекÑÑ Ð½Ð° ÑÑÑаниÑÑ Ñ ÑÑÑÑом html-Ñегов
#
# 1. html-Ñег должен бÑÑÑ Ñак же ÑазнеÑÑн на ÑÑÑаниÑÑ.
#
sub split_on_pages(@) {
my ($html, $symbols_on_page, $by) = @_;
# Ðа какое ÑаÑÑÑоÑние ÑÑÑаниÑа Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð±Ð¾Ð»ÑÑе
$by //= $symbols_on_page / 3 < 1000 ? int($symbols_on_page / 3): 1000;
my $max = $symbols_on_page + $by;
my @pages; # маÑÑив ÑÑÑаниÑ
my @page; # маÑÑив ÑлеменÑов ÑекÑÑа и Ñегов ÑекÑÑей ÑÑÑаниÑÑ
my $c = 0; # колиÑеÑÑво Ñимволов в ÑекÑÑей ÑÑÑаниÑе
my $i_page = 0; # Ð¸Ð½Ð´ÐµÐºÑ ÑлеменÑа @page коÑоÑÑй пÑивÑÑил ÑÐ°Ð·Ð¼ÐµÑ ÑÑÑаниÑÑ
my $c_page = 0; # колиÑеÑÑво Ñимволов @page по $i_page
my $is_proposal = 0; # РконÑе ÑекÑÑей ÑÑÑаниÑÑ Ð¾Ð±Ð½Ð°ÑÑжен ÐºÐ¾Ð½ÐµÑ Ð¿ÑедложениÑ
my $re_proposal = qr/[.?!â¦]/;
my @S; # маÑÑив оÑкÑÑваÑÑиÑ
Ñегов [tag, '<tag ...>']
# ФÑнкÑÐ¸Ñ ÑикÑиÑÑÐµÑ ÑÑÑаниÑÑ Ð¸ ÑбÑаÑÑÐ²Ð°ÐµÑ ÑÑÑÑÑики
my $make_page = sub {
push @pages, join "", @page, map { "</$_->[0]>" } reverse @S;
$i_page = $c = $is_proposal = 0;
@page = map $_->[1], @S;
};
for(grep length, split m{(
<[a-z] [^<>]* >
| </ \s* [a-z]\w* \s* >
| &(?: [a-z]\w* | \# \d+ | \#x[0-9a-f]+ ) ;?
| \n # ÐбзаÑ
| $re_proposal+ # ÐÑедложение
| \b # Слово
)}xiu, $html) {
if(/^&/) {$c++} # html-Ñимвол
elsif(/^<\/\s*([a-z]\w*)/) { # закÑÑваÑÑий Ñег
my $tag = lc $1;
eval { out_tag @S, $tag };
next if $@;
# </p> пÑевÑаÑаем в <p></p>
$_ = "<p></p>" if $tag eq "p";
}
elsif(/^<([a-z]\w*)/) { in_tag @S, lc $1, $_ } # Ñег
else {$c += length} # ÑекÑÑ
push @page, $_; # накапливаем ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ Ð² маÑÑиве @page
next if $c < $symbols_on_page; # ÑÑÑаниÑÑ Ð½Ðµ набÑали - Ñогда на next
$c_page = $c, $i_page = @page if !$i_page;
# ÐÑоÑмаÑÑиваем впеÑÑд пока не найдÑм гÑаниÑÑ Ð¸Ð»Ð¸ не доÑÑигнем огÑаниÑениÑ
if(/^\n/) { $make_page->() } # ÐбзаÑ
elsif(!$is_proposal && /^$re_proposal/) { $i_page = @page; $c_page = $c; $is_proposal = 1 }
elsif($c >= $max) {
# ÐÑли ÑледÑÑÑий за пÑедложением или Ñловом ÑÐ»ÐµÐ¼ÐµÐ½Ñ - пÑобелÑ, Ñо добавлÑем иÑ
к ÑÑÑаниÑе
$c_page -= length $page[$i_page++] if $page[$i_page] =~ /^\s/;
my @x = splice @page, $i_page;
$make_page->();
push @page, @x;
$c -= $c_page;
}
}
$make_page->() if @page;
# ÐÑли ÑÐ°Ð·Ð¼ÐµÑ Ð¿Ð¾Ñледней ÑÑÑаниÑÑ Ð¼ÐµÐ½ÑÑе Ñем 2/3, Ñо добавлÑем ÐµÑ Ðº пÑедпоÑледней
$pages[$#pages - 1] .= pop @pages if @pages > 1 and length($pages[$#pages]) < $symbols_on_page * 2 / 3;
#my $len = 0; $len += length for @pages;
#die "СÑммаÑнÑй ÑÐ°Ð·Ð¼ÐµÑ ÑÑÑÐ°Ð½Ð¸Ñ Ð½Ðµ изменилÑÑ: " . length($html) . " == $len pages=" . @pages . " ->\n\n$html" if $len == length $html;
my ($end1) = $html =~ m!([^<>\s]{1,13})\s*(</?\w[^<>]*>\s*)*$!a;
my ($end2) = $pages[$#pages] =~ m!([^<>\s]{1,13})\s*(</?\w[^<>]*>\s*)*$!a;
die "ÐонÑÑ ÑекÑÑа и поÑледней ÑÑÑаниÑÑ Ð½Ðµ ÑÑ
одÑÑÑÑ! `$end1` <> `$end2`" if $end1 ne $end2;
return @pages;
}
our %TAG2SPACE = (
"br" => "\n",
"dd" => "\n ",
"table" => "\n",
"tr" => "\n| ",
"td" => "\t| ",
"th" => "\t| ",
( run in 3.418 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )