1package HTML::Formatter; 2 3# ABSTRACT: Base class for HTML formatters 4 5 6use 5.006_001; 7use strict; 8use warnings; 9 10use Carp; 11use HTML::Element 3.15 (); 12 13# We now use Smart::Comments in place of the old DEBUG framework. 14# this should be commented out in release versions.... 15##use Smart::Comments; 16 17our $VERSION = '2.12'; # VERSION 18our $AUTHORITY = 'cpan:NIGELM'; # AUTHORITY 19 20# 21# A typical formatter will not use all of the features of this 22# class. But it will use some, as best fits the mapping 23# of HTML to the particular output format. 24# 25 26# ------------------------------------------------------------------------ 27 28 29sub new { 30 my ( $class, %arg ) = @_; 31 32 my $self = bless { $class->default_values }, $class; 33 $self->configure( \%arg ) if keys %arg; 34 35 return $self; 36} 37 38# ------------------------------------------------------------------------ 39sub default_values { 40 (); 41} 42 43# ------------------------------------------------------------------------ 44sub configure { 45 my ( $self, $arg ) = @_; 46 47 for ( keys %$arg ) { 48 warn "Unknown configure argument '$_'" if $^W; 49 } 50 51 return $self; 52} 53 54# ------------------------------------------------------------------------ 55sub massage_tree { 56 my ( $self, $html ) = @_; 57 58 return if $html->tag eq 'p'; # sanity 59 60 ### Before massaging: $html->dump() 61 62 $html->simplify_pres(); 63 64 # Does anything else need doing? 65 ### After massaging: $html->dump() 66 67 return; 68} 69 70# ------------------------------------------------------------------------ 71 72 73sub format_from_file { return shift->format_file(@_); } 74 75sub format_file { 76 my ( $self, $filename, @params ) = @_; 77 78 $self = $self->new(@params) unless ref $self; 79 80 croak "What filename to format from?" 81 unless ( defined($filename) and length($filename) ); 82 83 my $tree = $self->_default_tree(); 84 $tree->parse_file($filename); 85 86 my $out = $self->format($tree); 87 $tree->delete; 88 89 return $out; 90} 91 92# ------------------------------------------------------------------------ 93 94 95# ------------------------------------------------------------------------ 96sub format_from_string { shift->format_string(@_) } 97 98sub format_string { 99 my ( $self, $content, @params ) = @_; 100 101 $self = $self->new(@params) unless ref $self; 102 103 croak "What string to format?" unless defined $content; 104 105 my $tree = $self->_default_tree(); 106 $tree->parse($content); 107 $tree->eof(); 108 undef $content; 109 110 my $out = $self->format($tree); 111 $tree->delete; 112 113 return $out; 114} 115 116# ------------------------------------------------------------------------ 117sub _default_tree { 118 require HTML::TreeBuilder; 119 my $t = HTML::TreeBuilder->new; 120 121 # If nothing else works, try using these parser options:s 122 #$t->implicit_body_p_tag(1); 123 #$t->p_strict(1); 124 125 return $t; 126} 127 128# ------------------------------------------------------------------------ 129 130 131sub format { 132 my ( $self, $html ) = @_; 133 134 croak "Usage: \$formatter->format(\$tree)" unless ( defined($html) and ref($html) and $html->can('tag') ); 135 136 #### Tree to format: $html->dump 137 138 $self->set_version_tag($html); 139 $self->massage_tree($html); 140 $self->begin($html); 141 $html->number_lists(); 142 143 # Per-iteration scratch: 144 my ( $node, $start, $depth, $tag, $func ); 145 $html->traverse( 146 sub { 147 ( $node, $start, $depth ) = @_; 148 if ( ref $node ) { 149 $tag = $node->tag; 150 $func = $tag . '_' . ( $start ? "start" : "end" ); 151 152 # Use ->can so that we can recover if 153 # a handler is not defined for the tag. 154 if ( $self->can($func) ) { 155 ### Calling : (' ' x $depth) . $func 156 return $self->$func($node); 157 } 158 else { 159 ### Skipping: (' ' x $depth) . $func 160 return 1; 161 } 162 } 163 else { 164 $self->textflow($node); 165 } 166 1; 167 } 168 ); 169 170 $self->end($html); 171 172 return join( '', @{ $self->{output} } ); 173} 174 175# ------------------------------------------------------------------------ 176sub begin { 177 my $self = shift; 178 179 # Flags 180 $self->{anchor} = 0; 181 $self->{underline} = 0; 182 $self->{bold} = 0; 183 $self->{italic} = 0; 184 $self->{center} = 0; 185 186 $self->{superscript} = 0; 187 $self->{subscript} = 0; 188 $self->{strikethrough} = 0; 189 190 $self->{center_stack} = []; # push and pop 'center' states to it 191 $self->{nobr} = 0; 192 193 $self->{'font_size'} = [3]; # last element is current size 194 $self->{basefont_size} = [3]; 195 196 $self->{vspace} = undef; # vertical space (dimension) 197 198 $self->{output} = []; 199} 200 201# ------------------------------------------------------------------------ 202sub end { } 203 204# ------------------------------------------------------------------------ 205sub set_version_tag { 206 my ( $self, $html ) = @_; 207 208 if ($html) { 209 $self->{'version_tag'} = sprintf( 210 "%s (v%s, using %s v%s%s)", 211 ref($self), $self->VERSION || '?', 212 ref($html), 213 $html->VERSION || '?', 214 $HTML::Parser::VERSION ? ", and HTML::Parser v$HTML::Parser::VERSION" : '' 215 ); 216 } 217 elsif ($HTML::Parser::VERSION) { 218 $self->{'version_tag'} = 219 sprintf( "%s (v%s, using %s)", ref($self), $self->VERSION || "?", "HTML::Parser v$HTML::Parser::VERSION", ); 220 } 221 else { 222 $self->{'version_tag'} = sprintf( "%s (v%s)", ref($self), $self->VERSION || '?', ); 223 } 224} 225 226# ------------------------------------------------------------------------ 227sub version_tag { shift->{'version_tag'} } 228 229# ------------------------------------------------------------------------ 230sub html_start { 1; } 231sub html_end { } 232sub body_start { 1; } 233sub body_end { } 234sub head_start { 0; } 235sub script_start { 0; } 236sub style_start { 0; } 237sub frameset_start { 0; } 238 239# ------------------------------------------------------------------------ 240sub header_start { 241 my ( $self, undef, $node ) = @_; 242 243 my $align = $node->attr('align'); 244 if ( defined($align) && lc($align) eq 'center' ) { 245 $self->{center}++; 246 } 247 1; 248} 249 250# ------------------------------------------------------------------------ 251sub header_end { 252 my ( $self, undef, $node ) = @_; 253 254 my $align = $node->attr('align'); 255 if ( defined($align) && lc($align) eq 'center' ) { 256 $self->{center}--; 257 } 258} 259 260# ------------------------------------------------------------------------ 261sub h1_start { shift->header_start( 1, @_ ) } 262sub h2_start { shift->header_start( 2, @_ ) } 263sub h3_start { shift->header_start( 3, @_ ) } 264sub h4_start { shift->header_start( 4, @_ ) } 265sub h5_start { shift->header_start( 5, @_ ) } 266sub h6_start { shift->header_start( 6, @_ ) } 267 268# ------------------------------------------------------------------------ 269sub h1_end { shift->header_end( 1, @_ ) } 270sub h2_end { shift->header_end( 2, @_ ) } 271sub h3_end { shift->header_end( 3, @_ ) } 272sub h4_end { shift->header_end( 4, @_ ) } 273sub h5_end { shift->header_end( 5, @_ ) } 274sub h6_end { shift->header_end( 6, @_ ) } 275 276sub br_start { my $self = shift; $self->vspace( 0, 1 ); } 277sub hr_start { my $self = shift; $self->vspace(1); 1; } 278 279# ------------------------------------------------------------------------ 280sub img_start { 281 my ( $self, $node ) = @_; 282 283 my $alt = $node->attr('alt'); 284 $self->out( defined($alt) ? $alt : "[IMAGE]" ); 285} 286 287# ------------------------------------------------------------------------ 288sub a_start { shift->{anchor}++; 1; } 289sub a_end { shift->{anchor}--; } 290sub u_start { shift->{underline}++; 1; } 291sub u_end { shift->{underline}--; } 292sub b_start { shift->{bold}++; 1; } 293sub b_end { shift->{bold}--; } 294sub tt_start { shift->{teletype}++; 1; } 295sub tt_end { shift->{teletype}--; } 296sub i_start { shift->{italic}++; 1; } 297sub i_end { shift->{italic}--; } 298sub center_start { shift->{center}++; 1; } 299sub center_end { shift->{center}--; } 300 301# ------------------------------------------------------------------------ 302sub div_start { # interesting only for its 'align' attribute 303 my ( $self, $node ) = @_; 304 305 my $align = $node->attr('align'); 306 if ( defined($align) && lc($align) eq 'center' ) { 307 return $self->center_start; 308 } 309 1; 310} 311 312# ------------------------------------------------------------------------ 313sub div_end { 314 my ( $self, $node ) = @_; 315 316 my $align = $node->attr('align'); 317 if ( defined($align) && lc($align) eq 'center' ) { 318 return $self->center_end; 319 } 320} 321 322# ------------------------------------------------------------------------ 323sub nobr_start { shift->{nobr}++; 1; } 324sub nobr_end { shift->{nobr}--; } 325sub wbr_start { 1; } 326 327# ------------------------------------------------------------------------ 328sub font_start { 329 my ( $self, $elem ) = @_; 330 331 my $size = $elem->attr('size'); 332 return 1 unless ( defined($size) ); 333 if ( $size =~ /^\s*[+\-]/ ) { 334 my $base = $self->{basefont_size}[-1]; 335 336 # yes, base it on the most recent one 337 $size = $base + $size; 338 } 339 push @{ $self->{'font_size'} }, $size; 340 $self->new_font_size($size); 341 1; 342} 343 344# ------------------------------------------------------------------------ 345sub font_end { 346 my ( $self, $elem ) = @_; 347 my $size = $elem->attr('size'); 348 return unless defined $size; 349 pop @{ $self->{'font_size'} }; 350 $self->restore_font_size( $self->{'font_size'}[-1] ); 351} 352 353# ------------------------------------------------------------------------ 354sub big_start { 355 my $self = $_[0]; 356 push @{ $self->{'font_size'} }, $self->{basefont_size}[-1] + 1; # same as font size="+1" 357 $self->new_font_size( $self->{'font_size'}[-1] ); 358 1; 359} 360 361# ------------------------------------------------------------------------ 362sub small_start { 363 my $self = $_[0]; 364 push @{ $self->{'font_size'} }, $self->{basefont_size}[-1] - 1, # same as font size="-1" 365 ; 366 $self->new_font_size( $self->{'font_size'}[-1] ); 367 1; 368} 369 370# ------------------------------------------------------------------------ 371sub big_end { 372 my $self = $_[0]; 373 pop @{ $self->{'font_size'} }; 374 $self->restore_font_size( $self->{'font_size'}[-1] ); 375 1; 376} 377 378# ------------------------------------------------------------------------ 379sub small_end { 380 my $self = $_[0]; 381 pop @{ $self->{'font_size'} }; 382 $self->restore_font_size( $self->{'font_size'}[-1] ); 383 1; 384} 385 386# ------------------------------------------------------------------------ 387sub basefont_start { 388 my ( $self, $elem ) = @_; 389 my $size = $elem->attr('size'); 390 return unless defined $size; 391 push( @{ $self->{basefont_size} }, $size ); 392 1; 393} 394 395# ------------------------------------------------------------------------ 396sub basefont_end { 397 my ( $self, $elem ) = @_; 398 my $size = $elem->attr('size'); 399 return unless defined $size; 400 pop( @{ $self->{basefont_size} } ); 401} 402 403# ------------------------------------------------------------------------ 404# 405# Override in subclasses, if you like. 406# 407sub new_font_size { } #my( $self, $font_size_number ) = @_; 408sub restore_font_size { } #my( $self, $font_size_number ) = @_; 409 410# ------------------------------------------------------------------------ 411sub q_start { shift->out(q<">); 1; } 412sub q_end { shift->out(q<">); 1; } 413sub sup_start { shift->{superscript}++; 1; } 414sub sup_end { shift->{superscript}--; 1; } 415sub sub_start { shift->{subscript}++; 1; } 416sub sub_end { shift->{subscript}--; 1; } 417sub strike_start { shift->{strikethrough}++; 1; } 418sub strike_end { shift->{strikethrough}--; 1; } 419sub s_start { shift->strike_start(@_); } 420sub s_end { shift->strike_end(@_); } 421sub dfn_start { 1; } 422sub dfn_end { 1; } 423sub abbr_start { 1; } 424sub abbr_end { 1; } 425sub acronym_start { 1; } 426sub acronym_end { 1; } 427sub span_start { 1; } 428sub span_end { 1; } 429sub ins_start { 1; } 430sub ins_end { 1; } 431sub del_start { 0; } # Don't render the del'd bits 432sub del_end { 0; } 433 434# ------------------------------------------------------------------------ 435my @Size_magic_numbers = ( 436 0.60, 0.75, 0.89, 1, 1.20, 1.50, 2.00, 3.00 437 438 # #0 #1 #2 #3 #4 #5 #6 #7 439 #________________ - | + _________________________ 440 # -3 -2 -1 0 +1 +2 +3 +4 441); 442 443# ------------------------------------------------------------------------ 444sub scale_font_for { 445 my ( $self, $reference_size ) = @_; 446 447 # Mozilla's source, at 448 # http://lxr.mozilla.org/seamonkey/source/content/html/style/src/nsStyleUtil.cpp#299 449 # says: 450 # static PRInt32 sFontSizeFactors[8] = { 60,75,89,100,120,150,200,300 }; 451 # 452 # For comparison, Gisle's earlier HTML::FormatPS has: 453 # | # size 0 1 2 3 4 5 6 7 454 # | @FontSizes = ( 5, 6, 8, 10, 12, 14, 18, 24, 32); 455 # ...and gets different sizing via just a scaling factor. 456 457 my $size_number = int( defined( $_[2] ) ? $_[2] : $self->{'font_size'}[-1] ); 458 459 # force the size_number into range: 460 $size_number = 461 ( $size_number < 0 ) ? 0 462 : ( $size_number > $#Size_magic_numbers ) ? $#Size_magic_numbers 463 : int($size_number); 464 465 my $result = int( .5 + $reference_size * $Size_magic_numbers[$size_number] ); 466 467 ### Scale Font: sprintf("reference %s, size %s => %s", $reference_size, $size_number, $result); 468 469 return $result; 470} 471 472# ------------------------------------------------------------------------ 473# Aliases for logical markup: 474sub strong_start { shift->b_start(@_) } 475sub strong_end { shift->b_end(@_) } 476sub cite_start { shift->i_start(@_) } 477sub cite_end { shift->i_end(@_) } 478sub em_start { shift->i_start(@_) } 479sub em_end { shift->i_end(@_) } 480sub code_start { shift->tt_start(@_) } 481sub code_end { shift->tt_end(@_) } 482sub kbd_start { shift->tt_start(@_) } 483sub kbd_end { shift->tt_end(@_) } 484sub samp_start { shift->tt_start(@_) } 485sub samp_end { shift->tt_end(@_) } 486sub var_start { shift->tt_start(@_) } 487sub var_end { shift->tt_end(@_) } 488 489# ------------------------------------------------------------------------ 490sub p_start { 491 my $self = shift; 492 493 #$self->adjust_lm(0); # assert new paragraph 494 $self->vspace(1); 495 496 # assert one line's worth of vertical space at para-start 497 $self->out(''); 498 1; 499} 500 501# ------------------------------------------------------------------------ 502sub p_end { 503 shift->vspace(1); # assert one line's worth of vertical space at para-end 504} 505 506# ------------------------------------------------------------------------ 507sub pre_start { 508 my $self = shift; 509 510 $self->{pre}++; 511 $self->vspace(1); # assert one line's worth of vertical space at pre-start 512 1; 513} 514 515# ------------------------------------------------------------------------ 516sub pre_end { 517 my $self = shift; 518 519 $self->{pre}--; # assert one line's worth of vertical space at pre-end 520 $self->vspace(1); 521} 522 523# ------------------------------------------------------------------------ 524sub listing_start { shift->pre_start(@_) } 525sub listing_end { shift->pre_end(@_) } 526sub xmp_start { shift->pre_start(@_) } 527sub xmp_end { shift->pre_end(@_) } 528 529# ------------------------------------------------------------------------ 530sub blockquote_start { 531 my $self = shift; 532 533 $self->vspace(1); # assert one line's worth of vertical space at blockquote-start 534 $self->adjust_lm(+2); 535 $self->adjust_rm(-2); 536 1; 537} 538 539# ------------------------------------------------------------------------ 540sub blockquote_end { 541 my $self = shift; 542 543 $self->vspace(1); # assert one line's worth of vertical space at blockquote-end 544 $self->adjust_lm(-2); 545 $self->adjust_rm(+2); 546} 547 548# ------------------------------------------------------------------------ 549sub address_start { 550 my $self = shift; 551 552 $self->vspace(1); # assert one line's worth of vertical space at address-para-start 553 $self->i_start(@_); 554 1; 555} 556 557# ------------------------------------------------------------------------ 558sub address_end { 559 my $self = shift; 560 561 $self->i_end(@_); # assert one line's worth of vertical space at address-para-end 562 $self->vspace(1); 563} 564 565# ------------------------------------------------------------------------ 566# Handling of list elements 567sub ul_start { 568 my $self = shift; 569 570 $self->vspace(1); # assert one line's worth of vertical space at ul-start 571 $self->adjust_lm(+2); 572 1; 573} 574 575# ------------------------------------------------------------------------ 576sub ul_end { 577 my $self = shift; 578 579 $self->adjust_lm(-2); # assert one line's worth of vertical space at ul-end 580 $self->vspace(1); 581} 582 583# ------------------------------------------------------------------------ 584sub li_start { 585 my $self = shift; 586 587 $self->bullet( shift->attr('_bullet') || '' ); 588 $self->adjust_lm(+2); 589 1; 590} 591 592# ------------------------------------------------------------------------ 593sub bullet { shift->out(@_); } 594 595# ------------------------------------------------------------------------ 596sub li_end { 597 my $self = shift; 598 599 $self->vspace(1); 600 $self->adjust_lm(-2); 601} 602 603# ------------------------------------------------------------------------ 604sub menu_start { shift->ul_start(@_) } 605sub menu_end { shift->ul_end(@_) } 606sub dir_start { shift->ul_start(@_) } 607sub dir_end { shift->ul_end(@_) } 608 609# ------------------------------------------------------------------------ 610sub ol_start { 611 my $self = shift; 612 613 $self->vspace(1); 614 $self->adjust_lm(+2); 615 1; 616} 617 618# ------------------------------------------------------------------------ 619sub ol_end { 620 my $self = shift; 621 622 $self->adjust_lm(-2); 623 $self->vspace(1); 624} 625 626# ------------------------------------------------------------------------ 627sub dl_start { 628 my $self = shift; 629 630 # $self->adjust_lm(+2); 631 $self->vspace(1); # assert one line's worth of vertical space at dl-start 632 1; 633} 634 635# ------------------------------------------------------------------------ 636sub dl_end { 637 my $self = shift; 638 639 # $self->adjust_lm(-2); 640 $self->vspace(1); # assert one line's worth of vertical space at dl-end 641} 642 643# ------------------------------------------------------------------------ 644sub dt_start { 645 my $self = shift; 646 647 $self->vspace(1); # assert one line's worth of vertical space at dt-start 648 1; 649} 650 651# ------------------------------------------------------------------------ 652sub dt_end { } 653 654# ------------------------------------------------------------------------ 655sub dd_start { 656 my $self = shift; 657 658 $self->adjust_lm(+6); 659 $self->vspace(0); # hm, what's that do? nothing? 660 1; 661} 662 663# ------------------------------------------------------------------------ 664sub dd_end { 665 my $self = shift; 666 667 $self->vspace(1); # assert one line's worth of vertical space at dd-end 668 $self->adjust_lm(-6); 669} 670 671# ------------------------------------------------------------------------ 672 673# And now some things that are basically sane fall-throughs for classes 674# that don't really handle tables or forms specially... 675 676# Things not formatted at all 677sub input_start { 0; } 678sub textarea_start { 0; } 679sub select_start { 0; } 680sub option_start { 0; } 681 682# ------------------------------------------------------------------------ 683sub td_start { 684 my $self = shift; 685 686 push @{ $self->{'center_stack'} }, $self->{'center'}; 687 $self->{center} = 0; 688 689 $self->p_start(@_); 690} 691 692# ------------------------------------------------------------------------ 693sub td_end { 694 my $self = shift; 695 696 $self->{'center'} = pop @{ $self->{'center_stack'} }; 697 $self->p_end(@_); 698} 699 700# ------------------------------------------------------------------------ 701sub th_start { 702 my $self = shift; 703 704 push @{ $self->{'center_stack'} }, $self->{'center'}; 705 $self->{center} = 0; 706 707 $self->p_start(@_); 708 $self->b_start(@_); 709} 710 711# ------------------------------------------------------------------------ 712sub th_end { 713 my $self = shift; 714 715 $self->b_end(@_); 716 $self->{'center'} = pop @{ $self->{'center_stack'} }; 717 $self->p_end(@_); 718} 719 720# But if you wanted to just SKIP tables and forms, you'd do this: 721# sub table_start { shift->out('[TABLE NOT SHOWN]'); 0; } 722# sub form_start { shift->out('[FORM NOT SHOWN]'); 0; } 723 724# ------------------------------------------------------------------------ 725sub textflow { 726 my $self = shift; 727 728 if ( $self->{pre} ) { 729 730 # Strip one leading and one trailing newline so that a <pre> 731 # tag can be placed on a line of its own without causing extra 732 # vertical space as part of the preformatted text. 733 $_[0] =~ s/\n$//; 734 $_[0] =~ s/^\n//; 735 $self->pre_out( $_[0] ); 736 } 737 elsif ( $self->{blockquote} ) { 738 $_[0] =~ s/\A\s//; 739 $self->blockquote_out( $_[0] ); 740 } 741 else { 742 for ( split( /(\s+)/, $_[0] ) ) { 743 next unless length $_; 744 $self->out($_); 745 } 746 } 747} 748 749# ------------------------------------------------------------------------ 750sub vspace { 751 my ( $self, $min, $add ) = @_; 752 753 # This method sets the vspace attribute. When vspace is 754 # defined, then a new line should be started. If vspace 755 # is a nonzero value, then that should be taken as the 756 # number of lines to be skipped before following text 757 # is written out. 758 # 759 # You may think it odd to conflate the two concepts of 760 # ending this paragraph, and asserting how much space should 761 # follow; but it happens to work out pretty well. 762 763 my $old = $self->{vspace}; 764 if ( defined $old ) { 765 my $new = $old; 766 $new += $add || 0; 767 $new = $min if $new < $min; 768 $self->{vspace} = $new; 769 } 770 else { 771 $self->{vspace} = $min; 772 } 773 ### vspace: $self->{vspace} 774 $old; 775} 776 777# ------------------------------------------------------------------------ 778sub collect { push( @{ shift->{output} }, @_ ); } 779 780# ------------------------------------------------------------------------ 781sub out { confess "Must be overridden by subclass"; } # Output a word 782sub pre_out { confess "Must be overridden by subclass"; } 783sub adjust_lm { confess "Must be overridden by subclass"; } 784sub adjust_rm { confess "Must be overridden by subclass"; } 785 786# ------------------------------------------------------------------------ 787 788 7891; 790 791__END__ 792 793=pod 794 795=for test_synopsis 1; 796__END__ 797 798=for stopwords formatters CPAN homepage 799 800=head1 NAME 801 802HTML::Formatter - Base class for HTML formatters 803 804=head1 VERSION 805 806version 2.12 807 808=head1 SYNOPSIS 809 810 use HTML::FormatSomething; 811 my $infile = "whatever.html"; 812 my $outfile = "whatever.file"; 813 open OUT, ">$outfile" 814 or die "Can't write-open $outfile: $!\n"; 815 816 print OUT HTML::FormatSomething->format_file( 817 $infile, 818 'option1' => 'value1', 819 'option2' => 'value2', 820 ... 821 ); 822 close(OUT); 823 824=head1 DESCRIPTION 825 826HTML::Formatter is a base class for classes that take HTML and format it to 827some output format. When you take an object of such a base class and call 828C<$formatter->format( $tree )> with an L<HTML::TreeBuilder> (or 829L<HTML::Element>) object, they return the appropriately formatted string for 830the input HTML. 831 832HTML formatters are able to format a HTML syntax tree into various printable 833formats. Different formatters produce output for different output media. 834Common for all formatters are that they will return the formatted output when 835the format() method is called. The format() method takes a HTML::Element 836object (usually the HTML::TreeBuilder root object) as parameter. 837 838=head1 METHODS 839 840=head2 new 841 842 my $formatter = FormatterClass->new( 843 option1 => value1, option2 => value2, ... 844 ); 845 846This creates a new formatter object with the given options. 847 848=head2 format_file 849 850=head2 format_from_file 851 852 $string = FormatterClass->format_file( 853 $html_source, 854 option1 => value1, option2 => value2, ... 855 ); 856 857Return a string consisting of the result of using the given class to format the 858given HTML file according to the given (optional) options. Internally it calls 859C<< SomeClass->new( ... )->format( ... ) >> on a new HTML::TreeBuilder object 860based on the given HTML file. 861 862=head2 format_string 863 864=head2 format_from_string 865 866 $string = FormatterClass->format_string( 867 $html_source, 868 option1 => value1, option2 => value2, ... 869 ); 870 871Return a string consisting of the result of using the given class to format the 872given HTML source according to the given (optional) options. Internally it 873calls C<< SomeClass->new( ... )->format( ... ) >> on a new HTML::TreeBuilder 874object based on the given source. 875 876=head2 format 877 878 my $render_string = $formatter->format( $html_tree_object ); 879 880This renders the given HTML object according to the options set for $formatter. 881 882After you've used a particular formatter object to format a particular HTML 883tree object, you probably should not use either again. 884 885=head1 SEE ALSO 886 887The three specific formatters:- 888 889=over 890 891=item L<HTML::FormatText> 892 893Format HTML into plain text 894 895=item L<HTML::FormatPS> 896 897Format HTML into postscript 898 899=item L<HTML::FormatRTF> 900 901Format HTML into Rich Text Format 902 903=back 904 905Also the HTML manipulation libraries used - L<HTML::TreeBuilder>, 906L<HTML::Element> and L<HTML::Tree> 907 908=head1 INSTALLATION 909 910See perlmodinstall for information and options on installing Perl modules. 911 912=head1 BUGS AND LIMITATIONS 913 914You can make new bug reports, and view existing ones, through the 915web interface at L<http://rt.cpan.org/Public/Dist/Display.html?Name=HTML-Format>. 916 917=head1 AVAILABILITY 918 919The project homepage is L<https://metacpan.org/release/HTML-Format>. 920 921The latest version of this module is available from the Comprehensive Perl 922Archive Network (CPAN). Visit L<http://www.perl.com/CPAN/> to find a CPAN 923site near you, or see L<https://metacpan.org/module/HTML::Format/>. 924 925=head1 AUTHORS 926 927=over 4 928 929=item * 930 931Nigel Metheringham <nigelm@cpan.org> 932 933=item * 934 935Sean M Burke <sburke@cpan.org> 936 937=item * 938 939Gisle Aas <gisle@ActiveState.com> 940 941=back 942 943=head1 COPYRIGHT AND LICENSE 944 945This software is copyright (c) 2015 by Nigel Metheringham, 2002-2005 Sean M Burke, 1999-2002 Gisle Aas. 946 947This is free software; you can redistribute it and/or modify it under 948the same terms as the Perl 5 programming language system itself. 949 950=cut 951