File Coverage

blib/lib/EBook/Ishmael/TextBrowserDump.pm
Criterion Covered Total %
statement 23 42 54.7
branch 0 12 0.0
condition 0 12 0.0
subroutine 8 9 88.8
pod 1 1 100.0
total 32 76 42.1


line stmt bran cond sub pod time code
1             package EBook::Ishmael::TextBrowserDump;
2 2     2   42 use 5.016;
  2         9  
3             our $VERSION = '2.01';
4 2     2   14 use strict;
  2         5  
  2         94  
5 2     2   14 use warnings;
  2         5  
  2         147  
6              
7 2     2   14 use Exporter 'import';
  2         5  
  2         135  
8             our @EXPORT = qw(browser_dump);
9              
10 2     2   11 use Encode qw(decode);
  2         5  
  2         172  
11 2     2   31 use List::Util qw(first);
  2         6  
  2         163  
12              
13 2     2   13 use File::Which;
  2         5  
  2         125  
14              
15 2     2   13 use EBook::Ishmael::ShellQuote qw(safe_qx);
  2         4  
  2         1847  
16              
17             our $CAN_DUMP = 0;
18              
19             # From links
20             my $WIDTH_MAX = 512;
21             my $WIDTH_MIN = 10;
22              
23             my @ORDER = qw(
24             lynx
25             links
26             elinks
27             w3m
28             chawan
29             pandoc
30             queequeg
31             );
32              
33             my %Browsers = (
34             'lynx' => {
35             Bins => [ qw(lynx) ],
36             Bin => undef,
37             Opts => [ qw(-dump -force_html -nolist -display_charset=utf8) ],
38             Width => '-width %d',
39             Xhtml => [ qw(-xhtml_parsing) ],
40             },
41             'links' => {
42             Bins => [ qw(links links2) ],
43             Bin => undef,
44             Opts => [ qw(-dump -force-htm -codepage utf8) ],
45             Width => '-width %d',
46             Xhtml => [],
47             },
48             'elinks' => {
49             Bins => [ qw(elinks) ],
50             Bin => undef,
51             Opts => [ qw(-dump -force-html -no-home -no-references -no-numbering
52             -dump-charset utf8) ],
53             Width => '-dump-width %d',
54             Xhtml => [],
55             },
56             'w3m' => {
57             Bins => [ qw(w3m) ],
58             Bin => undef,
59             Opts => [ qw(-dump -T text/html -O utf8) ],
60             Width => '-cols %d',
61             Xhtml => [],
62             },
63             'chawan' => {
64             Bins => [ qw(cha) ],
65             Bin => undef,
66             Opts => [ qw(-d -I utf8 -O utf8 -T text/html) ],
67             Width => "-o 'display.columns=%d'",
68             Xhtml => [],
69             },
70             'pandoc' => {
71             Bins => [ qw(pandoc) ],
72             Bin => undef,
73             Opts => [ qw(-f html -t plain -o -) ],
74             Width => "--columns %d",
75             Xhtml => [],
76             },
77             'queequeg' => {
78             Bins => [ qw(queequeg) ],
79             Bin => undef,
80             Opts => [ qw(-e utf8) ],
81             Width => '-w %d',
82             Xhtml => [],
83             },
84             );
85              
86             my $Default = undef;
87             for my $k (@ORDER) {
88             my $bin = first { which $_ } @{ $Browsers{ $k }->{Bins} };
89             next unless defined $bin;
90             $Browsers{ $k }->{Bin} = $bin;
91             $Default //= $k;
92             }
93              
94             $CAN_DUMP = defined $Default;
95              
96             unless ($CAN_DUMP) {
97             warn "No valid text browser was found installed on your system, you " .
98             "will be unable to use any feature requiring a text browser\n";
99             }
100              
101             sub browser_dump {
102              
103 0 0   0 1   unless (defined $Default) {
104 0           die "Cannot format HTML; no valid program was found on your system\n";
105             }
106              
107 0           my $file = shift;
108 0   0       my $param = shift // {};
109              
110 0   0       my $browser = $param->{browser} // $Default;
111 0   0       my $xhtml = $param->{xhtml} // 0;
112 0   0       my $width = $param->{width} // 80;
113              
114 0 0         unless (exists $Browsers{ $browser }) {
115 0           die <<"HERE";
116             '$browser' is not a valid program; the following is a list of valid programs:
117             lynx
118             links
119             elinks
120             w3m
121             chawan
122             pandoc
123             queequeg
124             HERE
125             }
126              
127 0 0         unless (defined $Browsers{ $browser }->{Bin}) {
128 0           die "'$browser' is not installed on your system\n";
129             }
130              
131 0 0 0       unless ($width >= $WIDTH_MIN and $width <= $WIDTH_MAX) {
132 0           die "Width cannot be greater than $WIDTH_MAX or less than $WIDTH_MIN\n";
133             }
134              
135             my $dump = safe_qx(
136             $Browsers{ $browser }->{Bin},
137             sprintf($Browsers{ $browser }->{Width}, $width),
138 0           @{ $Browsers{ $browser }->{Opts} },
139 0 0         ($xhtml ? join(" ", @{ $Browsers{ $browser }->{Xhtml} }) : ()),
  0            
140             $file
141             );
142 0 0         unless ($? >> 8 == 0) {
143 0           die "Failed to dump $file with $Browsers{ $browser }->{Bin}\n";
144             }
145              
146             # We can't use 'open IN => ":encoding(UTF-8)"' because it was broken prior
147             # to 5.34, so we must manually decode :-/.
148 0           return decode('UTF-8', $dump);
149              
150             }
151              
152             1;
153              
154             =head1 NAME
155              
156             EBook::Ishmael::TextBrowserDump - Format HTML through different installed programs
157              
158             =head1 SYNOPSIS
159              
160             use EBook::Ishmael::TextBrowserDump;
161              
162             my $dump = browser_dump($file);
163              
164             =head1 DESCRIPTION
165              
166             B is a module for dumping the contents of
167             HTML files to formatted text, via programs like L. For
168             L user documentation, you should consult its manual (this is
169             developer documentation).
170              
171             B requires at least one of the following
172             programs to be installed:
173              
174             =over 4
175              
176             =item L
177              
178             =item L
179              
180             =item L
181              
182             =item L
183              
184             =item chawan
185              
186             =item L
187              
188             =item L
189              
190             =back
191              
192             =head1 SUBROUTINES
193              
194             =head2 $dump = browser_dump($file, $opt_ref)
195              
196             Subroutine that dumps the formatted text contents of C<$file> via a text
197             web browser.
198              
199             C can also be given a hash ref of options.
200              
201             =over 4
202              
203             =item browser
204              
205             The specific browser you would like to use for the dumping. See above for a list
206             of valid browsers. If not specified, defaults to the first browser
207             C finds installed on your system.
208              
209             =item xhtml
210              
211             Bool specifying whether the input file is XHTML or not. Defaults to C<0>.
212              
213             =item width
214              
215             Specify the width of the formatted text. Defaults to C<80>.
216              
217             =back
218              
219             =head1 GLOBAL VARIABLES
220              
221             =head2 $EBook::Ishmael::TextBrowserDump::CAN_DUMP
222              
223             Bool stating whether this module is able to dump or not (is a valid
224             text browser installed or not).
225              
226             =head1 AUTHOR
227              
228             Written by Samuel Young, Esamyoung12788@gmail.comE.
229              
230             This project's source can be found on its
231             L. Comments and pull
232             requests are welcome!
233              
234             =head1 COPYRIGHT
235              
236             Copyright (C) 2025-2026 Samuel Young
237              
238             This program is free software: you can redistribute it and/or modify
239             it under the terms of the GNU General Public License as published by
240             the Free Software Foundation, either version 3 of the License, or
241             (at your option) any later version.
242              
243             =head1 SEE ALSO
244              
245             L, L, L, L, L, L,
246             L,
247              
248             =cut