File Coverage

blib/lib/HTML/FormatMarkdown.pm
Criterion Covered Total %
statement 133 147 90.4
branch 31 52 59.6
condition n/a
subroutine 29 30 96.6
pod 0 26 0.0
total 193 255 75.6


line stmt bran cond sub pod time code
1             package HTML::FormatMarkdown;
2              
3             # ABSTRACT: Format HTML as Markdown
4              
5              
6 1     1   22502 use 5.006_001;
  1         3  
7 1     1   6 use strict;
  1         1  
  1         21  
8 1     1   5 use warnings;
  1         3  
  1         26  
9              
10 1     1   701 use parent 'HTML::Formatter';
  1         283  
  1         6  
11              
12             our $VERSION = '2.14'; # VERSION
13             our $AUTHORITY = 'cpan:NIGELM'; # AUTHORITY
14              
15             sub default_values {
16 2     2 0 12 ( shift->SUPER::default_values(),
17             lm => 0,
18             rm => 70,
19             );
20             }
21              
22             sub configure {
23 1     1 0 2 my ( $self, $hash ) = @_;
24              
25 1         7 my $lm = $self->{lm};
26 1         3 my $rm = $self->{rm};
27              
28 1 50       5 $lm = delete $hash->{lm} if exists $hash->{lm};
29 1 50       5 $lm = delete $hash->{leftmargin} if exists $hash->{leftmargin};
30 1 50       3 $rm = delete $hash->{rm} if exists $hash->{rm};
31 1 50       4 $rm = delete $hash->{rightmargin} if exists $hash->{rightmargin};
32              
33 1         3 my $width = $rm - $lm;
34 1 50       4 if ( $width < 1 ) {
35 0 0       0 warn "Bad margins, ignored" if $^W;
36 0         0 return;
37             }
38 1 50       3 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         2 $self->{lm} = $lm;
47 1         2 $self->{rm} = $rm;
48 1         3 $self;
49             }
50              
51             sub begin {
52 1     1 0 3 my $self = shift;
53              
54 1         7 $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 4 shift->collect("\n");
61             }
62              
63             sub header_start {
64 2     2 0 4 my ( $self, $level ) = @_;
65              
66 2         9 $self->vspace(1);
67 2         10 $self->out( '#' x $level . ' ' );
68 2         7 1;
69             }
70              
71             sub header_end {
72 2     2 0 3 my ( $self, $level ) = @_;
73              
74 2         7 $self->out( ' ' . '#' x $level );
75 2         7 $self->vspace(1);
76             }
77              
78             sub bullet {
79 4     4 0 54 my $self = shift;
80              
81 4         22 $self->SUPER::bullet( $_[0] . ' ' );
82              
83             }
84              
85             sub hr_start {
86 1     1 0 2 my $self = shift;
87              
88 1         4 $self->vspace(1);
89 1         3 $self->out('- - -');
90 1         3 $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       3 if ( $node->attr('name') ) {
    50          
107 0         0 1;
108             }
109             elsif ( $node->attr('href') =~ /^#/ ) {
110 0         0 1;
111             }
112             else {
113 1         25 $self->out("[");
114             }
115              
116             }
117              
118             sub a_end {
119 1     1 0 2 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       25 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 3 sub b_end { shift->out("**") }
134 1     1 0 3 sub i_start { shift->out("*") }
135 1     1 0 3 sub i_end { shift->out("*") }
136              
137             sub tt_start {
138 1     1 0 3 my $self = shift;
139              
140 1 50       4 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 3 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         4 $self->adjust_rm(-4);
165              
166 1         3 1;
167             }
168              
169             sub blockquote_end {
170 1     1 0 3 my $self = shift;
171              
172 1         2 $self->{blockquote}--;
173 1         5 $self->vspace(1);
174 1         3 $self->adjust_rm(+4);
175              
176             }
177              
178             sub blockquote_out {
179 1     1 0 2 my ( $self, $text ) = @_;
180              
181 1         3 $self->nl;
182 1         3 $self->goto_lm;
183              
184 1         3 my $line = "> ";
185 1         2 $self->{curpos} += 2;
186              
187 1         20 foreach my $word ( split /\s/, $text ) {
188 30         45 $line .= "$word ";
189 30 100       72 if ( ( $self->{curpos} + length($line) ) > $self->{rm} ) {
190 4         11 $self->collect($line);
191 4         7 $self->nl;
192 4         9 $self->goto_lm;
193 4         5 $line = "> ";
194 4         9 $self->{curpos} += 2;
195             }
196             }
197              
198 1         6 $self->collect($line);
199 1         3 $self->nl;
200              
201             }
202              
203             # Quoted from HTML::FormatText
204             sub pre_out {
205 1     1 0 1 my $self = shift;
206              
207 1 50       5 if ( defined $self->{vspace} ) {
208 1 50       3 if ( $self->{out} ) {
209 1         5 $self->nl() while $self->{vspace}-- >= 0;
210 1         3 $self->{vspace} = undef;
211             }
212             }
213              
214 1         4 my $indent = ' ' x $self->{lm};
215 1         3 $indent .= ' ' x 4;
216 1         1 my $pre = shift;
217 1         8 $pre =~ s/^/$indent/mg;
218 1         3 $self->collect($pre);
219 1         3 $self->{out}++;
220             }
221              
222             sub out {
223 699     699 0 830 my $self = shift;
224 699         931 my $text = shift;
225              
226 699         957 $text =~ tr/\xA0\xAD/ /d;
227              
228 699 100       1875 if ( $text =~ /^\s*$/ ) {
229 344         497 $self->{hspace} = 1;
230 344         777 return;
231             }
232              
233 355 100       730 if ( defined $self->{vspace} ) {
234 18 100       45 if ( $self->{out} ) {
235 17         62 $self->nl while $self->{vspace}-- >= 0;
236             }
237 18         34 $self->goto_lm;
238 18         31 $self->{vspace} = undef;
239 18         27 $self->{hspace} = 0;
240             }
241              
242 355 100       699 if ( $self->{hspace} ) {
243 323 100       660 if ( $self->{curpos} + length($text) > $self->{rm} ) {
244              
245             # word will not fit on line; do a line break
246 37         75 $self->nl;
247 37         76 $self->goto_lm;
248             }
249             else {
250              
251             # word fits on line; use a space
252 286         698 $self->collect(' ');
253 286         465 ++$self->{curpos};
254             }
255 323         450 $self->{hspace} = 0;
256             }
257              
258 355         806 $self->collect($text);
259 355         639 my $pos = $self->{curpos} += length $text;
260 355 100       740 $self->{maxpos} = $pos if $self->{maxpos} < $pos;
261 355         854 $self->{'out'}++;
262             }
263              
264             sub goto_lm {
265 72     72 0 87 my $self = shift;
266              
267 72         99 my $pos = $self->{curpos};
268 72         98 my $lm = $self->{lm};
269 72 100       197 if ( $pos < $lm ) {
270 60         75 $self->{curpos} = $lm;
271 60         200 $self->collect( " " x ( $lm - $pos ) );
272             }
273             }
274              
275             sub nl {
276 79     79 0 89 my $self = shift;
277              
278 79         106 $self->{'out'}++;
279 79         109 $self->{curpos} = 0;
280 79         185 $self->collect("\n");
281             }
282              
283             sub adjust_lm {
284 12     12 0 13 my $self = shift;
285              
286 12         24 $self->{lm} += $_[0];
287 12         23 $self->goto_lm;
288             }
289              
290             sub adjust_rm {
291 2     2 0 5 shift->{rm} += $_[0];
292             }
293              
294             1;
295              
296             __END__