source: gsdl/trunk/bin/script/gsConvert.pl@ 20933

Last change on this file since 20933 was 20933, checked in by oranfry, 14 years ago

modifications to environment vars LD_LIBRARY_PATH and PATH relating to wvWare on linux to be done in a narrower scope. this also fixes a probable bug which would have stopped the newer wvWare being used

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 44.4 KB
RevLine 
[1445]1#!/usr/bin/perl -w
2
3###########################################################################
4#
[2032]5# gsConvert.pl -- convert documents to HTML or TEXT format
[1445]6#
7# A component of the Greenstone digital library software
8# from the New Zealand Digital Library Project at the
9# University of Waikato, New Zealand.
10#
[3013]11# Copyright (C) 1999-2002 New Zealand Digital Library Project
[1445]12#
13# This program is free software; you can redistribute it and/or modify
14# it under the terms of the GNU General Public License as published by
15# the Free Software Foundation; either version 2 of the License, or
16# (at your option) any later version.
17#
18# This program is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21# GNU General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write to the Free Software
25# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26#
27###########################################################################
28
29# gsConvert.pl converts documents in a range of formats to HTML or TEXT
[2755]30# by exploiting third-party programs. The sources of these are usually found
31# in the $GSDLHOME/packages directory, and the executables should live in
32# $GSDLHOME/bin/$GSDLOS (which is on the search path).
[1445]33#
[3013]34# Currently, we can convert the following formats by using external
35# conversion utilities:
36# Microsoft Word (versions 2,6,7 [==95?], 8[==97?], 9[==2000?]), RTF,
37# Adobe PDF, PostScript, MS PowerPoint (95 and 97), and MS Excel (95 and 97).
[2032]38#
[3013]39# We can try to convert any file to text with a perl implementation of the
40# UNIX strings command.
41#
[2032]42# We try to convert Postscript files to text using "gs" which is often on
[2755]43# *nix machines. We fall back to performing weak text extraction by using
44# regular expressions.
[1445]45
46BEGIN {
47 die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
48 unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
49}
50
51use parsargv;
52use util;
53use Cwd;
54use File::Basename;
55
[2755]56# Are we running on WinNT or Win2000 (or later)?
57my $is_winnt_2000=eval {require Win32; return (Win32::IsWinNT()); return 0;};
58if (!defined($is_winnt_2000)) {$is_winnt_2000=0;}
[1445]59
[3350]60my $use_strings;
[3720]61my $pdf_complex;
[4103]62my $pdf_nohidden;
[3720]63my $pdf_zoom;
64my $pdf_ignore_images;
[10451]65my $pdf_allow_images_only;
[10282]66my $windows_scripting;
[3350]67
[1445]68sub print_usage
69{
[1970]70 print STDERR "\n";
71 print STDERR "gsConvert.pl: Converts documents in a range of formats to html\n";
72 print STDERR " or text using third-party programs.\n\n";
73 print STDERR " usage: $0 [options] filename\n";
[3400]74 print STDERR " options:\n\t-type\tdoc|dot|pdf|ps|ppt|rtf|xls\t(input file type)\n";
[2755]75 print STDERR "\t-errlog\t<filename>\t(append err messages)\n";
[17195]76 print STDERR "\t-output\tauto|html|text|pagedimage_jpg|pagedimage_gif|pagedimage_png\t(output file type)\n";
[2755]77 print STDERR "\t-timeout\t<max cpu seconds>\t(ulimit on unix systems)\n";
[3720]78 print STDERR "\t-use_strings\tuse strings to extract text if conversion fails\n";
[10282]79 print STDERR "\t-windows_scripting\tuse windows script when converting Microsoft Word and PPT via VB script\n";
[3720]80 print STDERR "\t-pdf_complex\tuse complex output when converting PDF to HTML\n";
[4103]81 print STDERR "\t-pdf_nohidden\tDon't attempt to extract hidden text from PDF files\n";
[3720]82 print STDERR "\t-pdf_ignore_images\tdon't attempt to extract images when\n";
83 print STDERR "\t\tconverting PDF to HTML\n";
[10451]84 print STDERR "\t-pdf_allow_images_only\tallow images only (continue even if no text is present when converting to HTML)\n";
[3720]85 print STDERR "\t-pdf_zoom\tfactor by which to zoom PDF (only useful if\n";
86 print STDERR "\t\t-pdf_complex is set\n";
[1445]87 exit(1);
88}
89
[2755]90my $faillogfile="";
[3538]91my $timeout=0;
[1445]92
93sub main
94{
95 my (@ARGV) = @_;
[3538]96 my ($input_type,$output_type,$verbose);
[1960]97
[1445]98 # read command-line arguments
99 if (!parsargv::parse(\@ARGV,
[3400]100 'type/(doc|dot|pdf|ps|ppt|rtf|xls)/', \$input_type,
[2755]101 '/errlog/.*/', \$faillogfile,
[17194]102 'output/(auto|html|text|pagedimage).*/', \$output_type,
[1692]103 'timeout/\d+/0',\$timeout,
[10282]104 'verbose/\d+/0', \$verbose,
[3720]105 'use_strings', \$use_strings,
[10282]106 'windows_scripting',\$windows_scripting,
[3720]107 'pdf_complex', \$pdf_complex,
[9482]108 'pdf_ignore_images', \$pdf_ignore_images,
[10451]109 'pdf_allow_images_only', \$pdf_allow_images_only,
[4103]110 'pdf_nohidden', \$pdf_nohidden,
[3720]111 'pdf_zoom/\d+/2', \$pdf_zoom
112 ))
[1445]113 {
114 print_usage();
115 }
[12704]116
[1445]117 # Make sure the input file exists and can be opened for reading
118 if (scalar(@ARGV!=1)) {
119 print_usage();
120 }
[1928]121
[1445]122 my $input_filename = $ARGV[0];
123 if (!-r $input_filename) {
124 print STDERR "Error: unable to open $input_filename for reading\n";
125 exit(1);
126 }
127
128 # Deduce filenames
129 my ($tailname,$dirname,$suffix)
[2241]130 = File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
131 my $output_filestem = &util::filename_cat($dirname, "$tailname");
[1445]132
133 if ($input_type eq "")
134 {
[2241]135 $input_type = lc (substr($suffix,1,length($suffix)-1));
[1445]136 }
137
138 # Change to temporary working directory
139 my $stored_dir = cwd();
140 chdir ($dirname) || die "Unable to change to directory $dirname";
[10357]141
[1445]142 # Select convert utility
143 if (!defined $input_type) {
144 print STDERR "Error: No filename extension or input type defined\n";
145 exit(1);
146 }
[3400]147 elsif ($input_type eq "doc" || $input_type eq "dot") {
[1445]148 print &convertDOC($input_filename, $output_filestem, $output_type);
149 print "\n";
150 }
[1684]151 elsif ($input_type eq "rtf") {
152 print &convertRTF($input_filename, $output_filestem, $output_type);
153 print "\n";
154 }
[1445]155 elsif ($input_type eq "pdf") {
156 print &convertPDF($dirname, $input_filename, $output_filestem, $output_type);
157 print "\n";
158 }
159 elsif ($input_type eq "ps") {
160 print &convertPS($input_filename, $output_filestem, $output_type);
161 print "\n";
162 }
[2977]163 elsif ($input_type eq "ppt") {
164 print &convertPPT($input_filename, $output_filestem, $output_type);
165 print "\n";
166 }
[2991]167 elsif ($input_type eq "xls") {
168 print &convertXLS($input_filename, $output_filestem, $output_type);
169 print "\n";
170 }
[1445]171 else {
172 print STDERR "Error: Unable to convert type '$input_type'\n";
173 exit(1);
174 }
175
176 # restore to original working directory
177 chdir ($stored_dir) || die "Unable to return to directory $stored_dir";
178
179}
180
181&main(@ARGV);
182
183
184
[2241]185# Document-type conversion functions
[1445]186#
187# The following functions attempt to convert documents from their
188# input type to the specified output type. If no output type was
189# given, then they first attempt HTML, and then TEXT.
190#
191# Each returns the output type ("html" or "text") or "fail" if no
192# conversion is possible.
193
194# Convert a Microsoft word document
195
196sub convertDOC {
197 ($input_filename, $output_filestem, $output_type) = @_;
198
[1654]199 # Many .doc files are not in fact word documents!
200 my $realtype = &find_docfile_type($input_filename);
201
[1734]202 if ($realtype eq "word6" || $realtype eq "word7" || $realtype eq "word8") {
[1654]203 return &convertWord678($input_filename, $output_filestem, $output_type);
204 } elsif ($realtype eq "rtf") {
205 return &convertRTF($input_filename, $output_filestem, $output_type);
206 } else {
207 return &convertAnything($input_filename, $output_filestem, $output_type);
208 }
209}
210
211# Convert a Microsoft word 6/7/8 document
212
213sub convertWord678 {
214 ($input_filename, $output_filestem, $output_type) = @_;
215
[1445]216 my $success = 0;
[16435]217 if (!$output_type || ($output_type =~ m/html/i)){
[10282]218 if ($windows_scripting) {
219 $success = &native_doc_to_html($input_filename, $output_filestem);
220 }
221 else {
222 $success = &doc_to_html($input_filename, $output_filestem);
223 }
[1445]224 if ($success) {
[10282]225 return "html";
[1445]226 }
227 }
[1654]228 return &convertAnything($input_filename, $output_filestem, $output_type);
229}
230
231
232# Convert a Rich Text Format (RTF) file
233
234sub convertRTF {
235 ($input_filename, $output_filestem, $output_type) = @_;
236
237 my $success = 0;
238
239 # Attempt specialised conversion to HTML
[16435]240 if (!$output_type || ($output_type =~ m/html/i)) {
[12704]241
242 if ($windows_scripting) {
243 $success = &native_doc_to_html($input_filename, $output_filestem);
244 }
245 else {
246 $success = &rtf_to_html($input_filename, $output_filestem);
247 }
[1654]248 if ($success) {
249 return "html";
250 }
251 }
252
[2755]253# rtf is so ugly that's it's not worth running strings over.
254# One day I'll write some quick'n'dirty regexps to try to extract text - jrm21
255# return &convertAnything($input_filename, $output_filestem, $output_type);
256 return "fail";
[1654]257}
258
259
260# Convert an unidentified file
261
262sub convertAnything {
263 ($input_filename, $output_filestem, $output_type) = @_;
264
265 my $success = 0;
[10464]266
[1445]267 # Attempt simple conversion to HTML
[16435]268 if (!$output_type || ($output_type =~ m/html/i)) {
[1445]269 $success = &any_to_html($input_filename, $output_filestem);
270 if ($success) {
271 return "html";
272 }
273 }
274
275 # Convert to text
[16435]276 if (!$output_type || ($output_type =~ m/text/i)) {
[2241]277 $success = &any_to_text($input_filename, $output_filestem);
[1445]278 if ($success) {
279 return "text";
280 }
281 }
282 return "fail";
283}
284
285
[1654]286
[1445]287# Convert an Adobe PDF document
288
289sub convertPDF {
[2755]290 my ($dirname, $input_filename, $output_filestem, $output_type) = @_;
[1445]291
292 my $success = 0;
[10357]293 $output_type =~ s/.*\-(.*)/$1/i;
294 # Attempt coversion to Image
[16435]295 if ($output_type =~ m/jp?g|gif|png/i) {
[17329]296 $success = &pdfps_to_img($dirname, $input_filename, $output_filestem, $output_type);
[10357]297 if ($success){
298 return "item";
299 }
300 }
[1445]301
302 # Attempt conversion to HTML
[16435]303 if (!$output_type || ($output_type =~ m/html/i)) {
[1445]304 $success = &pdf_to_html($dirname, $input_filename, $output_filestem);
305 if ($success) {
306 return "html";
307 }
308 }
309
310 # Attempt conversion to TEXT
[16435]311 if (!$output_type || ($output_type =~ m/text/i)) {
[2117]312 $success = &pdf_to_text($dirname, $input_filename, $output_filestem);
[1445]313 if ($success) {
314 return "text";
315 }
316 }
317
318 return "fail";
319
320}
321
322
323# Convert an Adobe PostScript document
324
325sub convertPS {
326 ($input_filename, $output_filestem, $output_type) = @_;
327
328 my $success = 0;
[10534]329 $output_type =~ s/.*\-(.*)/$1/i;
330 # Attempt coversion to Image
[16435]331 if ($output_type =~ m/jp?g|gif|png/i) {
[17329]332 $success = &pdfps_to_img($dirname, $input_filename, $output_filestem, $output_type);
[10534]333 if ($success){
334 return "item";
335 }
336 }
[1445]337
338 # Attempt conversion to TEXT
[16435]339 if (!$output_type || ($output_type =~ m/text/i)) {
[1445]340 $success = &ps_to_text($input_filename, $output_filestem);
341 if ($success) {
342 return "text";
343 }
344 }
345 return "fail";
346}
347
348
[2977]349sub convertPPT {
350 my ($input_filename, $output_filestem, $output_type) = @_;
[10357]351 my $success = 0;
[2977]352
[10282]353 my $ppt_convert_type = "";
[16435]354 #if (!$output_type || $windows_scripting || ($output_type !~ m/html/i) || ($output_type !~ m/text/i)){
355 if ($windows_scripting && ($output_type !~ m/html/i) && ($output_type !~ m/text/i)){
356 if ($output_type =~ m/gif/i) {
[10282]357 $ppt_convert_type = "-g";
[16435]358 } elsif ($output_type =~ m/jp?g/i){
[10282]359 $ppt_convert_type = "-j";
[16435]360 } elsif ($output_type =~ m/png/i){
[10282]361 $ppt_convert_type = "-p";
362 }
363 my $vbScript = &util::filename_cat($ENV{'GSDLHOME'}, "bin",
364 $ENV{'GSDLOS'}, "pptextract");
[16435]365 $vbScript = "pptextract" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
[10282]366
367 $cmd = "";
[10357]368 if ($timeout) {$cmd = "ulimit -t $timeout;";}
[10282]369 # if the converting directory has already existed
370 if (-d $output_filestem) {
371 print STDERR "**The conversion directory has existed\n";
372 return "item";
373 } else {
[10521]374 $cmd .= "$vbScript $ppt_convert_type \"$input_filename\" \"$output_filestem\"";
[10282]375 $cmd .= " 2>\"$output_filestem.err\""
[16435]376 if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
[10282]377 if (system($cmd) !=0) {
378 print STDERR "Powerpoint VB Scripting convert failed\n";
379 } else {
380 return "item";
381 }
382 }
[16435]383 } elsif (!$output_type || ($output_type =~ m/html/i)) {
[10282]384 # Attempt conversion to HTML
[16435]385 #if (!$output_type || ($output_type =~ m/html/i)) {
[2977]386 # formulate the command
387 $cmd = "";
388 $cmd .= "perl -S ppttohtml.pl ";
389 $cmd .= " \"$input_filename\" \"$output_filestem.html\"";
390 $cmd .= " 2>\"$output_filestem.err\""
[16435]391 if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
[10357]392
[2977]393 # execute the command
394 $!=0;
395 if (system($cmd)!=0)
396 {
[2991]397 print STDERR "Powerpoint 95/97 converter failed $!\n";
[2977]398 } else {
399 return "html";
400 }
[10464]401 }
[2977]402
403 $success = &any_to_text($input_filename, $output_filestem);
404 if ($success) {
405 return "text";
406 }
[10464]407
[2977]408 return "fail";
409}
410
411
[2991]412sub convertXLS {
413 my ($input_filename, $output_filestem, $output_type) = @_;
[2977]414
[2991]415 my $success = 0;
[2977]416
[2991]417 # Attempt conversion to HTML
[16435]418 if (!$output_type || ($output_type =~ m/html/i)) {
[2991]419 # formulate the command
420 $cmd = "";
421 $cmd .= "perl -S xlstohtml.pl ";
422 $cmd .= " \"$input_filename\" \"$output_filestem.html\"";
423 $cmd .= " 2>\"$output_filestem.err\""
[16435]424 if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
[2991]425
426
427 # execute the command
428 $!=0;
429 if (system($cmd)!=0)
430 {
431 print STDERR "Excel 95/97 converter failed $!\n";
432 } else {
433 return "html";
434 }
435 }
[2977]436
[2991]437 $success = &any_to_text($input_filename, $output_filestem);
438 if ($success) {
439 return "text";
440 }
441
442 return "fail";
443}
444
445
446
[1654]447# Find the real type of a .doc file
448#
[2012]449# We seem to have a lot of files with a .doc extension that are .rtf
[1654]450# files or Word 5 files. This function attempts to tell the difference.
451sub find_docfile_type {
452 ($input_filename) = @_;
453
454 open(CHK, "<$input_filename");
[1734]455 binmode(CHK);
[1654]456 my $line = "";
457 my $first = 1;
458
459 while (<CHK>) {
460
461 $line = $_;
[1960]462
[1654]463 if ($first) {
464 # check to see if this is an rtf file
[16435]465 if ($line =~ m/^\{\\rtf/) {
[1654]466 close(CHK);
467 return "rtf";
468 }
[2755]469 $first = 0;
[1654]470 }
471
[1734]472 # is this is a word 6/7/8 document?
[16435]473 if ($line =~ m/Word\.Document\.([678])/) {
[1654]474 close(CHK);
[1734]475 return "word$1";
[1654]476 }
477
478 }
479
480 return "unknown";
481}
482
483
[1734]484# Specific type-to-type conversions
[1445]485#
486# Each of the following functions attempts to convert a document from
[2755]487# a specific format to another. If they succeed they return 1 and leave
[1445]488# the output document(s) in the appropriate place; if they fail they
489# return 0 and delete any working files.
490
491
492# Attempt to convert a word document to html with the wv program
493sub doc_to_html {
494 ($input_filename, $output_filestem) = @_;
495
[20933]496 my $wvWare = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wvWare");
[1928]497
[20933]498 if ( -d "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}/wv" && $ENV{'GSDLOS'} eq "linux" ) {
499 $ENV{'PATH'} = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}/wv/bin:$ENV{'PATH'}";
500 $ENV{'LD_LIBRARY_PATH'} = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}/wv/lib:$ENV{'LD_LIBRARY_PATH'}";
501 $wvWare = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wv", "bin", "wvWare");
502 }
503
[2241]504 # don't include path on windows (to avoid having to play about
505 # with quoting when GSDLHOME might contain spaces) but assume
506 # that the PATH is set up correctly
[16435]507 $wvWare = "wvWare" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
[2241]508
[2512]509 my $wv_conf = &util::filename_cat($ENV{'GSDLHOME'}, "etc",
[2574]510 "packages", "wv", "wvHtml.xml");
[1928]511
[15120]512 # Added the following to work with replace_srcdoc_with_html.pl:
513 # Make wvWare put any associated (image) files of the word doc into
514 # folder docname-without-extention_files. This folder should be at
515 # the same level as the html file generated from the doc.
516 # wvWare will take care of proper interlinking.
517
518 # This step is necessary for replace_srcdoc_with_html.pl which will
519 # move the html and associated files into the import folder. We
520 # want to ensure that the associated files won't overwrite similarly
521 # named items already in import. Hence we put them in a folder first
522 # (to which the html links properly) and that will allow
523 # replace_srcdoc_with_html.pl to move them safely to /import.
524
525 # To do all this, we need to use wvWare's --dir and --basename options
526 # where dir is the full path to the image folder directory and
527 # basename is the full path to the image folder appended to the name
528 # which is to be prepended to every image file:
529 # eg. if the images were to have names like sample0.jpg to sampleN.jpg,
530 # then the basename is "/full/path/to/imgdir/sample".
531 # In this case, basename is the full path to and name of the document.
532 # HOWEVER: basename always takes full path, not relative url, so
533 # the greenstone browser is unable to display the images (absolute paths
534 # cause it to give an "external link" message)
535 # See http://osdir.com/ml/lib.wvware.devel/2002-11/msg00014.html
536 # and http://rpmfind.net/linux/RPM/freshmeat/rpms/wv/wv-0.5.44-1.i386.html
537 # "added --dir option to wvHtml so that pictures can be placed in
538 # a seperate directory"
539 # "running wvWare through IMP to view word documents as html. It gets
540 # invoked like this:
541 # wvWare --dir=/tmp-wvWare --basename=/tmp-wvWare/img$$- $tmp_word >$tmp_output"
542
543 # toppath is the folder where html is generated
544 # docname is the name (without extension) of the html to be generated
545 # suffix (extension) is thrown away
546 my ($docname, $toppath)
547 = &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
548
549 # We want the image folder generated to have the same name as windows
550 # would generate ($windows_scripting) when it converts from word to html.
551 # That is, foldername=docname_files
552 my $assoc_dir = &util::filename_cat($toppath, $docname."_files");
553 #print "assoc_dir: ".$assoc_dir."\n"; # same as "$output_filestem._files"
554
555 # ensure this image directory exists
556 # if it exists already, just delete and recreate
557 if(-e $assoc_dir) {
558 &util::rm_r($assoc_dir);
559 }
560 &util::mk_dir($assoc_dir);
561
562 # the images are all going to be called image0, image1,..., imageN
563 my $img_basenames = &util::filename_cat($assoc_dir, $docname);
564
565 #print STDERR "****toppath: $toppath\n****docname: $docname\n;
566 #print STDERR "****img_basenames: $img_basenames\n" if($img_basenames);
567 #print STDERR "****assoc_dir: $assoc_dir\n" if($assoc_dir);
568
[2241]569 my $cmd = "";
[1692]570 if ($timeout) {$cmd = "ulimit -t $timeout;";}
[15120]571 # wvWare's --dir and --basename options for image directory.
572 # Replaced the next line with the *2 lines* following it:
573 # $cmd .= "$wvWare --charset utf-8 --config \"$wv_conf\"";
574 $cmd .= "$wvWare --dir \"$assoc_dir\" --basename \"$img_basenames\"";
575 $cmd .= " --charset utf-8 --config \"$wv_conf\"";
[2241]576 $cmd .= " \"$input_filename\" > \"$output_filestem.html\"";
[15120]577
[2241]578 # redirecting STDERR is a bad idea on windows 95/98
579 $cmd .= " 2> \"$output_filestem.err\""
[16435]580 if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
[1445]581 # execute the command
[2755]582 $!=0;
[2060]583 if (system($cmd)!=0)
[1445]584 {
[2755]585 print STDERR "Error executing wv converter:$!\n";
586 if (-s "$output_filestem.err") {
587 open (ERRFILE, "<$output_filestem.err");
588
589 my $write_to_fail_log=0;
590 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
591 {$write_to_fail_log=1;}
592
593 my $line;
594 while ($line=<ERRFILE>) {
[16435]595 if ($line =~ m/\w/) {
[2755]596 print STDERR "$line";
597 print FAILLOG "$line" if ($write_to_fail_log);
598 }
599 if ($line !~ m/startup error/) {next;}
600 print STDERR " (given an invalid .DOC file?)\n";
601 print FAILLOG " (given an invalid .DOC file?)\n"
602 if ($write_to_fail_log);
603
604 } # while ERRFILE
605 close FAILLOG if ($write_to_fail_log);
606 }
607 return 0; # we can try any_to_text
[1445]608 }
[1578]609
[1445]610 # Was the conversion successful?
[2241]611
[15120]612 if (-s "$output_filestem.html") { # if file has non-zero size (i.e. it has contents)
[1445]613 open(TMP, "$output_filestem.html");
614 $line = <TMP>;
615 close(TMP);
[16435]616 if ($line && $line =~ m/DOCTYPE HTML/) {
[15120]617 &util::rm("$output_filestem.err") if -e "$output_filestem.err";
618
619 # Inserted this code to remove the images directory if it was still empty after
620 # the html was generated (in case there were no images in the word document)
[16435]621 if (&util::is_dir_empty($assoc_dir)) {
[15152]622 #print STDERR "***gsConvert.pl: Image dir $assoc_dir is empty, removing***\n";
[15120]623 &util::rm_r($assoc_dir);
624 } else { # there was an image folder (it was generated)
625 # Therefore, the html file generated contains absolute links to the images
[16435]626 # Replace them with relative links instead, so the folder can be moved elsewhere
[15152]627 &make_links_to_assocdir_relative($toppath, $docname, "$output_filestem.html", $assoc_dir, $docname."_files");
[15120]628 }
[1445]629 return 1;
630 }
631 }
[2755]632
633 # If here, an error of some sort occurred
634 &util::rm("$output_filestem.html") if -e "$output_filestem.html";
635 if (-e "$output_filestem.err") {
636 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile"))) {
637 open (ERRLOG,"$output_filestem.err");
638 while (<ERRLOG>) {print FAILLOG $_;}
639 close FAILLOG;
640 close ERRLOG;
641 }
642 &util::rm("$output_filestem.err");
643 }
644
[1445]645 return 0;
646}
647
[15120]648# Method to work with doc_to_html - Word docs might contain images.
649# When such word docs are converted with wvWare, we make it generate a
650# <filename>_files folder with the associated images, while the html file
651# <filename> refers to the images using absolute paths to <filename>_files.
652# This method reads in that html file and replaces all the absolute paths to
653# the images in <filename>_files with the relative paths to the images from
654# that folder. (I.e. with <filename>_files/<imagename.ext>).
655sub make_links_to_assocdir_relative{
656 # toppath is the top-level folder in which the html file we're going to be fixing resides
657 # docname is just the name (without extension) of the html file
658 # html_file is the full path to the html file: /full/path/docname.html
659 # assoc_dir_path is toppath/docname_files
660 # assoc_dirname is the directory name of the folder with associated imgs: docname_files
661 my ($toppath, $docname, $html_file, $assoc_dir_path, $assoc_dirname) = @_;
[10357]662
[15120]663 # 1. Read all the contents of the html into a string
664 # open the original file for reading
665 unless(open(FIN, "<$html_file")) {
[15168]666 print STDERR "gsConvert.pl: Unable to open $html_file for reading absolute urls...ERROR: $!\n";
[15152]667 return 0;
[15120]668 }
669 # From http://perl.plover.com/local.html
670 # "It's cheaper to read the file all at once, without all the splitting and reassembling.
671 # (Some people call this slurping the file.) Perl has a special feature to support this:
672 # If the $/ variable is undefined, the <...> operator will read the entire file all at once"
[15152]673 my $html_contents;
674 {
675 local $/ = undef; # Read entire file at once
676 $html_contents = <FIN>; # Now file is read in as one single 'line'
677 }
[15120]678 close(FIN); # close the file
[15152]679 #print STDERR $html_contents;
[15120]680
681 # 2. Replace (substitute) *all* ocurrences of the assoc_dir_path in a hrefs and img src
682 # values with assoc_dirname
683 # At the end: g means substitute all occurrences (global), while s at the end means treat
684 # all new lines as a regular space. This interacts with g to consider all the lines
685 # together as a single line so that multi-occurrences can be replaced.
[15152]686
687 # we can't just replace $assoc_dir_path with $assoc_dir
688 # $assoc_dir_path represents a regular expression that needs to be replaced
[16435]689 # if it contains ., -, [, ], or Windows style backslashes in paths -- which all have special
690 # meaning in Perl regular expressions -- we need to escape these first
[15152]691 my $safe_reg_expression = $assoc_dir_path;
[16435]692 $safe_reg_expression =~ s/\\/\\\\/g;
[15152]693 $safe_reg_expression =~ s/\./\\./g;
694 $safe_reg_expression =~ s/\-/\\-/g;
695 $safe_reg_expression =~ s/\[/\\[/g;
696 $safe_reg_expression =~ s/\]/\\]/g;
697 $safe_reg_expression =~ s/ /%20/g; # wvWare put %20 in place of space, so we need to change our prefix to match
698
[15120]699 # The following regular expression substitution looks for <a or <image, followed by any other
700 # attributes and values until it comes to the FIRST (indicated by ?) href= or src=
701 # followed by " or ' no quotes at all around path, followed by the associated folder's pathname
702 # followed by characters (for the img filename), then finally the optional closing quotes
703 # in " or ' form, followed by any other attributes and values until the first > to end the tag.
704 # The substitution: all the parts preceding associated folder's pathname are retained,
705 # the associated folder path name is replaced by associated folder directory name
706 # and the rest upto and including the closing > tag is retained.
707 # The sg at the end of the pattern match treats all of html_contents as a single line (s)
708 # and performs a global replace (g) meaning that all occurrences that match in that single line
709 # are substituted.
[15152]710 $html_contents =~ s/(<(a|img).*?(href|src)=(\"|\')?)$safe_reg_expression(.*?(\"|\')?.*?>)/$1$assoc_dirname$5/sg;
711 #$html_contents =~ s/$safe_reg_expression/$assoc_dirname/gs; # this works, used as fall-back
712 # now replace any %20 chars in filenames of href or src attributes to use literal space ' '. Calls a function for this
[16435]713 $html_contents =~ s/(<(a|img).*?(href|src)=(\"|\')?)(.*)(.*?(\"|\')?.*?>)/&post_process_assocfile_urls($1, $5, $6)/sge;
714
[16552]715 #print STDERR "****assoc_dirname: $assoc_dirname***\n";
716 #print STDERR "****safe_reg_expression: $safe_reg_expression***\n";
[15152]717
[15120]718 # delete the original file and recreate it
719 my $copy_of_filename = $html_file;
720 &util::rm($copy_of_filename); # deleted the file
721
722 # Recreate the original file for writing the updated contents
723 unless(open(FOUT, ">$html_file")) { # open it as a new file for writing
[15168]724 print STDERR "gsConvert.pl: Unable to open $html_file for writing relative links...ERROR: $!\n";
[15152]725 return 0;
[15120]726 }
[16435]727
[15120]728 # write out the updated contents and close the file
729 print FOUT $html_contents;
730 close(FOUT);
[15152]731 return 1;
[15120]732}
733
[16435]734# Utility routine to make sure HTML plugin gets img src/href link pathnames that contain
735# url slashes (/) instead of windows-style backwards slashes, and to convert all %20
[16899]736# introduced in link pathnames by wvWare into space again. Converts all percent signs
737# introduced by URL encoding filenames generated into %25 in these url links referencing them
[16435]738sub post_process_assocfile_urls
[15120]739{
[15152]740 my ($pre, $text, $post) = @_;
741
[19763]742 $text =~ s/%20/ /g; # Convert %20s to space and not underscore since underscores mess with incremental rebuild
743 # $text =~ s/%20/_/g; # reinstated this line, since we no longer replace spaces with %20. We replace them with underscores
[16435]744 $text =~ s/\\/\//g;
[16899]745 $text =~ s/%/%25/g;
[15152]746
747 return "$pre$text$post";
[15120]748}
749
[10282]750# Attempt to convert a word document to html with the word2html scripting program
751sub native_doc_to_html {
752 ($input_filename, $output_filestem) = @_;
[1445]753
[10282]754 my $vbScript = &util::filename_cat($ENV{'GSDLHOME'}, "bin",
755 $ENV{'GSDLOS'}, "word2html");
756
[16435]757 $vbScript = "word2html" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
[10445]758 if (-e "$output_filestem.html") {
759 print STDERR "*** The conversion file has existed\n";
760 return 1;
761 }
[10282]762
763 my $cmd = "";
764 if ($timeout) {$cmd = "ulimit -t $timeout;";}
765 #$cmd .= "$vbScript \"$input_filename\" \"$output_filestem.html\"";
[10445]766 #$cmd .= "$vbScript $input_filename $output_filestem.html";
[10521]767 $cmd .= "$vbScript \"$input_filename\" \"$output_filestem.html\"";
[10445]768
[10282]769 # redirecting STDERR
770 $cmd .= " 2> \"$output_filestem.err\""
[16435]771 if ($ENV {'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
[10282]772
773 # execute the command
774 $!=0;
775 if (system($cmd)!=0)
776 {
777 print STDERR "Error executing word2Html converter:$!\n";
778 if (-s "$output_filestem.err") {
779 open (ERRFILE, "<$output_filestem.err");
780
781 my $write_to_fail_log=0;
782 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
783 {$write_to_fail_log=1;}
784
785 my $line;
786 while ($line=<ERRFILE>) {
[16435]787 if ($line =~ m/\w/) {
[10282]788 print STDERR "$line";
789 print FAILLOG "$line" if ($write_to_fail_log);
790 }
791 if ($line !~ m/startup error/) {next;}
792 print STDERR " (given an invalid .DOC file?)\n";
793 print FAILLOG " (given an invalid .DOC file?)\n"
794 if ($write_to_fail_log);
795
796 } # while ERRFILE
797 close FAILLOG if ($write_to_fail_log);
798 }
799 return 0; # we can try any_to_text
800 }
801
802 # Was the conversion successful?
803 if (-s "$output_filestem.html") {
804 open(TMP, "$output_filestem.html");
805 $line = <TMP>;
806 close(TMP);
[16435]807 if ($line && $line =~ m/html/) {
[10282]808 &util::rm("$output_filestem.err") if -e "$output_filestem.err";
809 return 1;
810 }
811 }
812
813 # If here, an error of some sort occurred
814 &util::rm("$output_filestem.html") if -e "$output_filestem.html";
815 if (-e "$output_filestem.err") {
816 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile"))) {
817 open (ERRLOG,"$output_filestem.err");
818 while (<ERRLOG>) {print FAILLOG $_;}
819 close FAILLOG;
820 close ERRLOG;
821 }
822 &util::rm("$output_filestem.err");
823 }
824 return 0;
825}
826
[1654]827# Attempt to convert an RTF document to html with rtftohtml
828
829sub rtf_to_html {
[2241]830 my ($input_filename, $output_filestem) = @_;
[1654]831
832 # formulate the command
[1692]833 $cmd = "";
834 if ($timeout) {$cmd = "ulimit -t $timeout;";}
[2574]835 $cmd .= "rtftohtml";
[10282]836 #$cmd .= "rtf-converter";
[1654]837
[3246]838 $cmd .= " -o \"$output_filestem.html\" \"$input_filename\"";
[2574]839
840 $cmd .= " 2>\"$output_filestem.err\""
[16435]841 if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
[2574]842
843
[1654]844 # execute the command
[2755]845 $!=0;
[2060]846 if (system($cmd)!=0)
[1654]847 {
[2755]848 print STDERR "Error executing rtf converter $!\n";
[2656]849 # don't currently bother printing out error log...
850 # keep going, in case it still created an HTML file...
[1654]851 }
852
853 # Was the conversion successful?
[2755]854 my $was_successful=0;
[2656]855 if (-s "$output_filestem.html") {
[2755]856 # make sure we have some content other than header
857 open (HTML, "$output_filestem.html"); # what to do if fail?
858 my $line;
859 my $past_header=0;
860 while ($line=<HTML>) {
861
862 if ($past_header == 0) {
[16435]863 if ($line =~ m/<body>/) {$past_header=1;}
[2755]864 next;
865 }
866
867 $line =~ s/<[^>]+>//g;
[16435]868 if ($line =~ m/\w/ && $past_header) { # we found some content...
[2755]869 $was_successful=1;
870 last;
871 }
872 }
873 close HTML;
[1654]874 }
[2574]875
[2755]876 if ($was_successful) {
877 &util::rm("$output_filestem.err")
878 if (-e "$output_filestem.err");
879 # insert the (modified) table of contents, if it exists.
880 if (-e "${output_filestem}_ToC.html") {
881 &util::mv("$output_filestem.html","$output_filestem.src");
882 my $open_failed=0;
883 open HTMLSRC, "$output_filestem.src" || ++$open_failed;
884 open TOC, "${output_filestem}_ToC.html" || ++$open_failed;
885 open HTML, ">$output_filestem.html" || ++$open_failed;
886
887 if ($open_failed) {
888 close HTMLSRC;
889 close TOC;
890 close HTML;
891 &util::mv("$output_filestem.src","$output_filestem.html");
892 return 1;
893 }
894
895 # print out header info from src html.
[16435]896 while (defined($_ = <HTMLSRC>) && $_ =~ m/\w/) {
[2755]897 print HTML "$_";
898 }
899
900 # print out table of contents, making links relative
901 <TOC>; <TOC>; # ignore first 2 lines
902 print HTML scalar(<TOC>); # line 3 = "<ol>\n"
903 my $line;
904 while ($line=<TOC>) {
905 $line =~ s@</body></html>$@@ ; # only last line has this
906 # make link relative
907 $line =~ s@href=\"[^\#]+@href=\"@;
908 print HTML $line;
909 }
910 close TOC;
911
912 # rest of html src
913 while (<HTMLSRC>) {
914 print HTML $_;
915 }
916 close HTMLSRC;
917 close HTML;
918
919 &util::rm("${output_filestem}_ToC.html");
920 &util::rm("${output_filestem}.src");
921 }
922 # we don't yet do anything with footnotes ($output_filestem_fn.html) :(
923 return 1; # success
924 }
925
926 if (-e "$output_filestem.err") {
927 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
928 {
929 print FAILLOG "Error - rtftohtml - couldn't extract text\n";
[10282]930 #print FAILLOG "Error - rtf-converter - couldn't extract text\n";
[2755]931 print FAILLOG " (rtf file might be too recent):\n";
932 open (ERRLOG, "$output_filestem.err");
933 while (<ERRLOG>) {print FAILLOG $_;}
934 close ERRLOG;
935 close FAILLOG;
936 }
937 &util::rm("$output_filestem.err");
938 }
939
[2656]940 &util::rm("$output_filestem.html") if (-e "$output_filestem.html");
941
[1654]942 return 0;
943}
944
945
[1445]946# Convert a pdf file to html with the pdftohtml command
947
948sub pdf_to_html {
[2755]949 my ($dirname, $input_filename, $output_filestem) = @_;
[1445]950
[1692]951 $cmd = "";
952 if ($timeout) {$cmd = "ulimit -t $timeout;";}
[3720]953 $cmd .= "perl -S pdftohtml.pl -zoom $pdf_zoom";
954 $cmd .= " -c" if ($pdf_complex);
955 $cmd .= " -i" if ($pdf_ignore_images);
[10451]956 $cmd .= " -a" if ($pdf_allow_images_only);
[4103]957 $cmd .= " -hidden" unless ($pdf_nohidden);
[1928]958 $cmd .= " \"$input_filename\" \"$output_filestem\"";
[2755]959
[16435]960 if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000) {
[2755]961 $cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
962 } else {
963 $cmd .= " > \"$output_filestem.err\"";
964 }
965
[2117]966 $!=0;
[2241]967
[2656]968 my $retval=system($cmd);
969 if ($retval!=0)
[1445]970 {
[2755]971 print STDERR "Error executing pdftohtml.pl";
[2117]972 if ($!) {print STDERR ": $!";}
973 print STDERR "\n";
[1445]974 }
975
[1692]976 # make sure the converter made something
[2656]977 if ($retval!=0 || ! -s "$output_filestem.html")
[1692]978 {
979 &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
[2656]980 # print out the converter's std err, if any
981 if (-s "$output_filestem.err") {
[1692]982 open (ERRLOG, "$output_filestem.err") || die "$!";
[2755]983 print STDERR "pdftohtml error log:\n";
[1692]984 while (<ERRLOG>) {
985 print STDERR "$_";
986 }
987 close ERRLOG;
988 }
[2656]989 &util::rm("$output_filestem.html") if (-e "$output_filestem.html");
[2755]990 if (-e "$output_filestem.err") {
991 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
992 {
993 open (ERRLOG, "$output_filestem.err");
994 while (<ERRLOG>) {print FAILLOG $_;}
995 close ERRLOG;
996 close FAILLOG;
997 }
[10282]998 &util::rm("$output_filestem.err");
[2755]999 }
[1692]1000 return 0;
1001 }
[10357]1002
1003 &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
1004 &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
1005 return 1;
1006}
1007
1008# Convert a pdf file to various types of image with the convert command
1009
[17329]1010sub pdfps_to_img {
[10357]1011 my ($dirname, $input_filename, $output_filestem, $output_type) = @_;
[10401]1012
1013 # Check that ImageMagick is installed and available on the path (except for Windows 95/98)
1014 if (!($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT())) {
1015 my $result = `identify 2>&1`;
1016 if ($? == -1 || $? == 256) { # Linux and Windows return different values for "program not found"
1017 #ImageMagick is not installed, thus the convert utility is not available.
[17329]1018 print STDERR "*** ImageMagick is not installed, the convert utility is not available. Unable to convert PDF/PS to images\n";
[10401]1019 return 0;
1020 }
1021 }
1022
[10357]1023 $cmd = "";
1024 if ($timeout) {$cmd = "ulimit -t $timeout;";}
1025 $output_type =~ s/.*\_(.*)/$1/i;
[17329]1026 $cmd .= "perl -S pdfpstoimg.pl -convert_to $output_type \"$input_filename\" \"$output_filestem\"";
[16435]1027 if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000) {
[10357]1028 $cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
1029 } else {
1030 $cmd .= " > \"$output_filestem.err\"";
1031 }
1032
1033 # don't include path on windows (to avoid having to play about
1034 # with quoting when GSDLHOME might contain spaces) but assume
1035 # that the PATH is set up correctly
1036 $!=0;
1037 my $retval=system($cmd);
1038 if ($retval!=0)
1039 {
[10401]1040 print STDERR "Error executing pdftoimg.pl";
[10357]1041 if ($!) {print STDERR ": $!";}
1042 print STDERR "\n";
1043 }
1044
1045 #make sure the converter made something
1046 #if ($retval !=0) || ! -s "$output_filestem")
1047 if ($retval !=0)
1048 {
1049 &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
1050 #print out the converter's std err, if any
1051 if (-s "$output_filestem.err") {
1052 open (ERRLOG, "$output_filestem.err") || die "$!";
[17329]1053 print STDERR "pdfpstoimg error log:\n";
[10357]1054 while (<ERRLOG>) {
1055 print STDERR "$_";
1056 }
1057 close ERRLOG;
1058 }
[10534]1059 #&util::rm("$output_filestem.html") if (-e "$output_filestem.html");
[10357]1060 if (-e "$output_filestem.err") {
1061 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
1062 {
1063 open (ERRLOG, "$output_filestem.err");
1064 while (<ERRLOG>) {print FAILLOG $_;}
1065 close ERRLOG;
1066 close FAILLOG;
1067 }
1068 &util::rm("$output_filestem.err");
1069 }
1070 return 0;
1071 }
[2656]1072 &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
[1445]1073 &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
1074 return 1;
1075}
1076
1077# Convert a PDF file to text with the pdftotext command
1078
1079sub pdf_to_text {
[2755]1080 my ($dirname, $input_filename, $output_filestem) = @_;
[1445]1081
[2248]1082 my $cmd = "pdftotext \"$input_filename\" \"$output_filestem.text\"";
[2755]1083
[16435]1084 if ($ENV{'GSDLOS'} !~ m/^windows$/i) {
[2755]1085 $cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
1086 } else {
1087 $cmd .= " > \"$output_filestem.err\"";
1088 }
[1445]1089
[2060]1090 if (system($cmd)!=0)
[1445]1091 {
1092 print STDERR "Error executing $cmd: $!\n";
1093 &util::rm("$output_filestem.text") if (-e "$output_filestem.text");
1094 }
1095
[2755]1096 # make sure there is some extracted text.
1097 if (-e "$output_filestem.text") {
1098 open (EXTR_TEXT, "$output_filestem.text") || warn "open: $!";
1099 binmode(EXTR_TEXT); # just in case...
1100 my $line="";
1101 my $seen_text=0;
1102 while (($seen_text==0) && ($line=<EXTR_TEXT>)) {
[16435]1103 if ($line=~ m/\w/) {$seen_text=1;}
[2755]1104 }
1105 close EXTR_TEXT;
1106 if ($seen_text==0) { # no text was extracted
1107 print STDERR "Error: pdftotext found no text\n";
1108 &util::rm("$output_filestem.text");
1109 }
1110 }
1111
[1692]1112 # make sure the converter made something
[2656]1113 if (! -s "$output_filestem.text")
[1692]1114 {
1115 # print out the converters std err, if any
[2656]1116 if (-s "$output_filestem.err") {
[1692]1117 open (ERRLOG, "$output_filestem.err") || die "$!";
[2755]1118 print STDERR "pdftotext error log:\n";
[1692]1119 while (<ERRLOG>) {
1120 print STDERR "$_";
1121 }
1122 close ERRLOG;
1123 }
[2656]1124 # does this converter create a .out file?
1125 &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
1126 &util::rm("$output_filestem.text") if (-e "$output_filestem.text");
[2755]1127 if (-e "$output_filestem.err") {
1128 if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
1129 {
1130 open (ERRLOG,"$output_filestem.err");
1131 while (<ERRLOG>) {print FAILLOG $_;}
1132 close ERRLOG;
1133 close FAILLOG;
1134 }
1135 &util::rm("$output_filestem.err");
1136 }
[1692]1137 return 0;
1138 }
[1445]1139 &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
1140 return 1;
1141}
1142
[2012]1143# Convert a PostScript document to text
1144# note - just using "ps2ascii" isn't good enough, as it
1145# returns 0 for a postscript interpreter error. ps2ascii is just
1146# a wrapper to "gs" anyway, so we use that cmd here.
[1445]1147
1148sub ps_to_text {
[2241]1149 my ($input_filename, $output_filestem) = @_;
[1445]1150
[2241]1151 my $error = "";
1152
1153 # if we're on windows we'll fall straight through without attempting
1154 # to use gs
[16435]1155 if ($ENV{'GSDLOS'} =~ m/^windows$/i) {
[2241]1156 $error = "Windows does not support gs";
1157
1158 } else {
[3538]1159 my $cmd = "";
1160 if ($timeout) {$cmd = "ulimit -t $timeout; ";}
1161 $cmd .= "gs -q -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT -dSIMPLE -c save ";
[2241]1162 $cmd .= "-f ps2ascii.ps \"$input_filename\" -c quit > \"$output_filestem.text\"";
[10357]1163 #$cmd .= "pstotext -output \"$output_filestem.text\" $input_filename\"";
[2241]1164 $cmd .= " 2> $output_filestem.err";
1165 $!=0;
[10357]1166
[2241]1167 my $retcode=system($cmd);
1168 $retcode = $? >> 8; # see man perlfunc - system for this...
1169 # if system returns -1 | 127 (couldn't start program), look at $! for message
1170
1171 if ($retcode!=0) {if ($!) {$error=$!;} else {$error="couldn't run.\n";}}
1172 elsif (! -e "$output_filestem.text") {
1173 $error="did not create output file.\n";
[2012]1174 }
[2241]1175 else
1176 { # make sure the interpreter didn't get an error. It is technically
1177 # possible for the actual text to start with this, but....
1178 open PSOUT, "$output_filestem.text";
[16435]1179 if (<PSOUT> =~ m/^Error: (.*)/) {
[2241]1180 $error="interpreter error - \"$1\"";
1181 }
1182 close PSOUT;
1183 }
[2012]1184 }
[2241]1185
[2012]1186 if ($error ne "")
[1445]1187 {
[2755]1188 print STDERR "Warning: Error executing gs: $error\n";
[1445]1189 &util::rm("$output_filestem.text") if (-e "$output_filestem.text");
[2755]1190
1191 if ("$faillogfile" ne "" && defined(open (FAILLOG, ">>$faillogfile")))
1192 {
1193 print FAILLOG "gs - $error\n";
1194 if (-e "$output_filestem.err") {
1195 open(ERRLOG, "$output_filestem.err");
1196 while (<ERRLOG>) {print FAILLOG $_;}
1197 close ERRLOG;
1198 }
1199 close FAILLOG;
1200 }
[1445]1201 &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
[2012]1202
[2755]1203
[2012]1204 # Fine then. We'll just do a lousy job by ourselves...
[2031]1205 # Based on 5-line regexp sed script found at:
[2012]1206 # http://snark.ptc.spbu.ru/mail-archives/lout/brown/msg00003.html
1207 #
[2755]1208 print STDERR "Stripping text from postscript\n";
[2012]1209 my $errorcode=0;
1210 open (IN, "$input_filename")
1211 || ($errorcode=1, warn "Couldn't read file: $!");
1212 open (OUT, ">$output_filestem.text")
1213 || ($errorcode=1, warn "Couldn't write file: $!");
1214 if ($errorcode) {print STDERR "errors\n";return 0;}
1215
[2031]1216 my $text=""; # this is for whole .ps file...
[2755]1217 $text = join('', <IN>); # see man perlport, under "System Resources"
[2031]1218 close IN;
1219
[2447]1220 # Make sure this is a ps file...
[16435]1221 if ($text !~ m/^%!/) {
[2755]1222 print STDERR "Bad postscript header: not '%!'\n";
1223 if ($faillogfile ne "" && defined(open(FAILLOG, ">>$faillogfile")))
1224 {
1225 print FAILLOG "Bad postscript header: not '%!'\n";
1226 close FAILLOG;
1227 }
[2447]1228 return 0;
1229 }
1230
[2031]1231 # if ps has Page data, then use it to delete all stuff before it.
1232 $text =~ s/^.*?%%Page:.*?\n//s; # treat string as single line
1233
1234 # remove all leading non-data stuff
1235 $text =~ s/^.*?\(//s;
1236
1237 # remove all newline chars for easier processing
1238 $text =~ s/\n//g;
1239
1240 # Big assumption here - assume that if any co-ordinates are
1241 # given, then we are at the end of a sentence.
1242 $text =~ s/\)-?\d+\ -?\d+/\) \(\n\)/g;
1243
1244 # special characters--
1245 $text =~ s/\(\|\)/\(\ - \)/g; # j -> em-dash?
1246
1247 # ? ps text formatting (eg italics?) ?
1248 $text =~ s/Fn\(f\)/\(\{\)/g; # f -> {
1249 $text =~ s/Fn\(g\)/\(\}\)/g; # g -> }
1250 $text =~ s/Fn\(j\)/\(\|\)/g; # j -> |
1251 # default - remove the rest
1252 $text =~ s/\ ?F.\((.+?)\)/\($1\)/g;
1253
1254 # attempt to add whitespace between words...
1255 # this is based purely on observation, and may be completely wrong...
1256 $text =~ s/([^F])[defghijkuy]\(/$1 \( /g;
1257 # eg I notice "b(" is sometimes NOT a space if preceded by a
1258 # negative number.
1259 $text =~ s/\)\d+ ?b\(/\) \( /g;
1260
1261 # change quoted braces to brackets
1262 $text =~ s/([^\\])\\\(/$1\{/g;
1263 $text =~ s/([^\\])\\\)/$1\}/g ;
1264
1265 # remove everything that is not between braces
1266 $text =~ s/\)([^\(\)])+?\(//sg ;
1267
1268 # remove any Trailer eof stuff.
1269 $text =~ s/\)[^\)]*$//sg;
1270
1271 ### ligatures have special characters...
1272 $text =~ s/\\013/ff/g;
1273 $text =~ s/\\014/fi/g;
1274 $text =~ s/\\015/fl/g;
1275 $text =~ s/\\016/ffi/g;
1276 $text =~ s/\\214/fi/g;
1277 $text =~ s/\\215/fl/g;
1278 $text =~ s/\\017/\n\* /g; # asterisk?
1279 $text =~ s/\\023/\023/g; # e acute ('e)
1280 $text =~ s/\\177/\252/g; # u"
1281# $text =~ s/ ?? /\344/g; # a"
1282
1283 print OUT "$text";
1284 close OUT;
[1960]1285 }
[2600]1286 # wrap the text - use a minimum length. ie, first space after this length.
1287 my $wrap_length=72;
1288 &util::mv("$output_filestem.text", "$output_filestem.text.tmp");
1289 open INFILE, "$output_filestem.text.tmp" ||
1290 die "Couldn't open file: $!";
1291 open OUTFILE, ">$output_filestem.text" ||
1292 die "Couldn't open file for writing: $!";
1293 my $line="";
1294 while ($line=<INFILE>) {
1295 while (length($line)>0) {
1296 if (length($line)>$wrap_length) {
1297 $line =~ s/^(.{$wrap_length}[^\s]*)\s*//;
1298 print OUTFILE "$1\n";
1299 } else {
1300 print OUTFILE "$line";
1301 $line="";
1302 }
1303 }
1304 }
1305 close INFILE;
1306 close OUTFILE;
1307 &util::rm("$output_filestem.text.tmp");
1308
[1445]1309 &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
1310 return 1;
1311}
1312
1313
1314# Convert any file to HTML with a crude perl implementation of the
1315# UNIX strings command.
1316
1317sub any_to_html {
1318 ($input_filename, $output_filestem) = @_;
1319
1320 # First generate a text file
1321 return 0 unless (&any_to_text($input_filename, $output_filestem));
1322
1323 # create an HTML file from the text file
1324 open(TEXT, "<$output_filestem.text");
1325 open(HTML, ">$output_filestem.html");
1326
[2241]1327 print HTML "<html><head>\n";
1328 print HTML "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html\">\n";
1329 print HTML "<META NAME=\"GENERATOR\" CONTENT=\"Greenstone any_to_html\">\n";
1330 print HTML "</head><body>\n\n";
[1734]1331
[2755]1332 my $line;
1333 while ($line=<TEXT>) {
1334 $line =~ s/</&lt;/g;
1335 $line =~ s/>/&gt;/g;
[16435]1336 if ($line =~ m/^\s*$/) {
[2755]1337 print HTML "<p>";
1338 } else {
1339 print HTML "<br> ", $line;
1340 }
[1445]1341 }
[1734]1342 print HTML "\n</body></html>\n";
[1445]1343
[2241]1344 close HTML;
1345 close TEXT;
1346
[1445]1347 &util::rm("$output_filestem.text") if (-e "$output_filestem.text");
1348 return 1;
1349}
1350
1351# Convert any file to TEXT with a crude perl implementation of the
1352# UNIX strings command.
[2755]1353# Note - this assumes ascii charsets :( (jrm21)
[1445]1354
1355sub any_to_text {
1356 ($input_filename, $output_filestem) = @_;
1357
[3350]1358 if (!$use_strings) {
1359 return 0;
1360 }
[15120]1361
1362 print STDERR "\n**** In any to text****\n\n";
[2755]1363 open(IN, "<$input_filename") || return 0;
[1734]1364 binmode(IN);
[2755]1365 open(OUT, ">$output_filestem.text") || return 0;
[1445]1366
1367 my ($line);
[2755]1368 my $output_line_count = 0;
[1445]1369 while (<IN>) {
1370 $line = $_;
[1734]1371
[1445]1372 # delete anything that isn't a printable character
1373 $line =~ s/[^\040-\176]+/\n/sg;
1374
1375 # delete any string less than 10 characters long
[1734]1376 $line =~ s/^.{0,9}$/\n/mg;
[16435]1377 while ($line =~ m/^.{1,9}$/m) {
[1734]1378 $line =~ s/^.{0,9}$/\n/mg;
[1445]1379 $line =~ s/\n+/\n/sg;
1380 }
1381
1382 # remove extraneous whitespace
1383 $line =~ s/\n+/\n/gs;
1384 $line =~ s/^\n//gs;
[1578]1385
[1445]1386 # output whatever is left
[16435]1387 if ($line =~ m/[^\n ]/) {
[1445]1388 print OUT $line;
[2755]1389 ++$output_line_count;
[1445]1390 }
1391 }
[2241]1392
1393 close OUT;
1394 close IN;
1395
[2755]1396 if ($output_line_count) { # try to protect against binary only formats
1397 return 1;
1398 }
1399
1400 &util::rm("$output_filestem.text");
1401 return 0;
1402
[1445]1403}
Note: See TracBrowser for help on using the repository browser.