fix bug 4648, 'fails to build with gcc 13'
[claws.git] / tools / textviewer.pl
blobe9f04ae059d1090f13a178d255ffad5eacfab67c
1 #!/usr/bin/perl
3 # COPYRIGHT AND LICENSE
4 # Copyright (C) 2005-2018 H.Merijn Brand
6 # This script is free software; you can redistribute it and/or modify it
7 # under the same terms as Perl and/or Claws Mail itself. (GPL)
9 use 5.14.1;
10 use warnings;
12 our $VERSION = "1.01 - 2018-10-08";
13 our $CMD = $0 =~ s{.*/}{}r;
15 sub usage {
16 my ($err, $str) = (@_, "");
17 $err and select STDERR;
18 say "usage: $CMD [--html] [--type=<type>] file\n",
19 " --html Generate HTML (if supported)\n",
20 " --type=X X as mimetype (msword => doc)\n",
21 " $CMD --list will show all implemented conversions";
22 $str and say $str;
23 exit $err;
24 } # usage
26 use Getopt::Long qw(:config bundling nopermute);
27 my $opt_v = 0;
28 my $opt_h = "text";
29 GetOptions (
30 "help|?" => sub { usage (0); },
31 "V|version" => sub { say "$CMD [$VERSION]"; exit 0; },
33 "v|verbose:1" => \$opt_v,
34 "t|type|mimetype=s" => \my $opt_t,
35 "h|html" => sub { $opt_h = "html" },
36 "l|list!" => \my $opt_l,
37 ) or usage (1);
39 $opt_v and say "$0 @ARGV";
41 # anon-list contains all possible commands to show content
42 # plain text is a reference to same type (alias)
43 # %f will be replaced with file. If no %f, file will be the last arg
44 my %fh = (
45 text => {
46 bin => [ "strings" ], # fallback for binary files
48 txt => [ "cat" ], # Plain text
50 html => [ "htm2txt",
51 "html2text" ], # HTML
53 msword => "doc",
54 doc => [ "catdoc -x -dutf-8",
55 "wvText",
56 "antiword -w 72" ], # M$ Word
57 "vnd.ms-excel" => "xls",
58 "ms-excel" => "xls",
59 docx => [ "unoconv -f text --stdout" ], # MS Word
60 xlsx => "xls",
61 xls => [ "xlscat -L",
62 "catdoc -x -dutf-8",
63 "wvText" ], # M$ Excel
64 # ppt => [ "ppthtml" ], # M$ PowerPoint
65 # ppthtml "$1" | html2text
66 csv => "xls", # Comma Separated Values
68 ics => [ "ics2txt" ], # ICS calendar request
70 rtf => [ "rtf2text",
71 "unrtf -t text" ], # RTF
72 pdf => [ "pdftotext %f -" ], # Adobe PDF
74 ods => "xls", # OpenOffice spreadsheet
75 sxc => "xls", # OpenOffice spreadsheet
76 odt => [ "oo2pod %f | pod2text",
77 "ooo2txt" ], # OpenOffice writer
78 rtf => [ "rtf2text" ], # RTF
80 pl => [ "perltidy -st -se",
81 "cat" ], # Perl
82 pm => "pl",
84 jsn => [ "json_pp" ], # JSON
85 json => "jsn",
87 xml => [ "xml_pp" ], # XML
89 ( map { $_ => "txt" } qw(
90 patch diff
91 c h ic ec cc
92 sh sed awk
93 plain
94 yml yaml
95 )),
97 bz2 => [ "bzip2 -d < %f | strings" ],
99 zip => [ "unzip -l %f" ], # ZIP
101 test => [ \&test ], # Internal
103 tgz => [ "tar tvf" ], # Tar uncompressed
104 tgz => [ "tar tzvf" ], # Tar GZ compressed
105 tbz => [ "tar tjvf" ], # Tar BZip2 compressed
106 txz => [ "tar tJvf" ], # Tar XZ compressed
108 rar => [ "unrar l" ], # RAR
111 html => {
112 rtf => [ "rtf2html" ],
116 if ($opt_l) {
117 my %tc = %{$fh{text}};
118 foreach my $ext (sort keys %tc) {
119 my $exe = $tc{$ext};
120 ref $exe or $exe = $tc{$exe};
121 printf " .%-12s %s\n", $ext, $_ for @$exe;
123 exit 0;
126 my $file = shift or usage (1, "File argument is missing");
127 -f $file or usage (1, "File argument is not a plain file");
128 -r $file or usage (1, "File argument is not a readable file");
129 -s $file or usage (1, "File argument is an empty file");
131 my $ext = $file =~ m/\.(\w+)$/ ? lc $1 : "";
132 $opt_t && exists $fh{text}{lc $opt_t} and $ext = lc$opt_t;
133 unless (exists $fh{text}{$ext}) {
134 my $ftype = `file --brief $file`;
135 $ext =
136 $ftype =~ m/^pdf doc/i ? "pdf" :
137 $ftype =~ m/^ascii( english)? text/i ? "txt" :
138 $ftype =~ m/^(utf-8 unicode|iso-\d+)( english)? text/i ? "txt" :
139 $ftype =~ m/^xml doc/i ? "xml" :
140 $ftype =~ m/^\w+ compress/i ? "bin" :
141 "bin" ;
142 # \w+ archive
143 # \w+ image
144 # ...
146 $ext ||= "txt";
147 exists $fh{$opt_h}{$ext} or $opt_h = "text";
148 exists $fh{$opt_h}{$ext} or $ext = "txt";
149 my $ref = $fh{$opt_h}{$ext};
150 ref $ref or $ref = $fh{$opt_h}{$ref};
152 $opt_v and warn "[ @$ref ] $file\n";
154 sub which {
155 (my $cmd = shift) =~ s/\s.*//; # Only the command. Discard arguments here
156 foreach my $path (split m/:+/, $ENV{PATH}) {
157 -x "$path/$cmd" and return "$path/$cmd";
159 return 0;
160 } # which
162 my $cmd = "cat -ve";
163 foreach my $c (@$ref) {
164 if (ref $c) {
165 $c->($file);
166 exit;
169 my $cp = which ($c) or next;
170 $cmd = $c;
171 last;
174 my @cmd = split m/ +/ => $cmd;
175 grep { s/%f\b/$file/ } @cmd or push @cmd, $file;
176 #$cmd =~ s/%f\b/$file/g or $cmd .= " $file";
177 $opt_v and say "@cmd";
178 exec @cmd;