:-[ Домашняя страница девелопера ] :( + φ = :D

Разделение текста на 2 колонки на perl

Одному из клиентов нужно было сделать разделение текста на 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


В админку