Acme-AsciiArt2HtmlTable

 view release on metacpan or  search on metacpan

lib/Acme/AsciiArt2HtmlTable.pm  view on Meta::CPAN

      }
    }

    if (defined $new_config->{'optimization'}) {
      $config{'optimization'} = $new_config->{'optimization'};
    }

  }

##############

  # prepare the table, tr and td attributes
  my $table = join ' ', map { "$_=\"$config{'table'}{$_}\"" } sort keys %{$config{'table'}};

  my $tr    = join ' ', map { "$_:$config{'tr'}{$_};"       } sort keys %{$config{'tr'   }};
  my $td    = join ' ', map { "$_:$config{'td'}{$_};"       } sort keys %{$config{'td'   }};

  # our ascii text
  my $text = shift;

  # where we'll store our html
  my $html = '';

  # style (td and tr elements' attributes)
  $html .= "<style>\n" .
           ".$config{'id'} td { $td }\n.$config{'id'} tr { $tr }" .
           "\n</style>\n";

  # table header
  $html .= "<table class=\"$config{'id'}\" $table>\n";

  # prepare the cells
  my @lines = map { [ split //, $_ ] } split /\n/, $text;

  # just to make sure an optimized table has the same width as the normal one
  my $opt_fix = '';
  if ( $config{'optimization'} ) {
    my $width = 0;
    for my $l ( 0 .. $#lines ) {
      if ( $width < $#{$lines[$l]} ) {
        $width = $#{$lines[$l]};
      }
    }
    $opt_fix = '<tr>' . ( '<td></td>' x $width ) . '</tr>';
  }

  for my $line ( 0 .. $#lines ) {
    for my $cell ( 0 .. $#{$lines[$line]} ) {
      next if $lines[$line]->[$cell] eq '';

      # randomizing new colors
      if ( $config{'randomize-new-colors'} ) {
        if ( not defined $config{'colors'}{ $lines[$line]->[$cell] } ) {
          $config{'colors'}{ $lines[$line]->[$cell] } = _random_color();
        }
      }

      # optimization
      my $optimization = '';

      # debugging messages were kept for future reference

      # remember that lines and cells are not the exact values, as
      # arrays start at index 0 and both lines and cells start at
      # position 1

      #my $debug = "line $line, cell $cell, ";

      if ( $config{'optimization'} ) {

        #$debug .= "\nthis is line $line, cell $cell";
	# check how many cells we could have on each line from the line we're
	# in to the last one
        my %we_could_have;
        for ( $line .. $#lines ) {
          $we_could_have{$_} = _count_in_the_beginning(
                                        $lines[$line]->[$cell],
                                        @{$lines[$_]}[$cell .. $#{$lines[$_]}]
                                      );
          #$debug .= "\nwe could have $we_could_have{$_} on line $_";
        }

        # check, for each line, how many cells an area up to that line would have
        my %area;
        my %area_width;
        for ( $line .. $#lines ) {
          my $min = _min( @we_could_have{$line .. $_} );
          $area{$_} = (1 + $_ - $line) * $min;
          $area_width{$_} = $min;
          #$debug .="\nwe could make an area of $area{$_} up to line $_, with a maximum of $area_width{$_} cells per line";
        }

        # check which is the line that maximizes optimization
        my $max_area = _max(values %area);
        my $best_line = _max(grep { $area{$_} == $max_area } keys %area);
        #$debug .= "\nour best choice seem to be using line $best_line";

        # check the are width
        my $width = $cell + $area_width{$best_line} - 1;

        # clean everything in the area we're about to optimize
        #$debug .= "\nwe want to clean everything from lines $line to $best_line and cells $cell to $width";
        for my $l ( $line .. $best_line ) {
          for my $c ( $cell .. $width ) {
            next if ( $l == $line and $c == $cell );
            $lines[$l]->[$c] = '';
          }
        }

        # optimize
        my $rowspan = $best_line - $line + 1;
        my $colspan = $area_width{$best_line};

        if ( $rowspan > 1 ) { $optimization .= " rowspan=\"$rowspan\"" }
        if ( $colspan > 1 ) { $optimization .= " colspan=\"$colspan\"" }

        #$debug .= "\n";
      }

      $lines[$line]->[$cell] = "<td$optimization bgcolor=\"" .
                               ( $config{'colors'}{ $lines[$line]->[$cell] } ||
                                 $config{'colors'}{'default'} ) .
                               "\"></td>";

    }

    $lines[$line] = join "\n", grep /./, @{$lines[$line]};

    if ($config{'optimization'}) {
      # this is so empty rows aren't ignored by the browser
      $lines[$line] .= "\n<td></td>";
    }

  }

  # the table
  $html .= join "\n", map { "<tr>\n$_\n</tr>" } @lines;

  if ($config{'optimization'}) {
    # this is so empty columns aren't ignored by the browser
    $html .= "$opt_fix";
  }

  # table footer
  $html .= "\n</table>\n";

  # return the table
  return $html;
}

=head3 SPECIALS

=head4 optimization

Table optimization, which is disabled by default, uses the C<rowspan>
and C<colspan> C<td> attributes to save up space.

  my $html = aa2ht( { 'optimization' => 1 }, $ascii );

When the optimization algorithm sees a chance of turning some cells
into a big one, it does so. It always chooses the biggest area
possible for optimizing.

If two different areas suitable for optimization starting from a given
cell are available and both present the same area size, the algorithm
picks the one that maximizes width.

=head4 default color

By default, an unmapped character is mapped to the default color,
which is black.

You can override this color by assigning a different mapping to
"default" with the C<colors> option.

  my $html = aa2ht( { 'colors' => { 'default' => 'ffffff' } }, $ascii);



( run in 2.008 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )