File Coverage

blib/lib/HTML/FormatMarkdown.pm
Criterion Covered Total %
statement 134 148 90.5
branch 31 52 59.6
condition n/a
subroutine 29 30 96.6
pod 0 26 0.0
total 194 256 75.7


line stmt bran cond sub pod time code
1             package HTML::FormatMarkdown;
2              
3             # ABSTRACT: Format HTML as Markdown
4              
5              
6 1     1   23312 use 5.006_001;
  1         4  
  1         48  
7 1     1   6 use strict;
  1         1  
  1         36  
8 1     1   5 use warnings;
  1         2  
  1         42  
9              
10 1     1   870 use parent 'HTML::Formatter';
  1         329  
  1         8  
11              
12             our $VERSION = '2.11'; # VERSION
13             our $AUTHORITY = 'cpan:NIGELM'; # AUTHORITY
14              
15             sub default_values {
16 2     2 0 13 ( shift->SUPER::default_values(),
17             lm => 0,
18             rm => 70,
19             );
20             }
21              
22             sub configure {
23 1     1 0 3 my ( $self, $hash ) = @_;
24              
25 1         7 my $lm = $self->{lm};
26 1         3 my $rm = $self->{rm};
27              
28 1 50       8 $lm = delete $hash->{lm} if exists $hash->{lm};
29 1 50       7 $lm = delete $hash->{leftmargin} if exists $hash->{leftmargin};
30 1 50       6 $rm = delete $hash->{rm} if exists $hash->{rm};
31 1 50       6 $rm = delete $hash->{rightmargin} if exists $hash->{rightmargin};
32              
33 1         2 my $width = $rm - $lm;
34 1 50       3 if ( $width < 1 ) {
35 0 0       0 warn "Bad margins, ignored" if $^W;
36 0         0 return;
37             }
38 1 50       4 if ( $width < 20 ) {
39 0 0       0 warn "Page probably too narrow" if $^W;
40             }
41              
42 1         4 for ( keys %$hash ) {
43 0 0       0 warn "Unknown configure option '$_'" if $^W;
44             }
45              
46 1         3 $self->{lm} = $lm;
47 1         2 $self->{rm} = $rm;
48 1         3 $self;
49             }
50              
51             sub begin {
52 1     1 0 2 my $self = shift;
53              
54 1         10 $self->SUPER::begin();
55 1         2 $self->{maxpos} = 0;
56 1         3 $self->{curpos} = 0; # current output position.
57             }
58              
59             sub end {
60 1     1 0 5 shift->collect("\n");
61             }
62              
63             sub header_start {
64 2     2 0 5 my ( $self, $level ) = @_;
65              
66 2         12 $self->vspace(1);
67 2         18 $self->out( '#' x $level . ' ' );
68 2         6 1;
69             }
70              
71             sub header_end {
72 2     2 0 4 my ( $self, $level ) = @_;
73              
74 2         8 $self->out( ' ' . '#' x $level );
75 2         8 $self->vspace(1);
76             }
77              
78             sub bullet {
79 4     4 0 54 my $self = shift;
80              
81 4         18 $self->SUPER::bullet( $_[0] . ' ' );
82              
83             }
84              
85             sub hr_start {
86 1     1 0 2 my $self = shift;
87              
88 1         3 $self->vspace(1);
89 1         3 $self->out('- - -');
90 1         41 $self->vspace(1);
91             }
92              
93             sub img_start {
94 0     0 0 0 my ( $self, $node ) = @_;
95              
96 0         0 my $alt = $node->attr('alt');
97 0         0 my $src = $node->attr('src');
98              
99 0         0 $self->out("![$alt]($src)");
100             }
101              
102             sub a_start {
103 1     1 0 3 my ( $self, $node ) = @_;
104              
105             # ignore named anchors
106 1 50       8 if ( $node->attr('name') ) {
    50          
107 0         0 1;
108             }
109             elsif ( $node->attr('href') =~ /^#/ ) {
110 0         0 1;
111             }
112             else {
113 1         29 $self->out("[");
114             }
115              
116             }
117              
118             sub a_end {
119 1     1 0 3 my ( $self, $node ) = @_;
120              
121 1 50       4 if ( $node->attr('name') ) {
    50          
122 0         0 return;
123             }
124             elsif ( my $href = $node->attr('href') ) {
125 1 50       24 if ( $href =~ /^#/ ) {
126 0         0 return;
127             }
128 1         4 $self->out("]($href)");
129             }
130             }
131              
132 1     1 0 3 sub b_start { shift->out("**") }
133 1     1 0 4 sub b_end { shift->out("**") }
134 1     1 0 4 sub i_start { shift->out("*") }
135 1     1 0 3 sub i_end { shift->out("*") }
136              
137             sub tt_start {
138 1     1 0 1 my $self = shift;
139              
140 1 50       13 if ( $self->{pre} ) {
141 0         0 return 1;
142             }
143             else {
144 1         3 $self->out("`");
145             }
146             }
147              
148             sub tt_end {
149 1     1 0 2 my $self = shift;
150              
151 1 50       4 if ( $self->{pre} ) {
152 0         0 return;
153             }
154             else {
155 1         3 $self->out("`");
156             }
157             }
158              
159             sub blockquote_start {
160 1     1 0 2 my $self = shift;
161              
162 1         3 $self->{blockquote}++;
163 1         4 $self->vspace(1);
164 1         12 $self->adjust_rm(-4);
165              
166 1         4 1;
167             }
168              
169             sub blockquote_end {
170 1     1 0 3 my $self = shift;
171              
172 1         3 $self->{blockquote}--;
173 1         3 $self->vspace(1);
174 1         3 $self->adjust_rm(+4);
175              
176             }
177              
178             sub blockquote_out {
179 1     1 0 3 my ( $self, $text ) = @_;
180              
181 1         3 $self->nl;
182 1         3 $self->goto_lm;
183              
184 1         2 my $line = "> ";
185 1         3 $self->{curpos} += 2;
186              
187 1         16 foreach my $word ( split /\s/, $text ) {
188 30         36 $line .= "$word ";
189 30 100       65 if ( ( $self->{curpos} + length($line) ) > $self->{rm} ) {
190 4         11 $self->collect($line);
191 4         9 $self->nl;
192 4         9 $self->goto_lm;
193 4         7 $line = "> ";
194 4         6 $self->{curpos} += 2;
195             }
196             }
197              
198 1         7 $self->collect($line);
199 1         3 $self->nl;
200              
201             }
202              
203             # Quoted from HTML::FormatText
204             sub pre_out {
205 1     1 0 3 my $self = shift;
206              
207 1 50       6 if ( defined $self->{vspace} ) {
208 1 50       4 if ( $self->{out} ) {
209 1         6 $self->nl() while $self->{vspace}-- >= 0;
210 1         3 $self->{vspace} = undef;
211             }
212             }
213              
214 1         3 my $indent = ' ' x $self->{lm};
215 1         2 $indent .= ' ' x 4;
216 1         2 my $pre = shift;
217 1         9 $pre =~ s/^/$indent/mg;
218 1         5 $self->collect($pre);
219 1         3 $self->{out}++;
220             }
221              
222             sub out {
223 699     699 0 848 my $self = shift;
224 699         1176 my $text = shift;
225              
226 699         729 $text =~ tr/\xA0\xAD/ /d;
227              
228 699 100       1810 if ( $text =~ /^\s*$/ ) {
229 344         464 $self->{hspace} = 1;
230 344         873 return;
231             }
232              
233 355 100       635 if ( defined $self->{vspace} ) {
234 18 100       41 if ( $self->{out} ) {
235 17         55 $self->nl while $self->{vspace}-- >= 0;
236             }
237 18         33 $self->goto_lm;
238 18         24 $self->{vspace} = undef;
239 18         26 $self->{hspace} = 0;
240             }
241              
242 355 100       594 if ( $self->{hspace} ) {
243 323 100       624 if ( $self->{curpos} + length($text) > $self->{rm} ) {
244              
245             # word will not fit on line; do a line break
246 37         62 $self->nl;
247 37         62 $self->goto_lm;
248             }
249             else {
250              
251             # word fits on line; use a space
252 286         629 $self->collect(' ');
253 286         384 ++$self->{curpos};
254             }
255 323         365 $self->{hspace} = 0;
256             }
257              
258 355         720 $self->collect($text);
259 355         514 my $pos = $self->{curpos} += length $text;
260 355 100       670 $self->{maxpos} = $pos if $self->{maxpos} < $pos;
261 355         867 $self->{'out'}++;
262             }
263              
264             sub goto_lm {
265 72     72 0 71 my $self = shift;
266              
267 72         93 my $pos = $self->{curpos};
268 72         78 my $lm = $self->{lm};
269 72 100       150 if ( $pos < $lm ) {
270 60         62 $self->{curpos} = $lm;
271 60         193 $self->collect( " " x ( $lm - $pos ) );
272             }
273             }
274              
275             sub nl {
276 79     79 0 189 my $self = shift;
277              
278 79         87 $self->{'out'}++;
279 79         101 $self->{curpos} = 0;
280 79         166 $self->collect("\n");
281             }
282              
283             sub adjust_lm {
284 12     12 0 16 my $self = shift;
285              
286 12         14 $self->{lm} += $_[0];
287 12         24 $self->goto_lm;
288             }
289              
290             sub adjust_rm {
291 2     2 0 7 shift->{rm} += $_[0];
292             }
293              
294             1;
295              
296             __END__