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