|
Одному из клиентов нужно было сделать разделение текста на 2 колонки, при том, что этот текст редактируется в визуальном редакторе. Здесь возможности сильно урезаны, сохраняются картинки и базовое оформление (тегами a,b,i), и вырезаются [p table tbody tr td ol ul li], то есть я включил обработку только тех тегов, что используются в том визуальном редакторе.
################################################################################
# Subprogram: divide_text
# Description: Делит текст на колонки
#
sub divide_text {
my $content = shift;
my $divide_by = shift;
pack_html( \$content );
# затем вырезаем все теги, запоминая в массиве начало, конец и содержание тегов a,b,i
my %elements = { position => [], content => [] };
my @stripped_tags = qw!p table tbody tr td ol ul li!;
my $stripped_content = strip_tags( $content, @stripped_tags );
# добавляем пробел между тегами, потому что потом теги могут быть вырезаны, и слова склеятся
$stripped_content =~ s/></> </g;
# получаем позиции тегов и вырезаем их
my $tag_length = 0;
# пока есть теги
while( $stripped_content =~ /<[^>]*>/ ) {
my $position = index( $stripped_content, "<" );
# write_err_log($position);
$elements{ position }[$tag_length] = $position;
if( $stripped_content =~ s/(<[^>]*>)//s ) {
$elements{ content }[$tag_length] = $1;
} else { # контроль количества
$elements{ content }[$tag_length] = '';
} # End if
$tag_length++;
} # End while
# находим длину каждой колонки
my $clear_length = length( $stripped_content );
my $divide_result = $clear_length / $divide_by;
my $divide_remainder = $clear_length % $divide_by;
my $div_res_ceil = round( $divide_result );
my $div_res_floor = int( $divide_result );
# int - округляет в меньшую сторону
$div_res_ceil++ if( $divide_remainder != 0 && $div_res_ceil == $div_res_floor );
my @cols;
my $i = $divide_by;
while( $i-- ) {
# находим позицию 2-ого пробела начиная с позиции деления колонки
my $space_pos = index( $stripped_content, ' ', $div_res_ceil );
$space_pos = index( $stripped_content, ' ', $space_pos );
# если пробел не найден
$space_pos = $div_res_ceil if( $space_pos < $div_res_ceil );
push( @cols, substr( $stripped_content, 0, $space_pos ) );
substr( $stripped_content, 0, $space_pos ) = '';
} # End if
# вставляем теги на место
for( my $i = $tag_length-1; $i > -1 ; $i-- ) {
# если тег принадлежит первой колонке
my $offset = $elements{ position }[$i];
if( $elements{ position }[$i] < length( $cols[0] ) ) {
# вставляем тег на место
$cols[0] = substr( $cols[0], 0, $offset )
. $elements{ content }[$i]
. substr( $cols[0], $offset );
} elsif( $elements{ position }[$i] < ( length( $cols[0] ) + length( $cols[1] ) ) ) {
$offset = $offset - length( $cols[0] );
$cols[1] = substr( $cols[1], 0, $offset )
. $elements{ content }[$i]
. substr( $cols[1], $offset );
} elsif( $divide_by == 3 ) {
$offset = $offset - length( $cols[0] ) - length( $cols[1] );
$cols[2] = substr( $cols[2], 0, $offset )
. $elements{ content }[$i]
. substr( $cols[2], $offset );
} # End if
} # End for
my $result = join qq!
</td><td class="wi">
<img width="20" src="/new/i/p.gif"/>
</td><td>!, @cols;
my $width;
$width = qq!<col width="32%"><col width="16"><col width="32%"><col width="16"><col width="32%">! if( $divide_by == 3 );
$width = qq!<col width="48%"><col width="16"><col width="48%">! if( $divide_by == 2 );
$result = qq!
<table cellspacing="0" cellpadding="0">
$width
<tbody>
<tr>
<td>
! . $result . qq!
</td>
</tr>
</tbody></table>
!;
return $result;
} # End divide_text
################################################################################
# Subprogram: strip_tags
# Description: вырезает заданные теги
#
sub strip_tags {
my $text = shift;
# подставить пробелы в местах склейки тегов
my @tags = @_;
foreach my $tag ( @tags ) {
# if( $stripped_content =~ s/<$tag([^>]*)>(.*?)<\/$tag>/$2/s ) {
$text =~ s/<$tag[^>]*\/?>//g;
$text =~ s/<\/$tag>//g;
} # End for
return $text;
} # End strip_tags
Вернуться к списку записей комментарии работают на Disqus |
В админку |