root/gsdl/trunk/bin/script/gsConvert.pl @ 20933

Revision 20933, 44.4 KB (checked in by oranfry, 11 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
Line 
1#!/usr/bin/perl -w
2
3###########################################################################
4#
5# gsConvert.pl -- convert documents to HTML or TEXT format
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#
11# Copyright (C) 1999-2002 New Zealand Digital Library Project
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
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).
33#
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).
38#
39# We can try to convert any file to text with a perl implementation of the
40# UNIX strings command.
41#
42# We try to convert Postscript files to text using "gs" which is often on
43# *nix machines. We fall back to performing weak text extraction by using
44# regular expressions.
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
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;}
59
60my $use_strings;
61my $pdf_complex;
62my $pdf_nohidden;
63my $pdf_zoom;
64my $pdf_ignore_images;
65my $pdf_allow_images_only;
66my $windows_scripting;
67
68sub print_usage
69{
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";
74    print STDERR "  options:\n\t-type\tdoc|dot|pdf|ps|ppt|rtf|xls\t(input file type)\n";
75    print STDERR "\t-errlog\t<filename>\t(append err messages)\n";
76    print STDERR "\t-output\tauto|html|text|pagedimage_jpg|pagedimage_gif|pagedimage_png\t(output file type)\n";
77    print STDERR "\t-timeout\t<max cpu seconds>\t(ulimit on unix systems)\n";
78    print STDERR "\t-use_strings\tuse strings to extract text if conversion fails\n";
79    print STDERR "\t-windows_scripting\tuse windows script when converting Microsoft Word and PPT via VB script\n";
80    print STDERR "\t-pdf_complex\tuse complex output when converting PDF to HTML\n";
81    print STDERR "\t-pdf_nohidden\tDon't attempt to extract hidden text from PDF files\n";
82    print STDERR "\t-pdf_ignore_images\tdon't attempt to extract images when\n";
83    print STDERR "\t\tconverting PDF to HTML\n";
84    print STDERR "\t-pdf_allow_images_only\tallow images only (continue even if no text is present when converting to HTML)\n";
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";
87    exit(1);
88}
89
90my $faillogfile="";
91my $timeout=0;
92
93sub main
94{
95    my (@ARGV) = @_;
96    my ($input_type,$output_type,$verbose);
97
98    # read command-line arguments
99    if (!parsargv::parse(\@ARGV,
100             'type/(doc|dot|pdf|ps|ppt|rtf|xls)/', \$input_type,
101             '/errlog/.*/', \$faillogfile,
102             'output/(auto|html|text|pagedimage).*/', \$output_type,
103             'timeout/\d+/0',\$timeout,
104             'verbose/\d+/0', \$verbose,
105             'use_strings', \$use_strings,
106             'windows_scripting',\$windows_scripting,
107             'pdf_complex', \$pdf_complex,
108             'pdf_ignore_images', \$pdf_ignore_images,
109             'pdf_allow_images_only', \$pdf_allow_images_only,
110             'pdf_nohidden', \$pdf_nohidden,
111             'pdf_zoom/\d+/2', \$pdf_zoom
112             ))
113    {
114    print_usage();
115    }
116     
117    # Make sure the input file exists and can be opened for reading
118    if (scalar(@ARGV!=1)) {
119    print_usage();
120    }
121
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)
130    = File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
131    my $output_filestem = &util::filename_cat($dirname, "$tailname");
132
133    if ($input_type eq "")
134    {
135    $input_type = lc (substr($suffix,1,length($suffix)-1));
136    }
137   
138    # Change to temporary working directory
139    my $stored_dir = cwd();
140    chdir ($dirname) || die "Unable to change to directory $dirname";
141
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    }
147    elsif ($input_type eq "doc" || $input_type eq "dot") {
148    print &convertDOC($input_filename, $output_filestem, $output_type);
149    print "\n";
150    }
151    elsif ($input_type eq "rtf") {
152    print &convertRTF($input_filename, $output_filestem, $output_type);
153    print "\n";
154    }
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    }
163    elsif ($input_type eq "ppt") {
164    print &convertPPT($input_filename, $output_filestem, $output_type);
165    print "\n";
166    }
167    elsif ($input_type eq "xls") {
168    print &convertXLS($input_filename, $output_filestem, $output_type);
169    print "\n";
170    }
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
185# Document-type conversion functions
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
199    # Many .doc files are not in fact word documents!
200    my $realtype = &find_docfile_type($input_filename);
201
202    if ($realtype eq "word6" || $realtype eq "word7" || $realtype eq "word8") {
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
216    my $success = 0;
217    if (!$output_type || ($output_type =~ m/html/i)){
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    }
224    if ($success) {
225       return "html";
226    }
227    }
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
240    if (!$output_type || ($output_type =~ m/html/i)) {
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    }
248    if ($success) {
249        return "html";
250    }
251    }
252
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";
257}
258
259
260# Convert an unidentified file
261
262sub convertAnything {
263    ($input_filename, $output_filestem, $output_type) = @_;
264   
265    my $success = 0;
266 
267    # Attempt simple conversion to HTML
268    if (!$output_type || ($output_type =~ m/html/i)) {
269    $success = &any_to_html($input_filename, $output_filestem);
270    if ($success) {
271        return "html";
272    }
273    }
274
275    # Convert to text
276    if (!$output_type || ($output_type =~ m/text/i)) {
277    $success = &any_to_text($input_filename, $output_filestem);
278    if ($success) {
279        return "text";
280    }
281    }
282    return "fail";
283}
284
285
286
287# Convert an Adobe PDF document
288
289sub convertPDF {
290    my ($dirname, $input_filename, $output_filestem, $output_type) = @_;
291
292    my $success = 0;
293    $output_type =~ s/.*\-(.*)/$1/i;
294    # Attempt coversion to Image
295    if ($output_type =~ m/jp?g|gif|png/i) {
296    $success = &pdfps_to_img($dirname, $input_filename, $output_filestem, $output_type);
297    if ($success){
298        return "item";
299    }
300    }
301
302    # Attempt conversion to HTML
303    if (!$output_type || ($output_type =~ m/html/i)) {
304    $success = &pdf_to_html($dirname, $input_filename, $output_filestem);
305    if ($success) {
306        return "html";
307    }
308    }
309
310    # Attempt conversion to TEXT
311    if (!$output_type || ($output_type =~ m/text/i)) {
312    $success = &pdf_to_text($dirname, $input_filename, $output_filestem);
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;
329    $output_type =~ s/.*\-(.*)/$1/i;
330    # Attempt coversion to Image
331    if ($output_type =~ m/jp?g|gif|png/i) {
332    $success = &pdfps_to_img($dirname, $input_filename, $output_filestem, $output_type);
333    if ($success){
334        return "item";
335    }
336    }
337
338    # Attempt conversion to TEXT
339    if (!$output_type || ($output_type =~ m/text/i)) {
340    $success = &ps_to_text($input_filename, $output_filestem);
341    if ($success) {
342        return "text";
343    }
344    }
345    return "fail";
346}
347
348
349sub convertPPT {
350    my ($input_filename, $output_filestem, $output_type) = @_;
351    my $success = 0;
352
353    my $ppt_convert_type = "";
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) {
357        $ppt_convert_type = "-g";
358    } elsif ($output_type =~ m/jp?g/i){
359        $ppt_convert_type = "-j";
360    } elsif ($output_type =~ m/png/i){
361        $ppt_convert_type = "-p";
362    }
363    my $vbScript = &util::filename_cat($ENV{'GSDLHOME'}, "bin",
364                       $ENV{'GSDLOS'}, "pptextract");
365    $vbScript = "pptextract" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
366           
367    $cmd = "";
368    if ($timeout) {$cmd = "ulimit -t $timeout;";}
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 {
374        $cmd .=  "$vbScript $ppt_convert_type \"$input_filename\" \"$output_filestem\"";
375        $cmd .= " 2>\"$output_filestem.err\""
376        if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
377        if (system($cmd) !=0) {
378        print STDERR "Powerpoint VB Scripting convert failed\n";
379        } else {
380        return "item";
381        }
382    }
383    } elsif (!$output_type || ($output_type =~ m/html/i)) {
384    # Attempt conversion to HTML
385    #if (!$output_type || ($output_type =~ m/html/i)) {
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\""
391        if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
392
393    # execute the command
394    $!=0;
395    if (system($cmd)!=0)
396    {
397        print STDERR "Powerpoint 95/97 converter failed $!\n";
398    } else {
399        return "html";
400    }
401    }
402
403    $success = &any_to_text($input_filename, $output_filestem);
404    if ($success) {
405    return "text";
406    }
407   
408    return "fail";
409}
410
411
412sub convertXLS {
413    my ($input_filename, $output_filestem, $output_type) = @_;
414
415    my $success = 0;
416
417    # Attempt conversion to HTML
418    if (!$output_type || ($output_type =~ m/html/i)) {
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\""
424        if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
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    }
436
437    $success = &any_to_text($input_filename, $output_filestem);
438    if ($success) {
439    return "text";
440    }
441
442    return "fail";
443}
444
445
446
447# Find the real type of a .doc file
448#
449# We seem to have a lot of files with a .doc extension that are .rtf
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");
455    binmode(CHK);
456    my $line = "";
457    my $first = 1;
458
459    while (<CHK>) {
460   
461    $line = $_;
462
463    if ($first) {
464        # check to see if this is an rtf file
465        if ($line =~ m/^\{\\rtf/) {
466        close(CHK);
467        return "rtf";
468        }
469        $first = 0;
470    }
471   
472    # is this is a word 6/7/8 document?
473    if ($line =~ m/Word\.Document\.([678])/) {
474        close(CHK);
475        return "word$1";
476    }
477
478    }
479
480    return "unknown";
481}
482
483
484# Specific type-to-type conversions
485#
486# Each of the following functions attempts to convert a document from
487# a specific format to another.  If they succeed they return 1 and leave
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
496    my $wvWare = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wvWare");
497
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
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
507    $wvWare = "wvWare" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
508
509    my $wv_conf = &util::filename_cat($ENV{'GSDLHOME'}, "etc",
510                      "packages", "wv", "wvHtml.xml");
511   
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
569    my $cmd = "";
570    if ($timeout) {$cmd = "ulimit -t $timeout;";}
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\"";
576    $cmd .= " \"$input_filename\" > \"$output_filestem.html\"";
577
578    # redirecting STDERR is a bad idea on windows 95/98
579    $cmd .= " 2> \"$output_filestem.err\""
580    if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
581    # execute the command
582    $!=0;
583    if (system($cmd)!=0)
584    {
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>) {
595        if ($line =~ m/\w/) {
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
608    }
609
610    # Was the conversion successful?
611
612    if (-s "$output_filestem.html") { # if file has non-zero size (i.e. it has contents)
613    open(TMP, "$output_filestem.html");
614    $line = <TMP>;
615    close(TMP);
616    if ($line && $line =~ m/DOCTYPE HTML/) {
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)
621        if (&util::is_dir_empty($assoc_dir)) {
622        #print STDERR "***gsConvert.pl: Image dir $assoc_dir is empty, removing***\n";
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
626        # Replace them with relative links instead, so the folder can be moved elsewhere
627        &make_links_to_assocdir_relative($toppath, $docname, "$output_filestem.html", $assoc_dir, $docname."_files");   
628        }
629        return 1;
630    }
631    }
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   
645    return 0;
646}
647
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) = @_;
662
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")) {
666    print STDERR "gsConvert.pl: Unable to open $html_file for reading absolute urls...ERROR: $!\n";
667    return 0;
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"
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    }
678    close(FIN); # close the file
679    #print STDERR $html_contents;
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.
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
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
691    my $safe_reg_expression = $assoc_dir_path;
692    $safe_reg_expression =~ s/\\/\\\\/g;
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
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.
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
713    $html_contents =~ s/(<(a|img).*?(href|src)=(\"|\')?)(.*)(.*?(\"|\')?.*?>)/&post_process_assocfile_urls($1, $5, $6)/sge;
714
715    #print STDERR "****assoc_dirname: $assoc_dirname***\n";
716    #print STDERR "****safe_reg_expression: $safe_reg_expression***\n";
717   
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
724    print STDERR "gsConvert.pl: Unable to open $html_file for writing relative links...ERROR: $!\n";
725    return 0;
726    }
727
728    # write out the updated contents and close the file
729    print FOUT $html_contents;
730    close(FOUT);
731    return 1;
732}
733
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
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
738sub post_process_assocfile_urls
739{
740    my ($pre, $text, $post) = @_;
741
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
744    $text =~ s/\\/\//g;
745    $text =~ s/%/%25/g;
746
747    return "$pre$text$post";
748}
749
750# Attempt to convert a word document to html with the word2html scripting program
751sub native_doc_to_html {
752    ($input_filename, $output_filestem) = @_;
753
754    my $vbScript = &util::filename_cat($ENV{'GSDLHOME'}, "bin",
755                       $ENV{'GSDLOS'}, "word2html");
756
757    $vbScript = "word2html" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
758    if (-e "$output_filestem.html") {
759    print STDERR "*** The conversion file has existed\n";
760    return 1;
761    }
762
763    my $cmd = "";
764    if ($timeout) {$cmd = "ulimit -t $timeout;";}
765    #$cmd .= "$vbScript \"$input_filename\" \"$output_filestem.html\"";
766    #$cmd .=  "$vbScript $input_filename $output_filestem.html";
767    $cmd .=  "$vbScript \"$input_filename\" \"$output_filestem.html\"";
768
769    # redirecting STDERR
770    $cmd .= " 2> \"$output_filestem.err\""
771    if ($ENV {'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
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>) {
787        if ($line =~ m/\w/) {
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);
807    if ($line && $line =~ m/html/) {
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
827# Attempt to convert an RTF document to html with rtftohtml
828
829sub rtf_to_html {
830    my ($input_filename, $output_filestem) = @_;
831
832    # formulate the command
833    $cmd = "";
834    if ($timeout) {$cmd = "ulimit -t $timeout;";}
835    $cmd .= "rtftohtml";
836    #$cmd .= "rtf-converter";
837
838    $cmd .= " -o \"$output_filestem.html\" \"$input_filename\"";
839
840    $cmd .= " 2>\"$output_filestem.err\""
841        if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
842
843
844    # execute the command
845    $!=0;
846    if (system($cmd)!=0)
847    {
848    print STDERR "Error executing rtf converter $!\n";
849    # don't currently bother printing out error log...
850    # keep going, in case it still created an HTML file...
851    }
852
853    # Was the conversion successful?
854    my $was_successful=0;
855    if (-s "$output_filestem.html") {
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) {
863        if ($line =~ m/<body>/) {$past_header=1;}
864        next;
865        }
866
867        $line =~ s/<[^>]+>//g;
868        if ($line =~ m/\w/ && $past_header) {  # we found some content...
869        $was_successful=1;
870        last;
871        }
872    }
873    close HTML;
874    }
875
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.
896        while (defined($_ = <HTMLSRC>) && $_ =~ m/\w/) {
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";
930        #print FAILLOG "Error - rtf-converter - couldn't extract text\n";
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
940    &util::rm("$output_filestem.html") if (-e "$output_filestem.html");
941
942    return 0;
943}
944
945
946# Convert a pdf file to html with the pdftohtml command
947
948sub pdf_to_html {
949    my ($dirname, $input_filename, $output_filestem) = @_;
950
951    $cmd = "";
952    if ($timeout) {$cmd = "ulimit -t $timeout;";}
953    $cmd .= "perl -S pdftohtml.pl -zoom $pdf_zoom";
954    $cmd .= " -c" if ($pdf_complex);
955    $cmd .= " -i" if ($pdf_ignore_images);
956    $cmd .= " -a" if ($pdf_allow_images_only);
957    $cmd .= " -hidden" unless ($pdf_nohidden);
958    $cmd .= " \"$input_filename\" \"$output_filestem\"";
959   
960    if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000) {
961    $cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
962    } else {
963    $cmd .= " > \"$output_filestem.err\"";
964    }
965
966    $!=0;
967
968    my $retval=system($cmd);
969    if ($retval!=0)
970    {
971    print STDERR "Error executing pdftohtml.pl";
972    if ($!) {print STDERR ": $!";}
973    print STDERR "\n";
974    }
975
976    # make sure the converter made something
977    if ($retval!=0 || ! -s "$output_filestem.html")
978    {
979    &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
980    # print out the converter's std err, if any
981    if (-s "$output_filestem.err") {
982        open (ERRLOG, "$output_filestem.err") || die "$!";
983        print STDERR "pdftohtml error log:\n";
984        while (<ERRLOG>) {
985        print STDERR "$_";
986        }
987        close ERRLOG;
988    }
989    &util::rm("$output_filestem.html") if (-e "$output_filestem.html");
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        }   
998        &util::rm("$output_filestem.err");
999    }
1000    return 0;
1001    }
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
1010sub pdfps_to_img {
1011    my ($dirname, $input_filename, $output_filestem, $output_type) = @_;
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.
1018        print STDERR "*** ImageMagick is not installed, the convert utility is not available. Unable to convert PDF/PS to images\n";
1019        return 0;
1020    }
1021    }
1022
1023    $cmd = "";
1024    if ($timeout) {$cmd = "ulimit -t $timeout;";}
1025    $output_type =~ s/.*\_(.*)/$1/i;
1026    $cmd .= "perl -S pdfpstoimg.pl -convert_to $output_type \"$input_filename\" \"$output_filestem\"";
1027    if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000) {
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    {
1040    print STDERR "Error executing pdftoimg.pl";
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 "$!";
1053        print STDERR "pdfpstoimg error log:\n";
1054        while (<ERRLOG>) {
1055        print STDERR "$_";
1056        }
1057        close ERRLOG;
1058    }
1059    #&util::rm("$output_filestem.html") if (-e "$output_filestem.html");
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    }
1072    &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
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 {
1080    my ($dirname, $input_filename, $output_filestem) = @_;
1081
1082    my $cmd = "pdftotext \"$input_filename\" \"$output_filestem.text\"";
1083
1084    if ($ENV{'GSDLOS'} !~ m/^windows$/i) {
1085    $cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
1086    } else {
1087    $cmd .= " > \"$output_filestem.err\"";
1088    }
1089   
1090    if (system($cmd)!=0)
1091    {
1092    print STDERR "Error executing $cmd: $!\n";
1093    &util::rm("$output_filestem.text") if (-e "$output_filestem.text");
1094    }
1095
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>)) {
1103        if ($line=~ m/\w/) {$seen_text=1;}
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
1112    # make sure the converter made something
1113    if (! -s "$output_filestem.text")
1114    {
1115    # print out the converters std err, if any
1116    if (-s "$output_filestem.err") {
1117        open (ERRLOG, "$output_filestem.err") || die "$!";
1118        print STDERR "pdftotext error log:\n";
1119        while (<ERRLOG>) {
1120        print STDERR "$_";
1121        }
1122        close ERRLOG;
1123    }
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");
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    }
1137    return 0;
1138    }
1139    &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
1140    return 1;
1141}
1142
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.
1147
1148sub ps_to_text {
1149    my ($input_filename, $output_filestem) = @_;
1150
1151    my $error = "";
1152
1153    # if we're on windows we'll fall straight through without attempting
1154    # to use gs
1155    if ($ENV{'GSDLOS'} =~ m/^windows$/i) {
1156    $error = "Windows does not support gs";
1157
1158    } else {
1159    my $cmd = "";
1160    if ($timeout) {$cmd = "ulimit -t $timeout; ";}
1161    $cmd .= "gs -q -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT -dSIMPLE -c save ";
1162    $cmd .= "-f ps2ascii.ps \"$input_filename\" -c quit > \"$output_filestem.text\"";
1163    #$cmd .= "pstotext -output \"$output_filestem.text\" $input_filename\"";
1164    $cmd .= " 2> $output_filestem.err";
1165    $!=0;
1166
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";
1174    }
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";
1179        if (<PSOUT> =~ m/^Error: (.*)/) {
1180        $error="interpreter error - \"$1\"";
1181        }
1182        close PSOUT;
1183    }
1184    }
1185
1186    if ($error ne "")
1187    {
1188    print STDERR "Warning: Error executing gs: $error\n";
1189    &util::rm("$output_filestem.text") if (-e "$output_filestem.text");
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    }
1201    &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
1202
1203
1204    # Fine then. We'll just do a lousy job by ourselves...
1205    # Based on 5-line regexp sed script found at:
1206    # http://snark.ptc.spbu.ru/mail-archives/lout/brown/msg00003.html
1207    #
1208    print STDERR "Stripping text from postscript\n";
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   
1216    my $text="";  # this is for whole .ps file...
1217    $text = join('', <IN>); # see man perlport, under "System Resources"
1218    close IN;
1219
1220    # Make sure this is a ps file...
1221    if ($text !~ m/^%!/) {
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        }
1228        return 0;
1229    }
1230
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;
1285    }
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
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
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";
1331
1332    my $line;
1333    while ($line=<TEXT>) {
1334    $line =~ s/</&lt;/g;
1335    $line =~ s/>/&gt;/g;
1336    if ($line =~ m/^\s*$/) {
1337        print HTML "<p>";
1338    } else {
1339        print HTML "<br> ", $line;
1340    }
1341    }
1342    print HTML "\n</body></html>\n";
1343
1344    close HTML;
1345    close TEXT;
1346
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.
1353# Note - this assumes ascii charsets :(     (jrm21)
1354
1355sub any_to_text {
1356    ($input_filename, $output_filestem) = @_;
1357
1358    if (!$use_strings) {
1359      return 0;
1360    }
1361
1362    print STDERR "\n**** In any to text****\n\n";
1363    open(IN, "<$input_filename") || return 0;
1364    binmode(IN);
1365    open(OUT, ">$output_filestem.text") || return 0;
1366
1367    my ($line);
1368    my $output_line_count = 0;
1369    while (<IN>) {
1370    $line = $_;
1371
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
1376    $line =~ s/^.{0,9}$/\n/mg;
1377    while ($line =~ m/^.{1,9}$/m) {
1378        $line =~ s/^.{0,9}$/\n/mg;
1379        $line =~ s/\n+/\n/sg;
1380    }
1381
1382    # remove extraneous whitespace
1383    $line =~ s/\n+/\n/gs;
1384    $line =~ s/^\n//gs;
1385
1386    # output whatever is left
1387    if ($line =~ m/[^\n ]/) {
1388        print OUT $line;
1389        ++$output_line_count;
1390    }
1391    }
1392
1393    close OUT;
1394    close IN;
1395
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
1403}
Note: See TracBrowser for help on using the browser.