summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/hyper/dvi2pdf.pl
blob: 1a953c8e561f94d040170ea0bffd76884740afde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#!/usr/bin/perl

## File: backcite.dtx Copyright (C) 1995--1999 Michael Mehlich
## This program can be redistributed and/or modified under the terms
## of the LaTeX Project Public License Distributed from CTAN
## archives in directory macros/latex/base/lppl.txt; either
## version 1 of the License, or any later version.

### DESCRIPTION:
### This script transforms dvi-files to pdf-files using dvihps and ghostscripts pdfwriter
### It has been tested with emtex's dvips and ghostscript 4.01 on WindowsNT
### Usage: dvi2pdf <options>
###        where <options> are the usual dvips options and/or one of the following ones
###        -nopdf    produce only the ps-file not the pdf-file 
###                  (this option is automatically used if output file has suffix .ps)
###        -noborder produces an outputfile where the hyper-links don't have borders
###        -s<x>,<y> shifts the hyper-links by (<x>,<y>)

#Note: This script overwrites eventually existing files named
#        $$.ps, $pdffile.ps, $pdffile.pdf
#      where $$ is the process id (as provided by perl)
#      and $pdffile is the output file name given with the option -o or 
#      derived from the input file name, i.e. the input file name without suffix
 
### CONFIGURATION:
#Access paths for the programs dvihps and ghostscript
$GHOSTSCRIPT = "gswin32c"; #how to call ghostscript
$DVIHPS      = "dvips";    #how to call hyper postscript capable dvips
$REMOVEFILE  = "del";      #command to delete file

### Probably no changes necessary below this line

#some local initializations
$argno = 0;
$arglist = "";
$dvifile = "";
$psfile  = "";
$pdffile = "";
$xshift = 0; $yshift = 0;  #shift for hyper references
$referenceborder = 1;      #do we want to have a border surrounding hyper references?
$nopdf           = 0;      #we just patch the ps-file if ($nopdf == 1)

#scan arguments for input and output file and preserver rest for forwarding to dvips
while ($argno <= $#ARGV)
  { if ($ARGV[$argno] eq "")
      { #empty argument, ignore
      }
    elsif ($ARGV[$argno] =~ m/^-s([\+\-0-9]+)\,([\+\-0-9]+)$/)
      { $xshift = $1;
        $yshift = $2;
      }
    elsif ($ARGV[$argno] =~ m/^-nopdf$/)
      { $nopdf = 1;
      }
    elsif ($ARGV[$argno] =~ m/^-noborder$/)
      { $referenceborder = 0;
      }
    elsif ($ARGV[$argno] =~ m/^-(.)(.+)$/)
      { #argument follows flag directly 
        if ($1 eq "o")
          { #argument is output file
	    ($pdffile ne "") && die("Sorry, multiple output files cannot be handled");
	    $pdffile = $2;
          }
        else
          { #argument is dvi-argument
	    if ($ARGV[$argno] =~ m/ /)
	      { $arglist .= ' '.'"'.$ARGV[$argno].'"';
	      }
            else
              { $arglist .= ' '.$ARGV[$argno];
              }
          }
      }
    elsif ($ARGV[$argno] =~ m/^-(.)$/)
      { #flag without directly following argument
	if (   ($1 eq "a") || ($1 eq "k") || ($1 eq "m") || ($1 eq "q") || ($1 eq "r") 
	    || ($1 eq "s") || ($1 eq "z") || ($1 eq "A") || ($1 eq "B") || ($1 eq "E")
            || ($1 eq "F") || ($1 eq "K") || ($1 eq "M") || ($1 eq "N") || ($1 eq "R")
            || ($1 eq "U") || ($1 eq "V") || ($1 eq "Z")
	   )
          { #flag without argument
	    if (!($1 eq "z"))
              { $arglist .= ' '.$ARGV[$argno];
	      }
	  }
        elsif ($1 eq "i") 
          { die("Sorry, separate file per section cannot be handled");
          }
        elsif ($1 eq "f")
          { die("Sorry, run in filter mode not possible");
          }
        else
          { #flag with argument
	    if ($1 eq "o")
	      { #argument is output file
	       ($pdffile ne "") && die("Sorry, multiple output files cannot be handled");
                $pdffile = $ARGV[$argno+1];
              }
            else
              { #argument is dvi-argument
                if ($ARGV[$argno+1] =~ m/ /)
		  { $arglist .= ' '.$ARGV[$argno].' '.'"'.$ARGV[$argno+1].'"';
		  }
                else
		  { $arglist .= ' '.$ARGV[$argno].' '.$ARGV[$argno+1];
		  }
	      }
            $argno++;
          }
      }
    else
      { #nonflag argument
	($dvifile ne "") && die("Sorry, multiple input files cannot be handled");
        $dvifile = $ARGV[$argno];
      }
    $argno++;
  }
$arglist = substr($arglist,1,length($arglist)-1);

($dvifile eq "") && die("Sorry, no input file");
if (!($dvifile =~ m/\.[^\.\:\\\/]*$/))
  { $dvifile .= '.dvi';
  }
(!($dvifile =~ m/\.dvi$/)) && die("Sorry, input file has illegal suffix different from .dvi");

if ($pdffile eq "")
  { ($pdffile = $dvifile) =~ s/\.[^\:\\\/\.]*$/\.pdf/;
    if ($pdffile eq $dvifile)
      { $pdffile = $dvifile.'.pdf';
      }
  }
else
  { if ($pdffile =~ m/\.ps$/)
      { $nopdf = 1;
      }
  }

($psfile = $pdffile) =~ s/\.[^\:\\\/\.]*$/\.ps/;

$tmpfile = "$$.ps";

#output arguments
print STDERR "DVI file: $dvifile\n";
print STDERR "PS  file: $psfile\n";
if ($nopdf == 0)
  { print STDERR "PDF file: $pdffile\n";
  }
print STDERR "TMP file: $tmpfile\n";
print STDERR "Arg list: $arglist\n";
print STDERR "Shifting: ($xshift,$yshift)\n";
print STDERR "HyBorder: "; if ($referenceborder) { print STDERR "preserve"; } else { print STDERR "none"; }; print STDERR "\n";

#call dvips
print STDERR "*** $DVIHPS -z $arglist -o $tmpfile $dvifile\n";
system("$DVIHPS -z $arglist -o $tmpfile $dvifile");
(!(-f "$tmpfile")) && die("Error, $DVIHPS could not generate '$tmpfile'");

#path postscript file because we want to use a different fitheight for references to pages
print STDERR "*** PATCH $tmpfile $psfile\n";

open(STDIN,"<$tmpfile") || die("Input file '$tmpfile' not found.\n");
open(STDOUT,">$psfile") || do { close(STDIN); die("Cannot open file '$psfile' for writing.\n") };

while (<STDIN>)
  { if (/^\s*\((.+)\)\s+\[([0-9]+)\s+\[([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\]\s+([0-9]+)\]\s+def\s*$/)
      { $name      = $1;       # name of an anchor
        $page      = $2;       # page the anchor is on
        $xa        = $3 + $xshift;       # rectangular box of anchor
        $ya        = $4 + $yshift;
        $xb        = $5 + $xshift;
        $yb        = $6 + $yshift;
	$fitheight = (($ya > $yb) ? $ya : $yb) + 10; # screen top to show when reference to this anchor is choosen
        print STDOUT "($name) [$page [$xa $ya $xb $yb] $fitheight] def\n";
      }
    elsif (/^(.*)\s+\((.+)\)\s+\[\[([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\]\s+\[(.+)\]\s+\[(.+)\]\] pdfm\s+(.*)$/)
      { $before         = $1;
        $name           = $2;      # name of the reference
        $xa             = $3 + $xshift;      # rectangular box of reference
        $ya             = $4 + $yshift;
        $xb             = $5 + $xshift;
        $yb             = $6 + $yshift;
        $borderinfo     = $7; #horizontal_corner_radius vertical_corner_radius box_line_width [dash_on_size] [dash_off_size]
        $bordercolor    = $8; #red green blue
        $after          = $9;
	if ($borderinfo =~ m/^\s*([0-9]+)\s+([0-9]+)\s+([0-9]+)\s*\[\s*([0-9]+)\s+([0-9]+)\s*\]\s*$/)
          { $horizontalcornerradius = $1;
            $verticalcornerradius   = $2;
            $boxlinewidth           = $3;
            $dashonsize             = $4;
	    $dashoffsize            = $5;
	    if ($referenceborder == 0)
	      { $boxlinewidth = 0;
	      }
	    $borderinfo = "$horizontalcornerradius $verticalcornerradius $boxlinewidth [$dashonsize $dashoffsize]";
	  }
	print STDOUT "$before ($name) [[$xa $ya $xb $yb] [$borderinfo] [$bordercolor]] pdfm $after\n";
      }
    elsif (/^(.*)\s+\[\[([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\]\s+\[(.+)\]\s+\[(.+)\]\]\s+\((.+)\)\s+pdfm\s+(.*)$/)
      { $before         = $1;
        $xa             = $2 + $xshift;      # rectangular box of reference
        $ya             = $3 + $yshift;
        $xb             = $4 + $xshift;
        $yb             = $5 + $yshift;
        $borderinfo     = $6; #horizontal_corner_radius vertical_corner_radius box_line_width [dash_on_size] [dash_off_size]
        $bordercolor    = $7; #red green blue
        $name           = $8;
        $after          = $9;
	if ($borderinfo =~ m/^\s*([0-9]+)\s+([0-9]+)\s+([0-9]+)\s*\[\s*([0-9]+)\s+([0-9]+)\s*\]\s*$/)
          { $horizontalcornerradius = $1;
            $verticalcornerradius   = $2;
            $boxlinewidth           = $3;
            $dashonsize             = $4;
	    $dashoffsize            = $5;
	    if ($referenceborder == 0)
	      { $boxlinewidth = 0;
	      }
	    $borderinfo = "$horizontalcornerradius $verticalcornerradius $boxlinewidth [$dashonsize $dashoffsize]";
	  }
	print STDOUT "$before [[$xa $ya $xb $yb] [$borderinfo] [$bordercolor]] ($name) pdfm $after\n";
      }
    else
     { print STDOUT $_;
     }
  }

close(STDIN);
close(STDOUT);

# delete auxiliary file
print STDERR "*** $REMOVEFILE $tmpfile\n";
system("$REMOVEFILE $tmpfile");

if ($nopdf == 0)
  { # create pdf-file by calling ghostscript
    print STDERR "*** $GHOSTSCRIPT -q -dNOPAUSE -sDEVICE#pdfwrite -sOutputFile#$pdffile $psfile -c quit\n";
    system("$GHOSTSCRIPT -q -dNOPAUSE -sDEVICE#pdfwrite -sOutputFile#$pdffile $psfile -c quit");
    (!(-f "$pdffile")) && die("Error, $DVIHPS could not generate '$pdffile'");
  }