redsymbol / l2p
- Source
- Commits
- Network (0)
- Issues (1)
- Downloads (0)
- Wiki (1)
- Graphs
-
Tree:
9f3a730
commit 9f3a7303145a4e7228dca58c02464e95b0ff8ee8
tree 07988338ead2529b1e0f4806c9b51b9833377bdc
parent 10fbcd1831d04297d9b38e50b17007bc1580007e
tree 07988338ead2529b1e0f4806c9b51b9833377bdc
parent 10fbcd1831d04297d9b38e50b17007bc1580007e
l2p / l2p
| 93517c80 » | amax | 2007-05-10 | 1 | #!/usr/bin/perl -w | |
| 2 | # L2P - Convert LaTeX expressions to PNG | ||||
| 3 | |||||
| b4307024 » | redsymbol | 2007-10-06 | 4 | $version = '1.1.1'; | |
| 93517c80 » | amax | 2007-05-10 | 5 | ||
| 6 | =head1 NAME | ||||
| 7 | |||||
| 8 | l2p - create PNG images from LaTeX expressions | ||||
| 9 | |||||
| 10 | =head1 SYNOPSIS | ||||
| 11 | |||||
| 12 | B<l2p> [options...] -i '$I<latex_expression>$' | ||||
| 13 | |||||
| 14 | or | ||||
| 15 | |||||
| 16 | B<l2p> [options...] [I<expression_file>] | ||||
| 17 | |||||
| 18 | I<expression_file> contains an expression or expressions in (La)TeX | ||||
| 19 | format - one per line. If neither I<expression_file> nor an | ||||
| 20 | B<-i> option is given, the expression is read from standard input. | ||||
| 21 | |||||
| 22 | =head1 DESCRIPTION | ||||
| 23 | |||||
| 24 | Convert expressions in LaTeX format into PNGs | ||||
| 25 | |||||
| 26 | =head1 EXAMPLES | ||||
| 27 | |||||
| 28 | =over | ||||
| 29 | |||||
| 30 | =item | ||||
| 31 | |||||
| 32 | l2p -i '$4x^2-7=\cos{2 \pi x}$' -o 'eqn4.png' | ||||
| 33 | |||||
| 34 | Produce a PNG image, named 'eqn4.png', of the equation described by the | ||||
| 35 | LaTeX expression '$4x^2 - 7 = \cos{2 \pi x}$'. | ||||
| 36 | |||||
| 37 | =item | ||||
| 38 | |||||
| 39 | l2p -o big_equation.png big_hairy_equation | ||||
| 40 | |||||
| 41 | Produce a PNG image, called big_equation.png, from the LaTeX expression | ||||
| 42 | contained in the file big_hairy_equation (specifically, it contains | ||||
| 43 | '$x=2$'.) Note that this file is NOT a full LaTeX document - use the | ||||
| 44 | B<-F> option for that. | ||||
| 45 | |||||
| 46 | =item | ||||
| 47 | |||||
| 48 | l2p -d 250 -i '$\nabla \cdot \mathbf{D} = \rho$' | ||||
| 49 | |||||
| 50 | Produce a PNG image from the LaTeX code given with the B<-i> argument | ||||
| 51 | (which happens to be one of Maxwell's equations), at 250 dots per inch. | ||||
| 52 | Since we did not specify an output file name with the B<-o> option, the | ||||
| 53 | image will be 'eqn.png' (the default). | ||||
| 54 | |||||
| 55 | =item | ||||
| 56 | |||||
| 57 | l2p -p amssymb -i '$\mho$' -o mho.png | ||||
| 58 | |||||
| 59 | Produce a PNG image of the Mho symbol (an upside-down capital omega), | ||||
| 60 | saving the image in the file 'mho.png'. We include the amssymb package, | ||||
| 61 | which defines that symbol. | ||||
| 62 | |||||
| 63 | =item | ||||
| 64 | |||||
| 65 | l2p -B 20x30 -i '$\sum_{n=0}^{\infty}\frac{(-\phi^2)^n}{(2n)!}$' -o cosine.png | ||||
| 66 | |||||
| 67 | Produce an image of the indicated infinite summation, padded with a | ||||
| 68 | border that is 20 pixels on each side horizontally, and 30 pixels each | ||||
| 69 | side vertically. The color of this border region will be the same as | ||||
| 70 | the rest of the image background. | ||||
| 71 | |||||
| 72 | =back | ||||
| 73 | |||||
| 74 | =head1 OPTIONS | ||||
| 75 | |||||
| 76 | Many options have arguments that may contain characters, like '#' or | ||||
| 77 | spaces, that the shell considers special. Be sure to surround all | ||||
| 78 | such arguments with single or double quotes, so that the shell | ||||
| 79 | understands what is meant. (If unsure, it's always safe to use the | ||||
| 80 | quotes.) | ||||
| 81 | |||||
| 82 | =over | ||||
| 83 | |||||
| 84 | =item | ||||
| 85 | B<-i "$latex$"> | ||||
| 86 | |||||
| 87 | Argument is an equation/expression in (La)TeX format. In most cases, | ||||
| 88 | you will want to enclose the argument in quotes to protect it from shell | ||||
| 89 | expansion. | ||||
| 90 | |||||
| 91 | =item | ||||
| 92 | B<-b "rrggbb"> | ||||
| 93 | |||||
| 94 | Background color. There are several ways to specify the color. See the | ||||
| 95 | section L</COLORS>, below, for details. | ||||
| 96 | |||||
| 97 | =item | ||||
| 98 | B<-d dpi> | ||||
| 99 | |||||
| 100 | Pixel density at which the equation is rendered, in dots per inch | ||||
| 101 | (default 300). | ||||
| 102 | |||||
| 103 | An image with a DPI of 600 will have twice as many pixels in each of the | ||||
| 104 | x and y directions than an image with a DPI of 300. The effect is | ||||
| 105 | different in the normal context of printing, where a higher DPI will | ||||
| 106 | leave the text with the same physical size, but with a finer resolution. | ||||
| 107 | This is because the physical size of a pixel is not really variable; so | ||||
| 108 | to have double the resolution, a symbol in an image must be double the | ||||
| 109 | size. | ||||
| 110 | |||||
| 111 | =item | ||||
| 112 | B<-f "rrggbb"> | ||||
| 113 | |||||
| 114 | Foreground color. There are several ways to specify the color. See the | ||||
| 115 | section L</COLORS>, below, for details. | ||||
| 116 | |||||
| 117 | =item | ||||
| 118 | B<-h> | ||||
| 119 | |||||
| 120 | Show a help summary. | ||||
| 121 | |||||
| 122 | =item | ||||
| 123 | B<-o output.png> | ||||
| 124 | |||||
| 125 | Name of output file. Default is 'eqn.png'. | ||||
| 126 | |||||
| 127 | =item | ||||
| 128 | B<-p packagename[,packagename2[,...]]]> | ||||
| 129 | |||||
| 130 | Use additional LaTeX/TeX packages. You can specify several, separated | ||||
| 131 | by commas. | ||||
| 132 | |||||
| 133 | =item | ||||
| 134 | B<-B "WIDTHxHEIGHT [color]"> | ||||
| 135 | |||||
| 136 | or: B<-B "SIZE [color]"> | ||||
| 137 | |||||
| 138 | Pad the resulting image with a border of the indicated size, in pixels. | ||||
| 139 | |||||
| 140 | You can optionally specify a color for the border region. By default, | ||||
| 141 | the border will be the same color as the rest of the background. (See | ||||
| 142 | L</COLORS> below for the format.) | ||||
| 143 | |||||
| 144 | =item | ||||
| 145 | B<-C> | ||||
| 146 | |||||
| 147 | Suppress automatic removal (cleanup) of temporary files. This will be | ||||
| 148 | useful if something goes wrong, or if you want to use the intermediate | ||||
| 149 | DVI or Postscript renditions. B<l2p> will tell you which directory | ||||
| 150 | contains these files. | ||||
| 151 | |||||
| 152 | =item | ||||
| 153 | B<-F> | ||||
| 154 | |||||
| 155 | Supplied expression is a full LaTeX document, rather than just an | ||||
| 156 | expression fragment. Negates the B<-f>, B<-b>, B<-p>, B<-B> and B<-T> | ||||
| 157 | options. | ||||
| 158 | |||||
| 159 | B<Note>: B<l2p> currently only converts full LaTeX documents | ||||
| 160 | that are relatively simple: only one page in length, and with no external | ||||
| 161 | dependencies (such as included graphics). If you need to convert a more | ||||
| 162 | complex document, you can generate a DVI file with latex like normal, | ||||
| 163 | then convert the DVI into a series of PNG images using B<convert> from | ||||
| 164 | the ImageMagick distribution. See L<convert(1)>, or | ||||
| 165 | L<http://imagemagick.org/script/convert.php> for more information. | ||||
| 166 | |||||
| 167 | =item | ||||
| 168 | B<-T> | ||||
| 169 | |||||
| 170 | Create an image with a transparent background. | ||||
| 171 | |||||
| 172 | =item | ||||
| 173 | B<-V> | ||||
| 174 | |||||
| 175 | Show version information. | ||||
| 176 | |||||
| 177 | =back | ||||
| 178 | |||||
| 179 | =head1 COLORS | ||||
| 180 | |||||
| 181 | Some options, such as B<-b> and B<-f>, take an argument specifying a | ||||
| 182 | color in RGB format. B<l2p> will decipher most representations, such | ||||
| 183 | as: | ||||
| 184 | |||||
| 185 | =over | ||||
| 186 | |||||
| 187 | =item | ||||
| 188 | |||||
| 189 | A hexidecimal triplet. For example, '-f "FF0000" -b "#ffffff"' gives a | ||||
| 190 | red foreground on a white background. Case is not important, and the | ||||
| 191 | "#" is optional. | ||||
| 192 | |||||
| 193 | =item | ||||
| 194 | |||||
| 195 | Three decimal whole numbers, in the range of 0 to 255. These must be | ||||
| 196 | separated by spaces or punctuation (comma, semicolon or colon). For | ||||
| 197 | example, '-b "0 127 255" -f "0,0,0"' is black on a nice bluish | ||||
| 198 | background. | ||||
| 199 | |||||
| 200 | =item | ||||
| 201 | |||||
| 202 | Three fractions between 0 and 1, inclusive. At least one of the three | ||||
| 203 | numbers must contain a decimal point (to distinguish this format from | ||||
| 204 | the others), and they are separated by space or punctuation. For | ||||
| 205 | example, "0.87 .78 .41" is the same as the hex triplet "DEC769", and "0, | ||||
| 206 | 1.0, 0" is the color green. (Remember that decimal point. "0, 1, 0" | ||||
| 207 | will give you a nearly black color.) | ||||
| 208 | |||||
| 209 | =back | ||||
| 210 | |||||
| 211 | Note that you may need to put single or double quotes around the color | ||||
| 212 | string, to ensure the shell interprets it correctly. | ||||
| 213 | |||||
| 214 | =head1 BUGS | ||||
| 215 | |||||
| 216 | Error handling is imperfect. Among other things, If a needed | ||||
| 217 | LaTeX package is not included, B<l2p> will silently produce a | ||||
| 218 | broken image. | ||||
| 219 | |||||
| 220 | On certain platforms, images produced with the B<-T> option (transparent | ||||
| 221 | background) may leave pixels at the edges of symbols a mixture of the | ||||
| 222 | text color and some background color. This may not look good if the | ||||
| 223 | resulting image is put on a differently colored background. A | ||||
| 224 | workaround is to give a background color hint with the B<-b> option; | ||||
| 225 | the edge pixels will then be a mixture of specified foreground and | ||||
| 226 | background colors. | ||||
| 227 | |||||
| 379c84f7 » | amax | 2007-05-10 | 228 | =head1 ACKS | |
| 93517c80 » | amax | 2007-05-10 | 229 | ||
| 379c84f7 » | amax | 2007-05-10 | 230 | Thanks to Jesse Merriman (L<http://www.jessemerriman.com/>) for | |
| 231 | providing a patch that improved transparent background support. | ||||
| 232 | Integrated in version 1.1. | ||||
| 93517c80 » | amax | 2007-05-10 | 233 | ||
| 234 | =head1 COPYRIGHT | ||||
| 235 | |||||
| 236 | This software is in the public domain. | ||||
| 237 | |||||
| 379c84f7 » | amax | 2007-05-10 | 238 | =head1 AUTHOR | |
| 239 | |||||
| 240 | Aaron Maxwell (amax@redsymbol.net). Comments, feature requests, and | ||||
| 241 | patches are welcome. | ||||
| 242 | |||||
| 93517c80 » | amax | 2007-05-10 | 243 | =cut | |
| 244 | |||||
| 245 | use File::Temp qw/tempfile tempdir/; | ||||
| 246 | use Getopt::Std; | ||||
| 247 | |||||
| 248 | # Takes a string and extracts an RGB value from it. | ||||
| 249 | # Returns ($r,$g,$b), all values between 0 and 1 if parsing is successful, | ||||
| 250 | # otherwise returns undef. | ||||
| 251 | # Usage: ($r,$g,$b) = parsergb($string); | ||||
| 252 | sub parsergb { | ||||
| 253 | my $string=shift; | ||||
| 254 | $string =~s/^\s+//; | ||||
| 255 | $string =~s/\s+$//; | ||||
| 256 | $string =~s/^#//; | ||||
| 257 | my(@args,@vals,$arg,$val); | ||||
| 258 | |||||
| 259 | # hex triplet format? | ||||
| 260 | if($string=~/^[0-9a-fA-F]{6}$/) { | ||||
| 261 | @args=(substr($string,0,2), substr($string,2,2), substr($string,4,2)); | ||||
| 262 | foreach $arg (@args) { | ||||
| 263 | $val=hex($arg)/255; | ||||
| 264 | push @vals, $val; | ||||
| 265 | } | ||||
| 266 | return @vals; | ||||
| 267 | } | ||||
| 268 | $string =~s/[,:;]/ /g; | ||||
| 269 | @args = split /\s+/, $string; | ||||
| 270 | if (@args != 3) { | ||||
| 271 | return undef; | ||||
| 272 | } | ||||
| 273 | |||||
| 274 | # 0-255 decimal format? | ||||
| 275 | if ($string =~ /^[\d\s]+$/) { | ||||
| 276 | foreach $arg (@args) { | ||||
| 277 | if ($arg>=0 && $arg<=255) { | ||||
| 278 | $val=$arg/255; | ||||
| 279 | } else { return undef; } | ||||
| 280 | push @vals, $val; | ||||
| 281 | } | ||||
| 282 | |||||
| 283 | # 0.0-1.0 range format? | ||||
| 284 | } elsif ($string =~ /^[\d\.\s]+$/) { | ||||
| 285 | foreach $arg (@args) { | ||||
| 286 | if($arg>=0 && $arg<=1) { | ||||
| 287 | $val = 0+$arg; | ||||
| 288 | } else { return undef; } | ||||
| 289 | push @vals, $val; | ||||
| 290 | } | ||||
| 291 | |||||
| 292 | } else { | ||||
| 293 | return undef; # unrecognized format! | ||||
| 294 | } | ||||
| 295 | |||||
| 296 | return @vals; | ||||
| 297 | } | ||||
| 298 | |||||
| 299 | # norm2hex - convert an RGB color in the form 'r,g,b', 0<=[rgb]<=1, | ||||
| 300 | # to a hex triplet. Returns undef if invoked incorrectly. | ||||
| 301 | # usage: $hexrgb = norm2hex($normrgb); | ||||
| 302 | sub norm2hex { | ||||
| 303 | $_=shift; | ||||
| 304 | my @vals=split(/,/,$_); | ||||
| 305 | scalar(@vals)==3 or return undef; | ||||
| 306 | my($val,$hex); | ||||
| 307 | foreach $val (@vals) { | ||||
| 308 | unless($val>=0 and $val<=1) { return undef; } | ||||
| 309 | $hex .= sprintf('%02x',$val*255); | ||||
| 310 | } | ||||
| 311 | return $hex; | ||||
| 312 | } | ||||
| 313 | |||||
| 314 | my($pre,$post,$dpi,$eqn,$outfile,$fg,$bg); | ||||
| 315 | our($opt_o, # output file name | ||||
| 316 | $opt_d, # dpi | ||||
| 317 | $opt_i, # in-command-line latex expression | ||||
| 318 | $opt_f, # foreground RGB triplet | ||||
| 319 | $opt_b, # background RGB triplet | ||||
| 320 | $opt_F, # set if input is a full LaTeX document | ||||
| 321 | $opt_T, # transparent background | ||||
| 322 | $opt_C, # suppress autocleaning of temp files | ||||
| 323 | $opt_h, # display help message | ||||
| 324 | $opt_p, # additional package(s) | ||||
| 325 | $opt_V, # print version info | ||||
| 326 | $opt_B, # border | ||||
| 327 | $opt_Z, # reserved for hacks | ||||
| 328 | ); | ||||
| 329 | |||||
| 330 | # check to see if needed software is available | ||||
| 331 | my($latex,$dvips,$convert); | ||||
| 332 | $latex = `which latex`; chomp $latex; | ||||
| 333 | if($latex eq '' or not -X $latex) { | ||||
| 334 | print STDERR "Cannot find latex executable. Aborting.\n"; | ||||
| 335 | exit(2); | ||||
| 336 | } | ||||
| 337 | $dvips = `which dvips`; chomp $dvips; | ||||
| 338 | if($dvips eq '' or not -X $dvips) { | ||||
| 339 | print STDERR "Cannot find dvips executable. Aborting.\n"; | ||||
| 340 | exit(2); | ||||
| 341 | } | ||||
| 342 | $convert = `which convert`; chomp $convert; | ||||
| 343 | if($convert eq '' or not -X $convert) { | ||||
| 344 | print STDERR "Cannot find convert executable. Aborting.\n"; | ||||
| 345 | exit(2); | ||||
| 346 | } | ||||
| 347 | |||||
| 348 | # process command line opts | ||||
| 349 | getopt('odifbpB'); | ||||
| 350 | |||||
| 351 | if ($opt_V) { | ||||
| 352 | print $version, "\n"; | ||||
| 353 | exit(0); | ||||
| 354 | } | ||||
| 355 | |||||
| 356 | if ($opt_h) { | ||||
| 357 | print <<'EOT'; | ||||
| 358 | Generate PNG images from LaTeX expressions | ||||
| 359 | usage: | ||||
| 360 | l2p [options] [file_containing_latex_expressions] | ||||
| 361 | or | ||||
| 362 | l2p [options] -i '$LaTeX-expression$' | ||||
| 363 | |||||
| 364 | Note: Many options will require quotes around their arguments to | ||||
| 365 | ensure correct interpretation by the shell. | ||||
| 366 | |||||
| 367 | Options: | ||||
| 368 | -o output.png Name of output file. Default is 'eqn.png'. | ||||
| 369 | -i '$latex$' equation/expression in (La)TeX format | ||||
| 370 | -f 'rrggbb' foreground color | ||||
| 371 | -b 'rrggbb' background color | ||||
| 372 | -d dpi Conversion resolution (default 300) | ||||
| 373 | -T Transparent background | ||||
| 374 | -p pkg[,pkg2...] use TeX/LaTeX package(s) | ||||
| 375 | -C Suppress removal (cleanup) of temporary files | ||||
| 376 | -F Input is full LaTeX document, not just fragment | ||||
| 377 | -V Show version | ||||
| 378 | -B 'geom [color]' Pad image with a border | ||||
| 379 | -h Show this help and exit | ||||
| 380 | Also see the full documentation (try typing 'perldoc l2p'). | ||||
| 381 | EOT | ||||
| 382 | exit(0); | ||||
| 383 | } | ||||
| 384 | |||||
| 385 | $outfile = $opt_o || 'eqn.png'; | ||||
| 386 | $dpi = $opt_d || 300; | ||||
| 387 | |||||
| 388 | # determine foreground color | ||||
| 389 | $fg='0,0,0'; | ||||
| 390 | if($opt_f) { | ||||
| 391 | my($r,$g,$b) = parsergb($opt_f); | ||||
| 392 | if (not defined $r) { | ||||
| 393 | print STDERR "Foreground color not in recognizeable format. Reverting to default.\n"; | ||||
| 394 | ($r,$g,$b) = (0,0,0); | ||||
| 395 | } | ||||
| 396 | $fg=join(',',$r,$g,$b); | ||||
| 397 | } | ||||
| 398 | |||||
| 399 | $bg='1,1,1'; | ||||
| 400 | # determine background color | ||||
| 401 | if($opt_b) { | ||||
| 402 | my($r,$g,$b) = parsergb($opt_b); | ||||
| 403 | if (not defined $r) { | ||||
| 404 | print STDERR "Background color not in recognizeable format. Reverting to default.\n"; | ||||
| 405 | ($r,$g,$b) = (1,1,1); | ||||
| 406 | } | ||||
| 407 | $bg=join(',',$r,$g,$b); | ||||
| 408 | } | ||||
| 409 | # deal with transparent background | ||||
| 410 | $fuzz = 20; | ||||
| 411 | if ($opt_T) { | ||||
| 412 | if($opt_b) { | ||||
| 413 | # Workaround: with a BG hint, a nonzero fuzz can result in erased symbols | ||||
| 414 | $fuzz = 0; | ||||
| 415 | } | ||||
| 416 | # $bg and $fg must be different for transparency to work | ||||
| 417 | my($bR,$bG,$bB) = split(/,/, $bg); | ||||
| 418 | my($fR,$fG,$fB) = split(/,/, $fg); | ||||
| 419 | my($dR, $dG, $dB) = map { abs($_) } ($fR-$bR, $fG-$bG, $fB-$bB); | ||||
| 420 | if($dR<0.1 && $dG<0.1 && $dB<0.1) { | ||||
| 421 | $bg = (sqrt($fR**2+$fG**2+$fB**2)>0.5) ? '0,0,0' : '1,1,1'; | ||||
| 422 | } | ||||
| 423 | } | ||||
| 424 | |||||
| 425 | my @packages = ('color'); | ||||
| 426 | if ($opt_p) { | ||||
| 427 | @packages = (@packages, split(/,/, $opt_p)); | ||||
| 428 | } | ||||
| 429 | |||||
| 430 | # get expression to render | ||||
| 431 | $pre = join "\n", ( | ||||
| 432 | '\documentclass{article}', | ||||
| 433 | (map { '\usepackage{' . $_ . '}' } @packages), | ||||
| 434 | '\definecolor{bg}{rgb}{', $bg, '}', | ||||
| 435 | '\definecolor{fg}{rgb}{', $fg, '}', | ||||
| 436 | '\pagestyle{empty}', | ||||
| 437 | '\pagecolor{bg}', | ||||
| 438 | '\begin{document}', | ||||
| 439 | '\color{fg}', | ||||
| 440 | '\begin{center}', | ||||
| 441 | ""); | ||||
| 442 | |||||
| 443 | $post = <<'EOT'; | ||||
| 444 | \end{center} | ||||
| 445 | \end{document} | ||||
| 446 | EOT | ||||
| 447 | |||||
| 448 | # discover the LaTeX expression to render | ||||
| 449 | $eqn=''; | ||||
| 450 | if (defined $opt_i) { | ||||
| d57771e6 » | redsymbol | 2007-10-06 | 451 | # expression from command line | |
| 452 | $eqn = $opt_i . "\n"; | ||||
| 93517c80 » | amax | 2007-05-10 | 453 | } elsif (not $opt_F) { | |
| d57771e6 » | redsymbol | 2007-10-06 | 454 | # file/stdin contains LaTeX expression(s) | |
| 455 | # TODO: rewrite using an expression iterator subroutine | ||||
| 456 | while(<>) { | ||||
| 457 | next if /^\s*#/ or /^\s*$/; | ||||
| 458 | chomp; | ||||
| 459 | $eqn .= $_ . "\n"; | ||||
| 460 | # If this is line contains a single inline expression, add | ||||
| 461 | # an extra newline, so that it renders correctly | ||||
| 462 | if (/^\s*\$.*\$\s*$/) { | ||||
| 463 | $eqn .= "\n"; | ||||
| 464 | } | ||||
| 465 | } | ||||
| 93517c80 » | amax | 2007-05-10 | 466 | } | |
| 467 | if (not $opt_F and $eqn =~ /^\s*$/) { | ||||
| d57771e6 » | redsymbol | 2007-10-06 | 468 | print STDERR <<'EOT'; | |
| 93517c80 » | amax | 2007-05-10 | 469 | Did not find a LaTeX expression to render. Perhaps the supplied | |
| 470 | expression or file is empty, or does not exist. | ||||
| 471 | EOT | ||||
| d57771e6 » | redsymbol | 2007-10-06 | 472 | exit(3); | |
| 93517c80 » | amax | 2007-05-10 | 473 | } | |
| 474 | |||||
| 475 | # create a temporary latex file to use | ||||
| 476 | my $tempdir = tempdir(CLEANUP=> $opt_C ? 0 : 1) | ||||
| 477 | or die "Cannot not make temp dir. Unable to proceed - aborting."; | ||||
| 478 | print "Temporary files stored in $tempdir\n" if $opt_C; | ||||
| 479 | my $latexfn = $tempdir . "/foo.latex"; | ||||
| 480 | if($opt_F) { | ||||
| d57771e6 » | redsymbol | 2007-10-06 | 481 | $source = shift @ARGV; | |
| 482 | if(not -e $source) { | ||||
| 483 | die "LaTeX source ($source) does not exist!"; | ||||
| 484 | } elsif (not -r $source) { | ||||
| 485 | die "Cannot read file $source."; | ||||
| 486 | } | ||||
| 487 | if(substr($source,0,1) ne '/') { | ||||
| 488 | my $cwd = `pwd`; chomp $cwd; | ||||
| 489 | $source = $cwd . '/' . $source; | ||||
| 490 | } | ||||
| 491 | system("ln -s $source $latexfn"); | ||||
| 492 | -e "$latexfn" or die "Unable to create link to source file ($source)"; | ||||
| 93517c80 » | amax | 2007-05-10 | 493 | } else { | |
| d57771e6 » | redsymbol | 2007-10-06 | 494 | my $latexfh; | |
| 495 | open($latexfh,">",$latexfn) or die "could not write to latex temp file"; | ||||
| 496 | print $latexfh $pre, $eqn, $post; | ||||
| 497 | close($latexfh); | ||||
| 93517c80 » | amax | 2007-05-10 | 498 | } | |
| 499 | |||||
| 500 | # produce dvi output | ||||
| 501 | system("cd $tempdir; $latex -interaction=batchmode $latexfn >/dev/null"); | ||||
| 502 | unless (-e "${tempdir}/foo.dvi") { | ||||
| 503 | print STDERR <<'EOT'; | ||||
| 504 | latex run failed. Perhaps the input is invalid, or a specified | ||||
| 505 | package was not found. | ||||
| 506 | EOT | ||||
| 507 | exit(1); | ||||
| 508 | } | ||||
| 509 | |||||
| 510 | # convert dvi to ps | ||||
| 511 | # the -E option prevents convert from freaking out later | ||||
| 512 | my $dvipscmd = "$dvips " . ($opt_F ? "": "-E") . " foo -o 2>/dev/null"; | ||||
| 513 | system("cd $tempdir; $dvipscmd"); | ||||
| 514 | unless (-e "${tempdir}/foo.ps") { | ||||
| 515 | print STDERR <<'EOT'; | ||||
| 516 | Conversion of DVI to PS, a needed intermediate step, has failed. | ||||
| 517 | This probably should not happen. Please send a bug report to | ||||
| 518 | amax@redsymbol.net. | ||||
| 519 | EOT | ||||
| 520 | exit(2); | ||||
| 521 | } | ||||
| 522 | |||||
| 523 | # convert ps to png | ||||
| 524 | my @cargs; | ||||
| 525 | if($opt_F) { # make image of full latex document | ||||
| 526 | @cargs = (); | ||||
| 527 | } else { | ||||
| 528 | @cargs = ( | ||||
| 529 | '-units', | ||||
| 530 | 'PixelsPerInch', | ||||
| 531 | '-density', | ||||
| 532 | "$dpi", | ||||
| 533 | ); | ||||
| 534 | } | ||||
| 535 | if ($opt_T) { # transparent background | ||||
| 536 | @cargs = ( | ||||
| 537 | '-matte', | ||||
| 538 | '-fuzz', | ||||
| 539 | $fuzz . '%', | ||||
| 540 | '-transparent', | ||||
| 541 | '#' . norm2hex($bg), | ||||
| 542 | '-units', | ||||
| 543 | 'PixelsPerInch', | ||||
| 544 | '-density', | ||||
| 545 | "$dpi", | ||||
| 546 | ); | ||||
| 547 | } | ||||
| 548 | # Border | ||||
| 549 | if($opt_B) { | ||||
| 550 | my($geom, $color); | ||||
| 551 | if($opt_B =~ /\s/) { | ||||
| 552 | # user has defined a border color | ||||
| 553 | $opt_B =~ m|^(\S+)\s+(.+)$|; | ||||
| 554 | ($geom, $color) = ($1, $2); | ||||
| 555 | $color = join(',', parsergb($color)); | ||||
| 556 | } else { | ||||
| 557 | # no border color defined, so use regular background color | ||||
| 558 | ($geom, $color) = ($opt_B, $bg); | ||||
| 559 | } | ||||
| 560 | $color = '#' . norm2hex($color); | ||||
| 561 | unshift @cargs, ('-border', $geom, '-bordercolor', $color); | ||||
| 562 | } | ||||
| 563 | unshift @cargs, ("$convert"); | ||||
| 564 | push @cargs, ( | ||||
| 565 | "${tempdir}/foo.ps", | ||||
| 566 | "${tempdir}/foo.png", | ||||
| 567 | ); | ||||
| 568 | # The following system() call seems to be completely successful. | ||||
| 569 | # However, using the ``system(...) or die "died: $!"'' idiom results | ||||
| 570 | # in death with the error message 'Inappropriate ioctl for device'. I | ||||
| 571 | # never could discern why, so I've left it as is. If you know why, | ||||
| 572 | # please let me know (amax@redsymbol.net) | ||||
| 573 | system(@cargs); | ||||
| 574 | unless (-e "$tempdir/foo.png") { | ||||
| 575 | print STDERR <<'EOT'; | ||||
| 576 | Sorry, something went wrong. Final conversion to PNG format has failed. | ||||
| 577 | EOT | ||||
| 578 | exit(2); | ||||
| 579 | } | ||||
| 580 | |||||
| 581 | # rename final png | ||||
| 582 | system("cp $tempdir/foo.png $outfile"); | ||||
