eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
if 0;
use strict; # to be sure, that all is safe ... :-)
# $Id: tikz2pdf.pl 2012-01-17 08:41:35Z Pablo $
# v. 0.1 Extract tikzpicture, based on pst2pdf by Herbert Voss
# 2012-01-17 (c) Pablo González Luengo
# Thanks to Giuseppe Matarazzo.
# Couple to have the complete operation of the script, you need some software (Linux and Windows)
# xpdf (needed to create EPS / PPM)
# gnuplot (not necessary if not called from TiKZ)
# pdftk (not necessary with the-pdftk)
# ImageMagick (required if you want to create JPG / PNG or other format)
#
use File::Path;
use File::Copy;
use File::Basename;
use IO::File;
use Getopt::Long;
#----------------------- User part begin ------------------------
my $imageDir = "images";
my $Iext = ".pdf"; # leave empty, if not a special one
my $tempDir = "."; # temporary directory
my $verbose = 1; # 0 or 1, logfile
my $clear = 0; # 0 or 1, clears all temporary files
my $DPI = 75; # very low value for the png's
my $Iscale = 1; # for \includegraphics
my $noImages = 0; # 1->create no images
my $force = 0; # 1->force create images
my $ppm = 0; # 1->create .ppm files
my $norun = 0; # 1->runs pdflatex
my $miktex = 0; # 1->runs pdlatex for miktex
my $eps = 0; # 1->create .eps files
my $ifiles = 0; # 1->create image files .tex
my $all = 0; # 1->create all images and files for type
my $nopdftk = 0; # 1->create all images and files for type in force mode
#----------------------- User part end ---------------------------
#----------------------- program identification, options and help
my $program = "tikz2pdf";
my $ident = '$Id: tikz2pdf.pl 2012-01-17 pablo $';
my $copyright = <<END_COPYRIGHT ;
Copyright 2012-01-17 (c) Pablo Gonzalez L <pablgonz\@yahoo.com>
END_COPYRIGHT
my $licensetxt= <<END_LICENSE ;
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
END_LICENSE
my $title = "$program $ident\n";
my $usage = <<"END_OF_USAGE";
${title}Usage: $program <texfile.tex> [Options]
tikz2pdf run a TeX source, and extract all TiKZ-related part as
single images (pdf or eps or ppm, default pdf)
and then runs pdflatex. See tikz2pdf documentation for more info
Options:
--help - display this help and exit
--version - display version information and exit
--license - display license information and exit
--imageDir - the dir for the created images (default images)
--DPI=<int> - the dots per inch for a cretaed ppm files (default 75)
--ppm - create .ppm files
--eps - create .eps files
--Iscale=<real> - the value for [scale=] in \\includegraphics
--noImages - generate files without compile (need -norun)
--verbose - creates long log
--clear - delete all temp files
--norun - create file-pdf.tex, but, no run pdflatex
--miktex - for miktex users -enable-write18
--ifiles - create images files (.tex) for all TiKZ enviroment
--force - create images whitout pdftk.
--all - create all image type and images.tex
--nopdftk - create all image type and images.tex in force mode
Examples:
* $program test.tex --all
* produce test-pdf.tex and ppm,eps,tex and pdf for TiKZ-enviroment in image dir
END_OF_USAGE
#
my $result=GetOptions (
"help",
"version",
"license",
"DPI=i" => \$DPI, # numeric
"Iscale=f" => \$Iscale, # real
"imageDir=s" => \$imageDir, # string
"tempDir=s" => \$tempDir, # string
"Iext=s" => \$Iext, # string
"clear" => \$clear, # flag
"noImages" => \$noImages, # flag
"force" => \$force, # flag
"ppm" => \$ppm, # flag
"norun" => \$norun, # flag
"miktex" => \$miktex, # flag
"eps" => \$eps, # flag
"ifiles" => \$ifiles, # flag
"all" => \$all, # flag
"nopdftk" => \$nopdftk, # flag
"verbose" => \$verbose,
) or die $usage;
# help functions
sub errorUsage { die "Error: @_ (try --help for more information)\n"; }
# options for command line
if ($::opt_help) {
print $usage;
exit (0);
}
if ($::opt_version) {
print $title;
print $copyright;
exit (0);
}
if ($::opt_license) {
print $licensetxt;
exit (0);
}
# open file
my $InputFilename = "";
@ARGV > 0 or errorUsage "Input filename missing";
@ARGV < 2 or errorUsage "Unknown option or too many input files";
$InputFilename = $ARGV[0];
# end open file
my @SuffixList = (".tex","",".ltx"); # possible extensions
my ($name,$path,$ext) = fileparse($ARGV[0],@SuffixList);
if ($ext eq "") { $ext = ".tex"; } # me need the extension as well
my $TeXfile = "$path$name$ext";
my $Logfile = "$tempDir/$name.plog"; # our own log file
open (LOGfile,">$Logfile") or die "cannot open $Logfile!";
LOG ("Parameters:");
LOG ("==> imageDir = $imageDir");
LOG ("==> Iext = $Iext");
LOG ("==> DPI = $DPI");
LOG ("==> Iscale = $Iscale");
LOG ("==> tempDir = $tempDir");
LOG ("==> verbose = $verbose");
LOG ("==> clear = $clear");
LOG ("==> noImages = $noImages");
LOG ("==> force = $force");
LOG ("==> ppm = $ppm");
LOG ("==> norun = $norun");
LOG ("==> miktex = $miktex");
LOG ("==> eps = $eps");
LOG ("==> ifiles = $ifiles");
# General options
if ($ppm) {
LOG ("Generate .ppm files ...");
$ppm = 1;
}
if ($norun) {
LOG ("no compile file-pdf.tex");
$norun = 1;
}
if ($miktex) {
LOG ("enable write 18 ...");
$miktex = 1;
}
if ($eps) {
LOG ("Generate .eps files ...");
$eps = 1;
}
if ($ifiles) {
LOG ("Generate .tex images files ...");
$ifiles=1;
}
if ($all) {
LOG ("Generate all images files ...");
$ifiles=$eps = $ppm = $clear = 1;
}
if ($nopdftk) {
LOG ("Forced generate all images files ...");
$force=$ifiles=$eps = $ppm = $clear = 1;
}
# Internal counter
my $imgNo = 1;
# force mode , compile separte files
if ($force) {
LOG ("Running on [$path][$name][$ext]");
open (FILE, "<$TeXfile") or die "cannot open source file $TeXfile!";
LOG ("force generate images...");
if (-d $imageDir) { LOG ("$imageDir exists") }
else { mkdir("$imageDir", 0744) or die "cannot mkdir $imageDir: $!";}
savePreamble($name);
runFile($name);
close FILE;
close LOGfile;
}
else{
LOG ("Running on [$path][$name][$ext]");
open (FILE, "<$TeXfile") or die "cannot open source file $TeXfile!";
if (!$noImages ) {
if (-d $imageDir) { LOG ("$imageDir exists") }
else {
mkdir("$imageDir", 0744) or die "cannot mkdir $imageDir: $!";
LOG ("Imagedir created"); }
LOG ("go to savePreamble ... ");
runBurst($tempDir);
savePreamble($name);
runFile($name);
LOG ("done!\n go to runFile ...");
LOG ("done!");
close FILE;
close LOGfile;
}
}
#------------ Create filename-pics.pdf, split and generate .ppm
sub runBurst{
if ($force){ print "Force mode";}
else{
# Append preview
my $entrada="$TeXfile";
my $salida ="$name-pics.tex";
open (ENTRADA,"<$entrada");
open (SALIDA,">$salida") ;
print SALIDA "\\AtBeginDocument\{\n";
print SALIDA "\\RequirePackage\[active,tightpage\]\{preview\}\n";
print SALIDA "\\renewcommand\\PreviewBbAdjust\{-600pt -600pt 600pt 600pt\}\n";
print SALIDA "\\PreviewEnvironment\{tikzpicture\}\}\n";
while (my $linea=<ENTRADA>)
{
print SALIDA $linea;
}
close (ENTRADA);
close (SALIDA);
# close preview
if ($miktex){system("pdflatex -enable-write18 -interaction=batchmode $name");}
else{
system("pdflatex -shell-escape -interaction=batchmode $tempDir/$name-pics.tex");
system("pdfcrop $tempDir/$name-pics.pdf $tempDir/$name-pics.pdf");
system("pdftk $name-pics.pdf burst output $imageDir/$name-tikz-\%1d.pdf");
}
if ($ppm){
system("pdftoppm -r $DPI $name-pics.pdf $imageDir/$name-tikz");
}
}
}
#------------ end pdftk burst
LOG ("runpdfTeX ... ");
runpdfTeX("$path$name",$name);
LOG ("all finished ... :-)");
if ( $clear ) {
unlink "$path$name.txt";
unlink "$path$name.log";
unlink "$path$name.plog";
unlink "$path$name.preamble";
unlink "$path$name.pdf";
}
# Save preable
sub savePreamble {
my $filename = pop;
LOG ("----- Start Preamble -----");
open (FILEp, ">$tempDir/$filename.preamble")
or die "cannot open preamble file $tempDir/$filename.preamble!";
while (<FILE>) {
my $i = index($_,"begin{document}");
if ($i > 0) {
if ($i > 1) { print FILEp substr($_,0,--$i); }
if ($force) {
print FILEp "\\pagestyle{empty}\n";
}
close(FILEp);
LOG ("----- Close Preamble ------");
return;
} else {
print FILEp "$_";
LOG ("$_");
}
}
close(FILEp);
if ( $verbose ) { LOG("<-----Preamble<----"); }
return;
}
sub searchTiKZ {
my @TikZ = ();
my @TIKZtotal = ();
my $depth = -1;
my $type = -1;
my $EndDocument = 0;
my $iVerb = 0;
while (<FILE>) {
if (!$EndDocument) {
chomp;
my $line = $_;
if ( !$iVerb ) {
$iVerb = ((index($line,"begin{verbatim}") > 0) or (index($line,"begin{lstlisting}") > 0));
}
if ( !$iVerb ) {
my $iTIKZ = index($line,"begin{tikzpicture}");
if ( $type < 0 ) {
if ($iTIKZ > 0) {
$type = 2;
$line = substr($line,$iTIKZ-1);
LOG("TiKZ-line: $line");
}
}
if ($type > 0) {
LOG ("searchTiKZ: set \$type=$type");
$iTIKZ = index($line,"end{tikzpicture}");
if ($iTIKZ > 0) {
LOG ("searchTiKZ: $line");
$type = -1;
push @TikZ,substr($line,0,$iTIKZ+16);
LOG ("searchTiKZ: set \$type=$type");
push @TIKZtotal,[@TikZ];
LOG ("---->TiKZ---->\n@TikZ\n<----TikZ<----");
@TikZ =();
} else { push @TikZ,$line; } # add line
}
my $i = index($line,"end{document}");
if ($i > 0) { $EndDocument++; LOG("EndDocument in searchTiKZ"); }
}
if (( index($line,"end{verbatim}") > 0 ) or ( index($line,"end{lstlisting}") > 0 )) { $iVerb = 0; }
}}
if ( $verbose ) {
LOG("---->TIKZtotal---->");
for my $aref ( @TIKZtotal ) {
my @a = @$aref;
my $i = 1;
foreach ( @a ) { LOG ($a[$i]); $i=$i+1; }
}
LOG ("<----TIKZtotal<----");
}
close(FILE);
return @TIKZtotal;
}
# Creating ifile.tex and eps, pdf and ppm for images
if ($force){
sub runFORCE{
my $filename = pop;
if ($miktex){system("pdflatex -enable-write18 -interaction=batchmode $tempDir/$filename-tikz");}
else{system("pdflatex -interaction=batchmode $tempDir/$filename-tikz");}
if ($ifiles){
copy("$filename-tikz.tex", "$imageDir/$filename-tikz-$imgNo.tex") or die "Cannot copy Source file!";
}
system("pdfcrop $tempDir/$filename-tikz.pdf $imageDir/$filename-tikz-$imgNo.pdf");
if ($eps) {system("pdftops -level3 -eps $imageDir/$filename-tikz-$imgNo.pdf $imageDir/$filename-tikz-$imgNo.eps");}
if ($ppm) {system("pdftoppm -r $DPI $imageDir/$filename-tikz-$imgNo.pdf $imageDir/$filename-tikz-$imgNo");}
$imgNo=$imgNo+1;
}
}
else{
# Creating ifiles.tex and .eps for images
sub runTeX{
my $filename = pop;
if ($eps){
system("pdftops -level3 -eps $imageDir/$filename-$imgNo.pdf $imageDir/$filename-$imgNo.eps");
}
if ($ifiles){
copy("$filename.tex", "$imageDir/$filename-$imgNo.tex") or die "Cannot copy Source file!";
}
$imgNo=$imgNo+1;
}
}
sub runFile {
my $filename = pop;
my @TIKZarray = searchTiKZ();
if ( $verbose ) {
LOG("---->TIKZarray---->");
for my $aref ( @TIKZarray ) {
my @a = @$aref;
my $i = 1;
foreach ( @a ) { print LOG $a[$i]."\n"; $i=$i+1; }
}
LOG("<----TIKZarray<----");
my $no = @TIKZarray;
LOG("TiKZ: ".$no." TiKZ sequence(s)");
}
for my $aref ( @TIKZarray ) {
my @TikZ = @$aref;
open (FILEp,"<$tempDir/$filename.preamble") or die "cannot open $tempDir/$filename.preamble!";
open (FILEsub,">$tempDir/$filename-tikz.tex") or die "cannot open $tempDir/$filename-tikz.tex!";
while (<FILEp>) {print FILEsub $_; }
print FILEsub "\\begin{document}\n";
if ( $verbose ) { LOG("\@TikZ: $_"); }
foreach ( @TikZ ) { print FILEsub "$_\n"; }
print FILEsub "\\end{document}";
close (FILEsub);
close (FILEp);
if ($force) {
runFORCE("$name");
}
else{
runTeX("$tempDir/$name-tikz");
}
}
}
# Renaming ppm need for correct name
my $dren = "$tempDir/$imageDir";
my $fichero = '';
my $ppmren = '';
my $renNo = 1;
if(opendir(DIR,$dren)){
foreach (readdir DIR){
$fichero = $_;
if ( $fichero =~ /($name-tikz-)(\d+|\d+[-]\d+).ppm/) {
my $renNo = int($2);
my $newname="$1$renNo.ppm";
$ppmren = rename("$dren/$fichero","$dren/$newname");
}
}
}
closedir DIR;
# end renaming
# Replace files
sub runpdfTeX() {
my ($name,$pdfname) = @_;
open (PDF, ">$tempDir/$pdfname-pdf.tex") or die "cannot open $tempDir/$pdfname-pdf.tex!";
open (FILE, "<$name.tex") or die "cannot open $name!";
print PDF "\\RequirePackage{grfext}\n";
print PDF "\\PrependGraphicsExtensions*{$Iext}\n";
print PDF "\\RequirePackage{graphicx}\n";
print PDF "\\graphicspath{{$imageDir/}}\n";
my $ignore = 0;
my $IMGno = 1;
my $depth = -1;
my $type = -1;
my $EndDocument = 0;
my $iVerb = 0;
while (<FILE>) {
if ( !$iVerb ) {
$iVerb = ((index($_,"begin{verbatim}") > 0) or (index($_,"begin{lstlisting}") > 0));
}
if ( !$iVerb ) {
my $i = index($_,"end{document}");
if ($i > 0) { print PDF $_; $EndDocument++; LOG("EndDocument in runpdfTeX"); }
if ( !$EndDocument ) {
my $iTIKZ = index($_,"begin{tikzpicture}");
if ( $iTIKZ > 0 ) {
$type = 2;
$ignore = 1;
if ($iTIKZ > 1) { print PDF substr($_,0,--$iTIKZ); }
print PDF "\\includegraphics[scale=$Iscale]{$pdfname-tikz-$IMGno}";
$IMGno=$IMGno+1;
}
if ( !$ignore ) { print PDF "$_"; }
if ( $type == 2 ) {
my $iTIKZ = index($_,"end{tikzpicture}");
if ($iTIKZ > 0) {
print PDF substr($_,$iTIKZ+16);
$ignore = 0;
$type=-1;
}
}
}
} else { print PDF $_; }
if (( index($_,"end{verbatim}") > 0 ) or ( index($_,"end{lstlisting}") > 0 )) { $iVerb = 0; }
}
close (FILE);
close (PDF);
if ($norun){print "Done\n";}
else {
system("pdflatex -interaction=batchmode $pdfname-pdf");
if ($ppm){
print "If you need to create JPG/PNG type cd $imageDir and run\n";
print "mogrify -format jpg *.ppm\n";
}
print "Done\n";
}
if ( $clear ) {
unlink "$name.txt";
unlink "$tempDir/$name.aux";
unlink "$tempDir/$pdfname-pdf.log";
unlink "$tempDir/$pdfname-pdf.aux";
unlink "$tempDir/$pdfname-pdf-autopp.txt";
unlink "$tempDir/$pdfname-pics.pdf";
unlink "$tempDir/doc_data.txt";
unlink "$tempDir/$pdfname-tikz.tex";
unlink "$tempDir/$name-tikz.pdf";
unlink "$tempDir/$name-tikz.dvi";
unlink "$tempDir/$name-tikz.ps";
unlink "$tempDir/$name-tikz.aux";
unlink "$tempDir/$name-tikz.log";
unlink "$tempDir/$name.ps";
unlink "$tempDir/$name.dvi";
unlink "$tempDir/$name-pics.pdf";
unlink "$tempDir/$name-pics.tex";
unlink "$tempDir/$name-pics.aux";
unlink "$tempDir/$name-pics.log";
}
}
sub LOG() {
if ( $verbose ) { print LOGfile "@_\n"; }
}
__END__