<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package HTML::FormatMarkdown;

# ABSTRACT: Format HTML as Markdown


use 5.006_001;
use strict;
use warnings;

use parent 'HTML::Formatter';

our $VERSION = '2.12'; # VERSION
our $AUTHORITY = 'cpan:NIGELM'; # AUTHORITY

sub default_values {
    (   shift-&gt;SUPER::default_values(),
        lm =&gt; 0,
        rm =&gt; 70,
    );
}

sub configure {
    my ( $self, $hash ) = @_;

    my $lm = $self-&gt;{lm};
    my $rm = $self-&gt;{rm};

    $lm = delete $hash-&gt;{lm}          if exists $hash-&gt;{lm};
    $lm = delete $hash-&gt;{leftmargin}  if exists $hash-&gt;{leftmargin};
    $rm = delete $hash-&gt;{rm}          if exists $hash-&gt;{rm};
    $rm = delete $hash-&gt;{rightmargin} if exists $hash-&gt;{rightmargin};

    my $width = $rm - $lm;
    if ( $width &lt; 1 ) {
        warn "Bad margins, ignored" if $^W;
        return;
    }
    if ( $width &lt; 20 ) {
        warn "Page probably too narrow" if $^W;
    }

    for ( keys %$hash ) {
        warn "Unknown configure option '$_'" if $^W;
    }

    $self-&gt;{lm} = $lm;
    $self-&gt;{rm} = $rm;
    $self;
}

sub begin {
    my $self = shift;

    $self-&gt;SUPER::begin();
    $self-&gt;{maxpos} = 0;
    $self-&gt;{curpos} = 0;    # current output position.
}

sub end {
    shift-&gt;collect("\n");
}

sub header_start {
    my ( $self, $level ) = @_;

    $self-&gt;vspace(1);
    $self-&gt;out( '#' x $level . ' ' );
    1;
}

sub header_end {
    my ( $self, $level ) = @_;

    $self-&gt;out( ' ' . '#' x $level );
    $self-&gt;vspace(1);
}

sub bullet {
    my $self = shift;

    $self-&gt;SUPER::bullet( $_[0] . ' ' );

}

sub hr_start {
    my $self = shift;

    $self-&gt;vspace(1);
    $self-&gt;out('- - -');
    $self-&gt;vspace(1);
}

sub img_start {
    my ( $self, $node ) = @_;

    my $alt = $node-&gt;attr('alt');
    my $src = $node-&gt;attr('src');

    $self-&gt;out("![$alt]($src)");
}

sub a_start {
    my ( $self, $node ) = @_;

    # ignore named anchors
    if ( $node-&gt;attr('name') ) {
        1;
    }
    elsif ( $node-&gt;attr('href') =~ /^#/ ) {
        1;
    }
    else {
        $self-&gt;out("[");
    }

}

sub a_end {
    my ( $self, $node ) = @_;

    if ( $node-&gt;attr('name') ) {
        return;
    }
    elsif ( my $href = $node-&gt;attr('href') ) {
        if ( $href =~ /^#/ ) {
            return;
        }
        $self-&gt;out("]($href)");
    }
}

sub b_start { shift-&gt;out("**") }
sub b_end   { shift-&gt;out("**") }
sub i_start { shift-&gt;out("*") }
sub i_end   { shift-&gt;out("*") }

sub tt_start {
    my $self = shift;

    if ( $self-&gt;{pre} ) {
        return 1;
    }
    else {
        $self-&gt;out("`");
    }
}

sub tt_end {
    my $self = shift;

    if ( $self-&gt;{pre} ) {
        return;
    }
    else {
        $self-&gt;out("`");
    }
}

sub blockquote_start {
    my $self = shift;

    $self-&gt;{blockquote}++;
    $self-&gt;vspace(1);
    $self-&gt;adjust_rm(-4);

    1;
}

sub blockquote_end {
    my $self = shift;

    $self-&gt;{blockquote}--;
    $self-&gt;vspace(1);
    $self-&gt;adjust_rm(+4);

}

sub blockquote_out {
    my ( $self, $text ) = @_;

    $self-&gt;nl;
    $self-&gt;goto_lm;

    my $line = "&gt; ";
    $self-&gt;{curpos} += 2;

    foreach my $word ( split /\s/, $text ) {
        $line .= "$word ";
        if ( ( $self-&gt;{curpos} + length($line) ) &gt; $self-&gt;{rm} ) {
            $self-&gt;collect($line);
            $self-&gt;nl;
            $self-&gt;goto_lm;
            $line = "&gt; ";
            $self-&gt;{curpos} += 2;
        }
    }

    $self-&gt;collect($line);
    $self-&gt;nl;

}

# Quoted from HTML::FormatText
sub pre_out {
    my $self = shift;

    if ( defined $self-&gt;{vspace} ) {
        if ( $self-&gt;{out} ) {
            $self-&gt;nl() while $self-&gt;{vspace}-- &gt;= 0;
            $self-&gt;{vspace} = undef;
        }
    }

    my $indent = ' ' x $self-&gt;{lm};
    $indent .= ' ' x 4;
    my $pre = shift;
    $pre =~ s/^/$indent/mg;
    $self-&gt;collect($pre);
    $self-&gt;{out}++;
}

sub out {
    my $self = shift;
    my $text = shift;

    $text =~ tr/\xA0\xAD/ /d;

    if ( $text =~ /^\s*$/ ) {
        $self-&gt;{hspace} = 1;
        return;
    }

    if ( defined $self-&gt;{vspace} ) {
        if ( $self-&gt;{out} ) {
            $self-&gt;nl while $self-&gt;{vspace}-- &gt;= 0;
        }
        $self-&gt;goto_lm;
        $self-&gt;{vspace} = undef;
        $self-&gt;{hspace} = 0;
    }

    if ( $self-&gt;{hspace} ) {
        if ( $self-&gt;{curpos} + length($text) &gt; $self-&gt;{rm} ) {

            # word will not fit on line; do a line break
            $self-&gt;nl;
            $self-&gt;goto_lm;
        }
        else {

            # word fits on line; use a space
            $self-&gt;collect(' ');
            ++$self-&gt;{curpos};
        }
        $self-&gt;{hspace} = 0;
    }

    $self-&gt;collect($text);
    my $pos = $self-&gt;{curpos} += length $text;
    $self-&gt;{maxpos} = $pos if $self-&gt;{maxpos} &lt; $pos;
    $self-&gt;{'out'}++;
}

sub goto_lm {
    my $self = shift;

    my $pos = $self-&gt;{curpos};
    my $lm  = $self-&gt;{lm};
    if ( $pos &lt; $lm ) {
        $self-&gt;{curpos} = $lm;
        $self-&gt;collect( " " x ( $lm - $pos ) );
    }
}

sub nl {
    my $self = shift;

    $self-&gt;{'out'}++;
    $self-&gt;{curpos} = 0;
    $self-&gt;collect("\n");
}

sub adjust_lm {
    my $self = shift;

    $self-&gt;{lm} += $_[0];
    $self-&gt;goto_lm;
}

sub adjust_rm {
    shift-&gt;{rm} += $_[0];
}

1;

__END__

=pod

=for stopwords CPAN Markdown homepage

=for test_synopsis 1;
__END__

=head1 NAME

HTML::FormatMarkdown - Format HTML as Markdown

=head1 VERSION

version 2.12

=head1 SYNOPSIS

    use HTML::FormatMarkdown;

    my $string = HTML::FormatMarkdown-&gt;format_file(
        'test.html'
    );

    open my $fh, "&gt;", "test.md" or die "$!\n";
    print $fh $string;
    close $fh;

=head1 DESCRIPTION

HTML::FormatMarkdown is a formatter that outputs Markdown.

HTML::FormatMarkdown is built on L&lt;HTML::Formatter&gt; and documentation for that
module applies to this - especially L&lt;HTML::Formatter/new&gt;,
L&lt;HTML::Formatter/format_file&gt; and L&lt;HTML::Formatter/format_string&gt;.

=head1 INSTALLATION

See perlmodinstall for information and options on installing Perl modules.

=head1 BUGS AND LIMITATIONS

You can make new bug reports, and view existing ones, through the
web interface at L&lt;http://rt.cpan.org/Public/Dist/Display.html?Name=HTML-Format&gt;.

=head1 AVAILABILITY

The project homepage is L&lt;https://metacpan.org/release/HTML-Format&gt;.

The latest version of this module is available from the Comprehensive Perl
Archive Network (CPAN). Visit L&lt;http://www.perl.com/CPAN/&gt; to find a CPAN
site near you, or see L&lt;https://metacpan.org/module/HTML::Format/&gt;.

=head1 AUTHORS

=over 4

=item *

Nigel Metheringham &lt;nigelm@cpan.org&gt;

=item *

Sean M Burke &lt;sburke@cpan.org&gt;

=item *

Gisle Aas &lt;gisle@ActiveState.com&gt;

=back

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Nigel Metheringham, 2002-2005 Sean M Burke, 1999-2002 Gisle Aas.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
</pre></body></html>