summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-05-02 18:32:35 +0000
committerKarl Berry <karl@freefriends.org>2018-05-02 18:32:35 +0000
commit7118801c6c53b01dfad47da9c5498b08338c336e (patch)
tree09df808dfe701cb988078a16e221e5f5fd801316
parentac73f1b110ba60d5da94718ea8e0c5c098cb3f8b (diff)
ltximg (12apr18)
git-svn-id: svn://tug.org/texlive/trunk@47568 c570f23f-e606-0410-a88d-b1316a301751
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ltximg/ltximg.pl2345
-rw-r--r--Master/texmf-dist/doc/support/ltximg/CHANGES7
-rw-r--r--Master/texmf-dist/doc/support/ltximg/CHANGUES.md25
-rw-r--r--Master/texmf-dist/doc/support/ltximg/README51
-rw-r--r--Master/texmf-dist/doc/support/ltximg/README.md112
-rw-r--r--Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdfbin346033 -> 190044 bytes
-rw-r--r--Master/texmf-dist/doc/support/ltximg/ltximg-doc.tex337
-rwxr-xr-xMaster/texmf-dist/scripts/ltximg/ltximg.pl2345
-rw-r--r--Master/texmf-dist/source/support/ltximg/ltximg-doc.dtx1594
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds1
10 files changed, 4918 insertions, 1899 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl b/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
index d9aefa8164a..738ccb51cc0 100755
--- a/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
+++ b/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
@@ -1,53 +1,68 @@
-eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' if 0;
-use v5.18;
-use File::Path; # creating/removing dirs
-use File::Copy; # copying files
-use File::Basename; # scan argument
-use IO::File; # simple IO operation
-use Getopt::Long qw(:config bundling_override); # read parameter and activate "bundling"
-use autodie; # more safe
+#!/usr/bin/env perl
+use v5.22; # minimum version
+use File::Basename;
+use Getopt::Long qw(:config bundling_values require_order no_ignore_case);
+use File::Temp qw(tempdir);
+use File::Copy;
use Config;
-use File::Spec;
+use File::Spec::Functions qw(catfile devnull);
use File::Find;
+use Cwd;
+use autodie;
+#use Data::Dumper; # for test
-#------------------------ Constantes ----------------------------------#
-my $tempDir = "."; # temporary directory
-my $other = "other"; # other environment for search
-my $imageDir = "images"; # Dir for images (images default)
-my $ignore = "ignore"; # ignore verbatim environment
-my $exacount = 1; # Counter for source images
-my $imgNo = 1; # Counter for PGF/TIKZ/PST environments
-my $nopreview = 0; # 1->create images in nopreview mode
-my $noSource = 0; # Delete TeX source for images
-my $nopdf = 0; # No create a PDF image file
-my $clear = 0; # 0 or 1, clears all temporary files
-my $DPI = "150"; # value for ppm, png, jpg
-my $margins = "0"; # margins for pdf crop
-my $latex = 0; # 1->create all images using latex
-my $xetex = 0; # 1->create all images using xelatex
-my $luatex = 0; # 1->create all images using lualatex
-my $png = 0; # 1->create .png using Ghoscript
-my $jpg = 0; # 1->create .jpg using Ghoscript
-my $eps = 0; # 1->create .eps using pdftops
-my $svg = 0; # 1->create .svg files
-my $ppm = 0; # 1->create .ppm using pdftoppm
-my $all = 0; # 1->create all images and files for type
-my $output = 0; # 1->create output file whitout PGF/PST
-my $miktex = 0; # 1->enable write 18 for miktex system
-my $Verbose = 0; # 0 or 1, logfile
-
-#------------------------------ CHANGES -------------------------------#
-# v1.2 2015-04-21 - Change mogrify to gs for image formats
-# - Create output file
-# - Rewrite source code and fix regex
-# - Add more image format
-# - Change date to iso format
-# v1.0 2013-12-01 - First public release
-#----------------------------------------------------------------------#
-
-#----------------------------- Search GS ------------------------------#
-# The next code its part of pdfcrop from TexLive 2014
-# Windows detection
+### Directory for work and tmp files
+my $tempDir = tempdir( CLEANUP => 1);
+my $tempSys = dirname($tempDir);
+my $workdir = cwd;
+my $null = devnull();
+
+### Program identification
+my $program = "LTXimg";
+my $nv='v1.5';
+my $copyright = <<END_COPYRIGHT ;
+[2018-04-12] (c) 2013-2018 by Pablo Gonzalez, pablgonz<at>yahoo.com
+END_COPYRIGHT
+
+### Default values
+my $prefix = 'fig'; # defaul prefix for extract files
+my $skiptag = 'noltximg'; # internal tag for regex
+my $extrtag = 'ltximg'; # internal tag for regex
+my $imageDir = "images"; # dir for images
+my $verbcmd = "myverb"; # set \myverb command
+my $margins = "0"; # margins for pdfcrop
+my $DPI = "150"; # dpi for image formats
+my $arara = 0; # use arara to compiler
+my $force = 0; # force capture \psset|\tikzset
+my $latex = 0; # compiling all images using latex
+my $dvips = 0; # compiling output using dvips>ps2pdf
+my $dvipdf = 0; # compiling all images using dvipdfmx
+my $xetex = 0; # compiling all images using xelatex
+my $luatex = 0; # compiling all images using lualatex
+my $noprew = 0; # don't use preview packpage
+my $srcenv = 0; # create src code for environments
+my $subenv = 0; # create sub document for environments
+my @extr_env_tmp; # save extract environments
+my @skip_env_tmp; # save skip some environments
+my @verb_env_tmp; # save verbatim environments
+my @verw_env_tmp; # save verbatim write environments
+my @delt_env_tmp; # save delete environments in output file
+my @clean; # clean options
+my $pdf = 1; # create a PDF image file
+my $run = 1; # run mode compiler
+my $crop = 1; # croped pdf image files
+my $gray = 0; # create a gray scale images
+my $output; # set output name for outfile
+my $outfile = 0; # write output file
+my $outsrc = 0; # enable write src env files
+my $debug = 0; # debug
+my $PSTexa = 0; # extract PSTexample environment
+my $STDenv = 0; # extract standart environments
+my $verbose = 0; # verbose
+
+### Search Ghostscript
+# The next code it's part of pdfcrop adapted from TexLive 2014
+# Windows detection
my $Win = 0;
$Win = 1 if $^O =~ /mswin32/i;
$Win = 1 if $^O =~ /cygwin/i;
@@ -56,10 +71,10 @@ my $archname = $Config{'archname'};
$archname = 'unknown' unless defined $Config{'archname'};
# get Ghostscript command name
-$::opt_gscmd = '';
+my $gscmd = '';
sub find_ghostscript () {
- return if $::opt_gscmd;
- if ($Verbose) {
+ return if $gscmd;
+ if ($debug) {
print "* Perl executable: $^X\n";
if ($] < 5.006) {
print "* Perl version: $]\n";
@@ -83,9 +98,9 @@ sub find_ghostscript () {
$system = "cygwin" if $^O =~ /cygwin/i;
$system = "miktex" if defined($ENV{"TEXSYSTEM"}) and
$ENV{"TEXSYSTEM"} =~ /miktex/i;
- print "* OS name: $^O\n" if $Verbose;
- print "* Arch name: $archname\n" if $Verbose;
- print "* System: $system\n" if $Verbose;
+ print "* OS name: $^O\n" if $debug;
+ print "* Arch name: $archname\n" if $debug;
+ print "* System: $system\n" if $debug;
my %candidates = (
'unix' => [qw|gs gsc|],
'dos' => [qw|gs386 gs|],
@@ -121,12 +136,12 @@ sub find_ghostscript () {
foreach my $dir (@path) {
my $file = File::Spec->catfile($dir, "$candidate$exe");
if (-x $file) {
- $::opt_gscmd = $candidate;
+ $gscmd = $candidate;
$found = 1;
- print "* Found ($candidate): $file\n" if $Verbose;
+ print "* Found ($candidate): $file\n" if $debug;
last;
}
- print "* Not found ($candidate): $file\n" if $Verbose;
+ print "* Not found ($candidate): $file\n" if $debug;
}
last if $found;
}
@@ -134,11 +149,11 @@ sub find_ghostscript () {
$found = SearchRegistry();
}
if ($found) {
- print "* Autodetected ghostscript command: $::opt_gscmd\n" if $Verbose;
+ print "* Autodetected ghostscript command: $gscmd\n" if $debug;
}
else {
- $::opt_gscmd = $$candidates_ref[0];
- print "* Default ghostscript command: $::opt_gscmd\n" if $Verbose;
+ $gscmd = $$candidates_ref[0];
+ print "* Default ghostscript command: $gscmd\n" if $debug;
}
}
@@ -146,7 +161,7 @@ sub SearchRegistry () {
my $found = 0;
eval 'use Win32::TieRegistry qw|KEY_READ REG_SZ|;';
if ($@) {
- if ($Verbose) {
+ if ($debug) {
print "* Registry lookup for Ghostscript failed:\n";
my $msg = $@;
$msg =~ s/\s+$//;
@@ -162,24 +177,24 @@ sub SearchRegistry () {
my $software = new Win32::TieRegistry $current_key, $open_params;
if (not $software) {
print "* Cannot find or access registry key `$current_key'!\n"
- if $::opt_verbose;
+ if $debug;
return $found;
}
- print "* Search registry at `$current_key'.\n" if $Verbose;
+ print "* Search registry at `$current_key'.\n" if $debug;
my %list;
foreach my $key_name_gs (grep /Ghostscript/i, $software->SubKeyNames()) {
$current_key = "$key_name_software$key_name_gs/";
- print "* Registry entry found: $current_key\n" if $Verbose;
+ print "* Registry entry found: $current_key\n" if $debug;
my $key_gs = $software->Open($key_name_gs, $open_params);
if (not $key_gs) {
- print "* Cannot open registry key `$current_key'!\n" if $Verbose;
+ print "* Cannot open registry key `$current_key'!\n" if $debug;
next;
}
foreach my $key_name_version ($key_gs->SubKeyNames()) {
$current_key = "$key_name_software$key_name_gs/$key_name_version/";
- print "* Registry entry found: $current_key\n" if $Verbose;
+ print "* Registry entry found: $current_key\n" if $debug;
if (not $key_name_version =~ /^(\d+)\.(\d+)$/) {
- print " The sub key is not a version number!\n" if $Verbose;
+ print " The sub key is not a version number!\n" if $debug;
next;
}
my $version_main = $1;
@@ -187,13 +202,13 @@ sub SearchRegistry () {
$current_key = "$key_name_software$key_name_gs/$key_name_version/";
my $key_version = $key_gs->Open($key_name_version, $open_params);
if (not $key_version) {
- print "* Cannot open registry key `$current_key'!\n" if $Verbose;
+ print "* Cannot open registry key `$current_key'!\n" if $debug;
next;
}
$key_version->FixSzNulls(1);
my ($value, $type) = $key_version->GetValue('GS_DLL');
if ($value and $type == REG_SZ()) {
- print " GS_DLL = $value\n" if $Verbose;
+ print " GS_DLL = $value\n" if $debug;
$value =~ s|([\\/])([^\\/]+\.dll)$|$1gswin32c.exe|i;
my $value64 = $value;
$value64 =~ s/gswin32c\.exe$/gswin64c.exe/;
@@ -201,10 +216,10 @@ sub SearchRegistry () {
$value = $value64;
}
if (-f $value) {
- print "EXE found: $value\n" if $Verbose;
+ print "EXE found: $value\n" if $debug;
}
else {
- print "EXE not found!\n" if $Verbose;
+ print "EXE not found!\n" if $debug;
next;
}
my $sortkey = sprintf '%02d.%03d %s',
@@ -212,812 +227,1638 @@ sub SearchRegistry () {
$list{$sortkey} = $value;
}
else {
- print "Missing key `GS_DLL' with type `REG_SZ'!\n" if $Verbose;
+ print "Missing key `GS_DLL' with type `REG_SZ'!\n" if $debug;
}
}
}
foreach my $entry (reverse sort keys %list) {
- $::opt_gscmd = $list{$entry};
- print "* Found (via registry): $::opt_gscmd\n" if $Verbose;
+ $gscmd = $list{$entry};
+ print "* Found (via registry): $gscmd\n" if $debug;
$found = 1;
last;
}
return $found;
+} # end GS search
+
+### If windows
+if ($Win and $gscmd =~ /\s/) {
+ $gscmd = "\"$gscmd\"";
}
+### Call GS
find_ghostscript();
-if ($Win and $::opt_gscmd =~ /\s/) {
- $::opt_gscmd = "\"$::opt_gscmd\"";
-}
-# end GS search
-
-#-----------------Program identification, options and help ------------#
+### Program identification, options and help for command line
-my $program = "LTXimg";
-my $nv='1.1';
-my $copyright = <<END_COPYRIGHT ;
-2015-04-21 - Copyright (c) 2013-2015 by Pablo Gonzalez L.
-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
+ 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 3 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.
END_LICENSE
-my $title = "$program $nv, $copyright";
+
+my $title = "$program $nv $copyright";
my $usage = <<"END_OF_USAGE";
-${title}
-Usage: ltximg file.tex [options]
-
-LTXimg extract and convert all PGF|TiKZ|Pstricks environments from TeX
- source into single images files (pdf/png/eps/jpg/svg) using Ghostscript.
- By default search and extract environments using (pdf)LaTeX.
-
-Environments suports by LTXimg:
-
- pspicture tikzpicture pgfpicture forest ganttchart
- tikzcd circuitikz dependency other postscript
-
-Options:
-
- -h,--help - display this help and exit
- -l,--license - display license information and exit
- -v,--version - display version (current $nv) and exit
- -d,--dpi=<int> - the dots per inch for images (default $DPI)
- -j,--jpg - create .jpg files (need Ghostscript)
- -p,--png - create .png files (need Ghostscript)
- -e,--eps - create .eps files (need pdftops)
- -s,--svg - create .svg files (need pdf2svg)
- -P,--ppm - create .ppm files (need pdftoppm)
- -a,--all - create .(pdf,eps,jpg,png) images
- -c,--clear - delete all temp and aux files
- -o,--output - create a file-out.tex whitout PGF|TiKZ|PST code
- -m,--margins=<int> - margins in bp for pdfcrop (default 0)
- -np,--nopreview - create images files whitout preview package
- -ns,--nosource - delete all source for images files
- --miktex - use --enable-write18 for MikTeX users
- --xetex - using (Xe)LaTeX for create images
- --latex - using LaTeX for create images
- --luatex - using (Lua)LaTeX for create images
- --nopdf - don't create a PDF image files (default off)
- --other=<string> - search other environment (default other)
- --ignore=<string> - skip verbatim environment (default ignore)
- --imgdir=<string> - the folder for images (default images)
-
-
-
-Example:
-* ltximg test.tex -e -p -j -c -o --imgdir=pics
-* produce test-out.tex whitout PGF|TiKZ|PST environments and create "pics"
-* dir whit all images (pdf,eps,png,jpg) and source (.tex) for all related
-* parts using (pdf)LaTeX whit preview package and cleaning all tmp files.
-* Suport bundling for short options: ltximg test.tex -epjco --imgdir=pics
+${title}** Description **
+ LTXimg is a "perl" script that automates the process of extracting and
+ converting "environments" provided by tikz, pstricks and other packages
+ from LaTeX file to image formats in "individual files" using ghostscript
+ and poppler-utils. Generates a one file with only extracted environments
+ and other with all extracted environments converted to \\includegraphics.
+
+** Syntax **
+ \$ ltximg [<compiler>] [<options>] [--] <filename>.<tex|ltx>
+
+** Usage **
+ \$ ltximg --latex [<options>] <file.tex>
+ \$ ltximg --arara [<options>] <file.tex>
+ \$ ltximg [<options>] <file.tex>
+ \$ ltximg <file.tex>
+
+ If used without [<compiler>] and [<options>] the extracted environments
+ are converted to pdf image format and saved in the "/images" directory
+ using "pdflatex" and "preview" package. Relative or absolute paths for
+ directories and files is not supported, if the last option take a list
+ separated by commas you need -- at the end.
+
+** Default environments extract **
+ pspicture tikzpicture pgfpicture psgraph postscript PSTexample
+
+** Options **
+ [default]
+-h, --help Display command line help and exit [off]
+-l, --license Display GPL license and exit [off]
+-v, --version Display current version ($nv) and exit [off]
+-t, --tif Create .tif files using ghostscript [$gscmd]
+-b, --bmp Create .bmp files using ghostscript [$gscmd]
+-j, --jpg Create .jpg files using ghostscript [$gscmd]
+-p, --png Create .png files using ghostscript [$gscmd]
+-e, --eps Create .eps files using poppler-utils [pdftops]
+-s, --svg Create .svg files using poppler-utils [pdftocairo]
+-P, --ppm Create .ppm files using poppler-utils [pdftoppm]
+-g, --gray Gray scale for images using ghostscript [off]
+-f, --force Capture "\\psset" and "\\tikzset" to extract [off]
+-n, --noprew Create images files whitout "preview" package [off]
+-d <integer>, --dpi <integer>
+ Dots per inch resolution for images [150]
+-m <integer>, --margin <integer>
+ Set margins for pdfcrop [0]
+--imgdir <dirname> Set name of directory to save images [images]
+-o <filename>, --output <filename>
+ Create output file [off]
+--verbose Verbose printing [off]
+--srcenv Create files whit only code environment [off]
+--subenv Create files whit preamble and code [off]
+--latex Using latex>dvips>ps2pdf for compiler input
+ and pdflatex for compiler output [off]
+--dvips Using latex>dvips>ps2pdf for compiler input
+ and latex>dvips>ps2pdf for compiler output [off]
+--arara Use arara for compiler input and output [off]
+--xetex Using xelatex for compiler input and output [off]
+--dvipdf Using dvipdfmx for compiler input and output [off]
+--luatex Using lualatex for compiler input and output [off]
+--prefix <string> Set prefix append to each image file [off]
+--norun Run script, but no create images files [off]
+--nopdf Don't create a ".pdf" image files [off]
+--nocrop Don't run pdfcrop [off]
+--verbcmd <cmdname> Set "\\cmdname" verbatim command [myverb]
+--clean (doc|pst|tkz|all|off)
+ Removes specific text in output file [doc]
+--extrenv <env1,...> Add new environments to extract [empty]
+--skipenv <env1,...> Skip environments to extract [empty]
+--verbenv <env1,...> Add verbatim environments [empty]
+--writenv <env1,...> Add verbatim write environments [empty]
+--deltenv <env1,...> Delete environments in output file [empty]
+
+** Example **
+ \$ ltximg --latex -e -p --srcenv --imgdir=mypics -o test-out test-in.ltx
+ \$ ltximg --latex -ep --srcenv --imgdir mypics -o test-out test-in.ltx
+
+ Create a "/mypics" directory whit all extracted environments converted to
+ image formats (.pdf, .eps, .png), individual files whit source code (.tex)
+ for all extracted environments, a file "test-out.ltx" whit all extracted
+ environments converted to \\includegraphics and file "test-in-fig-all.tex"
+ with only the extracted environments using latex>dvips>ps2pdf and preview
+ package for <input file> and pdflatex for <output file>.
+
+** Documentation **
+ For extended documentation use:
+ \$ texdoc ltximg
END_OF_USAGE
-# Options
-my $result=GetOptions (
- 'h|help' => \$::opt_help,
- 'v|version' => \$::opt_version,
- 'l|license' => \$::opt_license,
- 'd|dpi=i' => \$DPI,# numeric
- 'm|margins=i' => \$margins,# numeric
- 'imgdir=s' => \$imageDir, # string
- 'ignore=s' => \$ignore, # string
- 'other=s' => \$other, # string
- 'c|clear' => \$clear, # flag
- 'np|nopreview' => \$nopreview, # flag
- 'e|eps' => \$eps, # flag
- 'j|jpg' => \$jpg, # flag
- 'p|png' => \$png, # flag
- 'P|ppm' => \$ppm, # flag
- 's|svg' => \$svg, # flag
- 'a|all' => \$all, # flag
- 'miktex' => \$miktex, # flag
- 'nopdf' => \$nopdf, # flag
- 'o|output' => \$output, # flag
- 'xetex' => \$xetex, # flag
- 'latex' => \$latex, # flag
- 'luatex' => \$luatex,# flag
- 'ns|nosource' => \$noSource, # flag
- 'Verbose' => \$Verbose,
-) or die $usage;
-
-# help functions
+### Error in command line
sub errorUsage { die "@_ (try ltximg --help for more information)\n"; }
-
-# options for command line
-if ($::opt_help) {
+
+### Getopt::Long configuration
+my %opts_cmd;
+
+my $result=GetOptions (
+# short and long options
+ 'h|help' => \$opts_cmd{help}, # help
+ 'v|version' => \$opts_cmd{version}, # version
+ 'l|license' => \$opts_cmd{license}, # license
+ 'd|dpi=i' => \$DPI, # numeric
+ 'm|margin=i' => \$margins, # numeric
+ 'b|bmp' => \$opts_cmd{bmp}, # gs
+ 't|tif' => \$opts_cmd{tif}, # gs
+ 'j|jpg' => \$opts_cmd{jpg}, # gs
+ 'p|png' => \$opts_cmd{png}, # gs
+ 's|svg' => \$opts_cmd{svg}, # pdftocairo
+ 'e|eps' => \$opts_cmd{eps}, # pdftops
+ 'P|ppm' => \$opts_cmd{ppm}, # pdftoppm
+ 'g|gray' => \$gray, # gray (bolean)
+ 'f|force' => \$force, # force (bolean)
+ 'n|noprew' => \$noprew, # no preview (bolean)
+ 'o|output=s{1}' => \$output, # output file name (string)
+# bolean options
+ 'subenv' => \$subenv, # subfile environments (bolean)
+ 'srcenv' => \$srcenv, # source files (bolean)
+ 'arara' => \$arara, # arara compiler
+ 'xetex' => \$xetex, # xelatex compiler
+ 'latex' => \$latex, # latex compiler
+ 'luatex' => \$luatex, # lualatex compiler
+ 'dvips' => \$dvips, # dvips compiler
+ 'dvipdf' => \$dvipdf, # dvipdfmx compiler
+# string options from command line
+ 'extrenv=s{1,9}' => \@extr_env_tmp, # extract environments
+ 'skipenv=s{1,9}' => \@skip_env_tmp, # skip environment
+ 'verbenv=s{1,9}' => \@verb_env_tmp, # verbatim environment
+ 'writenv=s{1,9}' => \@verw_env_tmp, # verbatim write environment
+ 'deltenv=s{1,9}' => \@delt_env_tmp, # delete environment
+# string options
+ 'imgdir=s{1}' => \$imageDir, # images dir name
+ 'verbcmd=s{1}' => \$verbcmd, # \myverb inline (string)
+ 'prefix=s{1}' => \$prefix, # prefix
+# negated options
+ 'crop!' => \$crop, # run pdfcrop
+ 'pdf!' => \$pdf, # pdf image format
+ 'clean=s{1}' => \@clean, # clean output file
+ 'run!' => \$run, # run compiler
+ 'debug!' => \$debug, # debug mode
+ 'verbose!' => \$verbose, # debug mode,
+ ) or die $usage;
+
+### Remove white space and '=' in array captured from command line
+s/^\s*(\=):?|\s*//mg foreach @extr_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @skip_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @verb_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @verw_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @delt_env_tmp;
+
+### Split comma separte list options from command line
+@extr_env_tmp = split(/,/,join('',@extr_env_tmp));
+@skip_env_tmp = split(/,/,join('',@skip_env_tmp));
+@verb_env_tmp = split(/,/,join('',@verb_env_tmp));
+@verw_env_tmp = split(/,/,join('',@verw_env_tmp));
+@delt_env_tmp = split(/,/,join('',@delt_env_tmp));
+
+### Validate input string options
+if ( grep( /(^\-|^\.).*?/, @extr_env_tmp ) ) {
+ die errorUsage "Invalid option for --extrenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @skip_env_tmp ) ) {
+ die errorUsage "Invalid option for --skipenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @verb_env_tmp ) ) {
+ die errorUsage "Invalid option for --verbenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @verw_env_tmp ) ) {
+ die errorUsage "Invalid option for --verwenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @delt_env_tmp ) ) {
+ die errorUsage "Invalid option for --deltenv, invalid environment name";
+}
+
+### Help
+if (defined $opts_cmd{help}){
+ find_ghostscript();
print $usage;
exit(0);
}
-if ($::opt_version) {
+
+### Version
+if (defined $opts_cmd{version}){
print $title;
exit(0);
}
-if ($::opt_license) {
+
+### Licence
+if (defined $opts_cmd{license}){
print $licensetxt;
exit(0);
-}
-# General options
-if ($latex) {
- $latex = 1;
}
-if ($xetex) {
- $xetex = 1;
+
+### Set tmp random name for name-fig-tmp (temp files)
+my $tmp = "$$";
+
+### Check --srcenv and --subenv option from command line
+if ($srcenv && $subenv) {
+ die errorUsage "--srcenv and --subenv options are mutually exclusive";
}
-if ($luatex) {
- $luatex = 1;
+
+### Check the input file from command line
+@ARGV > 0 or errorUsage "Input filename missing";
+@ARGV < 2 or errorUsage "Unknown option or too many input files";
+
+### Check input file extention
+my @SuffixList = ('.tex', '', '.ltx'); # posibles
+my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
+$ext = '.tex' if not $ext;
+
+### Read input file in memory (slurp), need :crlf for windows/linux
+open my $INPUTfile, '<:crlf', "$name$ext";
+my $archivo;
+ {
+ local $/;
+ $archivo = <$INPUTfile>;
+ }
+close $INPUTfile;
+
+### Funtion uniq
+sub uniq {
+ my %seen;
+ grep !$seen{$_}++, @_;
}
-if ($nopdf) {
- $nopdf = 1;
+### Funtion array_minus
+sub array_minus(\@\@) {
+ my %e = map{ $_ => undef } @{$_[1]};
+ return grep( ! exists( $e{$_} ), @{$_[0]} );
}
-if ($eps) {
- $eps = 1;
+
+### Funtion to create hash begin -> BEGIN, end -> END
+sub crearhash{
+ my %cambios;
+ for my $aentra(@_){
+ for my $initend (qw(begin end)) {
+ $cambios{"\\$initend\{$aentra"} = "\\\U$initend\E\{$aentra";
+ }
+ }
+ return %cambios;
}
-if ($jpg) {
- $jpg = 1;
+
+### Default environment to extract
+my @extr_tmp = qw (
+ postscript tikzpicture pgfpicture pspicture psgraph
+ );
+
+push(@extr_env_tmp,@extr_tmp);
+
+### Default verbatim environment
+my @verb_tmp = qw (
+ Example CenterExample SideBySideExample PCenterExample PSideBySideExample
+ verbatim Verbatim BVerbatim LVerbatim SaveVerbatim PSTcode
+ LTXexample tcblisting spverbatim minted listing lstlisting
+ alltt comment chklisting verbatimtab listingcont boxedverbatim
+ demo sourcecode xcomment pygmented pyglist program programl
+ programL programs programf programsc programt
+ );
+
+push(@verb_env_tmp,@verb_tmp);
+
+### Default verbatim write environment
+my @verbw_tmp = qw (
+ filecontents tcboutputlisting tcbexternal extcolorbox extikzpicture
+ VerbatimOut verbatimwrite PSTexample filecontentsdef filecontentshere
+ );
+
+push(@verw_env_tmp,@verbw_tmp);
+
+### Rules to capture in regex
+my $braces = qr/ (?:\{)(.+?)(?:\}) /msx;
+my $braquet = qr/ (?:\[)(.+?)(?:\]) /msx;
+my $no_corchete = qr/ (?:\[ .+? \])? /msx;
+
+### Capture new verbatim environments defined in input file
+my @new_verb = qw (
+ newtcblisting DeclareTCBListing ProvideTCBListing NewTCBListing
+ lstnewenvironment NewListingEnvironment NewProgram specialcomment
+ includecomment DefineVerbatimEnvironment newverbatim newtabverbatim
+ );
+
+### Regex to capture names for new verbatim environments from input file
+my $newverbenv = join "|", map quotemeta, sort { length $a <=> length $b } @new_verb;
+$newverbenv = qr/\b(?:$newverbenv) $no_corchete $braces/msx;
+
+### Capture new verbatim write environments defined in input file
+my @new_verb_write = qw (
+ renewtcbexternalizetcolorbox renewtcbexternalizeenvironment
+ newtcbexternalizeenvironment newtcbexternalizetcolorbox
+ );
+
+### Regex to capture names for new verbatim write environments from input file
+my $newverbwrt = join "|", map quotemeta, sort { length $a <=> length $b } @new_verb_write;
+$newverbwrt = qr/\b(?:$newverbwrt) $no_corchete $braces/msx;
+
+### Regex to capture MINTED related environments
+my $mintdenv = qr/\\ newminted $braces (?:\{.+?\}) /x;
+my $mintcenv = qr/\\ newminted $braquet (?:\{.+?\}) /x;
+my $mintdshrt = qr/\\ newmint $braces (?:\{.+?\}) /x;
+my $mintcshrt = qr/\\ newmint $braquet (?:\{.+?\}) /x;
+my $mintdline = qr/\\ newmintinline $braces (?:\{.+?\}) /x;
+my $mintcline = qr/\\ newmintinline $braquet (?:\{.+?\}) /x;
+
+### Pass input file to @array and remove % and comments
+my @verbinput = $archivo;
+s/%.*\n//mg foreach @verbinput; # del comments
+s/^\s*|\s*//mg foreach @verbinput; # del white space
+my $verbinput = join '', @verbinput;
+
+### Capture \newverbatim write names in input file
+my @newv_write = $verbinput =~ m/$newverbwrt/xg;
+
+### Add @newv_write defined in input file to @verw_env_tmp
+push(@verw_env_tmp,@newv_write);
+
+### Capture \newminted{$mintdenv}{options} (for)
+my @mint_denv = $verbinput =~ m/$mintdenv/xg;
+
+### Capture \newminted[$mintcenv]{lang} (for)
+my @mint_cenv = $verbinput =~ m/$mintcenv/xg;
+
+### Capture \newmint{$mintdshrt}{options} (while)
+my @mint_dshrt = $verbinput =~ m/$mintdshrt/xg;
+
+### Capture \newmint[$mintcshrt]{lang}{options} (while)
+my @mint_cshrt = $verbinput =~ m/$mintcshrt/xg;
+
+### Capture \newmintinline{$mintdline}{options} (while)
+my @mint_dline = $verbinput =~ m/$mintdline/xg;
+
+### Capture \newmintinline[$mintcline]{lang}{options} (while)
+my @mint_cline = $verbinput =~ m/$mintcline/xg;
+
+### Capture \newverbatim environments in input file (for)
+my @verb_input = $verbinput =~ m/$newverbenv/xg;
+
+### Add new verbatim environment defined in input file to @vrbenv
+push(@verb_env_tmp,@mint_denv,@mint_cenv,@verb_input);
+
+### Append "code" (minted)
+if (!@mint_denv == 0){
+$mintdenv = join "\n", map { qq/$_\Qcode\E/ } @mint_denv;
+@mint_denv = split /\n/, $mintdenv;
}
-if ($png) {
- $png = 1;
+
+### Append "inline" (minted)
+if (!@mint_dline == 0){
+$mintdline = join "\n", map { qq/$_\Qinline\E/ } @mint_dline;
+@mint_dline = split /\n/, $mintdline;
}
-if ($ppm) {
- $ppm = 1;
+
+### Join all minted inline/short and lstinline in @array
+my @mintline;
+my @mint_tmp = qw ( mint mintinline lstinline);
+push(@mintline,@mint_dline,@mint_cline,@mint_dshrt,@mint_cshrt,@mint_tmp);
+@mintline = uniq(@mintline);
+
+### Create a regex using @mintline
+my $mintline = join "|", map quotemeta, sort { length $a <=> length $b } @mintline;
+$mintline = qr/\b(?:$mintline)/x;
+
+### Options from input file
+# % ltximg : extrenv : {extrenv1, extrenv2, ... , extrenvn}
+# % ltximg : skipenv : {skipenv1, skipenv2, ... , skipenvn}
+# % ltximg : verbenv : {verbwrt1, verbwrt2, ... , verbwrtn}
+# % ltximg : writenv : {verbwrt1, verbwrt2, ... , verbwrtn}
+# % ltximg : deltenv : {deltenv1, deltenv2, ... , deltenvn}
+# % ltximg : options : {opt1=arg, opt2=arg, ... , bolean}
+
+### Regex to capture before preamble
+my $rx_myscrypt = qr/
+ ^ %+ \s* ltximg (?&SEPARADOR) (?<clave>(?&CLAVE)) (?&SEPARADOR) \{ (?<argumentos>(?&ARGUMENTOS)) \}
+ (?(DEFINE)
+ (?<CLAVE> \w+ )
+ (?<ARGUMENTOS> .+? )
+ (?<SEPARADOR> \s* : \s* )
+ )
+/mx;
+
+### Split input file, $optin contain % ltximg : <argument>
+my($optin, $documento) = $archivo =~ m/\A (\s* .*? \s*) (\\documentclass.*)\z/msx;
+
+### Process options from input file
+my %opts_file;
+
+while ($optin =~ /$rx_myscrypt/g) {
+ my($clave, $argumentos) = @+{qw(clave argumentos)};
+ my @argumentos = split /\s*,\s*?/, $argumentos;
+ for (@argumentos) {
+ s/^ \s* | \s* $//gx;
+ }
+ if ($clave eq 'options') {
+ for my $argumento (@argumentos) {
+ if ($argumento =~ /(?<key>\S+) \s* = \s* (?<valor>\S+)/x) {
+ $opts_file{$clave}{$+{'key'}} = $+{'valor'};
+ } # close for
+ else {
+ $opts_file{$clave}{$argumento} = 1;
+ }
+ } # close for
+ } # close if
+ else {
+ push @{ $opts_file{ $clave } }, @argumentos;
+ }
+} # close while
+
+### Validate clean
+my %clean = map { $_ => 1 } @clean;
+
+### By default clean = doc
+$clean{doc} = 1 ;
+
+### Set clean options from input file
+$clean{doc} = 1 if ($opts_file{options}{clean} eq 'doc');
+$clean{off} = 1 if ($opts_file{options}{clean} eq 'off');
+$clean{pst} = 1 if ($opts_file{options}{clean} eq 'pst');
+$clean{tkz} = 1 if ($opts_file{options}{clean} eq 'tkz');
+$clean{all} = 1 if ($opts_file{options}{clean} eq 'all');
+
+### Set clean options for script
+if ($clean{pst} or $clean{tikz}) {
+ $clean{doc} = 1;
}
-if ($svg) {
- $svg = 1;
+if ($clean{all}) {
+ @clean{qw(pst doc tkz)} = (1) x 3;
}
-if ($all){
- $eps = $png = $jpg = 1;
+if ($clean{off}) {
+ undef %clean;
}
-if ($nopreview) {
- $nopreview= 1;
+### Add extract options from input file
+if (exists $opts_file{extract} ) {
+ push @extr_env_tmp, @{ $opts_file{extract} };
}
-if ($output) {
- $output= 1;
+### Add skipenv options from input file
+if (exists $opts_file{skipenv} ) {
+ push @skip_env_tmp, @{ $opts_file{skipenv} };
}
-if ($miktex) {
- $miktex= 1;
+### Add verbenv options from input file
+if (exists $opts_file{verbenv} ) {
+ push @verb_env_tmp, @{ $opts_file{verbenv} };
}
-# 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];
+### Add writenv options from input file
+if (exists $opts_file{writenv} ) {
+ push @verw_env_tmp, @{ $opts_file{writenv} };
+}
-#--------------------- Arreglo de la extensión ------------------------#
-my @SuffixList = ('.tex', '', '.ltx'); # posible extensión
-my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
-$ext = '.tex' if not $ext;
-
-#---------------- Creamos el directorio para las imágenes -------------#
--e $imageDir or mkdir($imageDir,0744) or die "No puedo crear $imageDir: $!\n";
-
-# Define in file
-my $archivo_entrada = shift;
-
-# Standart line ltximg run
-print "$program $nv, $copyright";
-
-##---------------------------- PARTE 1 -------------------------------##
-#------------ Creamos un hash con los cambios para verbatim -----------#
-my %cambios = (
-# pst/tikz set
- '\psset' => '\PSSET',
- '\tikzset' => '\TIKZSET',
-# pspicture
- '\pspicture' => '\TRICKS',
- '\endpspicture' => '\ENDTRICKS',
+### Add deltenv options from input file
+if (exists $opts_file{deltenv} ) {
+ push @delt_env_tmp, @{ $opts_file{deltenv} };
+}
+
+### Set \myverb|<code>| options from input file
+if (exists $opts_file{options}{verbcmd}){
+ $verbcmd = $opts_file{options}{verbcmd};
+}
+
+### Create @env_all_tmp contain all environments
+my @env_all_tmp;
+push(@env_all_tmp,@extr_env_tmp,@skip_env_tmp,@verb_env_tmp,@verw_env_tmp,@delt_env_tmp);
+@env_all_tmp = uniq(@env_all_tmp);
+
+### Create @no_env_all_tmp contain all No extracted environments
+my @no_env_all_tmp;
+push(@no_env_all_tmp,@skip_env_tmp,@verb_env_tmp,@verw_env_tmp,@delt_env_tmp);
+@no_env_all_tmp = uniq(@no_env_all_tmp);
+
+### The operation return @extract environment
+my @extract = array_minus(@env_all_tmp,@no_env_all_tmp);
+@extract = uniq(@extract);
+
+### The operation return @no_extract
+my @no_extract = array_minus(@env_all_tmp,@extract);
+my @no_skip;
+push(@no_skip,@verb_env_tmp,@verw_env_tmp,@delt_env_tmp);
+my @skipped = array_minus(@no_extract,@no_skip);
+@skipped = uniq(@skipped);
+
+### The operation return @delte_env environment
+my @no_ext_skip = array_minus(@no_extract,@skipped);
+my @no_del;
+push(@no_del,@verb_env_tmp,@verw_env_tmp);
+my @delete_env = array_minus(@no_ext_skip,@no_del);
+@delete_env = uniq(@delete_env);
+
+### The operation return @verbatim environment
+my @no_ext_skip_del = array_minus(@no_ext_skip,@delete_env);
+my @verbatim = array_minus(@no_ext_skip_del,@verw_env_tmp);
+
+### The operation return @verbatim write environment
+my @verbatim_w = array_minus(@no_ext_skip_del,@verbatim);
+
+### Create @env_all for hash and replace in while
+my @no_verb_env;
+push(@no_verb_env,@extract,@skipped,@delete_env,@verbatim_w);
+my @no_verw_env;
+push(@no_verw_env,@extract,@skipped,@delete_env,@verbatim);
+
+### Reserved words in verbatim inline (while)
+my %changes_in = (
+# ltximg tags
+ '%<*ltximg>' => '%<*LTXIMG>',
+ '%</ltximg>' => '%</LTXIMG>',
+ '%<*noltximg>' => '%<*NOLTXIMG>',
+ '%</noltximg>' => '%</NOLTXIMG>',
+ '%<*remove>' => '%<*REMOVE>',
+ '%</remove>' => '%</REMOVE>',
+ '%<*ltximgverw>' => '%<*LTXIMGVERW>',
+ '%</ltximgverw>' => '%</LTXIMGVERW>',
+# pst/tikz set
+ '\psset' => '\PSSET',
+ '\tikzset' => '\TIKZSET',
# pspicture
- '\begin{pspicture' => '\begin{TRICKS',
- '\end{pspicture' => '\end{TRICKS',
-# postscript
- '\begin{postscript}' => '\begin{POSTRICKS}',
- '\end{postscript}' => '\end{POSTRICKS}',
-# $other
- "\\begin\{$other" => '\begin{OTHER',
- "\\end\{$other" => '\end{OTHER',
-# document
- '\begin{document}' => '\begin{DOCTRICKS}',
- '\end{document}' => '\end{DOCTRICKS}',
+ '\pspicture' => '\TRICKS',
+ '\endpspicture' => '\ENDTRICKS',
+# pgfpicture
+ '\pgfpicture' => '\PGFTRICKS',
+ '\endpgfpicture' => '\ENDPGFTRICKS',
# tikzpicture
- '\begin{tikzpicture}' => '\begin{TIKZPICTURE}',
- '\end{tikzpicture}' => '\end{TIKZPICTURE}',
-# pgfinterruptpicture
- '\begin{pgfinterruptpicture'=> '\begin{PGFINTERRUPTPICTURE',
- '\end{pgfinterruptpicture' => '\end{PGFINTERRUPTPICTURE',
+ '\tikzpicture' => '\TKZTRICKS',
+ '\endtikzpicture' => '\ENDTKZTRICKS',
+# psgraph
+ '\psgraph' => '\PSGRAPHTRICKS',
+ '\endpsgraph' => '\ENDPSGRAPHTRICKS',
+# some reserved
+ '\usepackage' => '\USEPACKAGE',
+ '{graphicx}' => '{GRAPHICX}',
+ '\graphicspath{' => '\GRAPHICSPATH{',
+ );
+
+### Changues for \begin... \end inline verbatim
+my %init_end = (
+# begin{ and end{
+ '\begin{' => '\BEGIN{',
+ '\end{' => '\END{',
+ );
+
+### Changues for \begin{document} ... \end{document}
+my %document = (
+# begin/end document for split
+ '\begin{document}' => '\BEGIN{document}',
+ '\end{document}' => '\END{document}',
+ );
+
+### Reverse for extract and output file
+my %changes_out = (
+# ltximg tags
+ '\begin{nopreview}' => '%<*noltximg>',
+ '\end{nopreview}' => '%</noltximg>',
+# pst/tikz set
+ '\PSSET' => '\psset',
+ '\TIKZSET' => '\tikzset',
+# pspicture
+ '\TRICKS' => '\pspicture',
+ '\ENDTRICKS' => '\endpspicture',
# pgfpicture
- '\begin{pgfpicture}' => '\begin{PGFPICTURE}',
- '\end{pgfpicture}' => '\end{PGFPICTURE}',
-# ganttchart
- '\begin{ganttchart}' => '\begin{GANTTCHART}',
- '\end{ganttchart}' => '\end{GANTTCHART}',
-# circuitikz
- '\begin{circuitikz}' => '\begin{CIRCUITIKZ}',
- '\end{circuitikz}' => '\end{CIRCUITIKZ}',
-# forest
- '\begin{forest}' => '\begin{FOREST}',
- '\end{forest}' => '\end{FOREST}',
-# tikzcd
- '\begin{tikzcd}' => '\begin{TIKZCD}',
- '\end{tikzcd}' => '\end{TIKZCD}',
-# dependency
- '\begin{dependency}' => '\begin{DEPENDENCY}',
- '\end{dependency}' => '\end{DEPENDENCY}',
-);
-
-#------------------------ Coment inline Verbatim ----------------------#
-open my $ENTRADA, '<', "$archivo_entrada";
-my $archivo;
-{
- local $/;
- $archivo = <$ENTRADA>;
-}
-close $ENTRADA;
+ '\PGFTRICKS' => '\pgfpicture',
+ '\ENDPGFTRICKS' => '\endpgfpicture',
+# tikzpicture
+ '\TKZTRICKS' => '\tikzpicture',
+ '\ENDTKZTRICKS' => '\endtikzpicture',
+# psgraph
+ '\PSGRAPHTRICKS' => '\psgraph',
+ '\ENDPSGRAPHTRICKS' => '\endpsgraph',
+# some reserved
+ '\USEPACKAGE' => '\usepackage',
+ '{GRAPHICX}' => '{graphicx}',
+ '\GRAPHICSPATH{' => '\graphicspath{',
+# begin{ and end{
+ '\BEGIN{' => '\begin{',
+ '\END{' => '\end{',
+ );
+
+### Reverse tags, need back in all file to extract
+my %reverse_tag = (
+# ltximg tags
+ '%<*LTXIMG>' => '%<*ltximg>',
+ '%</LTXIMG>' => '%</ltximg>',
+ '%<*NOLTXIMG>' => '%<*noltximg>',
+ '%</NOLTXIMG>' => '%</noltximg>',
+ '%<*REMOVE>' => '%<*remove>',
+ '%</REMOVE>' => '%</remove>',
+ '%<*LTXIMGVERW>' => '%<*ltximgverw>',
+ '%</LTXIMGVERW>' => '%</ltximgverw>',
+ );
+
+### Creatate a hash for changues
+my %extract_env = crearhash(@extract);
+my %skiped_env = crearhash(@skipped);
+my %verb_env = crearhash(@verbatim);
+my %verbw_env = crearhash(@verbatim_w);
+my %delete_env = crearhash(@delete_env);
+my %change_verbw_env = crearhash(@no_verw_env);
+my %change_verb_env = crearhash(@no_verb_env);
+
+### Join changues in new hash
+my %cambios = (%changes_in,%init_end);
-# Variables y constantes
+### Variables y constantes
my $no_del = "\0";
my $del = $no_del;
-# Reglas
-my $llaves = qr/\{ .+? \} /x;
-my $no_corchete = qr/(?:\[ .+? \])? /x;
-my $delimitador = qr/\{ (?<del>.+?) \} /x;
-my $verb = qr/(spv|v|V)erb [*]? /ix;
-my $lst = qr/lstinline (?!\*) $no_corchete /ix;
-my $mint = qr/mint (?!\*) $no_corchete $llaves /ix;
-my $marca = qr/\\ (?:$verb | $lst | $mint ) (\S) .+? \g{-1} /x;
-my $comentario = qr/^ \s* \%+ .+? $ /mx;
-my $definedel = qr/\\ (?: DefineShortVerb | lstMakeShortInline ) $no_corchete $delimitador /ix;
-my $indefinedel = qr/\\ (?: UndefineShortVerb | lstDeleteShortInline) $llaves /ix;
-
-while ($archivo =~
+### Rules
+my $llaves = qr/\{ .+? \} /x;
+my $no_llaves = qr/(?: $llaves )? /x;
+my $corchetes = qr/\[ .+? \] /x;
+my $anidado = qr/(\{(?:[^\{\}]++|(?1))*\}) /x;
+my $delimitador = qr/\{ (?<del>.+?) \} /x;
+my $verb = qr/(?:((spv|(?:q|f)?v|V)erb|$verbcmd)[*]?) /ix;
+my $lst = qr/(?:(lst|pyg)inline)(?!\*) $no_corchete /ix;
+my $mint = qr/(?: $mintline |SaveVerb) (?!\*) $no_corchete $no_llaves $llaves /ix;
+my $no_mint = qr/(?: $mintline) (?!\*) $no_corchete /ix;
+my $marca = qr/\\ (?:$verb | $lst | $mint |$no_mint) (?:\s*)? (\S) .+? \g{-1} /x;
+my $comentario = qr/^ \s* \%+ .+? $ /mx;
+my $definedel = qr/\\ (?: DefineShortVerb | lstMakeShortInline| MakeSpecialShortVerb ) [*]? $no_corchete $delimitador /ix;
+my $indefinedel = qr/\\ (?: (Undefine|Delete)ShortVerb | lstDeleteShortInline) $llaves /ix;
+
+### Changues in input file in memory
+while ($documento =~
/ $marca
| $comentario
| $definedel
| $indefinedel
- | $del .+? $del # delimitado
+ | $del .+? $del
/pgmx) {
-
- my($pos_inicial, $pos_final) = ($-[0], $+[0]); # posiciones
- my $encontrado = ${^MATCH}; # lo encontrado
-
- if ($encontrado =~ /$definedel/){ # definimos delimitador
- $del = $+{del};
- $del = "\Q$+{del}" if substr($del,0,1) ne '\\'; # es necesario "escapar" el delimitador
- }
- elsif($encontrado =~ /$indefinedel/) { # indefinimos delimitador
- $del = $no_del;
- }
- else { # aquí se hacen los cambios
+ my($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ if ($encontrado =~ /$definedel/) {
+ $del = $+{del};
+ $del = "\Q$+{del}" if substr($del,0,1) ne '\\';
+ }
+ elsif ($encontrado =~ /$indefinedel/) {
+ $del = $no_del;
+ }
+ else {
while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/g; # es necesario escapar $busco
- }
- substr $archivo, $pos_inicial, $pos_final-$pos_inicial, $encontrado; # insertamos los nuevos cambios
-
- pos($archivo)= $pos_inicial + length $encontrado; # re posicionamos la siguiente búsqueda
+ $encontrado =~ s/\Q$busco\E/$cambio/g;
}
+ substr $documento, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos($documento) = $pos_inicial + length $encontrado;
+ }
}
-# Constantes
-my $BP = '\\\\begin{postscript}';
-my $EP = '\\\\end{postscript}';
-my $BPL = '\begin{postscript}';
-my $EPL = '\end{postscript}';
-my $sipgf = 'pgfpicture';
-my $nopgf = 'pgfinterruptpicture';
-my $graphics = "graphic=\{\[scale=1\]$imageDir/$name-fig";
+### Regex for verbatim inline whit braces {...}
+my $mintd_ani = qr/\\ (?:$mintline|pygment) (?!\*) $no_corchete $no_llaves /x;
+my $tcbxverb = qr/\\ (?: tcboxverb [*]?|$verbcmd [*]?|lstinline) $no_corchete /x;
+my $tcbxmint = qr/(?:$tcbxverb|$mintd_ani) (?:\s*)? $anidado /x;
-# directorio en el cual están las imágenes
-my $dir = "$tempDir/$imageDir";
+### Changue \verb*{code} inline
+while ($documento =~ /$tcbxmint/pgmx) {
+ my($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ while (my($busco, $cambio) = each %cambios) {
+ $encontrado =~ s/\Q$busco\E/$cambio/g;
+ } # close while
+ substr $documento, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos($documento)= $pos_inicial + length $encontrado;
+} # close while
-#--------------------- Coment Verbatim environment --------------------#
+### Changue <*TAGS> to <*tags> in file
+my $ltxtags = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %reverse_tag;
+$documento =~ s/^($ltxtags)/$reverse_tag{$1}/gmsx;
-my @lineas = split /\n/, $archivo;
+### Defined environments Verbatim standart
+my $verbatim = join "|", map quotemeta, sort { length $a <=> length $b } @verbatim;
+$verbatim = qr/$verbatim/x;
-# Verbatim environments
-my $ENTORNO = qr/(?: (v|V)erbatim\*?| PSTexample | LTXexample| $ignore\*? | PSTcode | tcblisting\*? | spverbatim | minted | lstlisting | alltt | comment\*? | xcomment)/xi;
+### Defined environments Verbatim write
+my $verbatim_w = join "|", map quotemeta, sort { length $a <=> length $b } @verbatim_w;
+$verbatim_w = qr/$verbatim_w/x;
-# postscript environment
-my $POSTSCRIPT = qr/(?: postscript)/xi;
+### Define environments to skip
+my $skipenv = join "|", map quotemeta, sort { length $a <=> length $b } @skipped;
+$skipenv = qr/$skipenv/x;
-# tikzpicture environment
-my $TIKZENV = qr/(?: tikzpicture)/xi;
-#
-my $DEL;
+### Define environments to extract
+my $environ = join "|", map quotemeta, sort { length $a <=> length $b } @extract;
+$environ = qr/$environ/x;
+
+### Define environments to delete
+my $delenv = join "|", map quotemeta, sort { length $a <=> length $b } @delt_env_tmp;
+$delenv = qr/$delenv/x;
+
+### Split file by lines
+my @lineas = split /\n/, $documento;
-# tcbverb verbatim
-my $tcbverb = qr/\\(?:tcboxverb|myverb)/;
-my $arg_brac = qr/(?:\[.+?\])?/;
-my $arg_curl = qr/\{(.+)\}/;
+### Hash and Regex for changues
+my %replace = (%change_verb_env,%changes_in,%document);
+my $find = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %replace;
-# coment verbatim environment
+### Change in $verbatim and $verbatim_w
+my $DEL;
for (@lineas) {
- if (/\\begin\{($ENTORNO)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
- }
+ if (/\\begin\{($verbatim\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ s/($find)/$replace{$1}/g;
}
-}
-# coment tcolorbox inline
+ if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ my %replace = (%change_verbw_env,%changes_in,%document);
+ my $find = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %replace;
+ s/($find)/$replace{$1}/g;
+ }
+} # close for
+
+### Join lines in $documento
+$documento = join("\n", @lineas);
+
+### Split input file
+my($cabeza,$cuerpo,$final) = $documento =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
+
+### Regex for delete environment
+my $delt_env = qr /
+ (
+ (?:
+ \\begin\{$delenv\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$delenv\*?\})
+ (?!end\{$delenv\*?\})|
+ (?-1)
+ )*
+ \\end\{$delenv\*?\}
+ )
+ )
+ /x;
+
+### Regex for verbatim write environment
+my $verb_wrt = qr /
+ (
+ (?:
+ \\begin\{$verbatim_w\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim_w\*?\})
+ (?!end\{$verbatim_w\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim_w\*?\}
+ )
+ )
+ /x;
+
+### Pass $verb_wrt to %<*ltximgverw> ... %</ltximgverw>
+$cuerpo =~ s/($verb_wrt)/\%<\*ltximgverw>\n$1\n\%<\/ltximgverw>/gmsx;
+
+### Regex for skip environment
+my $skip_env = qr /
+ (
+ (?:
+ \\begin\{$skipenv\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$skipenv\*?\})
+ (?!end\{$skipenv\*?\})|
+ (?-1)
+ )*
+ \\end\{$skipenv\*?\}
+ )
+ )
+ /x;
+
+### Pass %<*noltximg> ... %</noltximg> to \begin{nopreview} ... \end{nopreview}
+$cuerpo =~ s/^\%<\*$skiptag>(.+?)\%<\/$skiptag>/\\begin\{nopreview\}$1\\end\{nopreview\}/gmsx;
+
+### Pass $skip_env to \begin{nopreview} .+? \end{nopreview}
+$cuerpo =~ s/
+ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ ($skip_env)/\\begin\{nopreview\}\n$1\n\\end\{nopreview\}\n/gmsx;
+
+### Regex to extract environments
+my $extr_env = qr /
+ (
+ (?:
+ \\begin\{$environ\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$environ\*?\})
+ (?!end\{$environ\*?\})|
+ (?-1)
+ )*
+ \\end\{$environ\*?\}
+ )
+ )
+ /x;
+
+### Set bolean options from input file
+$force = 1 if exists $opts_file{options}{force};
+$run = 0 if exists $opts_file{options}{norun};
+$pdf = 0 if exists $opts_file{options}{nopdf};
+$crop = 0 if exists $opts_file{options}{nocrop};
+$noprew = 1 if exists $opts_file{options}{noprew};
+$force = 1 if exists $opts_file{options}{force};
+$arara = 1 if exists $opts_file{options}{arara};
+$xetex = 1 if exists $opts_file{options}{xetex};
+$latex = 1 if exists $opts_file{options}{latex};
+$dvips = 1 if exists $opts_file{options}{dvips};
+$dvipdf = 1 if exists $opts_file{options}{dvipdf};
+$luatex = 1 if exists $opts_file{options}{luatex};
+$srcenv = 1 if exists $opts_file{options}{srcenv};
+$subenv = 1 if exists $opts_file{options}{subenv};
+
+### Check plain TeX syntax
+my %special = map { $_ => 1 } @extract; # anon hash
+
+### Convert \pspicture to LaTeX syntax
+if(exists($special{pspicture})){
+ $cuerpo =~ s/
+ \\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
+}
+
+### Convert \psgraph to LaTeX syntax
+if(exists($special{psgraph})){
+ $cuerpo =~ s/
+ \\psgraph(\*)?(.+?)\\endpsgraph/\\begin{psgraph$1}$2\\end{psgraph$1}/gmsx;
+}
+
+### Convert \tikzpicture to LaTeX syntax
+if(exists($special{tikzpicture})){
+ $cuerpo =~ s/
+ \\tikzpicture(.+?)\\endtikzpicture/\\begin{tikzpicture}$1\\end{tikzpicture}/gmsx;
+}
+
+### Convert \pgfpicture to LaTeX syntax
+if(exists($special{pgfpicture})){
+ $cuerpo =~ s/
+ \\pgfpicture(.+?)\\endpgfpicture/\\begin{pgfpicture}$1\\end{pgfpicture}/gmsx;
+}
+
+### Pass %<*ltximg> (.+?) %</ltximg> to \begin{preview} (.+?) \end{preview}
+$cuerpo =~ s/^\%<\*$extrtag>(.+?)\%<\/$extrtag>/\\begin\{preview\}$1\\end\{preview\}/gmsx;
+
+### $force mode for pstricks/psgraph/tikzpiture
+if ($force) {
+# pspicture or psgraph found
+if(exists($special{pspicture}) or exists($special{psgraph})){
+$cuerpo =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ \\begin\{postscript\}.+?\\end\{postscript\}(*SKIP)(*F)|
+ (?<code>
+ (?:\\psset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
+ \\begin\{(?<env> pspicture\*?| psgraph)\} .+? \\end\{\k<env>\}
+ )
+ /\\begin\{preview\}\n$+{code}\n\\end\{preview\}/gmsx;
+ } # close pspicture
+# tikzpicture found
+if(exists($special{tikzpicture})){
+$cuerpo =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ \\begin\{postscript\}.+?\\end\{postscript\}(*SKIP)(*F)|
+ (?<code>
+ (?:\\tikzset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
+ \\begin\{(?<env> tikzpicture)\} .+? \\end\{\k<env>\}
+ )
+ /\\begin\{preview\}\n$+{code}\n\\end\{preview\}/gmsx;
+ } # close tikzpicture
+} # close force mode
+
+### Pass $extr_env to \begin{preview} .+? \end{preview}
+$cuerpo =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ($extr_env)/\\begin\{preview\}\n$1\n\\end\{preview\}/gmsx;
+
+### The extract environments need back word to original
+%replace = (%changes_out,%reverse_tag);
+$find = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %replace;
+
+### Split $cabeza by lines
+@lineas = split /\n/, $cabeza;
+
+### Changues in verbatim write
for (@lineas) {
- if (m/$tcbverb$arg_brac$arg_curl/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
- }
- } # close
- }
-# remove postscript from hash
-delete @cambios{'\begin{postscript}','\end{postscript}'};
-# coment in postscript environment
+ if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ s/($find)/$replace{$1}/g;
+ }
+} # close for
+
+### Join lines in $cabeza
+$cabeza = join("\n", @lineas);
+
+### Change back betwen \begin{preview} ... \end{preview}
+@lineas = split /\n/, $cuerpo;
+
for (@lineas) {
- if (/\\begin\{($POSTSCRIPT)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
+ if (/\\begin\{(preview)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) { # range operator
+ s/($find)/$replace{$1}/g;
}
- } # close postcript environment
-}
-# remove tikzpicture from hash
-delete @cambios{'\begin{tikzpicture}','\end{tikzpicture}'};
-# coment in tikzpicture environment
-for (@lineas) {
- if (/\\begin\{($TIKZENV)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
+ if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ s/($find)/$replace{$1}/g;
}
- } # close TIKZ environment
-}
+} # close for
-undef %cambios; # erase hash
+### Join lines in $cuerpo
+$cuerpo = join("\n", @lineas);
-#------------- Convert ALL into Postscript environments ---------------#
+### If environment extract found, the run script
+my $BP = '\\\\begin\{preview\}';
+my $EP = '\\\\end\{preview\}';
-$archivo = join("\n", @lineas);
-## Partición del documento
+my @env_extract = $cuerpo =~ m/(?<=$BP)(.+?)(?=$EP)/gms;
+my $envNo = scalar @env_extract;
-my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+?) (\\begin{document} .+?)(\\end{document}.*)\z/msx;
+### PSTexample suport
+my $BE = '\\\\begin\{PSTexample\}';
+my $EE = '\\\\end\{PSTexample\}';
-# \pspicture to \begin{pspicture}
-$cuerpo =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
+my @exa_extract = $cuerpo =~ m/(?<=$BE)(.+?)(?=$EE)/gms;
+my $exaNo = scalar @exa_extract;
-# pspicture to Postscript
-$cuerpo =~ s/
- (
- (?:\\psset\{[^\}]+\}.*?)?
- (?:\\begin\{pspicture(\*)?\})
- .*?
- (?:\\end\{pspicture(\*)?\})
- )
- /$BPL\n$1\n$EPL/gmsx;
+### Check if PSTexample environment found
+if($exaNo!= 0){
+ $PSTexa=1;
+}
-# pgfpicture to Postscript
-$cuerpo =~ s/
- (
- \\begin{$sipgf}
- .*?
- (
- \\begin{$nopgf}
- .+?
- \\end{$nopgf}
- .*?
- )*?
- \\end{$sipgf}
- )
- /$BPL\n$1\n$EPL/gmsx;
+### Check if standart environment found
+if($envNo!= 0){
+ $STDenv=1;
+}
-# tikz to Postscript
-$cuerpo =~ s/
- (
- (?:\\tikzset(\{(?:\{.*?\}|[^\{])*\}).*?)? # si está lo guardo
- (?:\\begin\{tikzpicture\}) # aquí comienza la búsqueda
- .*? # guardo el contenido en $1
- (?:\\end\{tikzpicture\}) # termina la búsqueda
- ) # cierra $1
- /$BPL\n$1\n$EPL/gmsx;
-
-# rest to PostScript
-my $export = qr/(forest|ganttchart|tikzcd|circuitikz|dependency|$other\*?)/x;
-
-$cuerpo =~ s/(\\begin\{($export)\} (.*?) \\end\{\g{-2}\})/$BPL\n$1\n$EPL/gmsx;
-
-#-------------------------- Reverse changes ---------------------------#
-$archivo = "$cabeza$cuerpo$final";
-my %cambios = (
-# pst/tikz set
- '\PSSET' => '\psset',
- '\TIKZSET' => '\tikzset',
-# pspicture
- '\TRICKS' => '\pspicture',
- '\ENDTRICKS' => '\endpspicture',
-# pspicture
- '\begin{TRICKS' => '\begin{pspicture',
- '\end{TRICKS' => '\end{pspicture',
-# $other
- '\begin{OTHER' => "\\begin\{$other",
- '\end{OTHER' => "\\end\{$other",
-# document
- '\begin{DOCTRICKS}' => '\begin{document}',
- '\end{DOCTRICKS}' => '\end{document}',
-# tikzpicture
- '\begin{TIKZPICTURE}' => '\begin{tikzpicture}',
- '\end{TIKZPICTURE}' => '\end{tikzpicture}',
-# pgfinterruptpicture
- '\begin{PGFINTERRUPTPICTURE'=> '\begin{pgfinterruptpicture',
- '\end{PGFINTERRUPTPICTURE' => '\end{pgfinterruptpicture',
-# pgfpicture
- '\begin{PGFPICTURE}' => '\begin{pgfpicture}',
- '\end{PGFPICTURE}' => '\end{pgfpicture}',
-# ganttchart
- '\begin{GANTTCHART}' => '\begin{ganttchart}',
- '\end{GANTTCHART}' => '\end{ganttchart}',
-# circuitikz
- '\begin{CIRCUITIKZ}' => '\begin{circuitikz}',
- '\end{CIRCUITIKZ}' => '\end{circuitikz}',
-# forest
- '\begin{FOREST}' => '\begin{forest}',
- '\end{FOREST}' => '\end{forest}',
-# tikzcd
- '\begin{TIKZCD}' => '\begin{tikzcd}',
- '\end{TIKZCD}' => '\end{tikzcd}',
-# dependency
- '\begin{DEPENDENCY}' => '\begin{dependency}',
- '\end{DEPENDENCY}' => '\end{dependency}',
-);
-
-#-------------------------- Back Postscript ---------------------------#
-
-my @lineas = split /\n/, $archivo;
-# reverse in postscript environment
-for (@lineas) {
- if (/\\begin\{($POSTSCRIPT)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
+### PSTexample environment suport
+### Append graphic= to \begin{PSTexample}[...]
+if($PSTexa){
+my $exaNo = 1;
+while ($cuerpo =~ /\\begin\{PSTexample\}(\[.+?\])?/gsm) {
+ my $swpl_grap = "graphic=\{\[scale=1\]$imageDir/$name-$prefix-exa";
+ my $corchetes = $1;
+ my($pos_inicial, $pos_final) = ($-[1], $+[1]);
+ if (not $corchetes) {
+ $pos_inicial = $pos_final = $+[0];
}
- } # close postscript environment changes
-}
+ if (not $corchetes or $corchetes =~ /\[\s*\]/) {
+ $corchetes = "[$swpl_grap-$exaNo}]";
+ }
+ else {
+ $corchetes =~ s/\]/,$swpl_grap-$exaNo}]/;
+ }
+ substr($cuerpo, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
+ pos($cuerpo) = $pos_inicial + length $corchetes;
+} # close while
+continue {
+ $exaNo++;
+ }
-# join changes
-$archivo = join("\n", @lineas);
+### Pass PSTexample to nopreview envirnment
+$cuerpo =~ s/\%<\*ltximgverw>\n
+ (?<code>
+ \\begin\{PSTexample\} .+? \\end\{PSTexample\}
+ )
+ \n\%<\/ltximgverw>
+ /\\begin\{nopreview\}\n$+{code}\n\\end\{nopreview\}/gmsx;
+} # close PSTexa
-#--------------- Extract source code for PST/PGF/TIKZ -----------------#
-# Dividir el archivo
-my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+?) (\\begin{document} .+?)(\\end{document}.*)\z/msx;
+### Command line script identification
+print "$program $nv $copyright" ;
-# Poner el atributo añadido a PostScript
-while ($cuerpo =~ /\\begin\{postscript\}/gsm) {
-
- my $corchetes = $1;
- my($pos_inicial, $pos_final) = ($-[1], $+[1]); # posición donde están los corchetes
-
- if (not $corchetes) {
- $pos_inicial = $pos_final = $+[0]; # si no hay corchetes, nos ponemos al final de \begin
+### Check if enviroment found in input file
+if ($envNo == 0 and $exaNo == 0){
+ die errorUsage "ltximg can not find any environment to extract in file $name$ext";
+ }
+elsif ($envNo!= 0 and $exaNo!= 0){
+ say "The file $name$ext contain $envNo environment to extract and $exaNo PSTexample environment to extract";
}
- if (not $corchetes or $corchetes =~ /\[\s*\]/) { # si no hay corchetes, o están vacíos,
- $corchetes = "[$graphics-$exacount}]"; # ponemos los nuestros
+elsif ($envNo == 0 and $exaNo!= 0){
+ say "The file $name$ext contain $exaNo PSTexample environment to extract";
+ }
+else {
+ say "The file $name$ext contain $envNo environment to extract";
}
- substr($cuerpo, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
- pos($cuerpo) = $pos_inicial + length $corchetes; # reposicionamos la búsqueda de la exp. reg.
+
+### Set output file name from input file
+if (exists $opts_file{options}{output}){
+ $output = $opts_file{options}{output};
}
-continue {
- $exacount++;
+
+### Validate output file name
+if (defined $output) {
+# Not contain - at begin
+if ($output =~ /(^\-|^\.).*?/){
+ die errorUsage "$output it is not a valid name for output file";
}
-# Delte source files
-if (-e "$imageDir/$name-fig-1$ext") {
-unlink <"$imageDir/$name-fig-*$ext">;
+
+# The name of the output file must be different that $name
+if ($output eq "$name") { # $output = $input
+ $output = "$name-out$ext";
}
-#---------------------- Extract source code in images -----------------#
-while ($cuerpo =~ /$BP\[.+?(?<img_src_name>$imageDir\/.+?-\d+)\}\](?<code>.+?)(?=$EP)/gsm) {
- open my $SALIDA, '>', "$+{'img_src_name'}$ext";
- print $SALIDA <<"EOC";
-$cabeza\\pagestyle{empty}\n\\begin{document}$+{'code'}\\end{document}
-EOC
-close $SALIDA;
+# The name of the output file must be different that $name.ext
+if ($output eq "$name$ext") { # $output = $input.tex
+ $output = "$name-out$ext";
}
+# Remove .ltx or .tex extension
+if ($output =~ /.*?$ext/){
+ $output =~ s/(.+?)$ext/$1/gms;
+ }
+} # close output string check
-#--------------- Create a one file whit all figs file -----------------#
-if ($nopreview) {
-if (-e "$imageDir/$name-fig-1$ext") {
-# 1- Leer los source files
-my @pstexafiles = glob("$imageDir/$name-fig-*$ext");
+### If output name are ok, then $outfile = 1
+if(defined($output)){
+ $outfile = 1;
+}
-# 2- Ordenar según el índice y extención
-@pstexafiles =
- map { $_->[1] }
- sort { $a->[0] <=> $b->[0] }
- map { [ ($_ =~ /(\d+$ext)/), $_ ] }
- @pstexafiles;
-
-# 3- Bucle para leer las secciones
-my @almacen;
-for my $exafile (@pstexafiles) {
-
- # 3.1- Leer el archivo
- open my $FH, '<', $exafile; #
- my $tex = join q{}, <$FH>; #
- close $FH;
-
- # 3.2- Extraer la parte que nos interesa
- my($pedazo) = $tex =~ m/\\begin\{document\}\s*(.+?)\s*\\end\{document\}/sm;
-
- # 3.3- Almacenamos, si hemos encontrado algo
- push @almacen, $pedazo if $pedazo;
+### If --srcenv or --subenv option are OK then execute script
+if($srcenv){
+ $outsrc = 1;
+ $subenv = 0;
}
-# 4- Salida
-open my $SALIDA, '>', "$tempDir/$name-fig$ext";
-print $SALIDA "$cabeza\\pagestyle{empty}\n\\begin\{document\}\n";
+if ($subenv){
+ $outsrc = 1;
+ $srcenv = 0;
+}
-my $fig = 1;
-for my $item (@almacen) {
- print $SALIDA $item;
- print $SALIDA "\n%% fig $fig\n";
- print $SALIDA "\\newpage\n";
- $fig++;
+### Set imgdir name from input file
+if (exists $opts_file{options}{imgdir}){
+ $imageDir = $opts_file{options}{imgdir};
}
-
-print $SALIDA '\end{document}';
-close $SALIDA;
- } # close join files
-} # close $nopreview
-else {
-my $opcion = $xetex ? 'xetex,'
- : $latex ? ''
- : 'pdftex,'
- ;
+### Set prefix name from input file
+if (exists $opts_file{options}{prefix}){
+ $prefix = $opts_file{options}{prefix};
+}
+
+### Set pdfcrop margins from input file
+if (exists $opts_file{options}{margins}){
+ $margins = $opts_file{options}{margins};
+}
+
+### Set DPI resolution for images from input file
+if (exists $opts_file{options}{dpi}){
+ $DPI = $opts_file{options}{dpi};
+}
+
+### Create /images dir to save image and source code
+-e $imageDir or mkdir($imageDir,0744) or die "Can't create $imageDir: $!\n";
+
+### Options for \pagestyle{empty} ($crop)
+my $opt_page = $crop ? "\n\\pagestyle\{empty\}\n\\begin\{document\}"
+ : "\n\\begin\{document\}"
+ ;
+
+### Preamble options for subfiles
+my $sub_prea = "$optin$cabeza$opt_page";
+
+### Delete <*remove> ... </remove> in $sub_prea
+$sub_prea =~s/^\%<\*remove>\s*(.+?)\s*\%<\/remove>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+
+my $opt_prew = $xetex ? 'xetex,'
+ : $latex ? ''
+ : 'pdftex,'
+ ;
+
+### Lines to add at begin input file
my $preview = <<"EXTRA";
\\AtBeginDocument\{%
-\\RequirePackage\[${opcion}active,tightpage\]\{preview\}%
-\\renewcommand\\PreviewBbAdjust\{-60pt -60pt 60pt 60pt\}%
-\\newenvironment\{postscript\}\{\}\{\}%
-\\PreviewEnvironment\{postscript\}\}%
+\\RequirePackage\[${opt_prew}active,tightpage\]\{preview\}%
+\\renewcommand\\PreviewBbAdjust\{-60pt -60pt 60pt 60pt\}\}%
EXTRA
- # write
- open my $SALIDA, '>', "$tempDir/$name-fig$ext";
- print $SALIDA $preview . $archivo;
- close $SALIDA;
-}
-
-#---------------------- Create images files ---------------------------#
-# Define compilers
-my $compile = $xetex ? 'xelatex'
- : $luatex ? 'lualatex'
- : $latex ? 'latex'
- : 'pdftex'
- ;
-my $opt_compile = $miktex ? '--enable-write18 --interaction=batchmode'
- : '--shell-escape --interaction=batchmode'
- ;
-
-# Option for gs
-my $opt_gspdf='-q -dSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress';
-my $opt_gspng="-q -dSAFER -sDEVICE=pngalpha -r$DPI";
-my $opt_gsjpg="-q -dSAFER -sDEVICE=jpeg -r$DPI -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
-
-# Option for pdfcrop
-my $opt_crop= $xetex ? "--xetex --margins $margins"
- : $luatex ? "--luatex --margins $margins"
- : $latex ? "--margins $margins"
- : "--pdftex --margins $margins"
- ;
-# Fix pdftops error message in windows
-if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
-open my $ppmconf, '>', "$tempDir/xpd";
-print $ppmconf <<'EOH';
-errQuiet yes
-EOH
-close $ppmconf;
+
+### Extract source $outsrc
+if ($outsrc) {
+my $src_name = "$name-$prefix-";
+my $srcNo = 1;
+
+### Source file whitout preamble for standart environment
+if ($srcenv) {
+
+### Extract standart environment in single files
+if($STDenv){
+say "Creating $envNo files with source code for all environments";
+while ($cuerpo =~ m/$BP\s*(?<env_src>.+?)\s*$EP/gms) {
+open my $OUTsrc, '>', "$imageDir/$src_name$srcNo$ext";
+ print $OUTsrc $+{env_src};
+close $OUTsrc;
+ } # close while
+continue {
+ $srcNo++;
}
-#-------------------------- Compiling image file ----------------------#
-if($nopreview){
- print "Create $name-fig.pdf in $imageDir dir whit all PGF/TIKZ/PST using $compile\n";
+} # close STDenv
+
+### Extract PSTexample in single files
+if($PSTexa){
+say "Creating $exaNo files with source code for all PSTexample environments";
+while ($cuerpo =~ m/$BE\[.+?(?<pst_exa_name>$imageDir\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
+open my $OUTexa, '>', "$+{'pst_exa_name'}$ext";
+ print $OUTexa $+{'exa_src'};
+close $OUTexa;
+ }
+ } # close PSTexa
+} # close srcenv
+
+### Subfile whit preamble
+if ($subenv) {
+
+### Extract standart environments in subfiles
+if($STDenv){
+say "Creating a $envNo files whit source code and preamble for all environments";
+while ($cuerpo =~ m/(?<=$BP)(?<env_src>.+?)(?=$EP)/gms) { # search $cuerpo
+open my $OUTsub, '>', "$imageDir/$src_name$srcNo$ext";
+print $OUTsub <<"EOC";
+$sub_prea$+{'env_src'}\\end\{document\}
+EOC
+close $OUTsub;
+ } # close while
+continue {
+ $srcNo++;
}
-else{
- print "Create $name-fig.pdf in $imageDir dir whit all PGF/TIKZ/PST using $compile and preview package\n";
+} # close STDenv
+
+### Extract PSTexample environments in subfiles
+if($PSTexa){
+say "Creating a $exaNo files whit source code and preamble for all PSTexample environments";
+while ($cuerpo =~ m/$BE\[.+?(?<pst_exa_name>$imageDir\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
+open my $OUTsub, '>', "$+{'pst_exa_name'}$ext";
+print $OUTsub "$sub_prea\n$+{'exa_src'}\n\\end\{document\}";
+close $OUTsub;
+ } # close while
+ } # close $PSTexa
+ } # close subenv
+} # close $outsrc
+
+### Create a one file whit all PSTexample environments
+if($PSTexa){
+say "Creating the temporary file $name-$prefix-exa-$tmp$ext whit $exaNo PSTexample environments extracted";
+@exa_extract = undef;
+while ( $cuerpo =~ m/$BE\[.+? $imageDir\/.+?-\d+\}\](?<exa_src>.+?)$EE/gmsx ) { # search $cuerpo
+push @exa_extract, $+{exa_src}."\n\\newpage\n";
+open my $OUTfig, '>', "$name-$prefix-exa-$tmp$ext";
+ print $OUTfig "$optin"."$cabeza"."$opt_page"."@exa_extract\n"."\\end\{document\}";
+close $OUTfig;
+ }# close while
+
+### Move and rename tmp-exa-rand file to /image dir
+if(!$run){
+say "Moving the file $name-$prefix-exa-$tmp$ext to /$imageDir/$name-$prefix-exa-all$ext";
+move("$workdir/$name-$prefix-exa-$tmp$ext", "$imageDir/$name-$prefix-exa-all$ext");
}
-
-# Run TeX mode
-system("$compile $opt_compile -output-directory=$imageDir $tempDir/$name-fig$ext");
-if($latex){
- system("dvips -q -Ppdf -o $imageDir/$name-fig.ps $imageDir/$name-fig.dvi");
- system("ps2pdf -dPDFSETTINGS=/prepress $imageDir/$name-fig.ps $imageDir/$name-fig.pdf");
+}# close $PSTexa
+
+### Creating one file whit all environments extracted (noprew option)
+if($STDenv){
+open my $OUTfig, '>', "$name-$prefix-$tmp$ext";
+if ($noprew) {
+say "Creating the temporary file $name-$prefix-$tmp$ext whit $envNo environments extracted";
+my @env_extract;
+while ( $cuerpo =~ m/(?<=$BP)(?<env_src>.+?)(?=$EP)/gms ) { # search $cuerpo
+ push @env_extract, $+{env_src}."\n\\newpage\n";
+ } # close while
+print $OUTfig "$optin"."$cabeza"."$opt_page"."@env_extract\n"."\\end{document}";
+ } # close noprew
+else {
+say "Creating the temporary file $name-$prefix-$tmp$ext whit $envNo environment extracted using preview package";
+print $OUTfig $optin.$preview.$cabeza."\n".$cuerpo."\n\\end{document}";
+ }
+close $OUTfig;
+
+### Move tmp-rand file to /image dir
+if(!$run){
+say "Moving the file $name-$prefix-$tmp$ext to /$imageDir/$name-$prefix-all$ext";
+ move("$workdir/$name-$prefix-$tmp$ext", "$imageDir/$name-$prefix-all$ext");
}
-print "The file $imageDir/$name-fig.pdf need a cropping using pdfcrop whit options: $opt_crop\n";
-system("pdfcrop $opt_crop $imageDir/$name-fig.pdf $imageDir/$name-fig.pdf");
+} # close $STDenv
+
+### Define --shell-escape for TeXLive and MikTeX
+my $write18 = '-shell-escape'; # TeXLive
+ $write18 = '-enable-write18' if defined($ENV{"TEXSYSTEM"}) and
+ $ENV{"TEXSYSTEM"} =~ /miktex/i;
+
+### Define --interaction=mode for compilers
+my $opt_compiler = $verbose ? "$write18 -interaction=nonstopmode -recorder"
+ : "$write18 -interaction=batchmode -recorder"
+ ;
+
+### Define $silence
+my $silence = $verbose ? ''
+ : ">$null"
+ ;
+
+### Append -q to gs/poppler for system command line
+my $quiet = $verbose ? ''
+ : '-q'
+ ;
+
+### Compilers
+my $compiler = $xetex ? "xelatex $opt_compiler"
+ : $luatex ? "lualatex $opt_compiler"
+ : $latex ? "latex $opt_compiler"
+ : $dvips ? "latex $opt_compiler"
+ : $dvipdf ? "latex $opt_compiler"
+ : $arara ? 'arara'
+ : "pdflatex $opt_compiler"
+ ;
+
+### Message in command line for compilers
+my $msg_compiler = $xetex ? 'xelatex'
+ : $luatex ? 'lualatex'
+ : $latex ? 'latex>dvips>ps2pdf'
+ : $dvips ? 'latex>dvips>ps2pdf'
+ : $dvipdf ? 'latex>dvipdfmx'
+ : $arara ? 'arara'
+ : 'pdflatex'
+ ;
+
+### Options for ghostscript in command line
+my %opt_gs_dev = (
+ pdf => "$gscmd $quiet -dNOSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress",
+ gray => "$gscmd $quiet -dNOSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray",
+ png => "$gscmd $quiet -dNOSAFER -sDEVICE=pngalpha -r$DPI",
+ bmp => "$gscmd $quiet -dNOSAFER -sDEVICE=bmp32b -r$DPI",
+ jpg => "$gscmd $quiet -dNOSAFER -sDEVICE=jpeg -r$DPI -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4",
+ tif => "$gscmd $quiet -dNOSAFER -sDEVICE=tiff32nc -r$DPI",
+ );
-##-------------------------- Create image formats ----------------------#
+### Options for poppler-utils in command line
+my %opt_poppler = (
+ eps => "pdftops $quiet -eps",
+ ppm => "pdftoppm $quiet -r $DPI",
+ svg => "pdftocairo $quiet -svg",
+ );
+### Option for pdfcrop in command line
+my $opt_crop = $xetex ? "--xetex --margins $margins"
+ : $luatex ? "--luatex --margins $margins"
+ : $latex ? "--margins $margins"
+ : "--pdftex --margins $margins"
+ ;
+
+### Compiler generate file whit all environment extracted
+if($run){
+opendir(my $DIR, $workdir);
+while (readdir $DIR) {
+### Compiler generate file
+if (/(?<nombre>$name-$prefix(-exa)?)(?<type>-$tmp$ext)/) {
+ system("$compiler $+{nombre}$+{type} $silence");
+ say "Compiling the file $+{nombre}$+{type} using $msg_compiler";
+
+### Compiling file using latex>dvips>ps2pdf
+if($dvips or $latex){
+ system("dvips -q -Ppdf -o $+{nombre}-$tmp.ps $+{nombre}-$tmp.dvi");
+ system("ps2pdf -dPDFSETTINGS=/prepress -dAutoRotatePages=/None $+{nombre}-$tmp.ps $+{nombre}-$tmp.pdf");
+} # close latex
+
+### Compiling file using latex>dvipdfmx
+if($dvipdf){
+ system("dvipdfmx -q $+{nombre}-$tmp.dvi");
+} # close dvipdfmx
+
+### If option gray
+if($gray){
+say "Moving the file $+{nombre}-$tmp.pdf to $tempDir/$+{nombre}-all.pdf (gray scale)";
+system("$opt_gs_dev{gray} -o $tempDir/$+{nombre}-all.pdf $workdir/$+{nombre}-$tmp.pdf");
+ move("$workdir/$+{nombre}-$tmp.pdf","$tempDir/$+{nombre}-$tmp.pdf");
+ }
+else{
+ say "Moving the file $+{nombre}-$tmp.pdf to $tempDir/$+{nombre}-all.pdf";
+ move("$workdir/$+{nombre}-$tmp.pdf", "$tempDir/$+{nombre}-all.pdf");
+}
+
+### Crop generate file
+if($crop){
+say "The file $+{nombre}-all.pdf need a crop, using pdfcrop $opt_crop";
+system("pdfcrop $opt_crop $tempDir/$+{nombre}-all.pdf $tempDir/$+{nombre}-all.pdf $silence");
+}
+
+### Move tmp-rand.tex file whit all source code for environments to /images dir
+move("$workdir/$+{nombre}$+{type}", "$imageDir/$+{nombre}-all$ext");
+ } # close if m/.../
+ } # close while
+closedir $DIR;
+} # close run
+
+### Append image format options
+$opts_cmd{pdf} = 'pdf' if $pdf; # ghostscript
+$opts_cmd{eps} = 1 if exists $opts_file{options}{eps}; # pdftops
+$opts_cmd{ppm} = 1 if exists $opts_file{options}{ppm}; # pdftoppm
+$opts_cmd{svg} = 1 if exists $opts_file{options}{svg}; # pdftocairo
+$opts_cmd{png} = 1 if exists $opts_file{options}{png}; # ghostscript
+$opts_cmd{jpg} = 1 if exists $opts_file{options}{jpg}; # ghostscript
+$opts_cmd{bmp} = 1 if exists $opts_file{options}{bmp}; # ghostscript
+$opts_cmd{tif} = 1 if exists $opts_file{options}{tif}; # ghostscript
+
+### Suported format
+my %format = (%opts_cmd);
+my $format = join " ",grep { defined $format{$_} } keys %format;
+
+### Create image formats in separate files
+if($run){
+opendir(my $DIR, $tempDir);
+while (readdir $DIR) {
+### PDF/PNG/JPG/BMP/TIFF format suported by ghostscript
+if (/(?<nombre>$name-$prefix(-exa)?)(?<type>-all\.pdf)/) {
+for my $var (qw(pdf png jpg bmp tif)) {
+ if (defined $opts_cmd{$var}) {
+ my $ghostcmd = "$opt_gs_dev{$var} -o $workdir/$imageDir/$+{nombre}-%1d.$var $tempDir/$+{nombre}$+{type}";
+ system("$ghostcmd");
+ print "Create a $var image format: runing command $opt_gs_dev{$var} in $+{nombre}$+{type}\r\n";
+ } # close defined for ghostscript
+ }# close for
+} # close if m/.../
+
+### EPS/PPM/SVG format suported by poppler-utils
+if (/(?<nombre>$name-$prefix)(?<type>-all\.pdf)/) {
+for my $var (qw(eps ppm svg)) {
+ if (defined $opts_cmd{$var}) {
+ for (my $epsNo = 1; $epsNo <= $envNo; $epsNo++) {
+my $poppler = "$opt_poppler{$var} -f $epsNo -l $epsNo $tempDir/$+{nombre}$+{type} $workdir/$imageDir/$+{nombre}-$epsNo.$var";
+system("$poppler");
+ } # close for C style
+print "Create a $var image format: runing command $opt_poppler{$var} in $+{nombre}$+{type}\r\n";
+ } # close defined
+ } # close for my $var
+} # close if m/.../
+
+### EPS/PPM/SVG for pst-exa package
+if (/(?<nombre>$name-$prefix-exa)(?<type>-all\.pdf)/) {
+for my $var (qw(eps ppm svg)) {
+ if (defined $opts_cmd{$var}) {
+ for (my $epsNo = 1; $epsNo <= $exaNo; $epsNo++) {
+my $poppler = "$opt_poppler{$var} -f $epsNo -l $epsNo $tempDir/$+{nombre}$+{type} $workdir/$imageDir/$+{nombre}-$epsNo.$var";
+system("$poppler");
+ } # close for C style
+print "Create a $var image format: runing command $opt_poppler{$var} in $+{nombre}$+{type}\r\n";
+ } # close defined
+ } # close for my $var
+ } # close if m/.../
+} # close while
+closedir $DIR; #close dir
+
+### Renaming PPM image files
+if(defined $opts_cmd{ppm}){
opendir(my $DIR, $imageDir);
-my @figs = sort readdir $DIR;
+while (readdir $DIR) {
+ if (/(?<nombre>$name-fig(-exa)?-\d+\.ppm)(?<sep>-\d+)(?<ppm>\.ppm)/) {
+ move("$imageDir/$+{nombre}$+{sep}$+{ppm}", "$imageDir/$+{nombre}");
+ } # close if m/.../
+ } # close while
closedir $DIR;
-for my $fig (@figs) {
-if ($fig =~ /(?<fig>$name-fig-)(?<num>\d+)$ext/) {
-print "Create $imageDir/$name-fig-$+{num} from $name$ext\r";
-# PDF format
-if (!$nopdf) {
-system("$::opt_gscmd $opt_gspdf -o $imageDir/$name-fig-%1d.pdf $imageDir/$name-fig.pdf");
-}
-# PNG format
-if ($png) {
-system("$::opt_gscmd $opt_gspng -o $imageDir/$name-fig-%1d.png $imageDir/$name-fig.pdf");
- }
-# JPEG format
-if ($jpg) {
-system("$::opt_gscmd $opt_gsjpg -o $imageDir/$name-fig-%1d.jpg $imageDir/$name-fig.pdf");
- }
-
-# SVG format pdf2svg
-if ($svg) {
- system("pdf2svg $imageDir/$name-fig.pdf $imageDir/$+{fig}%1d.svg all");
- }
-# EPS format
-if ($eps) {
- if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
- system("pdftops -cfg $tempDir/xpd -q -eps -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}.eps");
- }else{
- system("pdftops -q -eps -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}.eps");
- }
- } # close EPS
-# PPM format
-if ($ppm) {
- if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
- system("pdftoppm -cfg $tempDir/xpd -q -r $DPI -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}");
- }
- else{
- system("pdftoppm -q -r $DPI -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}");
- }
- } # close PPM
- } # close if ($fig =
-} # close for
-
-## Renaming PPM
-if ($ppm) {
-if (opendir(DIR,$dir)) { # abro el directorio
- while (my $oldname = readdir DIR) { # lo recorro
- # el nuevo nombre es fruto de una sustitución
- my $newname = $oldname =~ s/^($name-(fig|exa)-\d+)(-\d+).ppm$/$1 . ".ppm"/re;
-
- if ($oldname ne $newname) { # comprobación
- rename("$dir/$oldname", "$dir/$newname"); # renombro
- }
- }
- closedir DIR;
- } # close rename ppm
-} # close ppm
-
-#------- Creating output file whitout PGF/PST/TIKZ code ---------------#
-if ($output) {
-print "Create file $name-out$ext whitout PGF/PST/TIKZ code\n";
-
-#----------------- Convert Postscript to includegraphics --------------#
-my $grap="\\includegraphics[scale=1]{$name-fig-";
+ } # close renaming PPM
+} # close run
+
+### Create a output file
+if ($outfile) {
+say "Creating the file $output$ext, changue extracted environments to \\includegraphics";
+
+### Convert extracted environments to \includegraphics
+my $grap="\\includegraphics[scale=1]{$name-$prefix-";
my $close = '}';
-my $IMGno = 1;
+my $imgNo = 1;
+$cuerpo =~ s/$BP.+?$EP/$grap@{[$imgNo++]}$close/msg; # changes
-$cuerpo =~ s/$BP.+?$EP/$grap@{[$IMGno++]}$close/msg;
+### Constant
+my $USEPACK = quotemeta('\usepackage');
+my $GRAPHICPATH = quotemeta('\graphicspath{');
-#------------------------ Clean output file --------------------------#
-# append postscript to hash
-$cambios{'\begin{POSTRICKS}'} = '\begin{postscript}';
-$cambios{'\end{POSTRICKS}'} = '\end{postscript}';
-
-# Constantes
-my $BEGINDOC = quotemeta('\begin{document}');
-my $USEPACK = quotemeta('\usepackage');
-my $REQPACK = quotemeta('\usepackage');
-my $GRAPHICX = quotemeta('{graphicx}');
-
-# Exp. Reg.
+### Precompiled regex
my $CORCHETES = qr/\[ [^]]*? \]/x;
-my $PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add )? | psfrag |psgo |vaucanson-g| auto-pst-pdf | graphicx )/x;
-my $FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}/x;
-
-# comentar
-$cabeza =~ s/ ^ ($USEPACK $CORCHETES $GRAPHICX) /%$1/msxg;
-
-# eliminar líneas enteras
-$cabeza =~ s/ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \n//msxg;
-
-# eliminar palabras sueltas
-$cabeza =~ s/ (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
-
-# Añadir
+my $PALABRAS = qr/\b (?: graphicx )/x;
+my $FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
+
+### Regex to capture \graphicspath
+my $graphix = qr/(\\ usepackage \s*\[\s* .+? \s*\] \s*\{\s* graphicx \s*\} )/ix;
+
+### Capture graphix package for future use
+my (@graphix) = $cabeza =~ m/$graphix/x;
+
+### Remove graphix package
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
+
+### Comment \graphicspath for order and future use
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ ^ ($GRAPHICPATH) /%$1/msxg;
+
+### Regex to capture [options] for pst-exa package
+my $pstexa = qr/(?:\\ usepackage) \[\s*(.+?)\s*\] (?:\{\s*(pst-exa)\s*\} ) /x;
+
+### Capture [option] for pst-exa package
+my (@pst_exa) = $cabeza =~ m/$pstexa/xg;
+
+### Search [option] in pst-exa package
+my %pst_exa = map { $_ => 1 } @pst_exa;
+
+### Clean file (pst/tags)
+if($clean{pst}){
+$PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add )? | psfrag |psgo |vaucanson-g| auto-pst-pdf )/x;
+$FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
+
+### Remove package lines
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
+
+### Delete package words
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+(?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
+
+### Delete \psset
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+
+### Delete \SpecialCoor
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\SpecialCoor(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+} # close clean{pst}
+
+### Delete empty package line \usepackage{}
+$cabeza =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+
+### Append graphix to end of preamble
+if(!@graphix == 0){
+$cabeza .= <<"EXTRA";
+@graphix
+EXTRA
+}else{
$cabeza .= <<"EXTRA";
+
\\usepackage{graphicx}
-\\graphicspath{{$imageDir/}}
+EXTRA
+}
+
+### Regex to capture \graphicspath
+my $graphicspath= qr/\\ graphicspath \{ ((?: $llaves )+) \}/ix;
+
+### If preamble contain \graphicspath
+if($cabeza =~ m/($graphicspath)/m){
+while ($cabeza =~ /$graphicspath /pgmx) {
+ my($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ if ($encontrado =~ /$graphicspath/) {
+ my $argumento = $1;
+ if ($argumento !~ /\{$imageDir\\\}/) {
+ $argumento .= "\{$imageDir/\}";
+ my $cambio = "\\graphicspath{$argumento}";
+ substr $cabeza, $pos_inicial, $pos_final-$pos_inicial, $cambio;
+ pos($cabeza) = $pos_inicial + length $cambio;
+ }
+ }
+ } #close while
+
+### Regex to capture
+my ($GraphicsPath) = $cabeza =~ m/($graphicspath)/msx;
+
+### Append graphicspath to end of preamble
+$cabeza .= <<"EXTRA";
+$GraphicsPath
\\usepackage{grfext}
\\PrependGraphicsExtensions*{.pdf}
EXTRA
-
-# Clear PST content in preamble
-$cabeza =~ s/\\usepackage\{\}/% delete/gmsx;
-$cabeza =~ s/\\psset\{.+?\}/% \\psset delete/gmsx;
-$cabeza =~ s/\\SpecialCoor/% \\SpecialCoor/gmsx;
-
-# Recorremos el archivo y realizamos los cambios
-while (my($busco, $cambio) = each %cambios) {
- $cabeza =~ s/\Q$busco\E/$cambio/g;
- $cuerpo =~ s/\Q$busco\E/$cambio/g;
- }
-
-# write
-open my $SALIDA, '>', "$tempDir/$name-out$ext";
-print $SALIDA "$cabeza$cuerpo$final";
-close $SALIDA;
-
-# compile output file
-
-if ($xetex){
- system("xelatex $opt_compile $tempDir/$name-out$ext");
- } # xetex
-elsif($luatex){
- system("lualatex $opt_compile $tempDir/$name-out$ext");
- } # luatex
+ } # close if ($cabeza)
else{
- system("pdflatex $opt_compile $tempDir/$name-out$ext");
- } # pdftex
-
-}# close output file
-
-#--------------------------------- Clean ------------------------------#
-if ($clear) {
-my @del_aux_tex;
-find(\&del_aux_tex, $tempDir);
-sub del_aux_tex{
-my $auximgfile = $_;
-# search .(aux|log)
-if(-f $auximgfile && $auximgfile =~ /$name-out\.(aux|log)$/){
-push @del_aux_tex, $File::Find::name;
- }
-if(-f $auximgfile && $auximgfile =~ /$name-fig$ext/){
-push @del_aux_tex, $File::Find::name;
- }
-}
-unlink @del_aux_tex;
-} # close clear in $tempDir
-
-if ($clear) {
-my @del_tmp;
-find(\&del_tmp, $imageDir);
-sub del_tmp{
-my $auximgfile = $_;
-# search .(aux|log)
-if(-f $auximgfile && $auximgfile =~ /$name-fig\.(aux|dvi|log|ps|pdf)/){
-push @del_tmp, $File::Find::name;
- }
-}
-
-unlink @del_tmp;
-} # close clear $name-fig.tex
-
-# Clear source files
-if ($noSource) {
-unlink <"$imageDir/$name-fig-*$ext">;
-}# end source clear
-
-if ($output) {
-print "Finish, LTXimg create $name-out$ext and put all figures in $imageDir dir\n";
-}else{
-print "Finish, LTXimg create all figures in $imageDir dir\n";
+### If preamble not contain graphicspath, append to premble
+my $GraphicsPath = "\\graphicspath\{\{$imageDir/\}\}";
+
+### Append graphicspath to end of preamble
+$cabeza .= <<"EXTRA";
+$GraphicsPath
+\\usepackage{grfext}
+\\PrependGraphicsExtensions*{.pdf}
+EXTRA
+} # close graphicspath
+
+### Suport for \usepackage[swpl]{pst-exa}
+if(exists($pst_exa{swpl})){
+$cabeza .= <<'EXTRA';
+\usepackage[swpl,pdf]{pst-exa}
+EXTRA
+}
+
+### Suport for \usepackage[tcb]{pst-exa}
+if(exists($pst_exa{tcb})){
+$cabeza .= <<'EXTRA';
+\usepackage[tcb,pdf]{pst-exa}
+EXTRA
+### Regex
+$cuerpo =~ s/(graphic=\{)\[(scale=\d*)\]($imageDir\/$name-$prefix-exa-\d*)\}/$1$2\}\{$3\}/gsmx;
+} # close if
+
+### Options for out_file (add $end to outfile)
+my $out_file = $clean{doc} ? "$optin$cabeza$cuerpo\n\\end\{document\}"
+ : "$optin$cabeza$cuerpo\n$final"
+ ;
+
+### Clean \psset content in output file
+if($clean{pst}){
+$out_file =~s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \%<\*ltximgverw> .+? \%<\/ltximgverw>(*SKIP)(*F)|
+ \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+} # close clean
+
+### Clean \tikzset content in output file
+if($clean{tkz}){
+$out_file =~s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \%<\*ltximgverw> .+? \%<\/ltximgverw>(*SKIP)(*F)|
+ \\tikzset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+} # close clean
+
+### Back changues in all words in outfile
+$out_file =~s/\\begin\{nopreview\}\s*(.+?)\s*\\end\{nopreview\}/$1/gmsx;
+$out_file =~s/\%<\*ltximgverw>\s*(.+?)\s*\%<\/ltximgverw>/$1/gmsx;
+$out_file =~s/\%<\*noltximg>\n(.+?)\n\%<\/noltximg>/$1/gmsx;
+$out_file =~s/^\%<\*remove>\s*(.+?)\s*\%<\/remove>(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+$out_file =~ s/($delt_env)(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+$out_file =~s/($find)/$replace{$1}/g;
+
+### Write output file
+open my $OUTfile, '>', "$output$ext";
+print $OUTfile "$out_file";
+close $OUTfile;
+
+### Process the output file
+if($run){
+### Set correct $compiler, if input use latex then output use pdflatex
+$compiler = "pdflatex $opt_compiler" if $latex;
+$msg_compiler = "pdflatex" if $latex;
+
+### Compiling output file using pdflatex or arara
+say "Compiling file $output$ext using $msg_compiler";
+system("$compiler $output$ext $silence");
+
+### Compiling output file using latex>dvips>ps2pdf
+if($dvips){
+ system("dvips -q -Ppdf $output.dvi");
+ system("ps2pdf -dPDFSETTINGS=/prepress -dAutoRotatePages=/None $output.ps $output.pdf");
+} # close dvips
+
+### Compiling output file using latex>dvipdfmx
+if($dvipdf){
+ system("dvipdfmx -q $output.dvi");
+ } # close dvipdf
+ } # close run
+} # close outfile file
+
+### Deleting temporary files
+if($run){
+say "Deleting (most) temporary files created during the process";
+my @protected = qw();
+push (@protected,"$output$ext","$output.pdf") if defined $output;
+
+my $flsline = "OUTPUT";
+my @flsfile;
+
+if ($PSTexa) {
+push @flsfile,"$name-$prefix-exa-$tmp.fls";
+}
+
+if ($STDenv) {
+push @flsfile,"$name-$prefix-$tmp.fls";
}
-if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
-unlink "$tempDir/xpd";
+push(@flsfile,"$output.fls") if defined $output;
+
+my @tmpfiles;
+for my $filename(@flsfile){
+ open my $RECtmp, '<', "$filename";
+ push @tmpfiles, grep /^$flsline/,<$RECtmp>;
+ close $RECtmp;
+}
+
+foreach (@tmpfiles) {
+ s/^$flsline\s+|\s+$//g;
+}
+
+if($latex or $dvips){
+ push @tmpfiles,"$name-$prefix-$tmp.ps";
+}
+
+if(-e "$name-$prefix-$tmp.ps"){
+ push @tmpfiles,"$name-$prefix-$tmp.ps";
+}
+
+if ($PSTexa) {
+ push @tmpfiles,"$name-$prefix-exa-$tmp.ps";
+}
+
+if(-e "$output.ps"){
+ push @tmpfiles,"$output.ps";
+}
+
+push @tmpfiles,@flsfile,"$name-$prefix-$tmp$ext","$name-$prefix-$tmp.pdf";
+
+my @delfiles = array_minus(@tmpfiles, @protected);
+
+foreach my $tmpfile (@delfiles){
+ move("$tmpfile", "$tempDir");
}
+} # close clean tmp files
+
+### End of script process
+if($run){
+ say "Finish, image formats: $format are in $workdir/$imageDir/";
+ }
+ else{
+ say "Done";
+} # end run
__END__
diff --git a/Master/texmf-dist/doc/support/ltximg/CHANGES b/Master/texmf-dist/doc/support/ltximg/CHANGES
deleted file mode 100644
index ea7d3e82c8f..00000000000
--- a/Master/texmf-dist/doc/support/ltximg/CHANGES
+++ /dev/null
@@ -1,7 +0,0 @@
-#------------------------------ CHANGES -------------------------------#
-v1.1 2015-04-21 - Change mogrify to gs for image formats
- - Create output file
- - Rewrite source code and fix regex
- - Add more image format
- - Change date to iso format
-v1.0 2013-12-01 - First public release
diff --git a/Master/texmf-dist/doc/support/ltximg/CHANGUES.md b/Master/texmf-dist/doc/support/ltximg/CHANGUES.md
new file mode 100644
index 00000000000..c7ff7ea2fdd
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ltximg/CHANGUES.md
@@ -0,0 +1,25 @@
+## Changues
+```
+ v1.5. (d) 2018-04-12 - Use GitHub to control version
+ - Rewrite and optimize most part of code and options
+ - Changue pdf2svg for pdftocairo
+ - Complete support for pst-exa packpage
+ - Clean take and optional
+ v1.4. (d) 2016-11-29 - Remove and rewrite code for regex and system call
+ - Append arara compiler, clean and comment code
+ - Append dvips and dvipdfm for creation images
+ - Append bmp, tif image format
+ v1.3. (d) 2016-10-16 - All options its read from cmd line and input file
+ - Rewrite some part of code (norun, nocrop, clean)
+ - Suport minted and tcolorbox packpage for verbatim
+ - Use /tmp dir for work process
+ - Escape some characters in regex according to v5.2xx
+ v1.2 (p) 2015-04-22 - Remove unused modules
+ v1.1 (p) 2015-04-21 - Change mogrify to gs for image formats
+ - Create output file
+ - Rewrite source code and fix regex
+ - Add more image format
+ - Change date to iso format
+ v1.0 (p) 2013-12-01 - First public release
+```
+Copyright 2013 - 2018 by Pablo González L <pablgonz@yahoo.com>.
diff --git a/Master/texmf-dist/doc/support/ltximg/README b/Master/texmf-dist/doc/support/ltximg/README
deleted file mode 100644
index 4a783f5a3bc..00000000000
--- a/Master/texmf-dist/doc/support/ltximg/README
+++ /dev/null
@@ -1,51 +0,0 @@
-ltximg is a Perl script which isolates all Tikz or
-PSTricks related parts of the TeX document into single
-pdf file, split and convert in eps/pdf/png/jpg/svg format.
-
-The advantage of "ltximg" is the ability to discuss the
-environments that give problems using the "preview" package
-as "verbatim" inline (verb|...|) or beginning with %, and
-other environments (LTXexample, Verbatim,etc).
-
-The images files are saved in a subdirectory images.
-
-Syntax: perl ltximg.pl file.tex [options]
-
-ltximg create a copy for TeX source whit all PGF|TiKZ|Pstricks environments
- and convert all environments into single images (pdf/png/eps/jpg).
- By default search and extract environments using (pdf)LaTeX
- and ghostscript (gs).
-
-Environments suports by LTXimg:
-
- pspicture tikzpicture pgfpicture forest ganttchart
- tikzcd circuitikz dependency other postscript
-
-Options:
-
- -h,--help - display this help and exit
- -l,--license - display license information and exit
- -v,--version - display version (current 1.2) and exit
- -d,--dpi=<int> - the dots per inch for images (default 150)
- -j,--jpg - create .jpg files (need Ghostscript)
- -p,--png - create .png files (need Ghostscript)
- -e,--eps - create .eps files (need pdftops)
- -s,--svg - create .svg files (need pdf2svg)
- -P,--ppm - create .ppm files (need pdftoppm)
- -a,--all - create .(pdf,eps,jpg,png) images
- -c,--clear - delete all temp and aux files
- -o,--output - create a file-out.tex whitout PGF|TiKZ|PST code
- -m,--margins=<int> - margins in bp for pdfcrop (default 0)
- -np,--nopreview - create images files whitout preview package
- -ns,--nosource - delete all source for images files
- --miktex - use --enable-write18 for MikTeX users
- --xetex - using (Xe)LaTeX for create images
- --latex - using LaTeX for create images
- --luatex - using (Lua)LaTeX for create images
- --nopdf - don't create a PDF image files (default off)
- --other=<string> - search other environment (default other)
- --ignore=<string> - skip verbatim environment (default ignore)
- --imgdir=<string> - the folder for images (default images)
-
-
-Pablo González Luengo, 2015-04-21
diff --git a/Master/texmf-dist/doc/support/ltximg/README.md b/Master/texmf-dist/doc/support/ltximg/README.md
new file mode 100644
index 00000000000..2f56e3b6409
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ltximg/README.md
@@ -0,0 +1,112 @@
+## LTXimg &ndash; LaTeX environments to image format
+
+## Description
+
+**ltximg** is a perl *script* that automates the process of extracting and converting
+environments provided by **tikz**, **pstricks** and other packages from input file
+to image formats in individual files using `ghostscript` and `poppler-utils`. Generates a file
+with only extracted environments and other with environments converted to `\includegraphics`.
+
+## Syntax
+```
+$ ltximg [<compiler>] [<options>] [--] <input file>.<tex|ltx>
+```
+## Usage
+```
+$ ltximg --latex [<options>] <file.tex>
+$ ltximg --arara [<options>] <file.tex>
+$ ltximg [<options>] <file.tex>
+$ ltximg <file.tex>
+```
+If used without `[<compiler>]` and `[<options>]` the extracted environments are converted to `pdf` image format
+and saved in the `/images` directory using `pdflatex` and `preview` package. Relative or absolute `paths` for files
+and directories is not supported and if the last `[<options>]` take a list separated by commas you need `--` at the end.
+
+## Default environments extract
+```
+ pspicture tikzpicture pgfpicture psgraph postscript PSTexample
+```
+## Options
+
+```
+ [default]
+-h, --help Display command line help and exit [off]
+-l, --license Display GPL license and exit [off]
+-v, --version Display current version (v1.5) and exit [off]
+-t, --tif Create .tif files using ghostscript [gs]
+-b, --bmp Create .bmp files using ghostscript [gs]
+-j, --jpg Create .jpg files using ghostscript [gs]
+-p, --png Create .png files using ghostscript [gs]
+-e, --eps Create .eps files using poppler-utils [pdftops]
+-s, --svg Create .svg files using poppler-utils [pdftocairo]
+-P, --ppm Create .ppm files using poppler-utils [pdftoppm]
+-g, --gray Gray scale for images using ghostscript [off]
+-f, --force Capture "\psset" and "\tikzset" to extract [off]
+-n, --noprew Create images files whitout "preview" package [off]
+-d <integer>, --dpi <integer>
+ Dots per inch resolution for images [150]
+-m <integer>, --margin <integer>
+ Set margins for pdfcrop [0]
+--imgdir <dirname> Set name of directory to save images [images]
+-o <filename>, --output <filename>
+ Create output file [off]
+--verbose Verbose printing [off]
+--srcenv Create files whit only code environment [off]
+--subenv Create files whit preamble and code [off]
+--latex Using latex>dvips>ps2pdf for compiler input
+ and pdflatex for compiler output [off]
+--dvips Using latex>dvips>ps2pdf for compiler input
+ and latex>dvips>ps2pdf for compiler output [off]
+--arara Use arara for compiler input and output [off]
+--xetex Using xelatex for compiler input and output [off]
+--dvipdf Using dvipdfmx for compiler input and output [off]
+--luatex Using lualatex for compiler input and output [off]
+--prefix <string> Set prefix append to each image file [off]
+--norun Run script, but no create images files [off]
+--nopdf Don't create a ".pdf" image files [off]
+--nocrop Don't run pdfcrop [off]
+--verbcmd <cmdname> Set "\cmdname" verbatim command [myverb]
+--clean (doc|pst|tkz|all|off)
+ Removes specific text in output file [doc]
+--extrenv <env1,...> Add new environments to extract [empty]
+--skipenv <env1,...> Skip environments to extract [empty]
+--verbenv <env1,...> Add verbatim environments [empty]
+--writenv <env1,...> Add verbatim write environments [empty]
+--deltenv <env1,...> Delete environments in output file [empty]
+```
+## Example
+```
+$ ltximg --latex -e -p --srcenv --imgdir=mypics -o test-out test-in.ltx
+```
+```
+$ ltximg --latex -ep --srcenv --imgdir mypics -o test-out test-in.ltx
+```
+ Create a `/mypics` directory whit all extracted environments converted to
+ image formats(`.pdf`, `.eps`, `.png`), individual files whit source code (`.tex`)
+ for all extracted environments, a file `test-out.ltx` whit all environments converted to `\includegraphics`
+ and file `test-in-fig-all.tex` with only the extracted environments using
+ `latex>dvips>ps2pdf` and `preview` package for `<input file>` and `pdflatex`
+ for `<output file>`.
+
+## Documentation
+ For full documentation use:
+```
+$ texdoc ltximg
+```
+
+## Licence
+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 3 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.
+
+## Author
+
+Written by Pablo González L <pablgonz@yahoo.com>, last update 2018-04-12.
+
+## Copyright
+
+Copyright 2013 - 2018 by Pablo González L
diff --git a/Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdf b/Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdf
index 90856ffefd2..86b856a5ed9 100644
--- a/Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdf
+++ b/Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/support/ltximg/ltximg-doc.tex b/Master/texmf-dist/doc/support/ltximg/ltximg-doc.tex
deleted file mode 100644
index cfe90a9d057..00000000000
--- a/Master/texmf-dist/doc/support/ltximg/ltximg-doc.tex
+++ /dev/null
@@ -1,337 +0,0 @@
-\documentclass[10pt]{article}
-\usepackage[T1]{fontenc}%
-\usepackage{hologo}%
-\usepackage{fetamont}%
-\usepackage{libertine}%
-\usepackage{booktabs}%
-\usepackage{tabularx}%
-\usepackage{tcolorbox}%
-\tcbuselibrary{documentation}%
-\usepackage[margin=1.0in,letterpaper]{geometry}%
-\usepackage[scaled=0.9]{inconsolata}%
-\usepackage{listings}%
-% colors
-\definecolor{lightgrey}{rgb}{0.9,0.9,0.9}
-\definecolor{darkgreen}{rgb}{0,0.6,0}
-\definecolor{darkred}{rgb}{0.6,0,0}
-\definecolor{myblue}{RGB}{20,105,176}
-\definecolor{darkgreen}{rgb}{0,0.6,0}
-% languaje
-\lstdefinelanguage{mytex}[LaTeX]{TeX}{
-columns=flexible,
-frame=single,
-framerule=0pt,%
-backgroundcolor=\color{gray!10},%
-xleftmargin=\fboxsep,%
-xrightmargin=\fboxsep,
-alsoletter={\\,*,\&},
-morekeywords={\\AtBeginDocument,
- \\RequirePackage,
- \\PreviewEnvironment,
- \&},
-morekeywords=[2]{pspicture,
- verbatim,
- table,
- other,
- tikzpicture,
- postscript,
- preview,
- TRICKS,
- POSTRICKS,
- TIKZPICTURE,
- OTHER,
- nopreview},
-morekeywords=[3]{\\begin,
- \\pspicture,
- \\TRICKS,
- \\ENDTRICKS,
- \\endpspicture,
- \\end},
-literate=*{\{}{{\textcolor{myblue}{\{}}}{1}
- {\}}{{\textcolor{myblue}{\}}}}{1}
- {[}{{\textcolor{myblue}{[}}}{1}
- {]}{{\textcolor{myblue}{]}}}{1},
- }
-\lstset{language=mytex}
-
-\lstdefinestyle{mystyle1}{
- basicstyle=\small\ttfamily,
- keywordstyle=\bfseries\color{red},
- keywordstyle=[2]{\color{magenta}},
- keywordstyle=[3]{\color{blue}},
- commentstyle=\color{darkgreen},
- stringstyle=\color{orange},
- identifierstyle=\ttfamily,
- showstringspaces=true,
- breaklines=true,
- tabsize=4,
- columns=fullflexible,
- keepspaces=true,
- }
-% style
-\lstset{style=mystyle1}
-\begin{document}
-\title{{\Huge\textffm{LTX}\textffmw{img} \normalsize \Large\textffmw{v1.1}}\\\small\textffm{tikz|pgf|pstricks \\to image format}}
-\author{Pablo Gonz\'{a}lez Luengo\\ \small \ttfamily pablgonz at yahoo dot com}
-\date{\today}
-\maketitle
-\begin{abstract}
-\noindent
-
-\textsf{ltximg} is a \textsf{Perl} script that automates the process to extract and convert all PGF|TiKZ|Pstricks environments from input file to image formats (pdf,png,jpg,eps,ppm,svg) and source code for environments in individual files using \textsf{Ghostscript} and other software. By default search and extract environments using \hologo{pdfLaTeX}.
-\end{abstract}
-\tableofcontents
-\section{Required Software}
-
-For the full operation of the \textsf{ltximg} script you need the following opensource programs
-(available for windows and linux).
-
-\begin{itemize}
-\item \textsf{Perl} (version 5.18 or higer).
-
-\item \textsf{Ghostscript} (version 9.16).
-
-\item \textsf{pdftops} (optional, for images in \textsf{EPS} format).
-
-\item \textsf{pdftoppm} (optional, for images in \textsf{PPM} format).
-
-\item \textsf{pdf2svg} (optional, for images in \textsf{SVG} format).
-\end{itemize}
-\newpage
-\section{Run and options}
-the syntax for \textsf{ltximg} script is simple:
-\noindent
-For \TeX Live users:
-\begin{lstlisting}
-ltximg file.tex --options
-\end{lstlisting}
-For Mik\TeX\ users:
-\begin{lstlisting}
-perl ltximg file.tex --miktex --options
-\end{lstlisting}
-
-\begin{table}[htp]
-\caption{Options for \textsf{ltximg}}
-\begin{tabularx}{\linewidth}{@{}>{\ttfamily} l>{\ttfamily} l >{\ttfamily}l X @{}}\\\toprule
-\emph{short} & \emph{long} & \emph{default} & \emph{description}\\\midrule
- -h &--help & & Display help from command line and exit.\\
- -l &--license & & Display license information and exit.\\
- -v &--version & 1.1 & Display version of script and exit.\\
- -d &--dpi=<int> & 150 & The dots per inch for images.\\
- -j &--jpg & & Create \textsf{.jpg} files (need \textsf{Ghostscript}).\\
- -p &--png & & Create \textsf{.png}files (need \textsf{Ghostscript}).\\
- -e &--eps & & Create \textsf{.eps} files (need \textsf{pdftops}).\\
- -s &--svg & & Create \textsf{.svg} files (need \textsf{pdf2svg}).\\
- -P &--ppm & & Create \textsf{.ppm} files (need \textsf{pdftoppm}).\\
- -a &--all & & Create \textsf{.(pdf,eps,jpg,png)} images.\\
- -c &--clear & & Delete all temp and aux files.\\
- -o &--output & & Create a \textsf{file-out.tex} whitout \textsf{PGF|TiKZ|PST} code.\\
- -m &--margins=<int>& 0 & Margins in bp for \textsf{pdfcrop}.\\
- -np &--nopreview & off & Create images files whitout \textsf{preview} package.\\
- -ns &--nosource & off & Delete all source for images files\\
- &--miktex &-shell-escape & Use \textsf{--enable-write18} for \hologo{MiKTeX} users.\\
- &--xetex & off & Using \hologo{XeLaTeX} for create images.\\
- &--latex & off & Using \hologo{LaTeX} for create images.\\
- &--luatex & off & Using \hologo{LuaLaTeX} for create images.\\
- &--nopdf & off & Don't create a PDF image files.\\
- &--other=<string> & other & Search \textsf{other} environment for export.\\
- &--ignore=<string> & ignore& Skip verbatim environment.\\
- &--imgdir=<string> & images & The folder for images.\\
- \bottomrule
-\end{tabularx}
-\end{table}
-
-
-
-\section{How it works}
-
-The script works in two steps for create image, source code and output file \emph{without PGF/TIKZ/PST} environments.
-
-
-\subsection{Environment Suports}
-
-\textsf{ltximg} export and convert this environment:
-
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{pspicture}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{pspicture*}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{postscript}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{circuitikz}%
-{}
-\end{docEnvironment}
-\end{minipage}
-
-\vspace{0.5cm}
-
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{tikzpicture}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{pgfpicture}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{ganttchart}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{forest}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\vspace{0.5cm}
-
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{tikzcd}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{circuitikz}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{dependency}%
-{}
-\end{docEnvironment}
-\end{minipage}
-\begin{minipage}[c]{0.25\columnwidth}
-\begin{docEnvironment}%
-{other}%
-{}
-\end{docEnvironment}
-\end{minipage}
-
-
-
-\subsection{Comment and ignore}
-
-The first step \textsf{ltximg } script create a image dir (\textsf{images/})
-and read all input file in memory, processing is as follows, being assumed that our file is \texttt{test.tex}:
-
-\begin{enumerate}
-\item Create a copy file in memory and change problematic environments (verbatim, verbatim\*, lstlisting,
- LTXexample, Verbatim, comment, alltt, minted, tcblisting, xcomment and ignore)
-
-\item Change problematic inline verbatim from varius package (lstlisting,LTXexample, Verbatim, comment, alltt, minted, tcblisting, etc) include line whit \%.
-\end{enumerate}
-
-
-
-\subsection{Create source and images}
-\begin{enumerate}
-
-\item If script is call whitout \textsf{--nopreview} option (default), adds the following lines to the beginning of the test.tex in memory and save file test-fig.tex in images dir :
-
-\begin{lstlisting}
-\AtBeginDocument{
-\RequirePackage[active,tightpage]{preview}
-\renewcommand\PreviewBbAdjust{-60pt -60pt 60pt 60pt}%
-\newenvironment{postscript}{}{}%
-\PreviewEnvironment{postscript}}%
-\end{lstlisting}
-
-\item If script is call whit \textsf{--nopreview} option, all environment code its put inside the :
-
-\begin{lstlisting}
-\begin{postscript}
-...
-\end{postscript}
-\end{lstlisting}
-
-and separate in individual files (test-fig-1.tex, test-fig-2.tex, etc) in image dir and join in test-fig.tex. The postscript environment can be used to place any material to be exported if that is not supported or fails the \textsf{--other} option.
-
-
-\item Now, the script call (pdf/lua/xe)latex in \texttt{test-fig.tex} and \textsf{pdfcrop} in
-\texttt{test-fig.pdf} and create image files.
-\end{enumerate}
-
-\section{Example}
-\begin{lstlisting}
-ltximg test.tex -e -p -j -c -o --imgdir=pics
-\end{lstlisting}
-produce test-out.tex whitout PGF|TiKZ|PST environments and create "pics" dir whit all images (pdf,eps,png,jpg) and source (.tex) for all related parts using \hologo{pdfLaTeX} whit preview package and cleaning all tmp files.
-
-\noindent
-Suport bundling for short options:
-\begin{lstlisting}
-ltximg test.tex -epjco --imgdir=pics
-\end{lstlisting}
-\end{document}
-
-
-
-LTXimg extract and convert all PGF|TiKZ|Pstricks environments from TeX
- source into single images files (pdf/png/eps/jpg/svg) using Ghostscript.
- By default search and extract environments using (pdf)LaTeX.
-
-Environments suports by LTXimg:
-
- pspicture tikzpicture pgfpicture forest ganttchart
- tikzcd circuitikz dependency other postscript
-
-Options:
-\begin{tabularx}{\linewidth}{@{}>{\ttfamily} l>{\ttfamily} l >{\ttfamily}l X @{}}\\\toprule
-\emph{short} & \emph{name} & \emph{default} & \emph{description}\\\midrule
- -h&--help & &display this help and exit
- -l&--license & &- display license information and exit
- -v&--version & & - display version (current 1.2) and exit
- -d&--dpi=<int> & 150 & - the dots per inch for images
- -j&--jpg & &- create .jpg files (need Ghostscript)
- -p&--png & &- create .png files (need Ghostscript)
- -e&--eps & &- create .eps files (need pdftops)
- -s&--svg & &- create .svg files (need pdf2svg)
- -P&--ppm & &- create .ppm files (need pdftoppm)
- -a&--all & &- create .(pdf,eps,jpg,png) images
- -c&--clear & &- delete all temp and aux files
- -o&--output & &- create a file-out.tex whitout PGF|TiKZ|PST code
- -m&--margins=<int>& &- margins in bp for pdfcrop (default 0)
- -np&--nopreview & &- create images files whitout preview package
- -ns&--nosource & &- delete all source for images files
- &--miktex & &- use --enable-write18 for MikTeX users
- &--xetex & &- using (Xe)LaTeX for create images
- &--latex & &- using LaTeX for create images
- &--luatex & &- using (Lua)LaTeX for create images
- &--nopdf & &- don't create a PDF image files (default off)
- &--other=<string> & &- search other environment (default other)
- &--ignore=<string> & &- skip verbatim environment (default ignore)
- &--imgdir=<string> & &- the folder for images (default images)
- \bottomrule
-\end{tabularx}
-
-
-Example:
-* ltximg test.tex -e -p -j -c -o --imgdir=pics
-* produce test-out.tex whitout PGF|TiKZ|PST environments and create "pics"
-* dir whit all images (pdf,eps,png,jpg) and source (.tex) for all related
-* parts using (pdf)LaTeX whit preview package and cleaning all tmp files.
-* Suport bundling for short options: ltximg test.tex -epjco --imgdir=pics
-END_OF_USAGE
diff --git a/Master/texmf-dist/scripts/ltximg/ltximg.pl b/Master/texmf-dist/scripts/ltximg/ltximg.pl
index d9aefa8164a..738ccb51cc0 100755
--- a/Master/texmf-dist/scripts/ltximg/ltximg.pl
+++ b/Master/texmf-dist/scripts/ltximg/ltximg.pl
@@ -1,53 +1,68 @@
-eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' if 0;
-use v5.18;
-use File::Path; # creating/removing dirs
-use File::Copy; # copying files
-use File::Basename; # scan argument
-use IO::File; # simple IO operation
-use Getopt::Long qw(:config bundling_override); # read parameter and activate "bundling"
-use autodie; # more safe
+#!/usr/bin/env perl
+use v5.22; # minimum version
+use File::Basename;
+use Getopt::Long qw(:config bundling_values require_order no_ignore_case);
+use File::Temp qw(tempdir);
+use File::Copy;
use Config;
-use File::Spec;
+use File::Spec::Functions qw(catfile devnull);
use File::Find;
+use Cwd;
+use autodie;
+#use Data::Dumper; # for test
-#------------------------ Constantes ----------------------------------#
-my $tempDir = "."; # temporary directory
-my $other = "other"; # other environment for search
-my $imageDir = "images"; # Dir for images (images default)
-my $ignore = "ignore"; # ignore verbatim environment
-my $exacount = 1; # Counter for source images
-my $imgNo = 1; # Counter for PGF/TIKZ/PST environments
-my $nopreview = 0; # 1->create images in nopreview mode
-my $noSource = 0; # Delete TeX source for images
-my $nopdf = 0; # No create a PDF image file
-my $clear = 0; # 0 or 1, clears all temporary files
-my $DPI = "150"; # value for ppm, png, jpg
-my $margins = "0"; # margins for pdf crop
-my $latex = 0; # 1->create all images using latex
-my $xetex = 0; # 1->create all images using xelatex
-my $luatex = 0; # 1->create all images using lualatex
-my $png = 0; # 1->create .png using Ghoscript
-my $jpg = 0; # 1->create .jpg using Ghoscript
-my $eps = 0; # 1->create .eps using pdftops
-my $svg = 0; # 1->create .svg files
-my $ppm = 0; # 1->create .ppm using pdftoppm
-my $all = 0; # 1->create all images and files for type
-my $output = 0; # 1->create output file whitout PGF/PST
-my $miktex = 0; # 1->enable write 18 for miktex system
-my $Verbose = 0; # 0 or 1, logfile
-
-#------------------------------ CHANGES -------------------------------#
-# v1.2 2015-04-21 - Change mogrify to gs for image formats
-# - Create output file
-# - Rewrite source code and fix regex
-# - Add more image format
-# - Change date to iso format
-# v1.0 2013-12-01 - First public release
-#----------------------------------------------------------------------#
-
-#----------------------------- Search GS ------------------------------#
-# The next code its part of pdfcrop from TexLive 2014
-# Windows detection
+### Directory for work and tmp files
+my $tempDir = tempdir( CLEANUP => 1);
+my $tempSys = dirname($tempDir);
+my $workdir = cwd;
+my $null = devnull();
+
+### Program identification
+my $program = "LTXimg";
+my $nv='v1.5';
+my $copyright = <<END_COPYRIGHT ;
+[2018-04-12] (c) 2013-2018 by Pablo Gonzalez, pablgonz<at>yahoo.com
+END_COPYRIGHT
+
+### Default values
+my $prefix = 'fig'; # defaul prefix for extract files
+my $skiptag = 'noltximg'; # internal tag for regex
+my $extrtag = 'ltximg'; # internal tag for regex
+my $imageDir = "images"; # dir for images
+my $verbcmd = "myverb"; # set \myverb command
+my $margins = "0"; # margins for pdfcrop
+my $DPI = "150"; # dpi for image formats
+my $arara = 0; # use arara to compiler
+my $force = 0; # force capture \psset|\tikzset
+my $latex = 0; # compiling all images using latex
+my $dvips = 0; # compiling output using dvips>ps2pdf
+my $dvipdf = 0; # compiling all images using dvipdfmx
+my $xetex = 0; # compiling all images using xelatex
+my $luatex = 0; # compiling all images using lualatex
+my $noprew = 0; # don't use preview packpage
+my $srcenv = 0; # create src code for environments
+my $subenv = 0; # create sub document for environments
+my @extr_env_tmp; # save extract environments
+my @skip_env_tmp; # save skip some environments
+my @verb_env_tmp; # save verbatim environments
+my @verw_env_tmp; # save verbatim write environments
+my @delt_env_tmp; # save delete environments in output file
+my @clean; # clean options
+my $pdf = 1; # create a PDF image file
+my $run = 1; # run mode compiler
+my $crop = 1; # croped pdf image files
+my $gray = 0; # create a gray scale images
+my $output; # set output name for outfile
+my $outfile = 0; # write output file
+my $outsrc = 0; # enable write src env files
+my $debug = 0; # debug
+my $PSTexa = 0; # extract PSTexample environment
+my $STDenv = 0; # extract standart environments
+my $verbose = 0; # verbose
+
+### Search Ghostscript
+# The next code it's part of pdfcrop adapted from TexLive 2014
+# Windows detection
my $Win = 0;
$Win = 1 if $^O =~ /mswin32/i;
$Win = 1 if $^O =~ /cygwin/i;
@@ -56,10 +71,10 @@ my $archname = $Config{'archname'};
$archname = 'unknown' unless defined $Config{'archname'};
# get Ghostscript command name
-$::opt_gscmd = '';
+my $gscmd = '';
sub find_ghostscript () {
- return if $::opt_gscmd;
- if ($Verbose) {
+ return if $gscmd;
+ if ($debug) {
print "* Perl executable: $^X\n";
if ($] < 5.006) {
print "* Perl version: $]\n";
@@ -83,9 +98,9 @@ sub find_ghostscript () {
$system = "cygwin" if $^O =~ /cygwin/i;
$system = "miktex" if defined($ENV{"TEXSYSTEM"}) and
$ENV{"TEXSYSTEM"} =~ /miktex/i;
- print "* OS name: $^O\n" if $Verbose;
- print "* Arch name: $archname\n" if $Verbose;
- print "* System: $system\n" if $Verbose;
+ print "* OS name: $^O\n" if $debug;
+ print "* Arch name: $archname\n" if $debug;
+ print "* System: $system\n" if $debug;
my %candidates = (
'unix' => [qw|gs gsc|],
'dos' => [qw|gs386 gs|],
@@ -121,12 +136,12 @@ sub find_ghostscript () {
foreach my $dir (@path) {
my $file = File::Spec->catfile($dir, "$candidate$exe");
if (-x $file) {
- $::opt_gscmd = $candidate;
+ $gscmd = $candidate;
$found = 1;
- print "* Found ($candidate): $file\n" if $Verbose;
+ print "* Found ($candidate): $file\n" if $debug;
last;
}
- print "* Not found ($candidate): $file\n" if $Verbose;
+ print "* Not found ($candidate): $file\n" if $debug;
}
last if $found;
}
@@ -134,11 +149,11 @@ sub find_ghostscript () {
$found = SearchRegistry();
}
if ($found) {
- print "* Autodetected ghostscript command: $::opt_gscmd\n" if $Verbose;
+ print "* Autodetected ghostscript command: $gscmd\n" if $debug;
}
else {
- $::opt_gscmd = $$candidates_ref[0];
- print "* Default ghostscript command: $::opt_gscmd\n" if $Verbose;
+ $gscmd = $$candidates_ref[0];
+ print "* Default ghostscript command: $gscmd\n" if $debug;
}
}
@@ -146,7 +161,7 @@ sub SearchRegistry () {
my $found = 0;
eval 'use Win32::TieRegistry qw|KEY_READ REG_SZ|;';
if ($@) {
- if ($Verbose) {
+ if ($debug) {
print "* Registry lookup for Ghostscript failed:\n";
my $msg = $@;
$msg =~ s/\s+$//;
@@ -162,24 +177,24 @@ sub SearchRegistry () {
my $software = new Win32::TieRegistry $current_key, $open_params;
if (not $software) {
print "* Cannot find or access registry key `$current_key'!\n"
- if $::opt_verbose;
+ if $debug;
return $found;
}
- print "* Search registry at `$current_key'.\n" if $Verbose;
+ print "* Search registry at `$current_key'.\n" if $debug;
my %list;
foreach my $key_name_gs (grep /Ghostscript/i, $software->SubKeyNames()) {
$current_key = "$key_name_software$key_name_gs/";
- print "* Registry entry found: $current_key\n" if $Verbose;
+ print "* Registry entry found: $current_key\n" if $debug;
my $key_gs = $software->Open($key_name_gs, $open_params);
if (not $key_gs) {
- print "* Cannot open registry key `$current_key'!\n" if $Verbose;
+ print "* Cannot open registry key `$current_key'!\n" if $debug;
next;
}
foreach my $key_name_version ($key_gs->SubKeyNames()) {
$current_key = "$key_name_software$key_name_gs/$key_name_version/";
- print "* Registry entry found: $current_key\n" if $Verbose;
+ print "* Registry entry found: $current_key\n" if $debug;
if (not $key_name_version =~ /^(\d+)\.(\d+)$/) {
- print " The sub key is not a version number!\n" if $Verbose;
+ print " The sub key is not a version number!\n" if $debug;
next;
}
my $version_main = $1;
@@ -187,13 +202,13 @@ sub SearchRegistry () {
$current_key = "$key_name_software$key_name_gs/$key_name_version/";
my $key_version = $key_gs->Open($key_name_version, $open_params);
if (not $key_version) {
- print "* Cannot open registry key `$current_key'!\n" if $Verbose;
+ print "* Cannot open registry key `$current_key'!\n" if $debug;
next;
}
$key_version->FixSzNulls(1);
my ($value, $type) = $key_version->GetValue('GS_DLL');
if ($value and $type == REG_SZ()) {
- print " GS_DLL = $value\n" if $Verbose;
+ print " GS_DLL = $value\n" if $debug;
$value =~ s|([\\/])([^\\/]+\.dll)$|$1gswin32c.exe|i;
my $value64 = $value;
$value64 =~ s/gswin32c\.exe$/gswin64c.exe/;
@@ -201,10 +216,10 @@ sub SearchRegistry () {
$value = $value64;
}
if (-f $value) {
- print "EXE found: $value\n" if $Verbose;
+ print "EXE found: $value\n" if $debug;
}
else {
- print "EXE not found!\n" if $Verbose;
+ print "EXE not found!\n" if $debug;
next;
}
my $sortkey = sprintf '%02d.%03d %s',
@@ -212,812 +227,1638 @@ sub SearchRegistry () {
$list{$sortkey} = $value;
}
else {
- print "Missing key `GS_DLL' with type `REG_SZ'!\n" if $Verbose;
+ print "Missing key `GS_DLL' with type `REG_SZ'!\n" if $debug;
}
}
}
foreach my $entry (reverse sort keys %list) {
- $::opt_gscmd = $list{$entry};
- print "* Found (via registry): $::opt_gscmd\n" if $Verbose;
+ $gscmd = $list{$entry};
+ print "* Found (via registry): $gscmd\n" if $debug;
$found = 1;
last;
}
return $found;
+} # end GS search
+
+### If windows
+if ($Win and $gscmd =~ /\s/) {
+ $gscmd = "\"$gscmd\"";
}
+### Call GS
find_ghostscript();
-if ($Win and $::opt_gscmd =~ /\s/) {
- $::opt_gscmd = "\"$::opt_gscmd\"";
-}
-# end GS search
-
-#-----------------Program identification, options and help ------------#
+### Program identification, options and help for command line
-my $program = "LTXimg";
-my $nv='1.1';
-my $copyright = <<END_COPYRIGHT ;
-2015-04-21 - Copyright (c) 2013-2015 by Pablo Gonzalez L.
-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
+ 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 3 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.
END_LICENSE
-my $title = "$program $nv, $copyright";
+
+my $title = "$program $nv $copyright";
my $usage = <<"END_OF_USAGE";
-${title}
-Usage: ltximg file.tex [options]
-
-LTXimg extract and convert all PGF|TiKZ|Pstricks environments from TeX
- source into single images files (pdf/png/eps/jpg/svg) using Ghostscript.
- By default search and extract environments using (pdf)LaTeX.
-
-Environments suports by LTXimg:
-
- pspicture tikzpicture pgfpicture forest ganttchart
- tikzcd circuitikz dependency other postscript
-
-Options:
-
- -h,--help - display this help and exit
- -l,--license - display license information and exit
- -v,--version - display version (current $nv) and exit
- -d,--dpi=<int> - the dots per inch for images (default $DPI)
- -j,--jpg - create .jpg files (need Ghostscript)
- -p,--png - create .png files (need Ghostscript)
- -e,--eps - create .eps files (need pdftops)
- -s,--svg - create .svg files (need pdf2svg)
- -P,--ppm - create .ppm files (need pdftoppm)
- -a,--all - create .(pdf,eps,jpg,png) images
- -c,--clear - delete all temp and aux files
- -o,--output - create a file-out.tex whitout PGF|TiKZ|PST code
- -m,--margins=<int> - margins in bp for pdfcrop (default 0)
- -np,--nopreview - create images files whitout preview package
- -ns,--nosource - delete all source for images files
- --miktex - use --enable-write18 for MikTeX users
- --xetex - using (Xe)LaTeX for create images
- --latex - using LaTeX for create images
- --luatex - using (Lua)LaTeX for create images
- --nopdf - don't create a PDF image files (default off)
- --other=<string> - search other environment (default other)
- --ignore=<string> - skip verbatim environment (default ignore)
- --imgdir=<string> - the folder for images (default images)
-
-
-
-Example:
-* ltximg test.tex -e -p -j -c -o --imgdir=pics
-* produce test-out.tex whitout PGF|TiKZ|PST environments and create "pics"
-* dir whit all images (pdf,eps,png,jpg) and source (.tex) for all related
-* parts using (pdf)LaTeX whit preview package and cleaning all tmp files.
-* Suport bundling for short options: ltximg test.tex -epjco --imgdir=pics
+${title}** Description **
+ LTXimg is a "perl" script that automates the process of extracting and
+ converting "environments" provided by tikz, pstricks and other packages
+ from LaTeX file to image formats in "individual files" using ghostscript
+ and poppler-utils. Generates a one file with only extracted environments
+ and other with all extracted environments converted to \\includegraphics.
+
+** Syntax **
+ \$ ltximg [<compiler>] [<options>] [--] <filename>.<tex|ltx>
+
+** Usage **
+ \$ ltximg --latex [<options>] <file.tex>
+ \$ ltximg --arara [<options>] <file.tex>
+ \$ ltximg [<options>] <file.tex>
+ \$ ltximg <file.tex>
+
+ If used without [<compiler>] and [<options>] the extracted environments
+ are converted to pdf image format and saved in the "/images" directory
+ using "pdflatex" and "preview" package. Relative or absolute paths for
+ directories and files is not supported, if the last option take a list
+ separated by commas you need -- at the end.
+
+** Default environments extract **
+ pspicture tikzpicture pgfpicture psgraph postscript PSTexample
+
+** Options **
+ [default]
+-h, --help Display command line help and exit [off]
+-l, --license Display GPL license and exit [off]
+-v, --version Display current version ($nv) and exit [off]
+-t, --tif Create .tif files using ghostscript [$gscmd]
+-b, --bmp Create .bmp files using ghostscript [$gscmd]
+-j, --jpg Create .jpg files using ghostscript [$gscmd]
+-p, --png Create .png files using ghostscript [$gscmd]
+-e, --eps Create .eps files using poppler-utils [pdftops]
+-s, --svg Create .svg files using poppler-utils [pdftocairo]
+-P, --ppm Create .ppm files using poppler-utils [pdftoppm]
+-g, --gray Gray scale for images using ghostscript [off]
+-f, --force Capture "\\psset" and "\\tikzset" to extract [off]
+-n, --noprew Create images files whitout "preview" package [off]
+-d <integer>, --dpi <integer>
+ Dots per inch resolution for images [150]
+-m <integer>, --margin <integer>
+ Set margins for pdfcrop [0]
+--imgdir <dirname> Set name of directory to save images [images]
+-o <filename>, --output <filename>
+ Create output file [off]
+--verbose Verbose printing [off]
+--srcenv Create files whit only code environment [off]
+--subenv Create files whit preamble and code [off]
+--latex Using latex>dvips>ps2pdf for compiler input
+ and pdflatex for compiler output [off]
+--dvips Using latex>dvips>ps2pdf for compiler input
+ and latex>dvips>ps2pdf for compiler output [off]
+--arara Use arara for compiler input and output [off]
+--xetex Using xelatex for compiler input and output [off]
+--dvipdf Using dvipdfmx for compiler input and output [off]
+--luatex Using lualatex for compiler input and output [off]
+--prefix <string> Set prefix append to each image file [off]
+--norun Run script, but no create images files [off]
+--nopdf Don't create a ".pdf" image files [off]
+--nocrop Don't run pdfcrop [off]
+--verbcmd <cmdname> Set "\\cmdname" verbatim command [myverb]
+--clean (doc|pst|tkz|all|off)
+ Removes specific text in output file [doc]
+--extrenv <env1,...> Add new environments to extract [empty]
+--skipenv <env1,...> Skip environments to extract [empty]
+--verbenv <env1,...> Add verbatim environments [empty]
+--writenv <env1,...> Add verbatim write environments [empty]
+--deltenv <env1,...> Delete environments in output file [empty]
+
+** Example **
+ \$ ltximg --latex -e -p --srcenv --imgdir=mypics -o test-out test-in.ltx
+ \$ ltximg --latex -ep --srcenv --imgdir mypics -o test-out test-in.ltx
+
+ Create a "/mypics" directory whit all extracted environments converted to
+ image formats (.pdf, .eps, .png), individual files whit source code (.tex)
+ for all extracted environments, a file "test-out.ltx" whit all extracted
+ environments converted to \\includegraphics and file "test-in-fig-all.tex"
+ with only the extracted environments using latex>dvips>ps2pdf and preview
+ package for <input file> and pdflatex for <output file>.
+
+** Documentation **
+ For extended documentation use:
+ \$ texdoc ltximg
END_OF_USAGE
-# Options
-my $result=GetOptions (
- 'h|help' => \$::opt_help,
- 'v|version' => \$::opt_version,
- 'l|license' => \$::opt_license,
- 'd|dpi=i' => \$DPI,# numeric
- 'm|margins=i' => \$margins,# numeric
- 'imgdir=s' => \$imageDir, # string
- 'ignore=s' => \$ignore, # string
- 'other=s' => \$other, # string
- 'c|clear' => \$clear, # flag
- 'np|nopreview' => \$nopreview, # flag
- 'e|eps' => \$eps, # flag
- 'j|jpg' => \$jpg, # flag
- 'p|png' => \$png, # flag
- 'P|ppm' => \$ppm, # flag
- 's|svg' => \$svg, # flag
- 'a|all' => \$all, # flag
- 'miktex' => \$miktex, # flag
- 'nopdf' => \$nopdf, # flag
- 'o|output' => \$output, # flag
- 'xetex' => \$xetex, # flag
- 'latex' => \$latex, # flag
- 'luatex' => \$luatex,# flag
- 'ns|nosource' => \$noSource, # flag
- 'Verbose' => \$Verbose,
-) or die $usage;
-
-# help functions
+### Error in command line
sub errorUsage { die "@_ (try ltximg --help for more information)\n"; }
-
-# options for command line
-if ($::opt_help) {
+
+### Getopt::Long configuration
+my %opts_cmd;
+
+my $result=GetOptions (
+# short and long options
+ 'h|help' => \$opts_cmd{help}, # help
+ 'v|version' => \$opts_cmd{version}, # version
+ 'l|license' => \$opts_cmd{license}, # license
+ 'd|dpi=i' => \$DPI, # numeric
+ 'm|margin=i' => \$margins, # numeric
+ 'b|bmp' => \$opts_cmd{bmp}, # gs
+ 't|tif' => \$opts_cmd{tif}, # gs
+ 'j|jpg' => \$opts_cmd{jpg}, # gs
+ 'p|png' => \$opts_cmd{png}, # gs
+ 's|svg' => \$opts_cmd{svg}, # pdftocairo
+ 'e|eps' => \$opts_cmd{eps}, # pdftops
+ 'P|ppm' => \$opts_cmd{ppm}, # pdftoppm
+ 'g|gray' => \$gray, # gray (bolean)
+ 'f|force' => \$force, # force (bolean)
+ 'n|noprew' => \$noprew, # no preview (bolean)
+ 'o|output=s{1}' => \$output, # output file name (string)
+# bolean options
+ 'subenv' => \$subenv, # subfile environments (bolean)
+ 'srcenv' => \$srcenv, # source files (bolean)
+ 'arara' => \$arara, # arara compiler
+ 'xetex' => \$xetex, # xelatex compiler
+ 'latex' => \$latex, # latex compiler
+ 'luatex' => \$luatex, # lualatex compiler
+ 'dvips' => \$dvips, # dvips compiler
+ 'dvipdf' => \$dvipdf, # dvipdfmx compiler
+# string options from command line
+ 'extrenv=s{1,9}' => \@extr_env_tmp, # extract environments
+ 'skipenv=s{1,9}' => \@skip_env_tmp, # skip environment
+ 'verbenv=s{1,9}' => \@verb_env_tmp, # verbatim environment
+ 'writenv=s{1,9}' => \@verw_env_tmp, # verbatim write environment
+ 'deltenv=s{1,9}' => \@delt_env_tmp, # delete environment
+# string options
+ 'imgdir=s{1}' => \$imageDir, # images dir name
+ 'verbcmd=s{1}' => \$verbcmd, # \myverb inline (string)
+ 'prefix=s{1}' => \$prefix, # prefix
+# negated options
+ 'crop!' => \$crop, # run pdfcrop
+ 'pdf!' => \$pdf, # pdf image format
+ 'clean=s{1}' => \@clean, # clean output file
+ 'run!' => \$run, # run compiler
+ 'debug!' => \$debug, # debug mode
+ 'verbose!' => \$verbose, # debug mode,
+ ) or die $usage;
+
+### Remove white space and '=' in array captured from command line
+s/^\s*(\=):?|\s*//mg foreach @extr_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @skip_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @verb_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @verw_env_tmp;
+s/^\s*(\=):?|\s*//mg foreach @delt_env_tmp;
+
+### Split comma separte list options from command line
+@extr_env_tmp = split(/,/,join('',@extr_env_tmp));
+@skip_env_tmp = split(/,/,join('',@skip_env_tmp));
+@verb_env_tmp = split(/,/,join('',@verb_env_tmp));
+@verw_env_tmp = split(/,/,join('',@verw_env_tmp));
+@delt_env_tmp = split(/,/,join('',@delt_env_tmp));
+
+### Validate input string options
+if ( grep( /(^\-|^\.).*?/, @extr_env_tmp ) ) {
+ die errorUsage "Invalid option for --extrenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @skip_env_tmp ) ) {
+ die errorUsage "Invalid option for --skipenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @verb_env_tmp ) ) {
+ die errorUsage "Invalid option for --verbenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @verw_env_tmp ) ) {
+ die errorUsage "Invalid option for --verwenv, invalid environment name";
+}
+if ( grep( /(^\-|^\.).*?/, @delt_env_tmp ) ) {
+ die errorUsage "Invalid option for --deltenv, invalid environment name";
+}
+
+### Help
+if (defined $opts_cmd{help}){
+ find_ghostscript();
print $usage;
exit(0);
}
-if ($::opt_version) {
+
+### Version
+if (defined $opts_cmd{version}){
print $title;
exit(0);
}
-if ($::opt_license) {
+
+### Licence
+if (defined $opts_cmd{license}){
print $licensetxt;
exit(0);
-}
-# General options
-if ($latex) {
- $latex = 1;
}
-if ($xetex) {
- $xetex = 1;
+
+### Set tmp random name for name-fig-tmp (temp files)
+my $tmp = "$$";
+
+### Check --srcenv and --subenv option from command line
+if ($srcenv && $subenv) {
+ die errorUsage "--srcenv and --subenv options are mutually exclusive";
}
-if ($luatex) {
- $luatex = 1;
+
+### Check the input file from command line
+@ARGV > 0 or errorUsage "Input filename missing";
+@ARGV < 2 or errorUsage "Unknown option or too many input files";
+
+### Check input file extention
+my @SuffixList = ('.tex', '', '.ltx'); # posibles
+my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
+$ext = '.tex' if not $ext;
+
+### Read input file in memory (slurp), need :crlf for windows/linux
+open my $INPUTfile, '<:crlf', "$name$ext";
+my $archivo;
+ {
+ local $/;
+ $archivo = <$INPUTfile>;
+ }
+close $INPUTfile;
+
+### Funtion uniq
+sub uniq {
+ my %seen;
+ grep !$seen{$_}++, @_;
}
-if ($nopdf) {
- $nopdf = 1;
+### Funtion array_minus
+sub array_minus(\@\@) {
+ my %e = map{ $_ => undef } @{$_[1]};
+ return grep( ! exists( $e{$_} ), @{$_[0]} );
}
-if ($eps) {
- $eps = 1;
+
+### Funtion to create hash begin -> BEGIN, end -> END
+sub crearhash{
+ my %cambios;
+ for my $aentra(@_){
+ for my $initend (qw(begin end)) {
+ $cambios{"\\$initend\{$aentra"} = "\\\U$initend\E\{$aentra";
+ }
+ }
+ return %cambios;
}
-if ($jpg) {
- $jpg = 1;
+
+### Default environment to extract
+my @extr_tmp = qw (
+ postscript tikzpicture pgfpicture pspicture psgraph
+ );
+
+push(@extr_env_tmp,@extr_tmp);
+
+### Default verbatim environment
+my @verb_tmp = qw (
+ Example CenterExample SideBySideExample PCenterExample PSideBySideExample
+ verbatim Verbatim BVerbatim LVerbatim SaveVerbatim PSTcode
+ LTXexample tcblisting spverbatim minted listing lstlisting
+ alltt comment chklisting verbatimtab listingcont boxedverbatim
+ demo sourcecode xcomment pygmented pyglist program programl
+ programL programs programf programsc programt
+ );
+
+push(@verb_env_tmp,@verb_tmp);
+
+### Default verbatim write environment
+my @verbw_tmp = qw (
+ filecontents tcboutputlisting tcbexternal extcolorbox extikzpicture
+ VerbatimOut verbatimwrite PSTexample filecontentsdef filecontentshere
+ );
+
+push(@verw_env_tmp,@verbw_tmp);
+
+### Rules to capture in regex
+my $braces = qr/ (?:\{)(.+?)(?:\}) /msx;
+my $braquet = qr/ (?:\[)(.+?)(?:\]) /msx;
+my $no_corchete = qr/ (?:\[ .+? \])? /msx;
+
+### Capture new verbatim environments defined in input file
+my @new_verb = qw (
+ newtcblisting DeclareTCBListing ProvideTCBListing NewTCBListing
+ lstnewenvironment NewListingEnvironment NewProgram specialcomment
+ includecomment DefineVerbatimEnvironment newverbatim newtabverbatim
+ );
+
+### Regex to capture names for new verbatim environments from input file
+my $newverbenv = join "|", map quotemeta, sort { length $a <=> length $b } @new_verb;
+$newverbenv = qr/\b(?:$newverbenv) $no_corchete $braces/msx;
+
+### Capture new verbatim write environments defined in input file
+my @new_verb_write = qw (
+ renewtcbexternalizetcolorbox renewtcbexternalizeenvironment
+ newtcbexternalizeenvironment newtcbexternalizetcolorbox
+ );
+
+### Regex to capture names for new verbatim write environments from input file
+my $newverbwrt = join "|", map quotemeta, sort { length $a <=> length $b } @new_verb_write;
+$newverbwrt = qr/\b(?:$newverbwrt) $no_corchete $braces/msx;
+
+### Regex to capture MINTED related environments
+my $mintdenv = qr/\\ newminted $braces (?:\{.+?\}) /x;
+my $mintcenv = qr/\\ newminted $braquet (?:\{.+?\}) /x;
+my $mintdshrt = qr/\\ newmint $braces (?:\{.+?\}) /x;
+my $mintcshrt = qr/\\ newmint $braquet (?:\{.+?\}) /x;
+my $mintdline = qr/\\ newmintinline $braces (?:\{.+?\}) /x;
+my $mintcline = qr/\\ newmintinline $braquet (?:\{.+?\}) /x;
+
+### Pass input file to @array and remove % and comments
+my @verbinput = $archivo;
+s/%.*\n//mg foreach @verbinput; # del comments
+s/^\s*|\s*//mg foreach @verbinput; # del white space
+my $verbinput = join '', @verbinput;
+
+### Capture \newverbatim write names in input file
+my @newv_write = $verbinput =~ m/$newverbwrt/xg;
+
+### Add @newv_write defined in input file to @verw_env_tmp
+push(@verw_env_tmp,@newv_write);
+
+### Capture \newminted{$mintdenv}{options} (for)
+my @mint_denv = $verbinput =~ m/$mintdenv/xg;
+
+### Capture \newminted[$mintcenv]{lang} (for)
+my @mint_cenv = $verbinput =~ m/$mintcenv/xg;
+
+### Capture \newmint{$mintdshrt}{options} (while)
+my @mint_dshrt = $verbinput =~ m/$mintdshrt/xg;
+
+### Capture \newmint[$mintcshrt]{lang}{options} (while)
+my @mint_cshrt = $verbinput =~ m/$mintcshrt/xg;
+
+### Capture \newmintinline{$mintdline}{options} (while)
+my @mint_dline = $verbinput =~ m/$mintdline/xg;
+
+### Capture \newmintinline[$mintcline]{lang}{options} (while)
+my @mint_cline = $verbinput =~ m/$mintcline/xg;
+
+### Capture \newverbatim environments in input file (for)
+my @verb_input = $verbinput =~ m/$newverbenv/xg;
+
+### Add new verbatim environment defined in input file to @vrbenv
+push(@verb_env_tmp,@mint_denv,@mint_cenv,@verb_input);
+
+### Append "code" (minted)
+if (!@mint_denv == 0){
+$mintdenv = join "\n", map { qq/$_\Qcode\E/ } @mint_denv;
+@mint_denv = split /\n/, $mintdenv;
}
-if ($png) {
- $png = 1;
+
+### Append "inline" (minted)
+if (!@mint_dline == 0){
+$mintdline = join "\n", map { qq/$_\Qinline\E/ } @mint_dline;
+@mint_dline = split /\n/, $mintdline;
}
-if ($ppm) {
- $ppm = 1;
+
+### Join all minted inline/short and lstinline in @array
+my @mintline;
+my @mint_tmp = qw ( mint mintinline lstinline);
+push(@mintline,@mint_dline,@mint_cline,@mint_dshrt,@mint_cshrt,@mint_tmp);
+@mintline = uniq(@mintline);
+
+### Create a regex using @mintline
+my $mintline = join "|", map quotemeta, sort { length $a <=> length $b } @mintline;
+$mintline = qr/\b(?:$mintline)/x;
+
+### Options from input file
+# % ltximg : extrenv : {extrenv1, extrenv2, ... , extrenvn}
+# % ltximg : skipenv : {skipenv1, skipenv2, ... , skipenvn}
+# % ltximg : verbenv : {verbwrt1, verbwrt2, ... , verbwrtn}
+# % ltximg : writenv : {verbwrt1, verbwrt2, ... , verbwrtn}
+# % ltximg : deltenv : {deltenv1, deltenv2, ... , deltenvn}
+# % ltximg : options : {opt1=arg, opt2=arg, ... , bolean}
+
+### Regex to capture before preamble
+my $rx_myscrypt = qr/
+ ^ %+ \s* ltximg (?&SEPARADOR) (?<clave>(?&CLAVE)) (?&SEPARADOR) \{ (?<argumentos>(?&ARGUMENTOS)) \}
+ (?(DEFINE)
+ (?<CLAVE> \w+ )
+ (?<ARGUMENTOS> .+? )
+ (?<SEPARADOR> \s* : \s* )
+ )
+/mx;
+
+### Split input file, $optin contain % ltximg : <argument>
+my($optin, $documento) = $archivo =~ m/\A (\s* .*? \s*) (\\documentclass.*)\z/msx;
+
+### Process options from input file
+my %opts_file;
+
+while ($optin =~ /$rx_myscrypt/g) {
+ my($clave, $argumentos) = @+{qw(clave argumentos)};
+ my @argumentos = split /\s*,\s*?/, $argumentos;
+ for (@argumentos) {
+ s/^ \s* | \s* $//gx;
+ }
+ if ($clave eq 'options') {
+ for my $argumento (@argumentos) {
+ if ($argumento =~ /(?<key>\S+) \s* = \s* (?<valor>\S+)/x) {
+ $opts_file{$clave}{$+{'key'}} = $+{'valor'};
+ } # close for
+ else {
+ $opts_file{$clave}{$argumento} = 1;
+ }
+ } # close for
+ } # close if
+ else {
+ push @{ $opts_file{ $clave } }, @argumentos;
+ }
+} # close while
+
+### Validate clean
+my %clean = map { $_ => 1 } @clean;
+
+### By default clean = doc
+$clean{doc} = 1 ;
+
+### Set clean options from input file
+$clean{doc} = 1 if ($opts_file{options}{clean} eq 'doc');
+$clean{off} = 1 if ($opts_file{options}{clean} eq 'off');
+$clean{pst} = 1 if ($opts_file{options}{clean} eq 'pst');
+$clean{tkz} = 1 if ($opts_file{options}{clean} eq 'tkz');
+$clean{all} = 1 if ($opts_file{options}{clean} eq 'all');
+
+### Set clean options for script
+if ($clean{pst} or $clean{tikz}) {
+ $clean{doc} = 1;
}
-if ($svg) {
- $svg = 1;
+if ($clean{all}) {
+ @clean{qw(pst doc tkz)} = (1) x 3;
}
-if ($all){
- $eps = $png = $jpg = 1;
+if ($clean{off}) {
+ undef %clean;
}
-if ($nopreview) {
- $nopreview= 1;
+### Add extract options from input file
+if (exists $opts_file{extract} ) {
+ push @extr_env_tmp, @{ $opts_file{extract} };
}
-if ($output) {
- $output= 1;
+### Add skipenv options from input file
+if (exists $opts_file{skipenv} ) {
+ push @skip_env_tmp, @{ $opts_file{skipenv} };
}
-if ($miktex) {
- $miktex= 1;
+### Add verbenv options from input file
+if (exists $opts_file{verbenv} ) {
+ push @verb_env_tmp, @{ $opts_file{verbenv} };
}
-# 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];
+### Add writenv options from input file
+if (exists $opts_file{writenv} ) {
+ push @verw_env_tmp, @{ $opts_file{writenv} };
+}
-#--------------------- Arreglo de la extensión ------------------------#
-my @SuffixList = ('.tex', '', '.ltx'); # posible extensión
-my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
-$ext = '.tex' if not $ext;
-
-#---------------- Creamos el directorio para las imágenes -------------#
--e $imageDir or mkdir($imageDir,0744) or die "No puedo crear $imageDir: $!\n";
-
-# Define in file
-my $archivo_entrada = shift;
-
-# Standart line ltximg run
-print "$program $nv, $copyright";
-
-##---------------------------- PARTE 1 -------------------------------##
-#------------ Creamos un hash con los cambios para verbatim -----------#
-my %cambios = (
-# pst/tikz set
- '\psset' => '\PSSET',
- '\tikzset' => '\TIKZSET',
-# pspicture
- '\pspicture' => '\TRICKS',
- '\endpspicture' => '\ENDTRICKS',
+### Add deltenv options from input file
+if (exists $opts_file{deltenv} ) {
+ push @delt_env_tmp, @{ $opts_file{deltenv} };
+}
+
+### Set \myverb|<code>| options from input file
+if (exists $opts_file{options}{verbcmd}){
+ $verbcmd = $opts_file{options}{verbcmd};
+}
+
+### Create @env_all_tmp contain all environments
+my @env_all_tmp;
+push(@env_all_tmp,@extr_env_tmp,@skip_env_tmp,@verb_env_tmp,@verw_env_tmp,@delt_env_tmp);
+@env_all_tmp = uniq(@env_all_tmp);
+
+### Create @no_env_all_tmp contain all No extracted environments
+my @no_env_all_tmp;
+push(@no_env_all_tmp,@skip_env_tmp,@verb_env_tmp,@verw_env_tmp,@delt_env_tmp);
+@no_env_all_tmp = uniq(@no_env_all_tmp);
+
+### The operation return @extract environment
+my @extract = array_minus(@env_all_tmp,@no_env_all_tmp);
+@extract = uniq(@extract);
+
+### The operation return @no_extract
+my @no_extract = array_minus(@env_all_tmp,@extract);
+my @no_skip;
+push(@no_skip,@verb_env_tmp,@verw_env_tmp,@delt_env_tmp);
+my @skipped = array_minus(@no_extract,@no_skip);
+@skipped = uniq(@skipped);
+
+### The operation return @delte_env environment
+my @no_ext_skip = array_minus(@no_extract,@skipped);
+my @no_del;
+push(@no_del,@verb_env_tmp,@verw_env_tmp);
+my @delete_env = array_minus(@no_ext_skip,@no_del);
+@delete_env = uniq(@delete_env);
+
+### The operation return @verbatim environment
+my @no_ext_skip_del = array_minus(@no_ext_skip,@delete_env);
+my @verbatim = array_minus(@no_ext_skip_del,@verw_env_tmp);
+
+### The operation return @verbatim write environment
+my @verbatim_w = array_minus(@no_ext_skip_del,@verbatim);
+
+### Create @env_all for hash and replace in while
+my @no_verb_env;
+push(@no_verb_env,@extract,@skipped,@delete_env,@verbatim_w);
+my @no_verw_env;
+push(@no_verw_env,@extract,@skipped,@delete_env,@verbatim);
+
+### Reserved words in verbatim inline (while)
+my %changes_in = (
+# ltximg tags
+ '%<*ltximg>' => '%<*LTXIMG>',
+ '%</ltximg>' => '%</LTXIMG>',
+ '%<*noltximg>' => '%<*NOLTXIMG>',
+ '%</noltximg>' => '%</NOLTXIMG>',
+ '%<*remove>' => '%<*REMOVE>',
+ '%</remove>' => '%</REMOVE>',
+ '%<*ltximgverw>' => '%<*LTXIMGVERW>',
+ '%</ltximgverw>' => '%</LTXIMGVERW>',
+# pst/tikz set
+ '\psset' => '\PSSET',
+ '\tikzset' => '\TIKZSET',
# pspicture
- '\begin{pspicture' => '\begin{TRICKS',
- '\end{pspicture' => '\end{TRICKS',
-# postscript
- '\begin{postscript}' => '\begin{POSTRICKS}',
- '\end{postscript}' => '\end{POSTRICKS}',
-# $other
- "\\begin\{$other" => '\begin{OTHER',
- "\\end\{$other" => '\end{OTHER',
-# document
- '\begin{document}' => '\begin{DOCTRICKS}',
- '\end{document}' => '\end{DOCTRICKS}',
+ '\pspicture' => '\TRICKS',
+ '\endpspicture' => '\ENDTRICKS',
+# pgfpicture
+ '\pgfpicture' => '\PGFTRICKS',
+ '\endpgfpicture' => '\ENDPGFTRICKS',
# tikzpicture
- '\begin{tikzpicture}' => '\begin{TIKZPICTURE}',
- '\end{tikzpicture}' => '\end{TIKZPICTURE}',
-# pgfinterruptpicture
- '\begin{pgfinterruptpicture'=> '\begin{PGFINTERRUPTPICTURE',
- '\end{pgfinterruptpicture' => '\end{PGFINTERRUPTPICTURE',
+ '\tikzpicture' => '\TKZTRICKS',
+ '\endtikzpicture' => '\ENDTKZTRICKS',
+# psgraph
+ '\psgraph' => '\PSGRAPHTRICKS',
+ '\endpsgraph' => '\ENDPSGRAPHTRICKS',
+# some reserved
+ '\usepackage' => '\USEPACKAGE',
+ '{graphicx}' => '{GRAPHICX}',
+ '\graphicspath{' => '\GRAPHICSPATH{',
+ );
+
+### Changues for \begin... \end inline verbatim
+my %init_end = (
+# begin{ and end{
+ '\begin{' => '\BEGIN{',
+ '\end{' => '\END{',
+ );
+
+### Changues for \begin{document} ... \end{document}
+my %document = (
+# begin/end document for split
+ '\begin{document}' => '\BEGIN{document}',
+ '\end{document}' => '\END{document}',
+ );
+
+### Reverse for extract and output file
+my %changes_out = (
+# ltximg tags
+ '\begin{nopreview}' => '%<*noltximg>',
+ '\end{nopreview}' => '%</noltximg>',
+# pst/tikz set
+ '\PSSET' => '\psset',
+ '\TIKZSET' => '\tikzset',
+# pspicture
+ '\TRICKS' => '\pspicture',
+ '\ENDTRICKS' => '\endpspicture',
# pgfpicture
- '\begin{pgfpicture}' => '\begin{PGFPICTURE}',
- '\end{pgfpicture}' => '\end{PGFPICTURE}',
-# ganttchart
- '\begin{ganttchart}' => '\begin{GANTTCHART}',
- '\end{ganttchart}' => '\end{GANTTCHART}',
-# circuitikz
- '\begin{circuitikz}' => '\begin{CIRCUITIKZ}',
- '\end{circuitikz}' => '\end{CIRCUITIKZ}',
-# forest
- '\begin{forest}' => '\begin{FOREST}',
- '\end{forest}' => '\end{FOREST}',
-# tikzcd
- '\begin{tikzcd}' => '\begin{TIKZCD}',
- '\end{tikzcd}' => '\end{TIKZCD}',
-# dependency
- '\begin{dependency}' => '\begin{DEPENDENCY}',
- '\end{dependency}' => '\end{DEPENDENCY}',
-);
-
-#------------------------ Coment inline Verbatim ----------------------#
-open my $ENTRADA, '<', "$archivo_entrada";
-my $archivo;
-{
- local $/;
- $archivo = <$ENTRADA>;
-}
-close $ENTRADA;
+ '\PGFTRICKS' => '\pgfpicture',
+ '\ENDPGFTRICKS' => '\endpgfpicture',
+# tikzpicture
+ '\TKZTRICKS' => '\tikzpicture',
+ '\ENDTKZTRICKS' => '\endtikzpicture',
+# psgraph
+ '\PSGRAPHTRICKS' => '\psgraph',
+ '\ENDPSGRAPHTRICKS' => '\endpsgraph',
+# some reserved
+ '\USEPACKAGE' => '\usepackage',
+ '{GRAPHICX}' => '{graphicx}',
+ '\GRAPHICSPATH{' => '\graphicspath{',
+# begin{ and end{
+ '\BEGIN{' => '\begin{',
+ '\END{' => '\end{',
+ );
+
+### Reverse tags, need back in all file to extract
+my %reverse_tag = (
+# ltximg tags
+ '%<*LTXIMG>' => '%<*ltximg>',
+ '%</LTXIMG>' => '%</ltximg>',
+ '%<*NOLTXIMG>' => '%<*noltximg>',
+ '%</NOLTXIMG>' => '%</noltximg>',
+ '%<*REMOVE>' => '%<*remove>',
+ '%</REMOVE>' => '%</remove>',
+ '%<*LTXIMGVERW>' => '%<*ltximgverw>',
+ '%</LTXIMGVERW>' => '%</ltximgverw>',
+ );
+
+### Creatate a hash for changues
+my %extract_env = crearhash(@extract);
+my %skiped_env = crearhash(@skipped);
+my %verb_env = crearhash(@verbatim);
+my %verbw_env = crearhash(@verbatim_w);
+my %delete_env = crearhash(@delete_env);
+my %change_verbw_env = crearhash(@no_verw_env);
+my %change_verb_env = crearhash(@no_verb_env);
+
+### Join changues in new hash
+my %cambios = (%changes_in,%init_end);
-# Variables y constantes
+### Variables y constantes
my $no_del = "\0";
my $del = $no_del;
-# Reglas
-my $llaves = qr/\{ .+? \} /x;
-my $no_corchete = qr/(?:\[ .+? \])? /x;
-my $delimitador = qr/\{ (?<del>.+?) \} /x;
-my $verb = qr/(spv|v|V)erb [*]? /ix;
-my $lst = qr/lstinline (?!\*) $no_corchete /ix;
-my $mint = qr/mint (?!\*) $no_corchete $llaves /ix;
-my $marca = qr/\\ (?:$verb | $lst | $mint ) (\S) .+? \g{-1} /x;
-my $comentario = qr/^ \s* \%+ .+? $ /mx;
-my $definedel = qr/\\ (?: DefineShortVerb | lstMakeShortInline ) $no_corchete $delimitador /ix;
-my $indefinedel = qr/\\ (?: UndefineShortVerb | lstDeleteShortInline) $llaves /ix;
-
-while ($archivo =~
+### Rules
+my $llaves = qr/\{ .+? \} /x;
+my $no_llaves = qr/(?: $llaves )? /x;
+my $corchetes = qr/\[ .+? \] /x;
+my $anidado = qr/(\{(?:[^\{\}]++|(?1))*\}) /x;
+my $delimitador = qr/\{ (?<del>.+?) \} /x;
+my $verb = qr/(?:((spv|(?:q|f)?v|V)erb|$verbcmd)[*]?) /ix;
+my $lst = qr/(?:(lst|pyg)inline)(?!\*) $no_corchete /ix;
+my $mint = qr/(?: $mintline |SaveVerb) (?!\*) $no_corchete $no_llaves $llaves /ix;
+my $no_mint = qr/(?: $mintline) (?!\*) $no_corchete /ix;
+my $marca = qr/\\ (?:$verb | $lst | $mint |$no_mint) (?:\s*)? (\S) .+? \g{-1} /x;
+my $comentario = qr/^ \s* \%+ .+? $ /mx;
+my $definedel = qr/\\ (?: DefineShortVerb | lstMakeShortInline| MakeSpecialShortVerb ) [*]? $no_corchete $delimitador /ix;
+my $indefinedel = qr/\\ (?: (Undefine|Delete)ShortVerb | lstDeleteShortInline) $llaves /ix;
+
+### Changues in input file in memory
+while ($documento =~
/ $marca
| $comentario
| $definedel
| $indefinedel
- | $del .+? $del # delimitado
+ | $del .+? $del
/pgmx) {
-
- my($pos_inicial, $pos_final) = ($-[0], $+[0]); # posiciones
- my $encontrado = ${^MATCH}; # lo encontrado
-
- if ($encontrado =~ /$definedel/){ # definimos delimitador
- $del = $+{del};
- $del = "\Q$+{del}" if substr($del,0,1) ne '\\'; # es necesario "escapar" el delimitador
- }
- elsif($encontrado =~ /$indefinedel/) { # indefinimos delimitador
- $del = $no_del;
- }
- else { # aquí se hacen los cambios
+ my($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ if ($encontrado =~ /$definedel/) {
+ $del = $+{del};
+ $del = "\Q$+{del}" if substr($del,0,1) ne '\\';
+ }
+ elsif ($encontrado =~ /$indefinedel/) {
+ $del = $no_del;
+ }
+ else {
while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/g; # es necesario escapar $busco
- }
- substr $archivo, $pos_inicial, $pos_final-$pos_inicial, $encontrado; # insertamos los nuevos cambios
-
- pos($archivo)= $pos_inicial + length $encontrado; # re posicionamos la siguiente búsqueda
+ $encontrado =~ s/\Q$busco\E/$cambio/g;
}
+ substr $documento, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos($documento) = $pos_inicial + length $encontrado;
+ }
}
-# Constantes
-my $BP = '\\\\begin{postscript}';
-my $EP = '\\\\end{postscript}';
-my $BPL = '\begin{postscript}';
-my $EPL = '\end{postscript}';
-my $sipgf = 'pgfpicture';
-my $nopgf = 'pgfinterruptpicture';
-my $graphics = "graphic=\{\[scale=1\]$imageDir/$name-fig";
+### Regex for verbatim inline whit braces {...}
+my $mintd_ani = qr/\\ (?:$mintline|pygment) (?!\*) $no_corchete $no_llaves /x;
+my $tcbxverb = qr/\\ (?: tcboxverb [*]?|$verbcmd [*]?|lstinline) $no_corchete /x;
+my $tcbxmint = qr/(?:$tcbxverb|$mintd_ani) (?:\s*)? $anidado /x;
-# directorio en el cual están las imágenes
-my $dir = "$tempDir/$imageDir";
+### Changue \verb*{code} inline
+while ($documento =~ /$tcbxmint/pgmx) {
+ my($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ while (my($busco, $cambio) = each %cambios) {
+ $encontrado =~ s/\Q$busco\E/$cambio/g;
+ } # close while
+ substr $documento, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos($documento)= $pos_inicial + length $encontrado;
+} # close while
-#--------------------- Coment Verbatim environment --------------------#
+### Changue <*TAGS> to <*tags> in file
+my $ltxtags = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %reverse_tag;
+$documento =~ s/^($ltxtags)/$reverse_tag{$1}/gmsx;
-my @lineas = split /\n/, $archivo;
+### Defined environments Verbatim standart
+my $verbatim = join "|", map quotemeta, sort { length $a <=> length $b } @verbatim;
+$verbatim = qr/$verbatim/x;
-# Verbatim environments
-my $ENTORNO = qr/(?: (v|V)erbatim\*?| PSTexample | LTXexample| $ignore\*? | PSTcode | tcblisting\*? | spverbatim | minted | lstlisting | alltt | comment\*? | xcomment)/xi;
+### Defined environments Verbatim write
+my $verbatim_w = join "|", map quotemeta, sort { length $a <=> length $b } @verbatim_w;
+$verbatim_w = qr/$verbatim_w/x;
-# postscript environment
-my $POSTSCRIPT = qr/(?: postscript)/xi;
+### Define environments to skip
+my $skipenv = join "|", map quotemeta, sort { length $a <=> length $b } @skipped;
+$skipenv = qr/$skipenv/x;
-# tikzpicture environment
-my $TIKZENV = qr/(?: tikzpicture)/xi;
-#
-my $DEL;
+### Define environments to extract
+my $environ = join "|", map quotemeta, sort { length $a <=> length $b } @extract;
+$environ = qr/$environ/x;
+
+### Define environments to delete
+my $delenv = join "|", map quotemeta, sort { length $a <=> length $b } @delt_env_tmp;
+$delenv = qr/$delenv/x;
+
+### Split file by lines
+my @lineas = split /\n/, $documento;
-# tcbverb verbatim
-my $tcbverb = qr/\\(?:tcboxverb|myverb)/;
-my $arg_brac = qr/(?:\[.+?\])?/;
-my $arg_curl = qr/\{(.+)\}/;
+### Hash and Regex for changues
+my %replace = (%change_verb_env,%changes_in,%document);
+my $find = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %replace;
-# coment verbatim environment
+### Change in $verbatim and $verbatim_w
+my $DEL;
for (@lineas) {
- if (/\\begin\{($ENTORNO)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
- }
+ if (/\\begin\{($verbatim\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ s/($find)/$replace{$1}/g;
}
-}
-# coment tcolorbox inline
+ if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ my %replace = (%change_verbw_env,%changes_in,%document);
+ my $find = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %replace;
+ s/($find)/$replace{$1}/g;
+ }
+} # close for
+
+### Join lines in $documento
+$documento = join("\n", @lineas);
+
+### Split input file
+my($cabeza,$cuerpo,$final) = $documento =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
+
+### Regex for delete environment
+my $delt_env = qr /
+ (
+ (?:
+ \\begin\{$delenv\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$delenv\*?\})
+ (?!end\{$delenv\*?\})|
+ (?-1)
+ )*
+ \\end\{$delenv\*?\}
+ )
+ )
+ /x;
+
+### Regex for verbatim write environment
+my $verb_wrt = qr /
+ (
+ (?:
+ \\begin\{$verbatim_w\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim_w\*?\})
+ (?!end\{$verbatim_w\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim_w\*?\}
+ )
+ )
+ /x;
+
+### Pass $verb_wrt to %<*ltximgverw> ... %</ltximgverw>
+$cuerpo =~ s/($verb_wrt)/\%<\*ltximgverw>\n$1\n\%<\/ltximgverw>/gmsx;
+
+### Regex for skip environment
+my $skip_env = qr /
+ (
+ (?:
+ \\begin\{$skipenv\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$skipenv\*?\})
+ (?!end\{$skipenv\*?\})|
+ (?-1)
+ )*
+ \\end\{$skipenv\*?\}
+ )
+ )
+ /x;
+
+### Pass %<*noltximg> ... %</noltximg> to \begin{nopreview} ... \end{nopreview}
+$cuerpo =~ s/^\%<\*$skiptag>(.+?)\%<\/$skiptag>/\\begin\{nopreview\}$1\\end\{nopreview\}/gmsx;
+
+### Pass $skip_env to \begin{nopreview} .+? \end{nopreview}
+$cuerpo =~ s/
+ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ ($skip_env)/\\begin\{nopreview\}\n$1\n\\end\{nopreview\}\n/gmsx;
+
+### Regex to extract environments
+my $extr_env = qr /
+ (
+ (?:
+ \\begin\{$environ\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$environ\*?\})
+ (?!end\{$environ\*?\})|
+ (?-1)
+ )*
+ \\end\{$environ\*?\}
+ )
+ )
+ /x;
+
+### Set bolean options from input file
+$force = 1 if exists $opts_file{options}{force};
+$run = 0 if exists $opts_file{options}{norun};
+$pdf = 0 if exists $opts_file{options}{nopdf};
+$crop = 0 if exists $opts_file{options}{nocrop};
+$noprew = 1 if exists $opts_file{options}{noprew};
+$force = 1 if exists $opts_file{options}{force};
+$arara = 1 if exists $opts_file{options}{arara};
+$xetex = 1 if exists $opts_file{options}{xetex};
+$latex = 1 if exists $opts_file{options}{latex};
+$dvips = 1 if exists $opts_file{options}{dvips};
+$dvipdf = 1 if exists $opts_file{options}{dvipdf};
+$luatex = 1 if exists $opts_file{options}{luatex};
+$srcenv = 1 if exists $opts_file{options}{srcenv};
+$subenv = 1 if exists $opts_file{options}{subenv};
+
+### Check plain TeX syntax
+my %special = map { $_ => 1 } @extract; # anon hash
+
+### Convert \pspicture to LaTeX syntax
+if(exists($special{pspicture})){
+ $cuerpo =~ s/
+ \\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
+}
+
+### Convert \psgraph to LaTeX syntax
+if(exists($special{psgraph})){
+ $cuerpo =~ s/
+ \\psgraph(\*)?(.+?)\\endpsgraph/\\begin{psgraph$1}$2\\end{psgraph$1}/gmsx;
+}
+
+### Convert \tikzpicture to LaTeX syntax
+if(exists($special{tikzpicture})){
+ $cuerpo =~ s/
+ \\tikzpicture(.+?)\\endtikzpicture/\\begin{tikzpicture}$1\\end{tikzpicture}/gmsx;
+}
+
+### Convert \pgfpicture to LaTeX syntax
+if(exists($special{pgfpicture})){
+ $cuerpo =~ s/
+ \\pgfpicture(.+?)\\endpgfpicture/\\begin{pgfpicture}$1\\end{pgfpicture}/gmsx;
+}
+
+### Pass %<*ltximg> (.+?) %</ltximg> to \begin{preview} (.+?) \end{preview}
+$cuerpo =~ s/^\%<\*$extrtag>(.+?)\%<\/$extrtag>/\\begin\{preview\}$1\\end\{preview\}/gmsx;
+
+### $force mode for pstricks/psgraph/tikzpiture
+if ($force) {
+# pspicture or psgraph found
+if(exists($special{pspicture}) or exists($special{psgraph})){
+$cuerpo =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ \\begin\{postscript\}.+?\\end\{postscript\}(*SKIP)(*F)|
+ (?<code>
+ (?:\\psset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
+ \\begin\{(?<env> pspicture\*?| psgraph)\} .+? \\end\{\k<env>\}
+ )
+ /\\begin\{preview\}\n$+{code}\n\\end\{preview\}/gmsx;
+ } # close pspicture
+# tikzpicture found
+if(exists($special{tikzpicture})){
+$cuerpo =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ \\begin\{postscript\}.+?\\end\{postscript\}(*SKIP)(*F)|
+ (?<code>
+ (?:\\tikzset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
+ \\begin\{(?<env> tikzpicture)\} .+? \\end\{\k<env>\}
+ )
+ /\\begin\{preview\}\n$+{code}\n\\end\{preview\}/gmsx;
+ } # close tikzpicture
+} # close force mode
+
+### Pass $extr_env to \begin{preview} .+? \end{preview}
+$cuerpo =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ($extr_env)/\\begin\{preview\}\n$1\n\\end\{preview\}/gmsx;
+
+### The extract environments need back word to original
+%replace = (%changes_out,%reverse_tag);
+$find = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %replace;
+
+### Split $cabeza by lines
+@lineas = split /\n/, $cabeza;
+
+### Changues in verbatim write
for (@lineas) {
- if (m/$tcbverb$arg_brac$arg_curl/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
- }
- } # close
- }
-# remove postscript from hash
-delete @cambios{'\begin{postscript}','\end{postscript}'};
-# coment in postscript environment
+ if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ s/($find)/$replace{$1}/g;
+ }
+} # close for
+
+### Join lines in $cabeza
+$cabeza = join("\n", @lineas);
+
+### Change back betwen \begin{preview} ... \end{preview}
+@lineas = split /\n/, $cuerpo;
+
for (@lineas) {
- if (/\\begin\{($POSTSCRIPT)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
+ if (/\\begin\{(preview)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) { # range operator
+ s/($find)/$replace{$1}/g;
}
- } # close postcript environment
-}
-# remove tikzpicture from hash
-delete @cambios{'\begin{tikzpicture}','\end{tikzpicture}'};
-# coment in tikzpicture environment
-for (@lineas) {
- if (/\\begin\{($TIKZENV)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
+ if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ s/($find)/$replace{$1}/g;
}
- } # close TIKZ environment
-}
+} # close for
-undef %cambios; # erase hash
+### Join lines in $cuerpo
+$cuerpo = join("\n", @lineas);
-#------------- Convert ALL into Postscript environments ---------------#
+### If environment extract found, the run script
+my $BP = '\\\\begin\{preview\}';
+my $EP = '\\\\end\{preview\}';
-$archivo = join("\n", @lineas);
-## Partición del documento
+my @env_extract = $cuerpo =~ m/(?<=$BP)(.+?)(?=$EP)/gms;
+my $envNo = scalar @env_extract;
-my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+?) (\\begin{document} .+?)(\\end{document}.*)\z/msx;
+### PSTexample suport
+my $BE = '\\\\begin\{PSTexample\}';
+my $EE = '\\\\end\{PSTexample\}';
-# \pspicture to \begin{pspicture}
-$cuerpo =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
+my @exa_extract = $cuerpo =~ m/(?<=$BE)(.+?)(?=$EE)/gms;
+my $exaNo = scalar @exa_extract;
-# pspicture to Postscript
-$cuerpo =~ s/
- (
- (?:\\psset\{[^\}]+\}.*?)?
- (?:\\begin\{pspicture(\*)?\})
- .*?
- (?:\\end\{pspicture(\*)?\})
- )
- /$BPL\n$1\n$EPL/gmsx;
+### Check if PSTexample environment found
+if($exaNo!= 0){
+ $PSTexa=1;
+}
-# pgfpicture to Postscript
-$cuerpo =~ s/
- (
- \\begin{$sipgf}
- .*?
- (
- \\begin{$nopgf}
- .+?
- \\end{$nopgf}
- .*?
- )*?
- \\end{$sipgf}
- )
- /$BPL\n$1\n$EPL/gmsx;
+### Check if standart environment found
+if($envNo!= 0){
+ $STDenv=1;
+}
-# tikz to Postscript
-$cuerpo =~ s/
- (
- (?:\\tikzset(\{(?:\{.*?\}|[^\{])*\}).*?)? # si está lo guardo
- (?:\\begin\{tikzpicture\}) # aquí comienza la búsqueda
- .*? # guardo el contenido en $1
- (?:\\end\{tikzpicture\}) # termina la búsqueda
- ) # cierra $1
- /$BPL\n$1\n$EPL/gmsx;
-
-# rest to PostScript
-my $export = qr/(forest|ganttchart|tikzcd|circuitikz|dependency|$other\*?)/x;
-
-$cuerpo =~ s/(\\begin\{($export)\} (.*?) \\end\{\g{-2}\})/$BPL\n$1\n$EPL/gmsx;
-
-#-------------------------- Reverse changes ---------------------------#
-$archivo = "$cabeza$cuerpo$final";
-my %cambios = (
-# pst/tikz set
- '\PSSET' => '\psset',
- '\TIKZSET' => '\tikzset',
-# pspicture
- '\TRICKS' => '\pspicture',
- '\ENDTRICKS' => '\endpspicture',
-# pspicture
- '\begin{TRICKS' => '\begin{pspicture',
- '\end{TRICKS' => '\end{pspicture',
-# $other
- '\begin{OTHER' => "\\begin\{$other",
- '\end{OTHER' => "\\end\{$other",
-# document
- '\begin{DOCTRICKS}' => '\begin{document}',
- '\end{DOCTRICKS}' => '\end{document}',
-# tikzpicture
- '\begin{TIKZPICTURE}' => '\begin{tikzpicture}',
- '\end{TIKZPICTURE}' => '\end{tikzpicture}',
-# pgfinterruptpicture
- '\begin{PGFINTERRUPTPICTURE'=> '\begin{pgfinterruptpicture',
- '\end{PGFINTERRUPTPICTURE' => '\end{pgfinterruptpicture',
-# pgfpicture
- '\begin{PGFPICTURE}' => '\begin{pgfpicture}',
- '\end{PGFPICTURE}' => '\end{pgfpicture}',
-# ganttchart
- '\begin{GANTTCHART}' => '\begin{ganttchart}',
- '\end{GANTTCHART}' => '\end{ganttchart}',
-# circuitikz
- '\begin{CIRCUITIKZ}' => '\begin{circuitikz}',
- '\end{CIRCUITIKZ}' => '\end{circuitikz}',
-# forest
- '\begin{FOREST}' => '\begin{forest}',
- '\end{FOREST}' => '\end{forest}',
-# tikzcd
- '\begin{TIKZCD}' => '\begin{tikzcd}',
- '\end{TIKZCD}' => '\end{tikzcd}',
-# dependency
- '\begin{DEPENDENCY}' => '\begin{dependency}',
- '\end{DEPENDENCY}' => '\end{dependency}',
-);
-
-#-------------------------- Back Postscript ---------------------------#
-
-my @lineas = split /\n/, $archivo;
-# reverse in postscript environment
-for (@lineas) {
- if (/\\begin\{($POSTSCRIPT)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- while (my($busco, $cambio) = each %cambios) {
- s/\Q$busco\E/$cambio/g;
+### PSTexample environment suport
+### Append graphic= to \begin{PSTexample}[...]
+if($PSTexa){
+my $exaNo = 1;
+while ($cuerpo =~ /\\begin\{PSTexample\}(\[.+?\])?/gsm) {
+ my $swpl_grap = "graphic=\{\[scale=1\]$imageDir/$name-$prefix-exa";
+ my $corchetes = $1;
+ my($pos_inicial, $pos_final) = ($-[1], $+[1]);
+ if (not $corchetes) {
+ $pos_inicial = $pos_final = $+[0];
}
- } # close postscript environment changes
-}
+ if (not $corchetes or $corchetes =~ /\[\s*\]/) {
+ $corchetes = "[$swpl_grap-$exaNo}]";
+ }
+ else {
+ $corchetes =~ s/\]/,$swpl_grap-$exaNo}]/;
+ }
+ substr($cuerpo, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
+ pos($cuerpo) = $pos_inicial + length $corchetes;
+} # close while
+continue {
+ $exaNo++;
+ }
-# join changes
-$archivo = join("\n", @lineas);
+### Pass PSTexample to nopreview envirnment
+$cuerpo =~ s/\%<\*ltximgverw>\n
+ (?<code>
+ \\begin\{PSTexample\} .+? \\end\{PSTexample\}
+ )
+ \n\%<\/ltximgverw>
+ /\\begin\{nopreview\}\n$+{code}\n\\end\{nopreview\}/gmsx;
+} # close PSTexa
-#--------------- Extract source code for PST/PGF/TIKZ -----------------#
-# Dividir el archivo
-my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+?) (\\begin{document} .+?)(\\end{document}.*)\z/msx;
+### Command line script identification
+print "$program $nv $copyright" ;
-# Poner el atributo añadido a PostScript
-while ($cuerpo =~ /\\begin\{postscript\}/gsm) {
-
- my $corchetes = $1;
- my($pos_inicial, $pos_final) = ($-[1], $+[1]); # posición donde están los corchetes
-
- if (not $corchetes) {
- $pos_inicial = $pos_final = $+[0]; # si no hay corchetes, nos ponemos al final de \begin
+### Check if enviroment found in input file
+if ($envNo == 0 and $exaNo == 0){
+ die errorUsage "ltximg can not find any environment to extract in file $name$ext";
+ }
+elsif ($envNo!= 0 and $exaNo!= 0){
+ say "The file $name$ext contain $envNo environment to extract and $exaNo PSTexample environment to extract";
}
- if (not $corchetes or $corchetes =~ /\[\s*\]/) { # si no hay corchetes, o están vacíos,
- $corchetes = "[$graphics-$exacount}]"; # ponemos los nuestros
+elsif ($envNo == 0 and $exaNo!= 0){
+ say "The file $name$ext contain $exaNo PSTexample environment to extract";
+ }
+else {
+ say "The file $name$ext contain $envNo environment to extract";
}
- substr($cuerpo, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
- pos($cuerpo) = $pos_inicial + length $corchetes; # reposicionamos la búsqueda de la exp. reg.
+
+### Set output file name from input file
+if (exists $opts_file{options}{output}){
+ $output = $opts_file{options}{output};
}
-continue {
- $exacount++;
+
+### Validate output file name
+if (defined $output) {
+# Not contain - at begin
+if ($output =~ /(^\-|^\.).*?/){
+ die errorUsage "$output it is not a valid name for output file";
}
-# Delte source files
-if (-e "$imageDir/$name-fig-1$ext") {
-unlink <"$imageDir/$name-fig-*$ext">;
+
+# The name of the output file must be different that $name
+if ($output eq "$name") { # $output = $input
+ $output = "$name-out$ext";
}
-#---------------------- Extract source code in images -----------------#
-while ($cuerpo =~ /$BP\[.+?(?<img_src_name>$imageDir\/.+?-\d+)\}\](?<code>.+?)(?=$EP)/gsm) {
- open my $SALIDA, '>', "$+{'img_src_name'}$ext";
- print $SALIDA <<"EOC";
-$cabeza\\pagestyle{empty}\n\\begin{document}$+{'code'}\\end{document}
-EOC
-close $SALIDA;
+# The name of the output file must be different that $name.ext
+if ($output eq "$name$ext") { # $output = $input.tex
+ $output = "$name-out$ext";
}
+# Remove .ltx or .tex extension
+if ($output =~ /.*?$ext/){
+ $output =~ s/(.+?)$ext/$1/gms;
+ }
+} # close output string check
-#--------------- Create a one file whit all figs file -----------------#
-if ($nopreview) {
-if (-e "$imageDir/$name-fig-1$ext") {
-# 1- Leer los source files
-my @pstexafiles = glob("$imageDir/$name-fig-*$ext");
+### If output name are ok, then $outfile = 1
+if(defined($output)){
+ $outfile = 1;
+}
-# 2- Ordenar según el índice y extención
-@pstexafiles =
- map { $_->[1] }
- sort { $a->[0] <=> $b->[0] }
- map { [ ($_ =~ /(\d+$ext)/), $_ ] }
- @pstexafiles;
-
-# 3- Bucle para leer las secciones
-my @almacen;
-for my $exafile (@pstexafiles) {
-
- # 3.1- Leer el archivo
- open my $FH, '<', $exafile; #
- my $tex = join q{}, <$FH>; #
- close $FH;
-
- # 3.2- Extraer la parte que nos interesa
- my($pedazo) = $tex =~ m/\\begin\{document\}\s*(.+?)\s*\\end\{document\}/sm;
-
- # 3.3- Almacenamos, si hemos encontrado algo
- push @almacen, $pedazo if $pedazo;
+### If --srcenv or --subenv option are OK then execute script
+if($srcenv){
+ $outsrc = 1;
+ $subenv = 0;
}
-# 4- Salida
-open my $SALIDA, '>', "$tempDir/$name-fig$ext";
-print $SALIDA "$cabeza\\pagestyle{empty}\n\\begin\{document\}\n";
+if ($subenv){
+ $outsrc = 1;
+ $srcenv = 0;
+}
-my $fig = 1;
-for my $item (@almacen) {
- print $SALIDA $item;
- print $SALIDA "\n%% fig $fig\n";
- print $SALIDA "\\newpage\n";
- $fig++;
+### Set imgdir name from input file
+if (exists $opts_file{options}{imgdir}){
+ $imageDir = $opts_file{options}{imgdir};
}
-
-print $SALIDA '\end{document}';
-close $SALIDA;
- } # close join files
-} # close $nopreview
-else {
-my $opcion = $xetex ? 'xetex,'
- : $latex ? ''
- : 'pdftex,'
- ;
+### Set prefix name from input file
+if (exists $opts_file{options}{prefix}){
+ $prefix = $opts_file{options}{prefix};
+}
+
+### Set pdfcrop margins from input file
+if (exists $opts_file{options}{margins}){
+ $margins = $opts_file{options}{margins};
+}
+
+### Set DPI resolution for images from input file
+if (exists $opts_file{options}{dpi}){
+ $DPI = $opts_file{options}{dpi};
+}
+
+### Create /images dir to save image and source code
+-e $imageDir or mkdir($imageDir,0744) or die "Can't create $imageDir: $!\n";
+
+### Options for \pagestyle{empty} ($crop)
+my $opt_page = $crop ? "\n\\pagestyle\{empty\}\n\\begin\{document\}"
+ : "\n\\begin\{document\}"
+ ;
+
+### Preamble options for subfiles
+my $sub_prea = "$optin$cabeza$opt_page";
+
+### Delete <*remove> ... </remove> in $sub_prea
+$sub_prea =~s/^\%<\*remove>\s*(.+?)\s*\%<\/remove>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+
+my $opt_prew = $xetex ? 'xetex,'
+ : $latex ? ''
+ : 'pdftex,'
+ ;
+
+### Lines to add at begin input file
my $preview = <<"EXTRA";
\\AtBeginDocument\{%
-\\RequirePackage\[${opcion}active,tightpage\]\{preview\}%
-\\renewcommand\\PreviewBbAdjust\{-60pt -60pt 60pt 60pt\}%
-\\newenvironment\{postscript\}\{\}\{\}%
-\\PreviewEnvironment\{postscript\}\}%
+\\RequirePackage\[${opt_prew}active,tightpage\]\{preview\}%
+\\renewcommand\\PreviewBbAdjust\{-60pt -60pt 60pt 60pt\}\}%
EXTRA
- # write
- open my $SALIDA, '>', "$tempDir/$name-fig$ext";
- print $SALIDA $preview . $archivo;
- close $SALIDA;
-}
-
-#---------------------- Create images files ---------------------------#
-# Define compilers
-my $compile = $xetex ? 'xelatex'
- : $luatex ? 'lualatex'
- : $latex ? 'latex'
- : 'pdftex'
- ;
-my $opt_compile = $miktex ? '--enable-write18 --interaction=batchmode'
- : '--shell-escape --interaction=batchmode'
- ;
-
-# Option for gs
-my $opt_gspdf='-q -dSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress';
-my $opt_gspng="-q -dSAFER -sDEVICE=pngalpha -r$DPI";
-my $opt_gsjpg="-q -dSAFER -sDEVICE=jpeg -r$DPI -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
-
-# Option for pdfcrop
-my $opt_crop= $xetex ? "--xetex --margins $margins"
- : $luatex ? "--luatex --margins $margins"
- : $latex ? "--margins $margins"
- : "--pdftex --margins $margins"
- ;
-# Fix pdftops error message in windows
-if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
-open my $ppmconf, '>', "$tempDir/xpd";
-print $ppmconf <<'EOH';
-errQuiet yes
-EOH
-close $ppmconf;
+
+### Extract source $outsrc
+if ($outsrc) {
+my $src_name = "$name-$prefix-";
+my $srcNo = 1;
+
+### Source file whitout preamble for standart environment
+if ($srcenv) {
+
+### Extract standart environment in single files
+if($STDenv){
+say "Creating $envNo files with source code for all environments";
+while ($cuerpo =~ m/$BP\s*(?<env_src>.+?)\s*$EP/gms) {
+open my $OUTsrc, '>', "$imageDir/$src_name$srcNo$ext";
+ print $OUTsrc $+{env_src};
+close $OUTsrc;
+ } # close while
+continue {
+ $srcNo++;
}
-#-------------------------- Compiling image file ----------------------#
-if($nopreview){
- print "Create $name-fig.pdf in $imageDir dir whit all PGF/TIKZ/PST using $compile\n";
+} # close STDenv
+
+### Extract PSTexample in single files
+if($PSTexa){
+say "Creating $exaNo files with source code for all PSTexample environments";
+while ($cuerpo =~ m/$BE\[.+?(?<pst_exa_name>$imageDir\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
+open my $OUTexa, '>', "$+{'pst_exa_name'}$ext";
+ print $OUTexa $+{'exa_src'};
+close $OUTexa;
+ }
+ } # close PSTexa
+} # close srcenv
+
+### Subfile whit preamble
+if ($subenv) {
+
+### Extract standart environments in subfiles
+if($STDenv){
+say "Creating a $envNo files whit source code and preamble for all environments";
+while ($cuerpo =~ m/(?<=$BP)(?<env_src>.+?)(?=$EP)/gms) { # search $cuerpo
+open my $OUTsub, '>', "$imageDir/$src_name$srcNo$ext";
+print $OUTsub <<"EOC";
+$sub_prea$+{'env_src'}\\end\{document\}
+EOC
+close $OUTsub;
+ } # close while
+continue {
+ $srcNo++;
}
-else{
- print "Create $name-fig.pdf in $imageDir dir whit all PGF/TIKZ/PST using $compile and preview package\n";
+} # close STDenv
+
+### Extract PSTexample environments in subfiles
+if($PSTexa){
+say "Creating a $exaNo files whit source code and preamble for all PSTexample environments";
+while ($cuerpo =~ m/$BE\[.+?(?<pst_exa_name>$imageDir\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
+open my $OUTsub, '>', "$+{'pst_exa_name'}$ext";
+print $OUTsub "$sub_prea\n$+{'exa_src'}\n\\end\{document\}";
+close $OUTsub;
+ } # close while
+ } # close $PSTexa
+ } # close subenv
+} # close $outsrc
+
+### Create a one file whit all PSTexample environments
+if($PSTexa){
+say "Creating the temporary file $name-$prefix-exa-$tmp$ext whit $exaNo PSTexample environments extracted";
+@exa_extract = undef;
+while ( $cuerpo =~ m/$BE\[.+? $imageDir\/.+?-\d+\}\](?<exa_src>.+?)$EE/gmsx ) { # search $cuerpo
+push @exa_extract, $+{exa_src}."\n\\newpage\n";
+open my $OUTfig, '>', "$name-$prefix-exa-$tmp$ext";
+ print $OUTfig "$optin"."$cabeza"."$opt_page"."@exa_extract\n"."\\end\{document\}";
+close $OUTfig;
+ }# close while
+
+### Move and rename tmp-exa-rand file to /image dir
+if(!$run){
+say "Moving the file $name-$prefix-exa-$tmp$ext to /$imageDir/$name-$prefix-exa-all$ext";
+move("$workdir/$name-$prefix-exa-$tmp$ext", "$imageDir/$name-$prefix-exa-all$ext");
}
-
-# Run TeX mode
-system("$compile $opt_compile -output-directory=$imageDir $tempDir/$name-fig$ext");
-if($latex){
- system("dvips -q -Ppdf -o $imageDir/$name-fig.ps $imageDir/$name-fig.dvi");
- system("ps2pdf -dPDFSETTINGS=/prepress $imageDir/$name-fig.ps $imageDir/$name-fig.pdf");
+}# close $PSTexa
+
+### Creating one file whit all environments extracted (noprew option)
+if($STDenv){
+open my $OUTfig, '>', "$name-$prefix-$tmp$ext";
+if ($noprew) {
+say "Creating the temporary file $name-$prefix-$tmp$ext whit $envNo environments extracted";
+my @env_extract;
+while ( $cuerpo =~ m/(?<=$BP)(?<env_src>.+?)(?=$EP)/gms ) { # search $cuerpo
+ push @env_extract, $+{env_src}."\n\\newpage\n";
+ } # close while
+print $OUTfig "$optin"."$cabeza"."$opt_page"."@env_extract\n"."\\end{document}";
+ } # close noprew
+else {
+say "Creating the temporary file $name-$prefix-$tmp$ext whit $envNo environment extracted using preview package";
+print $OUTfig $optin.$preview.$cabeza."\n".$cuerpo."\n\\end{document}";
+ }
+close $OUTfig;
+
+### Move tmp-rand file to /image dir
+if(!$run){
+say "Moving the file $name-$prefix-$tmp$ext to /$imageDir/$name-$prefix-all$ext";
+ move("$workdir/$name-$prefix-$tmp$ext", "$imageDir/$name-$prefix-all$ext");
}
-print "The file $imageDir/$name-fig.pdf need a cropping using pdfcrop whit options: $opt_crop\n";
-system("pdfcrop $opt_crop $imageDir/$name-fig.pdf $imageDir/$name-fig.pdf");
+} # close $STDenv
+
+### Define --shell-escape for TeXLive and MikTeX
+my $write18 = '-shell-escape'; # TeXLive
+ $write18 = '-enable-write18' if defined($ENV{"TEXSYSTEM"}) and
+ $ENV{"TEXSYSTEM"} =~ /miktex/i;
+
+### Define --interaction=mode for compilers
+my $opt_compiler = $verbose ? "$write18 -interaction=nonstopmode -recorder"
+ : "$write18 -interaction=batchmode -recorder"
+ ;
+
+### Define $silence
+my $silence = $verbose ? ''
+ : ">$null"
+ ;
+
+### Append -q to gs/poppler for system command line
+my $quiet = $verbose ? ''
+ : '-q'
+ ;
+
+### Compilers
+my $compiler = $xetex ? "xelatex $opt_compiler"
+ : $luatex ? "lualatex $opt_compiler"
+ : $latex ? "latex $opt_compiler"
+ : $dvips ? "latex $opt_compiler"
+ : $dvipdf ? "latex $opt_compiler"
+ : $arara ? 'arara'
+ : "pdflatex $opt_compiler"
+ ;
+
+### Message in command line for compilers
+my $msg_compiler = $xetex ? 'xelatex'
+ : $luatex ? 'lualatex'
+ : $latex ? 'latex>dvips>ps2pdf'
+ : $dvips ? 'latex>dvips>ps2pdf'
+ : $dvipdf ? 'latex>dvipdfmx'
+ : $arara ? 'arara'
+ : 'pdflatex'
+ ;
+
+### Options for ghostscript in command line
+my %opt_gs_dev = (
+ pdf => "$gscmd $quiet -dNOSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress",
+ gray => "$gscmd $quiet -dNOSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray",
+ png => "$gscmd $quiet -dNOSAFER -sDEVICE=pngalpha -r$DPI",
+ bmp => "$gscmd $quiet -dNOSAFER -sDEVICE=bmp32b -r$DPI",
+ jpg => "$gscmd $quiet -dNOSAFER -sDEVICE=jpeg -r$DPI -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4",
+ tif => "$gscmd $quiet -dNOSAFER -sDEVICE=tiff32nc -r$DPI",
+ );
-##-------------------------- Create image formats ----------------------#
+### Options for poppler-utils in command line
+my %opt_poppler = (
+ eps => "pdftops $quiet -eps",
+ ppm => "pdftoppm $quiet -r $DPI",
+ svg => "pdftocairo $quiet -svg",
+ );
+### Option for pdfcrop in command line
+my $opt_crop = $xetex ? "--xetex --margins $margins"
+ : $luatex ? "--luatex --margins $margins"
+ : $latex ? "--margins $margins"
+ : "--pdftex --margins $margins"
+ ;
+
+### Compiler generate file whit all environment extracted
+if($run){
+opendir(my $DIR, $workdir);
+while (readdir $DIR) {
+### Compiler generate file
+if (/(?<nombre>$name-$prefix(-exa)?)(?<type>-$tmp$ext)/) {
+ system("$compiler $+{nombre}$+{type} $silence");
+ say "Compiling the file $+{nombre}$+{type} using $msg_compiler";
+
+### Compiling file using latex>dvips>ps2pdf
+if($dvips or $latex){
+ system("dvips -q -Ppdf -o $+{nombre}-$tmp.ps $+{nombre}-$tmp.dvi");
+ system("ps2pdf -dPDFSETTINGS=/prepress -dAutoRotatePages=/None $+{nombre}-$tmp.ps $+{nombre}-$tmp.pdf");
+} # close latex
+
+### Compiling file using latex>dvipdfmx
+if($dvipdf){
+ system("dvipdfmx -q $+{nombre}-$tmp.dvi");
+} # close dvipdfmx
+
+### If option gray
+if($gray){
+say "Moving the file $+{nombre}-$tmp.pdf to $tempDir/$+{nombre}-all.pdf (gray scale)";
+system("$opt_gs_dev{gray} -o $tempDir/$+{nombre}-all.pdf $workdir/$+{nombre}-$tmp.pdf");
+ move("$workdir/$+{nombre}-$tmp.pdf","$tempDir/$+{nombre}-$tmp.pdf");
+ }
+else{
+ say "Moving the file $+{nombre}-$tmp.pdf to $tempDir/$+{nombre}-all.pdf";
+ move("$workdir/$+{nombre}-$tmp.pdf", "$tempDir/$+{nombre}-all.pdf");
+}
+
+### Crop generate file
+if($crop){
+say "The file $+{nombre}-all.pdf need a crop, using pdfcrop $opt_crop";
+system("pdfcrop $opt_crop $tempDir/$+{nombre}-all.pdf $tempDir/$+{nombre}-all.pdf $silence");
+}
+
+### Move tmp-rand.tex file whit all source code for environments to /images dir
+move("$workdir/$+{nombre}$+{type}", "$imageDir/$+{nombre}-all$ext");
+ } # close if m/.../
+ } # close while
+closedir $DIR;
+} # close run
+
+### Append image format options
+$opts_cmd{pdf} = 'pdf' if $pdf; # ghostscript
+$opts_cmd{eps} = 1 if exists $opts_file{options}{eps}; # pdftops
+$opts_cmd{ppm} = 1 if exists $opts_file{options}{ppm}; # pdftoppm
+$opts_cmd{svg} = 1 if exists $opts_file{options}{svg}; # pdftocairo
+$opts_cmd{png} = 1 if exists $opts_file{options}{png}; # ghostscript
+$opts_cmd{jpg} = 1 if exists $opts_file{options}{jpg}; # ghostscript
+$opts_cmd{bmp} = 1 if exists $opts_file{options}{bmp}; # ghostscript
+$opts_cmd{tif} = 1 if exists $opts_file{options}{tif}; # ghostscript
+
+### Suported format
+my %format = (%opts_cmd);
+my $format = join " ",grep { defined $format{$_} } keys %format;
+
+### Create image formats in separate files
+if($run){
+opendir(my $DIR, $tempDir);
+while (readdir $DIR) {
+### PDF/PNG/JPG/BMP/TIFF format suported by ghostscript
+if (/(?<nombre>$name-$prefix(-exa)?)(?<type>-all\.pdf)/) {
+for my $var (qw(pdf png jpg bmp tif)) {
+ if (defined $opts_cmd{$var}) {
+ my $ghostcmd = "$opt_gs_dev{$var} -o $workdir/$imageDir/$+{nombre}-%1d.$var $tempDir/$+{nombre}$+{type}";
+ system("$ghostcmd");
+ print "Create a $var image format: runing command $opt_gs_dev{$var} in $+{nombre}$+{type}\r\n";
+ } # close defined for ghostscript
+ }# close for
+} # close if m/.../
+
+### EPS/PPM/SVG format suported by poppler-utils
+if (/(?<nombre>$name-$prefix)(?<type>-all\.pdf)/) {
+for my $var (qw(eps ppm svg)) {
+ if (defined $opts_cmd{$var}) {
+ for (my $epsNo = 1; $epsNo <= $envNo; $epsNo++) {
+my $poppler = "$opt_poppler{$var} -f $epsNo -l $epsNo $tempDir/$+{nombre}$+{type} $workdir/$imageDir/$+{nombre}-$epsNo.$var";
+system("$poppler");
+ } # close for C style
+print "Create a $var image format: runing command $opt_poppler{$var} in $+{nombre}$+{type}\r\n";
+ } # close defined
+ } # close for my $var
+} # close if m/.../
+
+### EPS/PPM/SVG for pst-exa package
+if (/(?<nombre>$name-$prefix-exa)(?<type>-all\.pdf)/) {
+for my $var (qw(eps ppm svg)) {
+ if (defined $opts_cmd{$var}) {
+ for (my $epsNo = 1; $epsNo <= $exaNo; $epsNo++) {
+my $poppler = "$opt_poppler{$var} -f $epsNo -l $epsNo $tempDir/$+{nombre}$+{type} $workdir/$imageDir/$+{nombre}-$epsNo.$var";
+system("$poppler");
+ } # close for C style
+print "Create a $var image format: runing command $opt_poppler{$var} in $+{nombre}$+{type}\r\n";
+ } # close defined
+ } # close for my $var
+ } # close if m/.../
+} # close while
+closedir $DIR; #close dir
+
+### Renaming PPM image files
+if(defined $opts_cmd{ppm}){
opendir(my $DIR, $imageDir);
-my @figs = sort readdir $DIR;
+while (readdir $DIR) {
+ if (/(?<nombre>$name-fig(-exa)?-\d+\.ppm)(?<sep>-\d+)(?<ppm>\.ppm)/) {
+ move("$imageDir/$+{nombre}$+{sep}$+{ppm}", "$imageDir/$+{nombre}");
+ } # close if m/.../
+ } # close while
closedir $DIR;
-for my $fig (@figs) {
-if ($fig =~ /(?<fig>$name-fig-)(?<num>\d+)$ext/) {
-print "Create $imageDir/$name-fig-$+{num} from $name$ext\r";
-# PDF format
-if (!$nopdf) {
-system("$::opt_gscmd $opt_gspdf -o $imageDir/$name-fig-%1d.pdf $imageDir/$name-fig.pdf");
-}
-# PNG format
-if ($png) {
-system("$::opt_gscmd $opt_gspng -o $imageDir/$name-fig-%1d.png $imageDir/$name-fig.pdf");
- }
-# JPEG format
-if ($jpg) {
-system("$::opt_gscmd $opt_gsjpg -o $imageDir/$name-fig-%1d.jpg $imageDir/$name-fig.pdf");
- }
-
-# SVG format pdf2svg
-if ($svg) {
- system("pdf2svg $imageDir/$name-fig.pdf $imageDir/$+{fig}%1d.svg all");
- }
-# EPS format
-if ($eps) {
- if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
- system("pdftops -cfg $tempDir/xpd -q -eps -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}.eps");
- }else{
- system("pdftops -q -eps -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}.eps");
- }
- } # close EPS
-# PPM format
-if ($ppm) {
- if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
- system("pdftoppm -cfg $tempDir/xpd -q -r $DPI -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}");
- }
- else{
- system("pdftoppm -q -r $DPI -f $+{num} -l $+{num} $imageDir/$name-fig.pdf $imageDir/$+{fig}$+{num}");
- }
- } # close PPM
- } # close if ($fig =
-} # close for
-
-## Renaming PPM
-if ($ppm) {
-if (opendir(DIR,$dir)) { # abro el directorio
- while (my $oldname = readdir DIR) { # lo recorro
- # el nuevo nombre es fruto de una sustitución
- my $newname = $oldname =~ s/^($name-(fig|exa)-\d+)(-\d+).ppm$/$1 . ".ppm"/re;
-
- if ($oldname ne $newname) { # comprobación
- rename("$dir/$oldname", "$dir/$newname"); # renombro
- }
- }
- closedir DIR;
- } # close rename ppm
-} # close ppm
-
-#------- Creating output file whitout PGF/PST/TIKZ code ---------------#
-if ($output) {
-print "Create file $name-out$ext whitout PGF/PST/TIKZ code\n";
-
-#----------------- Convert Postscript to includegraphics --------------#
-my $grap="\\includegraphics[scale=1]{$name-fig-";
+ } # close renaming PPM
+} # close run
+
+### Create a output file
+if ($outfile) {
+say "Creating the file $output$ext, changue extracted environments to \\includegraphics";
+
+### Convert extracted environments to \includegraphics
+my $grap="\\includegraphics[scale=1]{$name-$prefix-";
my $close = '}';
-my $IMGno = 1;
+my $imgNo = 1;
+$cuerpo =~ s/$BP.+?$EP/$grap@{[$imgNo++]}$close/msg; # changes
-$cuerpo =~ s/$BP.+?$EP/$grap@{[$IMGno++]}$close/msg;
+### Constant
+my $USEPACK = quotemeta('\usepackage');
+my $GRAPHICPATH = quotemeta('\graphicspath{');
-#------------------------ Clean output file --------------------------#
-# append postscript to hash
-$cambios{'\begin{POSTRICKS}'} = '\begin{postscript}';
-$cambios{'\end{POSTRICKS}'} = '\end{postscript}';
-
-# Constantes
-my $BEGINDOC = quotemeta('\begin{document}');
-my $USEPACK = quotemeta('\usepackage');
-my $REQPACK = quotemeta('\usepackage');
-my $GRAPHICX = quotemeta('{graphicx}');
-
-# Exp. Reg.
+### Precompiled regex
my $CORCHETES = qr/\[ [^]]*? \]/x;
-my $PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add )? | psfrag |psgo |vaucanson-g| auto-pst-pdf | graphicx )/x;
-my $FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}/x;
-
-# comentar
-$cabeza =~ s/ ^ ($USEPACK $CORCHETES $GRAPHICX) /%$1/msxg;
-
-# eliminar líneas enteras
-$cabeza =~ s/ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \n//msxg;
-
-# eliminar palabras sueltas
-$cabeza =~ s/ (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
-
-# Añadir
+my $PALABRAS = qr/\b (?: graphicx )/x;
+my $FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
+
+### Regex to capture \graphicspath
+my $graphix = qr/(\\ usepackage \s*\[\s* .+? \s*\] \s*\{\s* graphicx \s*\} )/ix;
+
+### Capture graphix package for future use
+my (@graphix) = $cabeza =~ m/$graphix/x;
+
+### Remove graphix package
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
+
+### Comment \graphicspath for order and future use
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ ^ ($GRAPHICPATH) /%$1/msxg;
+
+### Regex to capture [options] for pst-exa package
+my $pstexa = qr/(?:\\ usepackage) \[\s*(.+?)\s*\] (?:\{\s*(pst-exa)\s*\} ) /x;
+
+### Capture [option] for pst-exa package
+my (@pst_exa) = $cabeza =~ m/$pstexa/xg;
+
+### Search [option] in pst-exa package
+my %pst_exa = map { $_ => 1 } @pst_exa;
+
+### Clean file (pst/tags)
+if($clean{pst}){
+$PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add )? | psfrag |psgo |vaucanson-g| auto-pst-pdf )/x;
+$FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
+
+### Remove package lines
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
+
+### Delete package words
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+(?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
+
+### Delete \psset
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+
+### Delete \SpecialCoor
+$cabeza =~ s/ \%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\SpecialCoor(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+} # close clean{pst}
+
+### Delete empty package line \usepackage{}
+$cabeza =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+
+### Append graphix to end of preamble
+if(!@graphix == 0){
+$cabeza .= <<"EXTRA";
+@graphix
+EXTRA
+}else{
$cabeza .= <<"EXTRA";
+
\\usepackage{graphicx}
-\\graphicspath{{$imageDir/}}
+EXTRA
+}
+
+### Regex to capture \graphicspath
+my $graphicspath= qr/\\ graphicspath \{ ((?: $llaves )+) \}/ix;
+
+### If preamble contain \graphicspath
+if($cabeza =~ m/($graphicspath)/m){
+while ($cabeza =~ /$graphicspath /pgmx) {
+ my($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ if ($encontrado =~ /$graphicspath/) {
+ my $argumento = $1;
+ if ($argumento !~ /\{$imageDir\\\}/) {
+ $argumento .= "\{$imageDir/\}";
+ my $cambio = "\\graphicspath{$argumento}";
+ substr $cabeza, $pos_inicial, $pos_final-$pos_inicial, $cambio;
+ pos($cabeza) = $pos_inicial + length $cambio;
+ }
+ }
+ } #close while
+
+### Regex to capture
+my ($GraphicsPath) = $cabeza =~ m/($graphicspath)/msx;
+
+### Append graphicspath to end of preamble
+$cabeza .= <<"EXTRA";
+$GraphicsPath
\\usepackage{grfext}
\\PrependGraphicsExtensions*{.pdf}
EXTRA
-
-# Clear PST content in preamble
-$cabeza =~ s/\\usepackage\{\}/% delete/gmsx;
-$cabeza =~ s/\\psset\{.+?\}/% \\psset delete/gmsx;
-$cabeza =~ s/\\SpecialCoor/% \\SpecialCoor/gmsx;
-
-# Recorremos el archivo y realizamos los cambios
-while (my($busco, $cambio) = each %cambios) {
- $cabeza =~ s/\Q$busco\E/$cambio/g;
- $cuerpo =~ s/\Q$busco\E/$cambio/g;
- }
-
-# write
-open my $SALIDA, '>', "$tempDir/$name-out$ext";
-print $SALIDA "$cabeza$cuerpo$final";
-close $SALIDA;
-
-# compile output file
-
-if ($xetex){
- system("xelatex $opt_compile $tempDir/$name-out$ext");
- } # xetex
-elsif($luatex){
- system("lualatex $opt_compile $tempDir/$name-out$ext");
- } # luatex
+ } # close if ($cabeza)
else{
- system("pdflatex $opt_compile $tempDir/$name-out$ext");
- } # pdftex
-
-}# close output file
-
-#--------------------------------- Clean ------------------------------#
-if ($clear) {
-my @del_aux_tex;
-find(\&del_aux_tex, $tempDir);
-sub del_aux_tex{
-my $auximgfile = $_;
-# search .(aux|log)
-if(-f $auximgfile && $auximgfile =~ /$name-out\.(aux|log)$/){
-push @del_aux_tex, $File::Find::name;
- }
-if(-f $auximgfile && $auximgfile =~ /$name-fig$ext/){
-push @del_aux_tex, $File::Find::name;
- }
-}
-unlink @del_aux_tex;
-} # close clear in $tempDir
-
-if ($clear) {
-my @del_tmp;
-find(\&del_tmp, $imageDir);
-sub del_tmp{
-my $auximgfile = $_;
-# search .(aux|log)
-if(-f $auximgfile && $auximgfile =~ /$name-fig\.(aux|dvi|log|ps|pdf)/){
-push @del_tmp, $File::Find::name;
- }
-}
-
-unlink @del_tmp;
-} # close clear $name-fig.tex
-
-# Clear source files
-if ($noSource) {
-unlink <"$imageDir/$name-fig-*$ext">;
-}# end source clear
-
-if ($output) {
-print "Finish, LTXimg create $name-out$ext and put all figures in $imageDir dir\n";
-}else{
-print "Finish, LTXimg create all figures in $imageDir dir\n";
+### If preamble not contain graphicspath, append to premble
+my $GraphicsPath = "\\graphicspath\{\{$imageDir/\}\}";
+
+### Append graphicspath to end of preamble
+$cabeza .= <<"EXTRA";
+$GraphicsPath
+\\usepackage{grfext}
+\\PrependGraphicsExtensions*{.pdf}
+EXTRA
+} # close graphicspath
+
+### Suport for \usepackage[swpl]{pst-exa}
+if(exists($pst_exa{swpl})){
+$cabeza .= <<'EXTRA';
+\usepackage[swpl,pdf]{pst-exa}
+EXTRA
+}
+
+### Suport for \usepackage[tcb]{pst-exa}
+if(exists($pst_exa{tcb})){
+$cabeza .= <<'EXTRA';
+\usepackage[tcb,pdf]{pst-exa}
+EXTRA
+### Regex
+$cuerpo =~ s/(graphic=\{)\[(scale=\d*)\]($imageDir\/$name-$prefix-exa-\d*)\}/$1$2\}\{$3\}/gsmx;
+} # close if
+
+### Options for out_file (add $end to outfile)
+my $out_file = $clean{doc} ? "$optin$cabeza$cuerpo\n\\end\{document\}"
+ : "$optin$cabeza$cuerpo\n$final"
+ ;
+
+### Clean \psset content in output file
+if($clean{pst}){
+$out_file =~s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \%<\*ltximgverw> .+? \%<\/ltximgverw>(*SKIP)(*F)|
+ \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+} # close clean
+
+### Clean \tikzset content in output file
+if($clean{tkz}){
+$out_file =~s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \%<\*ltximgverw> .+? \%<\/ltximgverw>(*SKIP)(*F)|
+ \\tikzset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+} # close clean
+
+### Back changues in all words in outfile
+$out_file =~s/\\begin\{nopreview\}\s*(.+?)\s*\\end\{nopreview\}/$1/gmsx;
+$out_file =~s/\%<\*ltximgverw>\s*(.+?)\s*\%<\/ltximgverw>/$1/gmsx;
+$out_file =~s/\%<\*noltximg>\n(.+?)\n\%<\/noltximg>/$1/gmsx;
+$out_file =~s/^\%<\*remove>\s*(.+?)\s*\%<\/remove>(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+$out_file =~ s/($delt_env)(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+$out_file =~s/($find)/$replace{$1}/g;
+
+### Write output file
+open my $OUTfile, '>', "$output$ext";
+print $OUTfile "$out_file";
+close $OUTfile;
+
+### Process the output file
+if($run){
+### Set correct $compiler, if input use latex then output use pdflatex
+$compiler = "pdflatex $opt_compiler" if $latex;
+$msg_compiler = "pdflatex" if $latex;
+
+### Compiling output file using pdflatex or arara
+say "Compiling file $output$ext using $msg_compiler";
+system("$compiler $output$ext $silence");
+
+### Compiling output file using latex>dvips>ps2pdf
+if($dvips){
+ system("dvips -q -Ppdf $output.dvi");
+ system("ps2pdf -dPDFSETTINGS=/prepress -dAutoRotatePages=/None $output.ps $output.pdf");
+} # close dvips
+
+### Compiling output file using latex>dvipdfmx
+if($dvipdf){
+ system("dvipdfmx -q $output.dvi");
+ } # close dvipdf
+ } # close run
+} # close outfile file
+
+### Deleting temporary files
+if($run){
+say "Deleting (most) temporary files created during the process";
+my @protected = qw();
+push (@protected,"$output$ext","$output.pdf") if defined $output;
+
+my $flsline = "OUTPUT";
+my @flsfile;
+
+if ($PSTexa) {
+push @flsfile,"$name-$prefix-exa-$tmp.fls";
+}
+
+if ($STDenv) {
+push @flsfile,"$name-$prefix-$tmp.fls";
}
-if ($^O eq 'MSWin32' or $^O eq 'MSWin64'){
-unlink "$tempDir/xpd";
+push(@flsfile,"$output.fls") if defined $output;
+
+my @tmpfiles;
+for my $filename(@flsfile){
+ open my $RECtmp, '<', "$filename";
+ push @tmpfiles, grep /^$flsline/,<$RECtmp>;
+ close $RECtmp;
+}
+
+foreach (@tmpfiles) {
+ s/^$flsline\s+|\s+$//g;
+}
+
+if($latex or $dvips){
+ push @tmpfiles,"$name-$prefix-$tmp.ps";
+}
+
+if(-e "$name-$prefix-$tmp.ps"){
+ push @tmpfiles,"$name-$prefix-$tmp.ps";
+}
+
+if ($PSTexa) {
+ push @tmpfiles,"$name-$prefix-exa-$tmp.ps";
+}
+
+if(-e "$output.ps"){
+ push @tmpfiles,"$output.ps";
+}
+
+push @tmpfiles,@flsfile,"$name-$prefix-$tmp$ext","$name-$prefix-$tmp.pdf";
+
+my @delfiles = array_minus(@tmpfiles, @protected);
+
+foreach my $tmpfile (@delfiles){
+ move("$tmpfile", "$tempDir");
}
+} # close clean tmp files
+
+### End of script process
+if($run){
+ say "Finish, image formats: $format are in $workdir/$imageDir/";
+ }
+ else{
+ say "Done";
+} # end run
__END__
diff --git a/Master/texmf-dist/source/support/ltximg/ltximg-doc.dtx b/Master/texmf-dist/source/support/ltximg/ltximg-doc.dtx
new file mode 100644
index 00000000000..75e550b2baf
--- /dev/null
+++ b/Master/texmf-dist/source/support/ltximg/ltximg-doc.dtx
@@ -0,0 +1,1594 @@
+% arara: lualatex: {draft: yes}
+% arara: makeindex: {style: gind}
+% arara: lualatex: {draft: yes}
+% arara: lualatex
+% arara: clean: { files:[ltximg-doc.ilg, ltximg-doc.out, ltximg-doc.ind, ltximg-doc.aux, ltximg-doc.idx, ltximg-doc.log, ltximg-doc.toc] }
+% \iffalse meta-comment
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+## LTXimg &ndash; LaTeX environments to image format
+
+## Description
+
+**ltximg** is a perl *script* that automates the process of extracting and converting
+environments provided by **tikz**, **pstricks** and other packages from input file
+to image formats in individual files using `ghostscript` and `poppler-utils`. Generates a file
+with only extracted environments and other with environments converted to `\includegraphics`.
+
+## Syntax
+```
+$ ltximg [<compiler>] [<options>] [--] <input file>.<tex|ltx>
+```
+## Usage
+```
+$ ltximg --latex [<options>] <file.tex>
+$ ltximg --arara [<options>] <file.tex>
+$ ltximg [<options>] <file.tex>
+$ ltximg <file.tex>
+```
+If used without `[<compiler>]` and `[<options>]` the extracted environments are converted to `pdf` image format
+and saved in the `/images` directory using `pdflatex` and `preview` package. Relative or absolute `paths` for files
+and directories is not supported and if the last `[<options>]` take a list separated by commas you need `--` at the end.
+
+## Default environments extract
+```
+ pspicture tikzpicture pgfpicture psgraph postscript PSTexample
+```
+## Options
+
+```
+ [default]
+-h, --help Display command line help and exit [off]
+-l, --license Display GPL license and exit [off]
+-v, --version Display current version (v1.5) and exit [off]
+-t, --tif Create .tif files using ghostscript [gs]
+-b, --bmp Create .bmp files using ghostscript [gs]
+-j, --jpg Create .jpg files using ghostscript [gs]
+-p, --png Create .png files using ghostscript [gs]
+-e, --eps Create .eps files using poppler-utils [pdftops]
+-s, --svg Create .svg files using poppler-utils [pdftocairo]
+-P, --ppm Create .ppm files using poppler-utils [pdftoppm]
+-g, --gray Gray scale for images using ghostscript [off]
+-f, --force Capture "\psset" and "\tikzset" to extract [off]
+-n, --noprew Create images files whitout "preview" package [off]
+-d <integer>, --dpi <integer>
+ Dots per inch resolution for images [150]
+-m <integer>, --margin <integer>
+ Set margins for pdfcrop [0]
+--imgdir <dirname> Set name of directory to save images [images]
+-o <filename>, --output <filename>
+ Create output file [off]
+--verbose Verbose printing [off]
+--srcenv Create files whit only code environment [off]
+--subenv Create files whit preamble and code [off]
+--latex Using latex>dvips>ps2pdf for compiler input
+ and pdflatex for compiler output [off]
+--dvips Using latex>dvips>ps2pdf for compiler input
+ and latex>dvips>ps2pdf for compiler output [off]
+--arara Use arara for compiler input and output [off]
+--xetex Using xelatex for compiler input and output [off]
+--dvipdf Using dvipdfmx for compiler input and output [off]
+--luatex Using lualatex for compiler input and output [off]
+--prefix <string> Set prefix append to each image file [off]
+--norun Run script, but no create images files [off]
+--nopdf Don't create a ".pdf" image files [off]
+--nocrop Don't run pdfcrop [off]
+--verbcmd <cmdname> Set "\cmdname" verbatim command [myverb]
+--clean (doc|pst|tkz|all|off)
+ Removes specific text in output file [doc]
+--extrenv <env1,...> Add new environments to extract [empty]
+--skipenv <env1,...> Skip environments to extract [empty]
+--verbenv <env1,...> Add verbatim environments [empty]
+--writenv <env1,...> Add verbatim write environments [empty]
+--deltenv <env1,...> Delete environments in output file [empty]
+```
+## Example
+```
+$ ltximg --latex -e -p --srcenv --imgdir=mypics -o test-out test-in.ltx
+```
+```
+$ ltximg --latex -ep --srcenv --imgdir mypics -o test-out test-in.ltx
+```
+ Create a `/mypics` directory whit all extracted environments converted to
+ image formats(`.pdf`, `.eps`, `.png`), individual files whit source code (`.tex`)
+ for all extracted environments, a file `test-out.ltx` whit all environments converted to `\includegraphics`
+ and file `test-in-fig-all.tex` with only the extracted environments using
+ `latex>dvips>ps2pdf` and `preview` package for `<input file>` and `pdflatex`
+ for `<output file>`.
+
+## Documentation
+ For full documentation use:
+```
+$ texdoc ltximg
+```
+
+## Licence
+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 3 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.
+
+## Author
+
+Written by Pablo González L <pablgonz@yahoo.com>, last update 2018-04-12.
+
+## Copyright
+
+Copyright 2013 - 2018 by Pablo González L
+%</readme>
+%<*changues>
+## Changues
+```
+ v1.5. (d) 2018-04-12 - Use GitHub to control version
+ - Rewrite and optimize most part of code and options
+ - Changue pdf2svg for pdftocairo
+ - Complete support for pst-exa packpage
+ - Clean take and optional
+ v1.4. (d) 2016-11-29 - Remove and rewrite code for regex and system call
+ - Append arara compiler, clean and comment code
+ - Append dvips and dvipdfm for creation images
+ - Append bmp, tif image format
+ v1.3. (d) 2016-10-16 - All options its read from cmd line and input file
+ - Rewrite some part of code (norun, nocrop, clean)
+ - Suport minted and tcolorbox packpage for verbatim
+ - Use /tmp dir for work process
+ - Escape some characters in regex according to v5.2xx
+ v1.2 (p) 2015-04-22 - Remove unused modules
+ v1.1 (p) 2015-04-21 - Change mogrify to gs for image formats
+ - Create output file
+ - Rewrite source code and fix regex
+ - Add more image format
+ - Change date to iso format
+ v1.0 (p) 2013-12-01 - First public release
+```
+Copyright 2013 - 2018 by Pablo González L <pablgonz@yahoo.com>.
+%</changues>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%<*internal>
+\input docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\nopreamble\nopostamble
+\generate{
+ \file{README.md}{\from{\jobname.dtx}{readme}}
+ \file{CHANGUES.md}{\from{\jobname.dtx}{changues}}
+}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</internal>
+%<*documentation>
+\documentclass{ltxdoc}
+\usepackage[top=0.5in, bottom=0.5in, left=2in, right=1in,footskip=0.2in,%
+ headsep=10pt]{geometry} % page dimension
+\usepackage[totoc,columns=2]{idxlayout} % index
+\EnableCrossrefs
+\CodelineIndex
+\usepackage[mono=false]{libertine} % default roman/serif fonts
+\setmonofont[
+ Ligatures = TeX ,
+ Scale = 0.84,
+ Extension = .otf,
+ UprightFont = *-Regular ,
+ ItalicFont = *-RegularIt,
+ BoldFont = *-Medium ,
+ BoldItalicFont = *-MediumIt
+ ]{SourceCodePro} % srccode font
+\usepackage{microtype,fetamont,hologo} % LaTeX logo and LTXimg logo
+\usepackage{xspace,tocloft,enumitem,fancyhdr,lastpage} % custom
+\usepackage[svgnames]{xcolor} % colors :)
+\usepackage[sf,bf,compact,medium]{titlesec} % sections
+\usepackage{adjustbox,multicol,hyperref,xparse,listings,accsupp}
+\usepackage{interfaces,graphicx}
+
+% don't copy numbers in code example
+\newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}
+
+% parindent
+\setlength{\parindent}{0pt}
+
+% Colors for options
+\definecolor{optcolor}{rgb}{0.281,0.275,0.485}
+
+% Logo whit libertine font for title
+\newsavebox{\logobox}
+\savebox{\logobox}{%
+ \normalsize%
+ {\libertineInitial%
+ \textcolor{red}{L}\hspace{-3.0pt}%
+ \raisebox{-0.2em}{\small \textcolor{green}{T}}%
+ \hspace{-2.9pt}\textcolor{blue}{X}}%
+ \hspace{-1pt}\textffmw{\textcolor{gray}{img}}%
+}% close box
+
+\makeatletter % changes the catcode of @ to 11
+\newcommand{\LTXimg}{%
+ \settoheight{\@tempdima}{L}%
+ \resizebox{!}{\@tempdima}{\usebox{\logobox}}%
+}
+\makeatother % changes the catcode of @ back to 12
+
+% oldstyle for libertine, need after \LTXimg
+\useosf
+
+% logo for body docuement
+\newcommand*{\ltximg}{%
+ \normalsize\texttt{\bfseries
+ \textcolor{NavyBlue}{ltximg}}\xspace%
+}% close ltximg
+
+% Identification
+\def\myscript{ltximg}
+\def\fileversion{1.5}
+\def\filedate{2018-04-12}
+% Config hyperref
+\hypersetup{
+ linkcolor = blue!50,
+ citecolor = red!50,%
+ urlcolor = magenta,%
+ colorlinks = true,%
+ pdftitle ={.::ltximg v1.5 (2018-04-12) --- LaTeX environments to image formats::.},%
+ pdfauthor= {Pablo Gonz\'{a}lez Luengo},% á fails
+ pdfsubject={Documentation for version 1.5},%
+ pdfstartview={FitH},%
+ bookmarksopenlevel=2,%
+}
+
+% Configuration fancyhdr
+\fancypagestyle{plain}{%
+\fancyhf{}%
+\fancyfoot[R]{\small\textsf{\thepage{} /\pageref{LastPage}}}
+\renewcommand{\headrulewidth}{0pt}%
+\renewcommand{\footrulewidth}{0pt}%
+}% close plain style
+
+\renewcommand{\sectionmark}[1]{
+ \markboth{\textsf{\scshape\small\S\thesection. #1}}{}
+ }%
+
+\fancypagestyle{myheader}{%
+\fancyhf{}%
+\fancyhead[L]{\raisebox{-0.75\baselineskip}[0pt][0pt]{%
+\textsf{\small \textcolor{gray}{Documentation for version \fileversion{} [\filedate]}}%
+ }%
+ }%
+\fancyhead[R]{\raisebox{-0.75\baselineskip}[0pt][0pt]{%
+ \small\nouppercase{\leftmark}%
+ }%
+ }%
+\fancyfoot[R]{\small\textsf{\thepage{} /\pageref{LastPage}}}
+\fancyfoot[L]{%
+ \small\sffamily%
+ \LTXimg{}
+ \textcolor{gray}{%
+ \raisebox{-1pt}{\textcopyright}{}2013--2018 by Pablo González L%
+ }%
+}%
+\renewcommand{\headrulewidth}{0.5pt}%
+\renewcommand{\footrulewidth}{0pt}%
+\renewcommand{\headrule}{%
+ \hbox to\headwidth{%
+ \color{NavyBlue}\leaders\hrule height \headrulewidth\hfill}%
+ }%
+} % close myheader
+
+% add headheight
+\setlength{\headheight}{21pt}%
+
+% Custom \meta[...]{...}, \marg[...]{...} and \oarg[...]{...} for color
+\ExplSyntaxOn
+%^^A user level commands
+\RenewDocumentCommand{\meta}{O{}m}
+{
+ \ltximg_meta_generic:Nnn \ltximg_meta:n { #1 } { #2 }
+}
+\RenewDocumentCommand{\marg}{O{}m}
+{
+ \ltximg_meta_generic:Nnn \ltximg_marg:n { #1 } { #2 }
+}
+\RenewDocumentCommand{\oarg}{O{}m}
+{
+ \ltximg_meta_generic:Nnn \ltximg_oarg:n { #1 } { #2 }
+}
+%^^A variables and keys
+\tl_new:N \l_ltximg_meta_font_tl
+
+\keys_define:nn { ltximg/meta }
+{
+ type .choice:,
+ type / tt .code:n = \tl_set:Nn \l_ltximg_meta_font_tl { \ttfamily },
+ type / rm .code:n = \tl_set:Nn \l_ltximg_meta_font_tl { \rmfamily },
+ type .initial:n = tt,
+ cf .tl_set:N = \l_ltximg_meta_color_tl,
+ cf .initial:n = black,
+ ac .tl_set:N = \l_ltximg_meta_anglecolor_tl,
+ ac .initial:n = black,
+ sbc .tl_set:N = \l_ltximg_meta_brackcolor_tl,
+ sbc .initial:n = black,
+ cbc .tl_set:N = \l_ltximg_meta_bracecolor_tl,
+ cbc .initial:n = black,
+}
+%^^A internal commands
+\cs_new_protected:Npn \ltximg_meta_generic:Nnn #1 #2 #3
+{
+ \group_begin:
+ \keys_set:nn { ltximg/meta } { #2 }
+ \color{ \l_ltximg_meta_color_tl }
+ \l_ltximg_meta_font_tl
+ #1 { #3 } % #1 is \ltximg_meta:n, \ltximg_marg:n or \ltximg_oarg:n
+ \group_end:
+}
+\cs_new_protected:Npn \ltximg_meta:n #1
+{
+ \ltximg_meta_angle:n { \textlangle }
+ \ltximg_meta_meta:n { #1 }
+ \ltximg_meta_angle:n { \textrangle }
+}
+\cs_new_protected:Npn \ltximg_marg:n #1
+{
+ \ltximg_meta_brace:n { \textbraceleft }
+ \ltximg_meta:n { #1 }
+ \ltximg_meta_brace:n { \textbraceright }
+}
+\cs_new_protected:Npn \ltximg_oarg:n #1
+{
+ \ltximg_meta_brack:n { [ }
+ \ltximg_meta:n { #1 }
+ \ltximg_meta_brack:n { ] }
+}
+\cs_new_protected:Npn \ltximg_meta_meta:n #1
+{
+ \textnormal{\textit{#1}}
+}
+\cs_new_protected:Npn \ltximg_meta_angle:n #1
+{
+ \group_begin:
+ \fontfamily{cmr}\selectfont
+ \textcolor{\l_ltximg_meta_anglecolor_tl}{#1}
+ \group_end:
+}
+\cs_new_protected:Npn \ltximg_meta_brace:n #1
+{
+ \group_begin:
+ \color{\l_ltximg_meta_bracecolor_tl}
+ #1
+ \group_end:
+}
+\cs_new_protected:Npn \ltximg_meta_brack:n #1
+{
+ \textcolor{\l_ltximg_meta_brackcolor_tl}{#1}
+}
+\ExplSyntaxOff
+
+% \prgname{sm} : #1 index compiler, #2 index programs:
+\DeclareDocumentCommand\prgname{sm}{%
+ \IfBooleanTF{#1}
+ {
+ \textcolor{ForestGreen}{\ttfamily\bfseries{#2}}\xspace%
+ \SortIndex{compiler}{Compiler>\small\textsf{#2}}%
+ }
+ {
+ \textcolor{ForestGreen}{\ttfamily\bfseries{#2}}\xspace%
+ \SortIndex{programs}{Programs>\small\textsf{#2}}%
+ }
+}%
+
+% \prgopt{sm} : #1 compiler opt, #2 program opt:
+\DeclareDocumentCommand\prgopt{sm}{%
+ \IfBooleanTF{#1}
+ {
+ \textcolor{gray}{\ttfamily\bfseries{-{}#2}}%\xspace%
+ \SortIndex{compiler options}{Compiler options>\small\texttt{-{}#2}}%
+ }
+ {
+ \mbox{\texttt{-{}#2}}%
+ \SortIndex{#2}{\texttt{-{}#2} (program option)}%
+ }
+}
+
+% \scriptname*{m}
+\DeclareDocumentCommand\scriptname{m}{%
+ \textcolor{ForestGreen}{\ttfamily\bfseries{#1}}\xspace
+ \SortIndex{scripts}{Scripts>\textsf{#1}}%
+}%
+
+% \scriptopt{m}
+\DeclareDocumentCommand\scriptopt{m}{%
+ \mbox{\texttt{#1}}\xspace%
+ \SortIndex{script option}{Script options>\small\textsf{#1}}%
+}
+
+% \pkgname{m}
+\DeclareDocumentCommand\pkgname{m}{%
+ \textsf{\textcolor{SlateBlue}{#1}}%
+ \SortIndex{packages}{Packages>\textsf{#1}}%
+ %\SortIndex{#1}{\textsf{#1} (package)}%
+}%
+
+% \pkgopt{m}
+\DeclareDocumentCommand\pkgopt{m}{%
+ \textsf{\textcolor{Orange}{#1}}%
+ \SortIndex{package options}{Package options>\textsf{#1}}%
+ \SortIndex{#1}{\textsf{#1} (package option)}%
+}%
+
+% \env{sm}, #1 not used now
+\DeclareDocumentCommand\env{sm}{
+ \textcolor{optcolor}{\sffamily{#2}}%
+ \SortIndex{environment}{Environments>\small\textsf{#2}}%
+}
+
+% \ics{sm}, #1 not used now
+\DeclareDocumentCommand\ics{sm}{
+ \textcolor{optcolor}{\ttfamily{\textbackslash#2}}%
+ \SortIndex{#2}{\textsf{\small\textbackslash#2}}
+}
+
+% file extention
+\DeclareDocumentCommand\fext{m}{%
+ \mbox{\textcolor{optcolor}{\ttfamily\bfseries{.#1}}\xspace}%
+ \SortIndex{files extention}{File extentions (input)>\small\textsf{.#1}}%
+}
+
+% image format/extention
+\DeclareDocumentCommand\iext{m}{%
+ \textcolor{optcolor}{\ttfamily\bfseries{#1}}%
+ \SortIndex{Image format}{Image formats>\small\textsf{#1}}%
+}
+
+% \DescribeIF{m}, #1 image format
+\newsavebox{\marginIF}
+\NewDocumentCommand\DescribeIF{m}{%
+\begin{lrbox}{\marginIF}%
+ \begin{minipage}[t]{\marginparwidth}%
+ \raggedleft
+ \iext{#1}
+ \end{minipage}%
+\end{lrbox}%
+ \leavevmode%
+ \marginpar{\usebox{\marginIF}}%
+ \ignorespaces%
+}%
+
+% \sysydir{m}
+\DeclareDocumentCommand\sysdir{m}{%
+ \mbox{\textcolor{NavyBlue}{\ttfamily{/#1}}}%
+}
+
+% \sysfile{m} ...only for color in some examples
+\DeclareDocumentCommand\sysfile{m}{%
+ \mbox{\textcolor{gray}{\ttfamily{#1}}}\xspace%
+}
+
+% \OSsystem{m} ...only for color in some examples
+\DeclareDocumentCommand\OSsystem{m}{%
+ \mbox{\textcolor{NavyBlue}{\ttfamily\bfseries{#1}}}%
+ \SortIndex{Operating system}{Operating system>\small\textsf{#1}}%
+}
+
+% \cmdopt[short]{long}
+\NewDocumentCommand\cmdopt{om}{%
+ \IfNoValueTF{#1}%
+ {\textcolor{optcolor}{\ttfamily\bfseries{-\/-#2}}\xspace}%
+ {\textcolor{optcolor}{\ttfamily\bfseries{-{}#1}}, \textcolor{optcolor}{\ttfamily\bfseries{-\/-#2}}\xspace}%
+\SortIndex{options}{\textsf{\myscript}\ options in command line>\small\texttt{-\/-#2}}%
+}
+
+% \myenv{environ}
+\DeclareDocumentCommand\myenv{m}{%
+\moveright 0.0pt \hbox{%
+ \begin{minipage}[t]{\marginparwidth}%
+ \raggedleft\ttfamily%\small%
+ {\textcolor{gray}{\textbackslash begin\{}}{\bfseries\textcolor{optcolor}{#1}}\textcolor{gray}{\}}\par%
+ \meta[ac=gray,cf=gray]{env content}\par%
+ {\textcolor{gray}{\textbackslash end\{}}{\bfseries\textcolor{optcolor}{#1}}\textcolor{gray}{\}}%
+ \end{minipage}%
+ } % close hbox
+\SortIndex{Environment}{Environments suport by default>\small\textsf{#1}}%
+}%
+
+% \mytag{dtxtag}
+\DeclareDocumentCommand\mytag{m}{%
+\moveright 0.0pt \hbox{%
+ \begin{minipage}[t]{\marginparwidth}%
+ \raggedleft\ttfamily%\small%
+ \textcolor{gray}{\%<*}{\bfseries\textcolor{optcolor}{#1}}\textcolor{gray}{>}\par%
+ \meta[ac=gray,cf=gray]{content}\par%
+ \textcolor{gray}{\%</}{\bfseries\textcolor{optcolor}{#1}}\textcolor{gray}{>}%
+ \end{minipage}%
+ } % close hbox
+\SortIndex{docstrip}{Docstrip tag>\textsf{#1}}%
+}%
+
+% \DescribeTE{sm}, #1 tag, #2 env
+\newsavebox{\marginenvtag}
+\NewDocumentCommand\DescribeTE{sm}{%
+\begin{lrbox}{\marginenvtag}%
+ \begin{minipage}[t]{\marginparwidth}%
+ \raggedleft
+ \IfBooleanTF{#1}{\mytag{#2}}{\myenv{#2}}
+ \end{minipage}%
+\end{lrbox}%
+ \leavevmode%
+ \marginpar{\usebox{\marginenvtag}}%
+ \ignorespaces%
+}%
+
+% DescribeOptFile*{options}{example}[!]
+\newsavebox{\optinfile}
+\NewDocumentCommand\DescribeOptFile{s m m O{\hphantom{!}}}{
+\begin{lrbox}{\optinfile}%
+ \begin{minipage}[t]{\marginparwidth}%
+ \raggedleft\ttfamily\bfseries%
+ \textcolor{optcolor}{\%{#4}\myscript\hspace*{1.5pt}}%
+ \end{minipage}%
+\end{lrbox}%
+\leavevmode%
+\marginpar{\usebox{\optinfile}}%
+\lapbox[0pt]{-0.85\marginparsep}{\textcolor{red}{\texttt{:}}}%
+\textcolor{optcolor}{\bfseries\texttt{{#2}}}%
+\textcolor{red}{\hspace*{2.5pt}\texttt{:}}
+\hspace*{-1pt}\marg[cbc=optcolor,ac=gray,cf=gray]{#3}
+\vspace*{2pt}\par%
+\IfNoValueTF{#1}
+{}%%
+{%
+\SortIndex{options}{\textsf{\myscript}\ options in input file>\small\texttt{#2}}%
+}%
+}
+
+% \DescribeCmd[...]{...}{...}{...}, need changue to \DescribeOptCmd
+\newsavebox{\optcmdline}
+\NewDocumentCommand\DescribeCmd{ommm}{
+\begin{lrbox}{\optcmdline}%
+ \begin{minipage}[t]{\marginparwidth}%
+ \ttfamily\bfseries\raggedleft%
+ \IfNoValueTF{#1}
+ {\textcolor{optcolor}{-\/-#2}}
+ {\textcolor{optcolor}{-{#1}}\textcolor{gray}{,} \textcolor{optcolor}{-\/-#2}}%
+ \end{minipage}%
+\SortIndex{options}{\textsf{\myscript}\ options in command line>\small\texttt{-\/-#2}}%
+\end{lrbox}%
+ \leavevmode%
+ \marginpar{\usebox{\optcmdline}}%
+ \ignorespaces
+ \meta[ac=gray,cf=gray]{\textnormal{\sffamily{#3}}}
+ \hfill\textcolor{gray}{\textsf{(default: {#4})}}%
+ \vspace*{2pt}\par%
+}
+
+% Create a language for documentation
+\lstdefinelanguage{ltximg-doc}{
+ texcsstyle=*,%
+ escapechar=`,%
+ showstringspaces=false,%
+ extendedchars=true, %
+ stringstyle = {\color{red}},%
+% comments
+ morecomment=[l]{\%},%
+ commentstyle=\itshape\color{lightgray},%
+% Important words 1
+ keywordstyle=[1]{\bfseries\color{NavyBlue}},%
+ keywords=[1]{AtBeginDocument,begin,end,documentclass,BEGIN,END},%
+% Other words 2
+ keywordstyle=[2]{\color{blue!75}},%
+ keywords=[2]{usepackage,graphicspath,RequirePackage,renewcommand,%
+ PreviewBbAdjust,usetikzlibrary,tikzexternalize,psset,tikzset,PrependGraphicsExtensions,%
+ DefineShortVerb,lstMakeShortInline,MakeSpecialShortVerb,UndefineShortVerb},%
+% Other words 3
+ keywordstyle=[3]{\color{optcolor!85}},%
+ keywords=[3]{document,graphicx,preview,active,tightpage,article,grfext,description,filecontents,%
+ external,tikz,clean,pst,tkz,eps,pdf,xetex,latex,luatex,dvips,png,srcenv,noprew,imgdir,prefix,output},%
+% Reserved words 4(inputfile options)
+ keywordstyle=[4]{\bfseries\color{optcolor}},%
+ keywords=[4]{ltximg,noltximg,remove,options,pspicture,endpspicture,%
+ PSTexample,pgfpicture, endpgfpicture, tikzpicture, endtikzpicture, %
+ psgraph, endpsgraph,nopreview,postscript, arara,extrenv,deltenv,skipenv},%
+% Reserved in orange
+ keywordstyle=[5]{\color{OrangeRed}},%
+ keywords=[5]{images,includegraphics,env,file-out,pics,doc},%
+% Reserved in orange
+ keywordstyle=[6]{\color{red}},%
+ keywords=[6]{verb},%
+}[keywords,tex,comments,strings]% end languaje
+
+% \begin{examplecode}[optlst]...\end{examplecode}
+\lstnewenvironment{examplecode}[1][]{%
+\lstset{
+ language=ltximg-doc,%
+ stringstyle = {\color{red}},%
+ basicstyle=\ttfamily\small,%
+ numbersep=1em,%
+ numberstyle=\tiny\color{lightgray}\noaccsupp,%
+% literateee
+literate=*{\{}{{\bfseries\textcolor{gray}{\{}}}{1}
+ {\}}{{\bfseries\textcolor{gray}{\}}}}{1}
+ {[}{{\bfseries\textcolor{optcolor}{[}}}{1}
+ {]}{{\bfseries\textcolor{optcolor}{]}}}{1}
+ {*}{{\bfseries\textcolor{red}{*}}}{1}
+ {:}{{\textcolor{red}{:}}}{1}
+ {,}{{\textcolor{gray}{,}}}{1}
+ {=}{{\textcolor{gray}{=}}}{1}
+ {/}{{\textcolor{gray}{/}}}{1}
+ {\%\ ltximg}{{\textcolor{gray}{\%}\space\bfseries\textcolor{optcolor}{ltximg}}}{8}
+ {\%\ arara}{{\textcolor{gray}{\%}\space\bfseries\textcolor{optcolor}{arara}}}{7}
+ {\{arara}{{\textcolor{gray}{\{arara}}}{6}
+ {\%<*remove>}{{\bfseries\textcolor{gray}{\%<*remove>}}}{10}
+ {\%</remove>}{{\bfseries\textcolor{gray}{\%</remove>}}}{10}
+ {\%<*ltximg>}{{\bfseries\textcolor{gray}{\%<*ltximg>}}}{10}
+ {\%</ltximg>}{{\bfseries\textcolor{gray}{\%</ltximg>}}}{10}
+ {\%<*noltximg>}{{\bfseries\textcolor{gray}{\%<*noltximg>}}}{12}
+ {\%</noltximg>}{{\bfseries\textcolor{gray}{\%</noltximg>}}}{12},%
+ #1,%
+ }% close lstset
+}%
+{}% close examplecode
+
+% \begin{examplecmd}...\end{examplecmd}
+\lstnewenvironment{examplecmd}{%
+\lstset{
+ language=ltximg-doc,%
+ basicstyle=\ttfamily\small,%
+ frame=single,%
+ rulecolor=\color{gray!50},%
+ framesep=\fboxsep,%
+ framerule=\fboxrule,%
+ xleftmargin=\dimexpr\fboxsep+\fboxrule\relax,%
+ xrightmargin=\dimexpr\fboxsep+\fboxrule\relax,%
+% Reserved words (cmd line options)
+ classoffset=7,%
+ keywordstyle=\bfseries\color{optcolor},%
+ morekeywords={ltximg},%
+% % Reserved words (cmd line options)
+ classoffset=8,%
+ keywordstyle={\bfseries\color{ForestGreen}},%
+ morekeywords={gs,pdftoppm,pdftocairo,pdftops},%
+% Only for command line options
+ classoffset=5,%
+ keywordstyle=\color{blue},%
+ keywords={user,machine},%
+% literateee
+literate=*{[}{{\textcolor{darkgray}{[}}}{1}
+ {]}{{\textcolor{darkgray}{]}}}{1}
+ {@}{{\textcolor{blue}{@}}}{1}
+ {\$}{{\textcolor{blue}{\$}}}{1}
+ {:}{{\textcolor{blue}{:}}}{1}
+ {§}{{\textcolor{red}{\$}}}{1}
+ {"}{{\textcolor{red}{\textquotedbl}}}{1}
+ {~}{{\textcolor{blue}{\bfseries\textasciitilde}}}{1}%
+ }% close lstset {~}
+}%
+{}% close examplecmd
+
+% \lstinline[style=inline]|...|
+\lstdefinestyle{inline}
+{
+ language=ltximg-doc,%
+ basicstyle=\ttfamily\color{gray},%
+% literateee
+literate=*{\%}{{\bfseries\textcolor{gray}{\%}}}{1}
+}
+
+% set default style
+\lstset{style=inline}
+
+% email https://tex.stackexchange.com/a/663
+\catcode`\_=11\relax%
+\newcommand\email[1]{\_email #1\q_nil}%
+\def\_email#1@#2\q_nil{%
+ \href{mailto:#1@#2}{{\emailfont #1\emailampersat #2}}%
+}%
+\newcommand\emailfont{\sffamily}%
+\newcommand\emailampersat{{\color{NavyBlue}\footnotesize@}}%
+\catcode`\_=8\relax% %
+
+% Table of contents, need change font style
+\def\rulecolor{\color{NavyBlue}}
+\tocsetup{%
+ title=Contents\quad{\rulecolor\leaders\vrule height3.4pt depth-3pt\hfill\null},
+ title/after= \vspace{3pt},
+ title/font= \sffamily\bfseries\Large,%
+ title/top=10pt,%
+ title/bottom=0pt,%
+ twocolumns,
+ section/skip=4pt plus2pt minus2pt,%
+ subsection/skip=0pt plus2pt minus2pt,
+ section/leaders,section/dotsep,%
+ after=\vspace{-3pt}\noindent{\rulecolor\hrule height3.4pt depth-3pt\relax},
+}
+
+\begin{document}
+
+
+\title{%
+ \textffm{latex environments}\\[3pt]%
+ \scalebox{3.4}{\LTXimg}\\[2pt]%
+ \textls[150]{\textffm{to image format}}\\%
+ \Large
+ v\fileversion{} --- \filedate\thanks{%
+ This file describes a documentation for version \fileversion, last revised \filedate.}\\[25pt]%
+ \author{%
+ \large%
+ \raisebox{-1pt}{\textcopyright}{}2013--2018 by Pablo González L%
+ \thanks{E-mail:<\email{pablgonz@yahoo.com}>}%
+ }%
+\small
+\textsc{ctan}: \url{http://www.ctan.org/pkg/ltximg}\\
+\textsc{git}: \url{https://github.com/pablgonz/ltximg}
+\vspace*{-2cm}
+}%
+\date{}
+\maketitle
+
+\begin{abstract}
+\ltximg is a \prgname{perl} \emph{script} that automates the process of extracting and
+converting environments provided by \pkgname{tikz}, \pkgname{pstricks} and
+other packages from input file to image formats in individual files using \prgname{ghostscript}
+and \prgname{poppler-utils}. Generates a file with only extracted environments and another with environments
+converted to \ics{includegraphics}.
+\end{abstract}
+
+\tableofcontents
+\setlength{\parskip}{3pt}
+
+\section{Motivation}
+The original idea was to extend the functionality of the \scriptname{pst2pdf}
+script (only for \env{pspicture} and \env{postscript}) to work with \env{tikzpicture}
+and other environments.
+
+The \pkgname{tikz} package allows to externalize the environments, but, the idea was to be
+able to extend this to any type of environment covering three central points:
+
+\begin{enumerate}[font=\small, noitemsep,leftmargin=*]
+\item Generate separate files for environments and converted into images.
+\item Generate a file with only the extracted environments.
+\item Generate a file replacing the environments by \ics{includegraphics}.
+\end{enumerate}
+
+From the side of \TeX{} there are some packages that cover several of these
+points such as the \pkgname{preview}, \pkgname{xcomment}, \pkgname{external} and \pkgname{cachepic} packages among others,
+but none covered all points.
+
+In the network there are some solutions in \texttt{bash} that were able to
+extract and convert environments, but in general they presented problems when the document
+contained \emph{verbatim style} code or were only available for \OSsystem{Linux}.
+
+Analysed the situation the best thing was to create a new \emph{script} that was able
+to cover the three points and was multi platform, the union of all these ideas is
+born \ltximg. Finding the correct \emph{regular expressions} and writing \emph{documentation}
+would be the great mission (which does not end yet).
+
+\thispagestyle{plain}
+\newpage
+\pagestyle{myheader}
+\section{Required Software}\label{sec:software}
+
+For the complete operation of \ltximg{} you need to have a modern \hologo{TeX}
+distribution such as \hologo{TeX}Live 2017 or \hologo{MiKTeX} 2.9, have a version equal to or
+greater than \liningnums{5.22} of \prgname{perl}, a version equal to or greater than \liningnums{9.19} of
+\prgname{ghostscript} and have a version equal to or greater than \liningnums{0.52} of \prgname{poppler-utils}.
+
+The distribution of \hologo{TeX}Live 2017 for \OSsystem{Windows} includes \ltximg{} and all
+requirements, \hologo{MiKTeX} users must install the appropriate software for full operation.
+
+The script has been tested on \OSsystem{Windows} (version 10) and \OSsystem{Linux} (fedora 27) in x64 architecture using
+\prgname{ghostscript} \liningnums{v9.20}, \prgname{poppler-utils} \liningnums{v0.52} to \liningnums{v0.60} and
+\prgname{perl} from \liningnums{v5.22} to \liningnums{v5.26}.
+
+\section{How it works}\label{sec:howtowork}
+
+It is important to have a general idea of how the \emph{extraction and conversion}
+process works and the requirements that must be fulfilled so that everything
+works correctly, for this we must be clear about some concepts related to how to
+work with the \meta{verbatim content}, the \meta{input file}, the \meta{output file} and the
+\meta{steps process}.
+
+\subsection{The input file}\label{sec:inputfile}
+
+The \meta{input file} must comply with certain characteristics in
+order to be processed, the content at the beginning and at the end of the \meta{input file}
+is treated in a special way, before \lstinline|\documentclass| can only be commented lines and
+after \lstinline|\end{document}| can go any type of content, internally
+will split the \meta{input file} at this points.
+
+If the \meta{input file} contains files using \ics{input} or \ics{include} these
+will not be processed, from the side of the \emph{script} they only represent
+lines within the file, if you want them to be processed it is better to use the
+\scriptname{latexpand} first and then process the file.
+
+Like \ics{input} or \ics{include}, blank lines, vertical spaces and tab
+characters are treated literally, for the \emph{script} the \meta{input file} is just a set of
+characters, as if it was a simple text file. It is advisable to format the source code \meta{input file}
+using utilities such as lines such as \prgname{chktex} and \scriptname{latexindent}, especially if you want to
+extract the source code of the environments.
+
+An example of the \meta{input file}:
+
+\begin{examplecode}
+% some commented lines at begin document
+\documentclass{article}
+\usepackage{tikz}
+\begin{document}
+Some text
+\begin{tikzpicture}
+Some code
+\end{tikzpicture}
+Always use \verb|\begin{tikzpicture}|
+and \verb|\end{tikzpicture}| to open
+and close environment
+\begin{tikzpicture}
+Some code
+\end{tikzpicture}
+Some text
+\end{document}
+% some lines after end document
+\end{examplecode}
+
+\subsection{Verbatim contents}\label{sec:verbatim}
+
+One of the greatest capabilities of \ltximg{} script is to skip the complications
+that \emph{verbatim style} content produces with the extraction of environments.
+In order to skip the complications, the verbatim content is classified into
+three types:
+
+\begin{itemize}
+ \item Verbatim in line
+ \item Verbatim standard
+ \item Verbatim write
+\end{itemize}
+
+Each of these classifications works differently within the creation and
+extraction process using different regular expressions for it.
+\newpage
+
+\subsubsection{Verbatim in line}\label{sec:verbatim:inline}
+
+The small pieces of code written in the same line using a verbatim command are
+considered \meta{verbatim in line}, such as \lstinline+\verb|<code>|+. Most verbatim commands
+provide by packages \pkgname{minted}, \pkgname{fancyvrb} and \pkgname{listings} have
+been tested and are fully supported. They are automatically detected the verbatim command generates
+by \ics{newmint} and \ics{newmintinline} and the following command list:
+
+\begin{multicols}{3}
+\begin{itemize}[font=\sffamily\small, noitemsep,leftmargin=*]
+\small
+\item \ics{mint}
+\item \ics{spverb}
+\item \ics{qverb}
+\item \ics{fverb}
+\item \ics{verb}
+\item \ics{Verb}
+\item \ics{lstinline}
+\item \ics{pyginline}
+\item \ics{pygment}
+\item \ics{tcboxverb}
+\item \ics{mintinline}
+\end{itemize}
+\end{multicols}
+
+Some packages define abbreviated versions for verbatim commands as \ics{DefineShortVerb}, \ics{lstMakeShortInline}
+and \ics{MakeSpecialShortVerb}, will be detected automatically if are declared explicitly in \meta{input file}.
+
+The following consideration should be kept in mind for some packages that use
+abbreviations for verbatim commands, such as \pkgname{shortvrb} or \pkgname{doc}
+for example in which there is no explicit command in the document by means of
+which the abbreviated form can be detected, for automatic detection need to find
+\ics{DefineShortVerb} explicitly to process it correctly.
+The solution is quite simple, just add in \meta{input file}:
+
+\begin{examplecode}
+\UndefineShortVerb{\|}
+\DefineShortVerb{\|}
+\end{examplecode}
+
+depending on the package you are using. If your verbatim command is not supported
+by default or can not detect, use the options described in \ref{sec:optline} and \ref{sec:optfile}.
+
+\subsubsection{Verbatim standard}\label{sec:verbatim:std}
+
+These are the classic environments for writing code are considered \meta{verbatim standard},
+such as \env{verbatim} and \env{lstlisting} environments. The following list is considered
+as \meta{verbatim standard} environments:
+
+\begin{multicols}{4}
+\begin{itemize}[font=\sffamily\small, noitemsep,leftmargin=*]
+\sffamily\small
+\item Example
+\item CenterExample
+\item SideBySideExample
+\item PCenterExample
+\item PSideBySideExample
+\item verbatim
+\item Verbatim
+\item BVerbatim
+\item LVerbatim
+\item SaveVerbatim
+\item PSTcode
+\item LTXexample
+\item tcblisting
+\item spverbatim
+\item minted
+\item listing
+\item lstlisting
+\item alltt
+\item comment
+\item chklisting
+\item verbatimtab
+\item listingcont
+\item boxedverbatim
+\item demo
+\item sourcecode
+\item xcomment
+\item pygmented
+\item pyglist
+\item program
+\item programl
+\item programL
+\item programs
+\item programf
+\item programsc
+\item programt
+\end{itemize}
+\end{multicols}
+
+They are automatically detected \meta{verbatim standard} environments generates by commands:
+
+\begin{multicols}{2}
+\begin{itemize}[font=\sffamily\small, noitemsep,leftmargin=*]
+\small
+\item \ics{DefineVerbatimEnvironment}
+\item \ics{NewListingEnvironment}
+\item \ics{DeclareTCBListing}
+\item \ics{ProvideTCBListing}
+\item \ics{lstnewenvironment}
+\item \ics{newtabverbatim}
+\item \ics{specialcomment}
+\item \ics{includecomment}
+\item \ics{newtcblisting}
+\item \ics{NewTCBListing}
+\item \ics{newverbatim}
+\item \ics{NewProgram}
+\item \ics{newminted}
+\end{itemize}
+\end{multicols}
+
+If any of the \meta{verbatim standard} environments is not supported by default or can
+not detected, you can use the options described in \ref{sec:optline} and \ref{sec:optfile}.
+
+\subsubsection{Verbatim write}\label{sec:verbatim:write}
+
+Some environments have the ability to write external files directly, these environments are considered
+\meta{verbatim write}, such as \env{filecontents} or \env{VerbatimOut} environments. The following list
+is considered as \meta{verbatim write} environments:
+
+\begin{multicols}{3}
+\begin{itemize}[font=\sffamily\small, noitemsep,leftmargin=*]
+\small
+\item filecontents
+\item tcboutputlisting
+\item tcbexternal
+\item extcolorbox
+\item extikzpicture
+\item VerbatimOut
+\item verbatimwrite
+\item filecontentsdef
+\item filecontentshere
+\end{itemize}
+\end{multicols}
+
+They are automatically detected \meta{verbatim write} environments generates by commands:
+
+\begin{multicols}{2}
+\begin{itemize}[font=\sffamily\small, noitemsep,leftmargin=*]
+\small
+\item \ics{renewtcbexternalizetcolorbox}
+\item \ics{renewtcbexternalizeenvironment}
+\item \ics{newtcbexternalizeenvironment}
+\item \ics{newtcbexternalizetcolorbox}
+\end{itemize}
+\end{multicols}
+
+If any of the \meta{verbatim write} environments is not supported by default or can
+not detected, you can use the options described in \ref{sec:optline} and \ref{sec:optfile}.
+
+\subsection{Steps process}\label{sec:steps:process}
+
+For creation of the image formats, extraction of code and creation of an
+output file, \ltximg{} need a various steps. Let's assume that the \meta{input file} is \sysfile{test.tex},
+\meta{output file} is \sysfile{test-out}, the working directory are \sysdir{workdir}, the directory
+for images are \sysdir{workdir/images} and the user's temporary directory is \sysdir{tmp} and we
+want to generate images in \iext{pdf} format together with the source codes of the environments.
+
+\begin{description}[font=\sffamily\small, leftmargin=0em,style=nextline]
+\item[Comment and ignore]
+The first step is read and validated \oarg[type=rm,cf=gray,sbc=optcolor,ac=gray]{options} from the command
+line and \sysfile{test.tex}, verifying that \sysfile{test.tex}, \sysfile{test-out} and the
+directory \sysdir{images} are in \sysdir{workdir}, create the directory \sysdir{workdir/images} if it does
+not exist and a temporary directory \sysdir{tmp/hG45uVklv9}. The entire file \sysfile{test.tex} is loaded
+in memory and proceeds (in general terms) as follows:
+
+\begin{quotation}
+Search the words \lstinline|\begin{| and \lstinline|\end{| in verbatim standard, verbatim write, verbatim in line and
+commented lines, if it finds them, converts to \lstinline|\BEGIN{| and \lstinline|\END{|, then places all code to
+extract inside the \lstinline|\begin{preview}| \ldots \lstinline|\end{preview}|.
+\end{quotation}
+
+At this point all the code you want to extract is inside \lstinline|\begin{preview}| \ldots \lstinline|\end{preview}|
+and the files \sysfile{test-fig-1.tex}, \sysfile{test-fig-2.tex}, \ldots{} are generated and saved in \sysdir{images}.
+
+\item[Create random file]
+In the second step, with the file already loaded in memory, creating a temporary file with a
+random number (1981 for example) and proceed in two ways according to the \oarg[type=rm,cf=gray,sbc=optcolor,ac=gray]{options}
+passed to the script:
+
+\begin{enumerate}
+\item If script is call \emph{whitout} \cmdopt[n]{noprew} options, adds the
+following lines to the beginning of the \sysfile{test.tex} (in memory):
+
+\begin{examplecode}
+\AtBeginDocument{%
+\RequirePackage[active,tightpage]{preview}
+\renewcommand\PreviewBbAdjust{-60pt -60pt 60pt 60pt}}%
+% rest of input file
+\end{examplecode}
+And save in a temporary file \sysfile{test-fig-1981.tex} in \sysdir{workdir}.
+
+\item If script is call \emph{whit} \cmdopt[n]{noprew} options, all code to extract
+its put inside the \env{preview} environment. The \lstinline|\begin{preview}|\ldots \lstinline|\end{preview}|
+lines are only used as delimiters for extracting the content \emph{without} using the package \pkgname{preview}.
+
+Creating a temporary file \sysfile{test-fig-1981.tex} in \sysdir{workdir}
+whit the same preamble of \sysfile{test.tex} but the body only contains code that you want to extract.
+\end{enumerate}
+
+\item[Generate image formats]
+In the third step the script run:
+\begin{examplecmd}
+[user@machine ~:]§`\small\meta[type=tt,cf=ForestGreen,ac=ForestGreen]{compiler}` -recorder -shell-escape `\small\sysfile{test-fig-1981.tex}`
+\end{examplecmd}
+generating the file \sysfile{test-fig-1981.pdf} whit all code extracted, move \sysfile{test-fig-1981.pdf}
+to \sysdir{tmp/hG45uVklv9}, separate in individual files \sysfile{test-fig-1.pdf}, \sysfile{test-fig-2.pdf}, \ldots{}
+and copy to \sysdir{workdir/images/}. The file \sysfile{test-fig-1981.tex} is moved to the \sysdir{workdir/images/}
+and rename to \sysfile{test-fig-all.tex}.
+
+Note the options passed to \meta[type=tt,cf=ForestGreen,ac=ForestGreen]{compiler} does not include \prgopt*{output-directory}
+(it is not supported) and always use \prgopt*{recorder} \prgopt*{shell-escape} you must keep this in mind if you use \prgname{arara}.
+
+\item[Create output file]
+In the fourth step the script creates the output file \sysfile{test-out.tex} converting all extracted code to
+\ics{includegraphics} and adding the following lines at end of preamble:
+
+\begin{examplecode}
+\usepackage{graphicx}
+\graphicspath{{images/}}
+\usepackage{grfext}
+\PrependGraphicsExtensions*{.pdf}
+\end{examplecode}
+
+If the packages \pkgname{graphicx} and \pkgname{grfext} are already loaded and the command \ics{graphicspath}
+is found in the input file were detected automatically and only the changes will be added then proceed to run:
+\begin{examplecmd}
+[user@machine ~:]§`\small\meta[type=tt,cf=ForestGreen,ac=ForestGreen]{compiler}` -recorder -shell-escape `\small\sysfile{test-out.tex}`
+\end{examplecmd}
+generating the file \sysfile{test-out.pdf}.
+\end{description}
+Now the script read the files \sysfile{test-fig-1981.fls} and \sysfile{test-out.fls}, extract the information from the
+temporary files generated in the process and then delete them together with the directory \sysdir{tmp/hG45uVklv9}.
+An example for input and output file:
+
+\begin{minipage}[c]{0.5\textwidth}
+\begin{examplecode}
+\documentclass{article}
+\usepackage{tikz}
+\begin{document}
+Some text
+\begin{tikzpicture}
+Some code
+\end{tikzpicture}
+Always use \verb|\begin{tikzpicture}|
+and \verb|\end{tikzpicture}| to open
+and close environment
+\begin{tikzpicture}
+some code
+\end{tikzpicture}
+Some text
+\end{document}
+\end{examplecode}
+\begin{flushleft}
+\sysfile{test.tex}
+\end{flushleft}
+\end{minipage}
+\begin{minipage}[c]{0.5\textwidth}
+\begin{examplecode}
+\documentclass{article}
+\usepackage{tikz}
+\usepackage{graphicx}
+\graphicspath{{images/}}
+\usepackage{grfext}
+\PrependGraphicsExtensions*{.pdf}
+\begin{document}
+Some text
+\includegraphics[scale=1]{test-fig-1}
+Always use \verb|\begin{tikzpicture}|
+and \verb|\end{tikzpicture}| to open
+and close environment
+\includegraphics[scale=1]{test-fig-2}
+Some text
+\end{document}
+\end{examplecode}
+\begin{flushleft}
+\sysfile{test-out.tex}
+\end{flushleft}
+\end{minipage}
+\newpage
+
+\section{Extract content}\label{sec:extract}
+The script provides two ways to extract content from \meta{input file}, using \meta[type=rm,cf=optcolor,ac=gray]{environments}
+and \meta[type=rm,cf=optcolor,ac=gray]{docstrip tags}. Some environment (including a starred \texttt{\small\bfseries\textcolor{red}{*}} version)
+are supported by default and if the environments are nested, the outermost will be extracted.
+
+\subsection{Default environments}
+\label{sec:extract:env}
+\DescribeTE{preview}
+Environment provide by \pkgname{preview} package. If \env{preview} environments
+found in the input file will be extracted and converted these. Internally
+converts all environments to extract in \env{preview} environments.
+Is better comment this package in preamble unless the option \cmdopt[n]{noprew}{} is
+used.
+
+\vspace{\baselineskip}
+
+\DescribeTE{pspicture}
+Environment provide by \pkgname{pstricks} package. The plain
+syntax \lstinline|\pspicture ... \endpspicture| its converted to
+\lstinline|\begin{pspicture} ... \end{pspicture}|.
+\vspace{\baselineskip}
+
+\DescribeTE{psgraph}
+Environment provide by \pkgname{pst-plot} package. The plain syntax \lstinline|\psgraph ... \endpsgraph|
+its converted to \lstinline|\begin{psgraph} ... \end{psgraph}|.
+
+\vspace{\baselineskip}
+
+\DescribeTE{postscript}
+Environment provide by \pkgname{pst-pdf} and \pkgname{auto-pst-pdf} packages.
+Since the \pkgname{pst-pdf} and \pkgname{auto-pst-pdf} packages internally use
+the \pkgname{preview} package, is better comment this in preamble.
+
+\vspace{\baselineskip}
+
+\DescribeTE{tikzpicture}
+Environment provide by \pkgname{tikz} package. The plain syntax \lstinline|\tikzpicture ... \tikzpicture|
+its converted to \lstinline|\begin{tikzpicture} ... \end{tikzpicture}|
+but no a short \lstinline|\tikz...;|.
+\vspace{\baselineskip}
+
+\DescribeTE{pgfpicture}
+Environment provide by \pkgname{pgf} package. Since the script uses a
+\emph{recursive regular expression} to extract environments, no presents problems
+if present \lstinline|pgfinterruptpicture|.
+\vspace{\baselineskip}
+
+\DescribeTE{PSTexample}
+Environment provide by \pkgname{pst-exa} packages. The script automatically detects the
+\lstinline|\begin{PSTexample}| \lstinline|...\end{PSTexample}|
+environments and processes them as separately compiled files. The user should have loaded the
+package with the [\pkgopt{swpl}] or [\pkgopt{tcb}] option and run the script
+using \cmdopt{latex}{} or \cmdopt{xetex}.
+
+If you need to extract more environments you can use one of the options described in \ref{sec:optline} or \ref{sec:optfile}.
+\subsection{Extract whit docstrip tags}
+\label{sec:extract:tag}
+\DescribeTE*{ltximg}
+All content included between \lstinline|%<*ltximg> ... %</ltximg>| is extracted.
+The tags can not be nested and should be at the beginning of the line and in separate lines.
+
+\begin{examplecode}
+% no space before open tag %<*
+%<*ltximg>
+code to extract
+%</ltximg>
+% no space before close tag %</
+\end{examplecode}
+
+\subsection{Prevent extraction and remove}\label{sec:noextract}
+Sometimes you do not want to extract all the environments from \meta{input file} or you want to
+remove environments or arbitrary content, for example auxiliary files to generate a graphic.
+The script provides a convenient way to solve this situation.
+
+\DescribeTE{nopreview}
+Environment provide by \pkgname{preview} package. Internally the script
+converts all no extract environments to \lstinline|\begin{nopreview} ... \end{nopreview}|.
+Is better comment this package in preamble unless the option \cmdopt[n]{noprew}{} is used.
+\vspace{\baselineskip}
+
+\DescribeTE*{noltximg}
+All content betwen \lstinline|%<*noltximg> ... %</noltximg>| are ignored and no
+extract. The start and closing of the tag must be at the beginning of the line.
+
+\begin{examplecode}
+% no space before open tag %<*
+%<*noltximg>
+no extract this
+%</noltximg>
+% no space before close tag %</
+\end{examplecode}
+
+\DescribeTE*{remove}
+All content betwen \lstinline|%<*remove> ... %</remove>| are deleted in the \meta{output file}. The start and closing
+of the tag must be at the beginning of the line.
+
+\begin{examplecode}
+% no space before open tag %<*
+%<*remove>
+lines removed in output file
+%</remove>
+% no space before close tag %</
+\end{examplecode}
+
+If you want to remove specific environments automatically you can use one of the options described in \ref{sec:optline} or \ref{sec:optfile}.
+
+\section{Image Formats}\label{sec:image:format}
+The \meta{image formats} generated by the \ltximg{} using \prgname{ghostscript} and \textcolor{ForestGreen}{\ttfamily\bfseries poppler-utils}
+are the following command lines:
+
+\DescribeIF{pdf}
+The image format generated using \prgname{ghostscript}. The line executed by the system is:
+
+\begin{examplecmd}
+[user@machine ~:]§ gs -q -dNOSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress
+\end{examplecmd}
+
+\DescribeIF{eps}
+The image format generated using \prgname{pdftoeps}. The line executed by the system is:
+
+\begin{examplecmd}
+[user@machine ~:]§ pdftops -q -eps
+\end{examplecmd}
+
+\DescribeIF{png}
+The image format generated using \prgname{ghostscript}. The line executed by the system is:
+
+\begin{examplecmd}
+[user@machine ~:]§ gs -q -dNOSAFER -sDEVICE=pngalpha -r 150
+\end{examplecmd}
+
+\DescribeIF{jpg}
+The image format generated using \prgname{ghostscript}. The line executed by the system is:
+\begin{examplecmd}
+[user@machine ~:]§ gs -q -dNOSAFER -sDEVICE=jpeg -r 150 -dJPEGQ=100 \
+ -dGraphicsAlphaBits=4 -dTextAlphaBits=4
+\end{examplecmd}
+
+\DescribeIF{ppm}
+The image format generated using \prgname{pdftoppm}. The line executed by the system is:
+
+\begin{examplecmd}
+[user@machine ~:]§ pdftoppm -q -r 150
+\end{examplecmd}
+
+\DescribeIF{tif}
+The image format generated using \prgname{ghostscript}. The line executed by the system is:
+
+\begin{examplecmd}
+[user@machine ~:]§ gs -q -dNOSAFER -sDEVICE=tiff32nc -r 150
+\end{examplecmd}
+
+\DescribeIF{svg}
+The image format generated using \prgname{pdftocairo}. The line executed by the system is:
+
+\begin{examplecmd}
+[user@machine ~:]§ pdftocairo -q -r 150
+\end{examplecmd}
+
+\DescribeIF{bmp}
+The image format generated using \prgname{ghostscript}. The line executed by the system is:
+
+\begin{examplecmd}
+[user@machine ~:]§ gs -q -dNOSAFER -sDEVICE=bmp32b -r 150
+\end{examplecmd}
+\newpage
+
+\section{How to use}
+\subsection{Syntax}
+The syntax for \ltximg{} is simple:
+
+\begin{examplecmd}
+[user@machine ~:]§ ltximg `\small\meta[type=tt,cf=ForestGreen,ac=ForestGreen]{compiler} \oarg[type=tt,cf=gray,sbc=optcolor,ac=gray]{options} \textcolor{gray}{\texttt{[-\/-]}} \meta[type=tt,cf=OrangeRed,ac=OrangeRed]{file.ext}`
+\end{examplecmd}
+
+The extension \meta[type=tt,cf=OrangeRed,ac=OrangeRed]{ext} for \meta{input file} are \fext{tex} or \fext{ltx},
+relative or absolute paths for files and directories is not supported. If used without \meta[type=tt,cf=ForestGreen,ac=ForestGreen]{compiler}
+and \oarg[type=tt,cf=gray,sbc=optcolor,ac=gray]{options} the extracted environments are converted to \iext{pdf}
+image format and saved in the \sysdir{images} directory using \prgname*{pdflatex} and \pkgname{preview} package.
+
+\subsection{Options in command line}\label{sec:optline}
+
+\ltximg{} provides a \emph{command line interface} with short and long option names.
+They may be given before the name of the file. Also, the order of specifying the
+options is significant. Certain options accept a list separate by commas, this require a separated by
+white space or equals sign \textcolor{red}{\texttt{=}} between option and list and if it's the last option
+need \textcolor{red}{\texttt{-\/-}} at the end. Multiple short options can be bundling.
+
+\DescribeCmd[h]{help}{bolean}{off}
+Display a command line help text and exit.
+
+\DescribeCmd[l]{license}{bolean}{off}
+Display a license text and exit.
+
+\DescribeCmd[v]{version}{bolean}{off}
+Display the current version (1.5) and exit.
+
+\DescribeCmd[d]{dpi}{int}{150}
+Dots per inch for images files.
+
+\DescribeCmd[t]{tif}{bolean}{off}
+Create a .\iext{tif} images files using \prgname{ghostscript}.
+
+\DescribeCmd[b]{bmp}{bolean}{off}
+Create a .\iext{bmp} images files using \prgname{ghostscript}.
+
+\DescribeCmd[j]{jpg}{bolean}{off}
+Create a .\iext{jpg} images files using \prgname{ghostscript}.
+
+\DescribeCmd[p]{png}{bolean}{off}
+Create a .\iext{png} transparent image files using \prgname{ghostscript}.
+
+\DescribeCmd[e]{eps}{bolean}{off}
+Create a .\iext{eps} image files using \prgname{pdftops}.
+
+\DescribeCmd[s]{svg}{bolean}{off}
+Create a .\iext{svg} image files using \prgname{pdftocairo}.
+
+\DescribeCmd[P]{ppm}{bolean}{off}
+Create a .\iext{ppm} image files using \prgname{pdftoppm}.
+
+\DescribeCmd[g]{gray}{bolean}{off}
+Create a gray scale for all images using \prgname{ghostscript}. The line behind this options is:
+
+\begin{examplecmd}
+[user@machine ~:]§ gs -q -dNOSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
+ -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray
+\end{examplecmd}
+
+\DescribeCmd[f]{force}{bolean}{off}
+Try to capture \lstinline|\psset{...}| and \lstinline|\tikzset{...}| to extract.
+When using the \cmdopt{force} option the script will try to capture \lstinline|\psset{...}| or
+\lstinline|\tikzset{...}| and leave it inside the \env{preview} environment, any line that is between \lstinline|\psset{...}| and
+\lstinline|\begin{pspicture}| or between \lstinline|\tikzset{...}| and \lstinline|\begin{tikzpicture}| will be captured.
+
+\newpage
+\DescribeCmd[n]{noprew}{bolean}{off}
+Create images files without \pkgname{preview} package. The \lstinline|\begin{preview}|\ldots \lstinline|\end{preview}|
+lines are only used as delimiters for extracting the content \emph{without} using the package \pkgname{preview}.
+Sometimes it is better to use it together with \cmdopt{force}.
+
+\DescribeCmd[m]{margin}{numeric}{0}
+Set margins in bp for \scriptname{pdfcrop}.
+
+\DescribeCmd[o]{output}{output file name}{empty}
+Create \meta{output file name} whit all extracted environments/contents converted to \ics{includegraphics}.
+The \meta{output file name} must not contain extension.
+
+\DescribeCmd{imgdir}{string}{images}
+The name of directory for save images and source code.
+
+\DescribeCmd{verbose}{bolean}{off}
+Show verbose information in screen and change \prgopt*{interaction} for compiler.
+
+\DescribeCmd{srcenv}{bolean}{off}
+Create separate files whit \emph{only code} for all extracted environments, is mutually exclusive whit \cmdopt{subenv}.
+
+\DescribeCmd{subenv}{bolean}{off}
+Create sub files whit \emph{preamble} and code for all extracted environments, is mutually exclusive whit \cmdopt{srcenv}.
+
+\DescribeCmd{arara}{bolean}{off}
+Use \prgname*{arara} for compiler files, need to pass \prgopt*{recorder} option to \meta{input file}:\par
+\lstinline|% arara : <compiler> : {options: "-recorder"}|
+
+\DescribeCmd{xetex}{bolean}{off}
+Using \prgname*{xelatex} compiler \meta{input file} and \meta{output file}.
+
+\DescribeCmd{latex}{bolean}{off}
+Using \prgname*{latex}\texttt{\bfseries\guillemotright}\prgname*{dvips}\texttt{\bfseries\guillemotright}\scriptname{ps2pdf}
+compiler in \meta{input file} and \prgname*{pdflatex} for \meta{output file}.
+
+\DescribeCmd{dvips}{bolean}{off}
+Using \prgname*{latex}\texttt{\bfseries\guillemotright}\prgname*{dvips}\texttt{\bfseries\guillemotright}\scriptname{ps2pdf}
+for compiler \meta{input file} and \meta{output file}.
+
+\DescribeCmd{dvipdf}{bolean}{off}
+Using \prgname*{latex}\texttt{\bfseries\guillemotright}\prgname*{dvipdfmx} for compiler \meta{input file} and \meta{output file}.
+
+\DescribeCmd{luatex}{bolean}{off}
+Using \prgname*{lualatex} for compiler \meta{input file} and \meta{output file}.
+
+\DescribeCmd{prefix}{string}{fig}
+Add prefix append to each files created.
+
+\DescribeCmd{norun}{bolean}{off}
+Run script, but no create images. This option is designed to debug the file and
+when you only need to extract the code
+
+\DescribeCmd{nopdf}{bolean}{off}
+Don't create a .\iext{pdf} image files.
+
+\DescribeCmd{nocrop}{bolean}{off}
+Don't run \scriptname{pdfcrop} in image files.
+
+\DescribeCmd{clean}{doc\textbar pst\textbar tkz\textbar all\textbar off}{doc}
+Removes specific content in \meta{output file}. Valid values for this option are:
+
+\begin{description}[font=\small\sffamily, nosep, noitemsep, leftmargin=*]
+\item[doc] All content after \lstinline+\end{document}+ is removed.
+\item[pst] All \lstinline|\psset{...}| and \pkgname{pstricks} package is removed.
+\item[tkz] All \lstinline|\tikzset{...}| is removed.
+\item[all] Activates doc, pst and tkz.
+\item[off] Deactivate all.
+\end{description}
+
+\newpage
+\DescribeCmd{verbcmd}{command name}{myverb}
+Set custom verbatim command \lstinline+\myverb|<code>|+.
+
+\DescribeCmd{extrenv}{list separate by comma}{empty}
+List of environments to extract, need \texttt{-\/-} at end.\par
+
+\DescribeCmd{skipenv}{list separate by comma}{empty}
+
+List of environments that should not be extracted and that the script supports
+by default, need \texttt{-\/-} at end.\par
+
+\DescribeCmd{verbenv}{list separate by comma}{empty}
+
+List of \meta{verbatim standard} environment support, need \texttt{-\/-} at end.\par
+
+\DescribeCmd{writenv}{list separate by comma}{empty}
+
+List of \meta{verbatim write} environment support, need \texttt{-\/-} at end.\par
+
+\DescribeCmd{deltenv}{list separate by comma}{empty}
+List of environment deleted in \meta{output file}, need \texttt{-\/-} at end.
+
+\subsection{Options in input file}\label{sec:optfile}
+
+Many of the ideas in this section are inspired by the \prgname{arara} program (I adore it).
+A very useful way to pass options to the script is to place them in commented
+lines at the beginning of the file, very much in the style of \prgname{arara}.
+
+\DescribeOptFile*{\meta[ac=gray,cf=gray]{argument}}{option one, option two, option three, \ldots}
+\DescribeOptFile*{\meta[ac=gray,cf=gray]{argument}}{option one, option two, option three, \ldots}[!]
+
+The vast majority of the options can be passed into the \meta{input file}. These
+should be put at the beginning of the file in commented lines and everything must
+be on the same line, the exclamation mark deactivates the option. Valid values for
+\meta[ac=gray,cf=gray]{argument} are the following:
+
+\DescribeOptFile{options}{option one = value, option two = value, option three = value, \ldots}
+This line is to indicate to the script which options need to process.
+
+\DescribeOptFile{extrenv}{environment one, environment two, environment three, \ldots}
+This line is to indicate to the script which environments, not supported by
+default, are extracted.
+
+\DescribeOptFile{skipenv}{environment one, environment two, environment three, \ldots}
+This line is to indicate to the script which environments, of the ones
+supported by default, should not be extracted.
+
+\DescribeOptFile{verbenv}{environment one, environment two, environment three, \ldots}
+This line is to indicate to the script which environments, its considerate a \meta{verbatim standard}.
+
+\DescribeOptFile{writenv}{environment one, environment two, environment three, \ldots}
+This line is to indicate to the script which environments its consider \meta{verbatim write}.
+
+\DescribeOptFile{deltenv}{environment one, environment two, environment three, \ldots}
+This line is to indicate to the script which environments are deleted.
+
+If you are going to create an \meta{output file} and you do not want these lines to remain, it is better to
+place them inside the \lstinline|%<*remove> ... %</remove>|. Like this:
+
+\begin{examplecode}
+%<*remove>
+% ltximg : options : {png,srcenv,xetex}
+% ltximg : extrenv : {description}
+%</remove>
+\end{examplecode}
+\newpage
+
+\section{Examples} \label{sec:examples}
+\begin{examplecmd}
+[user@machine ~:]§ ltximg --latex -s -o test-out test-in.ltx
+\end{examplecmd}
+Create a \sysdir{images} directory whit all extracted environments converted to image
+formats (\iext{pdf}, \iext{svg}) in individual files, an \meta{output file} \sysfile{test-out.ltx} whit all supported environments
+converted to \ics{includegraphics} and a single file \sysfile{test-in-fig-all.ltx} with only the extracted environments
+using \prgname*{latex}\texttt{\bfseries\guillemotright}\prgname*{dvips}\texttt{\bfseries\guillemotright}\scriptname{ps2pdf}
+and \pkgname{preview} package for \meta{input file} and \prgname*{pdflatex} for \meta{output file}.
+
+Adding the following lines to the beginning of the file \sysfile{file-in.tex}:
+\begin{examplecode}
+%<*remove>
+% ltximg : options : {output = file-out, noprew, imgdir = pics, prefix = env, clean = doc}
+% ltximg : skipenv : {tikzpicture}
+% ltximg : deltenv : {filecontents}
+%</remove>
+\end{examplecode}
+and run:
+\begin{examplecmd}
+[user@machine~:]§ ltximg file-in.tex
+\end{examplecmd}
+Create a \sysdir{pics} directory whit all extracted environments, except \env{tikzpicture}, converted to image
+formats (\iext{pdf}) in individual files, an \meta{output file} \sysfile{file-out.tex} whit all extracted environments
+converted to \ics{includegraphics} and environment \env{filecontents} removed, a single file \sysfile{test-in-env-all.ltx}
+with only the extracted environments using \prgname*{pdflatex} and \pkgname{preview} package for \meta{input file} and \meta{output file}.
+
+\section{Change history}\label{sec:change:history}
+
+Some of the notable changes in the history of the \ltximg{} along with the
+versions, both development (devp) and public (ctan).
+
+\setlist[itemize, 1]{label=\textendash, wide=0.5em, nosep, noitemsep, leftmargin=10pt}
+% length for change history
+\newlength\descrwidth
+\settowidth{\descrwidth}{\textsf{v1.4.5, (ctan), 2013-01-23}}
+\begin{description}[font=\small\sffamily, wide=0pt, style=multiline, leftmargin=\descrwidth, nosep, noitemsep]
+\item [v1.5 (ctan), 2017-04-12]
+ \begin{itemize}
+ \item Use \texttt{GitHub} to control version
+ \item Rewrite and optimize most part of code and options
+ \item Change \texttt{pdf2svg} for \texttt{pdftocairo}
+ \item Complete support for \texttt{pst-exa} package
+ \item Escape characters in regex according to v5.4x.x
+ \end{itemize}
+\item [v1.4 (devp), 2016-11-29]
+ \begin{itemize}
+ \item Remove and rewrite code for regex and system call
+ \item Append \texttt{arara} compiler, clean and comment code
+ \item Append \texttt{dvips} and \texttt{dvipdfm(x)} for creation images
+ \item Append \texttt{bmp}, \texttt{tiff} image format
+ \end{itemize}
+\item [v1.3 (devp), 2016-08-14]
+ \begin{itemize}
+ \item Rewrite some part of code (norun, nocrop, clean)
+ \item Suport \texttt{minted} and \texttt{tcolorbox} package for verbatim
+ \item Escape some characters in regex according to v5.2x.x
+ \item All options read from command line and input file
+ \item Use \texttt{/tmp} dir for work process
+ \end{itemize}
+\item [v1.2 (ctan), 2015-04-22]
+ \begin{itemize}
+ \item Remove unused modules
+ \item Add more image format
+ \item Fix regex
+ \end{itemize}
+\item [v1.1 (ctan), 2015-04-21]
+ \begin{itemize}
+ \item Change \texttt{mogrify} to \texttt{gs} for image formats
+ \item Create output file
+ \item Rewrite source code and fix regex
+ \item Change format date to iso format
+ \end{itemize}
+\item [v1.0 (ctan), 2013-12-01]
+ \begin{itemize}
+ \item First public release
+ \end{itemize}
+\end{description}
+
+\newpage
+\clearpage
+\PrintIndex
+\end{document}
+%</documentation>
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index 71bec231d61..b56749076a7 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -2399,6 +2399,7 @@ $standardsource = '(\.(bat|c|drv|dtx|fea|fdd|ins|sfd)'
'cmbright', 'NULL',
'geometry-de', 'NULL', # doc, no need to build
'lettre', 'NULL',
+ 'ltximg', 'NULL', # doc, no need to build
'paper', 'install',
'seuthesis', 'NULL', # don't want to run iconv, etc.
'thesis', 'install.01|install.ndx',