root/main/trunk/greenstone2/bin/script/gsConvert.pl @ 22642

Revision 22642, 44.6 KB (checked in by kjdon, 9 years ago)

removed all open office stuff. Haven't tested it properly as am at home

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