diff options
author | Karl Berry <karl@freefriends.org> | 2018-05-02 18:32:35 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-05-02 18:32:35 +0000 |
commit | 7118801c6c53b01dfad47da9c5498b08338c336e (patch) | |
tree | 09df808dfe701cb988078a16e221e5f5fd801316 | |
parent | ac73f1b110ba60d5da94718ea8e0c5c098cb3f8b (diff) |
ltximg (12apr18)
git-svn-id: svn://tug.org/texlive/trunk@47568 c570f23f-e606-0410-a88d-b1316a301751
-rwxr-xr-x | Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl | 2345 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/ltximg/CHANGES | 7 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/ltximg/CHANGUES.md | 25 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/ltximg/README | 51 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/ltximg/README.md | 112 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdf | bin | 346033 -> 190044 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/support/ltximg/ltximg-doc.tex | 337 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/ltximg/ltximg.pl | 2345 | ||||
-rw-r--r-- | Master/texmf-dist/source/support/ltximg/ltximg-doc.dtx | 1594 | ||||
-rwxr-xr-x | Master/tlpkg/libexec/ctan2tds | 1 |
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 – 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 Binary files differindex 90856ffefd2..86b856a5ed9 100644 --- a/Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdf +++ b/Master/texmf-dist/doc/support/ltximg/ltximg-doc.pdf 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 – 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', |