summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-08-18 21:13:53 +0000
committerKarl Berry <karl@freefriends.org>2020-08-18 21:13:53 +0000
commit5272405de15717605a7528fa4842f475535ba2b6 (patch)
treefd71eb01e86e6e1e73d65a73eaf125cfc91c155d /Build
parent47249c75088d386d0981b666954c3e88010df3ac (diff)
ltximg (18aug20)
git-svn-id: svn://tug.org/texlive/trunk@56129 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ltximg/ltximg.pl3956
1 files changed, 2557 insertions, 1399 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl b/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
index 3b61635e426..4cc7440abbe 100755
--- a/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
+++ b/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
@@ -1,119 +1,464 @@
#!/usr/bin/env perl
use v5.26;
-use File::Basename;
+
+############################# 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. #
+########################################################################
+
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::Functions qw(catfile devnull);
-use File::Find;
-use IO::Compress::Zip qw(:all);
+use File::Basename;
use Archive::Tar;
+use Data::Dumper;
+use FileHandle;
+use IO::Compress::Zip qw(:all);
+use File::Path qw(remove_tree);
+use File::Temp qw(tempdir);
use POSIX qw(strftime);
-use Cwd;
+use File::Copy;
+use File::Find;
+use Env qw(PATH);
use autodie;
-#use Data::Dumper;
+use Config;
+use Cwd;
+use if $^O eq 'MSWin32', 'Win32';
+use if $^O eq 'MSWin32', 'Win32::Console::ANSI'; # need for color :)
+use Term::ANSIColor;
### Directory for work and temp files
my $tempDir = tempdir( CLEANUP => 1);
my $workdir = cwd;
-my $null = devnull();
-### Program identification
-my $program = "LTXimg";
-my $nv = 'v1.7';
-my $copyright = <<END_COPYRIGHT ;
-[2019-08-24] (c) 2013-2019 by Pablo Gonzalez, pablgonz<at>yahoo.com
+### Script identification
+my $scriptname = 'ltximg';
+my $program = 'LTXimg';
+my $nv = 'v1.8';
+my $date = '2020-08-18';
+my $copyright = <<"END_COPYRIGHT" ;
+[$date] (c) 2013-2020 by Pablo Gonzalez, pablgonz<at>yahoo.com
END_COPYRIGHT
+my $title = "$program $nv $copyright";
+
+### Log vars
+my $LogFile = "$scriptname.log";
+my $LogWrite;
+my $LogTime = strftime("%y/%m/%d %H:%M:%S", localtime);
+
### 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 $zip = 0; # zip images dir
-my $tar = 0; # tar.gz images dir
-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
+my $skiptag = 'noltximg'; # internal tag for regex
+my $extrtag = 'ltximg'; # internal tag for regex
+my @extr_env_tmp; # save extract environments
+my @skip_env_tmp; # save skip 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 document options
+my $outfile = 0; # write output file
+my $outsrc = 0; # write standalone files
+my $PSTexa = 0; # run extract PSTexample environments
+my $STDenv = 0; # run extract standart environments
+my $verbose = 0; # verbose info
+my $gscmd; # ghostscript executable name
+my $write18; # storing write18 for compiler in TeXLive and MikTeX
+my $log = 0; # log file
+my @currentopt; # storing current options for log file
+
+### Hash to store options for Getopt::Long and log file
+my %opts_cmd;
+$opts_cmd{string}{prefix} = 'fig';
+$opts_cmd{string}{dpi} = '150';
+$opts_cmd{string}{runs} = '1';
+$opts_cmd{string}{margin} = '0';
+$opts_cmd{string}{imgdir} = 'images';
+$opts_cmd{string}{myverb} = 'myverb';
+$opts_cmd{clean} = 'doc';
+
+### Error in command line
+sub errorUsage {
+ my $msg = shift;
+ die color('red').'* Error!!: '.color('reset').$msg.
+ " (run $scriptname --help for more information)\n";
+ return;
+}
+
+### Extended error messages
+sub exterr {
+ chomp(my $msg_errno = $!);
+ chomp(my $msg_extended_os_error = $^E);
+ if ($msg_errno eq $msg_extended_os_error) {
+ $msg_errno;
+ }
+ else {
+ "$msg_errno/$msg_extended_os_error";
+ }
+}
+
+### Funtion uniq
+sub uniq {
+ my %seen;
+ return grep !$seen{$_}++, @_;
+}
+
+### Funtion array_minus
+sub array_minus(\@\@) {
+ my %e = map{ $_ => undef } @{$_[1]};
+ return grep !exists $e{$_}, @{$_[0]};
+}
+
+### 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;
+}
+
+### Print colored info in screen
+sub Infocolor {
+ my $type = shift;
+ my $info = shift;
+ if ($type eq 'Running') {
+ print color('cyan'), '* ', color('reset'), color('green'),
+ "$type: ", color('reset'), color('cyan'), "$info\r\n", color('reset');
+ }
+ if ($type eq 'Warning') {
+ print color('bold red'), "* $type: ", color('reset'),
+ color('yellow'), "$info\r\n", color('reset');
+ }
+ if ($type eq 'Finish') {
+ print color('cyan'), '* ', color('reset'), color('magenta'),
+ "$type!: ", color('reset'), color('green'), "$info\r\n",color('reset');
+ }
+ return;
+}
+
+### Write Log line and print msg (common)
+sub Infoline {
+ my $msg = shift;
+ my $now = strftime("%y/%m/%d %H:%M:%S", localtime);
+ if ($log) { $LogWrite->print(sprintf "[%s] * %s\n", $now, $msg); }
+ say $msg;
+ return;
+}
+
+### Write Log line (no print msg and time stamp)
+sub Logline {
+ my $msg = shift;
+ if ($log) { $LogWrite->print("$msg\n"); }
+ return;
+}
+
+### Write Log line (time stamp)
+sub Log {
+ my $msg = shift;
+ my $now = strftime("%y/%m/%d %H:%M:%S", localtime);
+ if ($log) { $LogWrite->print(sprintf "[%s] * %s\n", $now, $msg); }
+ return;
+}
+
+### Write array env in Log
+sub Logarray {
+ my ($env_ref) = @_;
+ my @env_tmp = @{ $env_ref }; # dereferencing and copying each array
+ if ($log) {
+ if (@env_tmp) {
+ my $tmp = join "\n", map { qq/* $_/ } @env_tmp;
+ print {$LogWrite} "$tmp\n";
+ }
+ else {
+ print {$LogWrite} "Not found\n";
+ }
+ }
+ return;
+}
+
+### Extended print info for execute system commands using $ command
+sub Logrun {
+ my $msg = shift;
+ my $now = strftime("%y/%m/%d %H:%M:%S", localtime);
+ if ($log) { $LogWrite->print(sprintf "[%s] \$ %s\n", $now, $msg); }
+ return;
+}
+
+### Capture and execute system commands
+sub RUNOSCMD {
+ my $cmdname = shift;
+ my $argcmd = shift;
+ my $showmsg = shift;
+ my $captured = "$cmdname $argcmd";
+ Logrun($captured);
+ if ($showmsg eq 'show') {
+ if ($verbose) {
+ Infocolor('Running', $captured);
+ }
+ else{ Infocolor('Running', $cmdname); }
+ }
+ if ($showmsg eq 'only' and $verbose) {
+ Infocolor('Running', $captured);
+ }
+ # Run system system command
+ $captured = qx{$captured};
+ if ($log) { $LogWrite->print($captured); }
+ if ($? == -1) {
+ my $errorlog = "* Error!!: ".$cmdname." failed to execute (%s)!\n";
+ my $errorprint = "* Error!!: ".color('reset').$cmdname." failed to execute (%s)!\n";
+ if ($log) { $LogWrite->print(sprintf $errorlog, exterr); }
+ print STDERR color('red');
+ die sprintf $errorprint, exterr;
+ } elsif ($? & 127) {
+ my $errorlog = "* Error!!: ".$cmdname." died with signal %d!\n";
+ my $errorprint = "* Error!!: ".color('reset').$cmdname." died with signal %d!\n";
+ if ($log) { $LogWrite->print(sprintf $errorlog, ($? & 127)); }
+ print STDERR color('red');
+ die sprintf $errorprint, ($? & 127);
+ } elsif ($? != 0 ) {
+ my $errorlog = "* Error!!: ".$cmdname." exited with error code %d!\n";
+ my $errorprint = "* Error!!: ".color('reset').$cmdname." exited with error code %d!\n";
+ if ($log) { $LogWrite->print(sprintf $errorlog, $? >> 8); }
+ print STDERR color('red');
+ die sprintf $errorprint, $? >> 8;
+ }
+ if ($verbose) { print $captured; }
+ return;
+}
+
+### Help for command line
+sub usage {
+find_ghostscript();
+
+my $usage = <<"END_OF_USAGE";
+${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 and "standalone" 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 [<options>] [--] <filename>.<tex|ltx>
+
+ If used without [<options>] the extracted environments are converted
+ to pdf image format and saved in "./images" directory using pdflatex
+ and preview package for process <filename>.
+
+Default environments extract
+ preview pspicture tikzpicture pgfpicture psgraph postscript PSTexample
+
+Options
+ Options that accept a value require either a blank space or = between
+ the option and the value. Multiple short options can be bundling and
+ if the last option takes a comma separated list you need -- at the end.
+ Relative or absolute paths for directories and files is not supported.
+
+ [default]
+-h, --help Display command line help and exit [off]
+-v, --version Display current version ($nv) and exit [off]
+-V, --verbose Verbose printing information [off]
+-l, --log Write .log file with debug information [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 without "preview" package [off]
+-r <integer>, --runs <integer>
+ Set the number of times the compiler will run
+ on the input file for environment extraction [1]
+-d <integer>, --dpi <integer>
+ Dots per inch resolution for images [150]
+-m <integer>, --margins <integer>
+ Set margins in bp for pdfcrop [0]
+-o <filename>, --output <filename>
+ Create output file [off]
+--imgdir <dirname> Set name of directory to save images/files [images]
+--prefix <string> Set prefix append to each generated files [fig]
+--myverb <macroname> Add "\\macroname" to verbatim inline search [myverb]
+--clean (doc|pst|tkz|all|off)
+ Removes specific block text in output file [doc]
+--zip Compress files generated in .zip [off]
+--tar Compress files generated in .tar.gz [off]
+--srcenv Create files with only code of environments [off]
+--subenv Create standalone files for environments [off]
+--shell Enable \\write18\{SHELL COMMAND\} [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]
+--dvilua Using dvilualatex>dvips>ps2pdf for compiler
+ input and lualatex for compiler output [off]
+--dvipdf Using latex>dvipdfmx for compiler input and
+ latex>dvipdfmx for compiler output [off]
+--xetex Using xelatex for compiler input and output [off]
+--luatex Using lualatex for compiler input and output [off]
+--arara Use arara for compiler input and output [off]
+--latexmk Using latexmk for compiler output 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]
+--extrenv <env1,...> Add new environments to extract [empty]
+--skipenv <env1,...> Skip some default environments to extract [empty]
+--verbenv <env1,...> Add new verbatim environments [empty]
+--writenv <env1,...> Add new verbatim write environments [empty]
+--deltenv <env1,...> Delete environments in output file [empty]
+
+Example
+\$ ltximg --latex -e -p --subenv --imgdir mypics -o test-out test-in.ltx
+
+ Create a "./mypics" directory (if it doesn't exist) with all extracted
+ environments converted to images (.pdf, .eps, .png) and standalone files
+ (.ltx), a file "test-in-fig-all.ltx" with all extracted environments and
+ the file "test-out.ltx" with all environments converted to \\includegraphics
+ using latex>dvips>ps2pdf and preview package for <input file> and pdflatex
+ for <output file>.
+
+Documentation
+For full documentation use:
+\$ texdoc ltximg
+
+Issues and reports
+Repository : https://github.com/pablgonz/ltximg
+Bug tracker : https://github.com/pablgonz/ltximg/issues
+END_OF_USAGE
+print $usage;
+exit 0;
+}
+
+### Getopt configuration
+my $result=GetOptions (
+# image options
+ 'b|bmp' => \$opts_cmd{image}{bmp}, # gs
+ 't|tif' => \$opts_cmd{image}{tif}, # gs
+ 'j|jpg' => \$opts_cmd{image}{jpg}, # gs
+ 'p|png' => \$opts_cmd{image}{png}, # gs
+ 's|svg' => \$opts_cmd{image}{svg}, # pdftocairo
+ 'e|eps' => \$opts_cmd{image}{eps}, # pdftops
+ 'P|ppm' => \$opts_cmd{image}{ppm}, # pdftoppm
+# compilers
+ 'arara' => \$opts_cmd{compiler}{arara}, # arara compiler
+ 'xetex' => \$opts_cmd{compiler}{xetex}, # xelatex compiler
+ 'latex' => \$opts_cmd{compiler}{latex}, # latex compiler
+ 'latexmk' => \$opts_cmd{compiler}{latexmk}, # latex compiler
+ 'dvips' => \$opts_cmd{compiler}{dvips}, # dvips compiler
+ 'dvipdf' => \$opts_cmd{compiler}{dvipdf}, # dvipdfmx compiler
+ 'dvilua' => \$opts_cmd{compiler}{dvilua}, # dvilualatex compiler
+ 'luatex' => \$opts_cmd{compiler}{luatex}, # lualatex compiler
+# bolean
+ 'zip' => \$opts_cmd{boolean}{zip}, # zip images dir
+ 'tar' => \$opts_cmd{boolean}{tar}, # tar images dir
+ 'shell' => \$opts_cmd{boolean}{shell}, # set write18 for compiler
+ 'nopdf' => \$opts_cmd{boolean}{nopdf}, # no pdf image format
+ 'norun' => \$opts_cmd{boolean}{norun}, # no run compiler
+ 'nocrop' => \$opts_cmd{boolean}{nocrop}, # no run pdfcrop
+ 'subenv' => \$opts_cmd{boolean}{subenv}, # subfile environments (bolean)
+ 'srcenv' => \$opts_cmd{boolean}{srcenv}, # source files (bolean)
+ 'g|gray' => \$opts_cmd{boolean}{gray}, # gray (boolean)
+ 'f|force' => \$opts_cmd{boolean}{force}, # force (boolean)
+ 'n|noprew' => \$opts_cmd{boolean}{noprew}, # no preview (boolean)
+# string
+ 'd|dpi=i' => \$opts_cmd{string}{dpi}, # positive integer < 2500
+ 'r|runs=i' => \$opts_cmd{string}{runs}, # positive integer 1,2,3
+ 'm|margins=i' => \$opts_cmd{string}{margins}, # integer
+ 'extrenv=s{1,9}' => \@extr_env_tmp, # extract environments
+ 'skipenv=s{1,9}' => \@skip_env_tmp, # skip environments
+ 'verbenv=s{1,9}' => \@verb_env_tmp, # verbatim environments
+ 'writenv=s{1,9}' => \@verw_env_tmp, # verbatim write environments
+ 'deltenv=s{1,9}' => \@delt_env_tmp, # delete environments
+ 'o|output=s{1}' => \$opts_cmd{string}{output}, # output file name (string)
+ 'imgdir=s{1}' => \$opts_cmd{string}{imgdir}, # images dir name
+ 'myverb=s{1}' => \$opts_cmd{string}{myverb}, # \myverb inline (string)
+ 'prefix=s{1}' => \$opts_cmd{string}{prefix}, # prefix
+ 'clean=s{1}' => \$opts_cmd{clean}, # clean output file
+# internal
+ 'h|help' => \$opts_cmd{internal}{help}, # help
+ 'v|version' => \$opts_cmd{internal}{version}, # version
+ 'l|log' => \$log, # write log file
+ 'V|verbose' => \$verbose, # verbose mode
+ ) or do { $log = 0 ; die usage(0); };
+
+### Open log file
+if ($log) {
+ if (!defined $ARGV[0]) { errorUsage('Input filename missing'); }
+ my $tempname = $ARGV[0];
+ $tempname =~ s/\.(tex|ltx)$//;
+ if ($LogFile eq "$tempname.log") { $LogFile = "$scriptname-log.log"; }
+ $LogWrite = FileHandle->new("> $LogFile");
+}
+
+### Init ltximg.log file
+Log("The script $scriptname $nv was started in $workdir");
+Log("Creating the temporary directory $tempDir");
+
+### Make ENV safer (perldoc perlsec)
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+### 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;
+if ($^O =~ /mswin32/i) { $Win = 1; }
my $archname = $Config{'archname'};
$archname = 'unknown' unless defined $Config{'archname'};
-# get Ghostscript command name
-my $gscmd = '';
-sub find_ghostscript () {
- return if $gscmd;
- if ($debug) {
- print "* Perl executable: $^X\n";
+# Get ghostscript command name
+sub find_ghostscript {
+ if ($log) {
+ Log('General information about the Perl instalation and operating system');
+ print {$LogWrite} "* Perl executable: $^X\n";
if ($] < 5.006) {
- print "* Perl version: $]\n";
+ print {$LogWrite} "* Perl version: $]\n";
}
else {
- printf "* Perl version: v%vd\n", $^V;
+ printf {$LogWrite} "* Perl version: v%vd\n", $^V;
}
if (defined &ActivePerl::BUILD) {
- printf "* Perl product: ActivePerl, build %s\n", ActivePerl::BUILD();
+ printf {$LogWrite} "* Perl product: ActivePerl, build %s\n", ActivePerl::BUILD();
}
- printf "* Pointer size: $Config{'ptrsize'}\n";
- printf "* Pipe support: %s\n",
- (defined($Config{'d_pipe'}) ? 'yes' : 'no');
- printf "* Fork support: %s\n",
- (defined($Config{'d_fork'}) ? 'yes' : 'no');
+ printf {$LogWrite} "* Pointer size: $Config{'ptrsize'}\n";
+ printf {$LogWrite} "* Pipe support: %s\n",
+ (defined $Config{'d_pipe'} ? 'yes' : 'no');
+ printf {$LogWrite} "* Fork support: %s\n",
+ (defined $Config{'d_fork'} ? 'yes' : 'no');
}
my $system = 'unix';
- $system = "dos" if $^O =~ /dos/i;
- $system = "os2" if $^O =~ /os2/i;
- $system = "win" if $^O =~ /mswin32/i;
- $system = "cygwin" if $^O =~ /cygwin/i;
- $system = "miktex" if defined($ENV{"TEXSYSTEM"}) and
- $ENV{"TEXSYSTEM"} =~ /miktex/i;
- print "* OS name: $^O\n" if $debug;
- print "* Arch name: $archname\n" if $debug;
- print "* System: $system\n" if $debug;
+ $system = 'win' if $^O =~ /mswin32/i;
+ $system = 'msys' if $^O =~ /msys/i;
+ $system = 'cygwin' if $^O =~ /cygwin/i;
+ $system = 'miktex' if defined $ENV{'TEXSYSTEM'} and
+ $ENV{'TEXSYSTEM'} =~ /miktex/i;
+ if ($log) {
+ print {$LogWrite} "* OS name: $^O\n";
+ print {$LogWrite} "* Arch name: $archname\n";
+ if ($^O eq 'MSWin32') {
+ my $tmp = Win32::GetOSName();
+ print {$LogWrite} "* System: $tmp\n";
+ }
+ else { print {$LogWrite} "* System: $system\n"; }
+ }
+ Log('Trying to locate the executable for Ghostscript');
my %candidates = (
- 'unix' => [qw|gs gsc|],
- 'dos' => [qw|gs386 gs|],
- 'os2' => [qw|gsos2 gs|],
- 'win' => [qw|gswin32c gs|],
- 'cygwin' => [qw|gs gswin32c|],
- 'miktex' => [qw|mgs gswin32c gs|]
+ 'unix' => [qw|gs|],
+ 'win' => [qw|gswin32c|],
+ 'msys' => [qw|gswin64c gswin32c|],
+ 'cygwin' => [qw|gs|],
+ 'miktex' => [qw|mgs gswin32c|],
);
- if ($system eq 'win' or $system eq 'cygwin' or $system eq 'miktex') {
+ if ($system eq 'win' or $system eq 'miktex') {
if ($archname =~ /mswin32-x64/i) {
my @a = ();
foreach my $name (@{$candidates{$system}}) {
@@ -124,12 +469,11 @@ sub find_ghostscript () {
}
}
my %exe = (
- 'unix' => '',
- 'dos' => '.exe',
- 'os2' => '.exe',
- 'win' => '.exe',
+ 'unix' => q{},
+ 'win' => '.exe',
+ 'msys' => '.exe',
'cygwin' => '.exe',
- 'miktex' => '.exe'
+ 'miktex' => '.exe',
);
my $candidates_ref = $candidates{$system};
my $exe = $Config{'_exe'};
@@ -142,63 +486,68 @@ sub find_ghostscript () {
if (-x $file) {
$gscmd = $candidate;
$found = 1;
- print "* Found ($candidate): $file\n" if $debug;
+ if ($log) { print {$LogWrite} "* Found ($candidate): $file\n"; }
last;
}
- print "* Not found ($candidate): $file\n" if $debug;
+ if ($log) { print {$LogWrite} "* Not found ($candidate): $file\n"; }
}
last if $found;
}
- if (not $found and $Win) {
+ if (not $found and $Win and $system ne 'msys') {
$found = SearchRegistry();
}
+ if (not $found and $system eq 'msys') {
+ $found = Searchbyregquery();
+ }
if ($found) {
- print "* Autodetected ghostscript command: $gscmd\n" if $debug;
+ if ($log) { print {$LogWrite} "* Autodetected ghostscript command: $gscmd\n"; }
}
else {
$gscmd = $$candidates_ref[0];
- print "* Default ghostscript command: $gscmd\n" if $debug;
+ if ($log) { print {$LogWrite} "* Default ghostscript command: $gscmd\n"; }
}
}
-sub SearchRegistry () {
+sub SearchRegistry {
my $found = 0;
- eval 'use Win32::TieRegistry qw|KEY_READ REG_SZ|;';
+ # The module Win32::TieRegistry not aviable in cygwin/msys
+ eval 'use Win32::TieRegistry qw|KEY_READ REG_SZ|';
if ($@) {
- if ($debug) {
- print "* Registry lookup for Ghostscript failed:\n";
+ if ($log) {
+ print {$LogWrite} "* Registry lookup for Ghostscript failed:\n";
my $msg = $@;
$msg =~ s/\s+$//;
foreach (split /\r?\n/, $msg) {
- print " $_\n";
+ print {$LogWrite} " $_\n";
}
}
return $found;
}
- my $open_params = {Access => KEY_READ(), Delimiter => '/'};
+ my $open_params = {Access => KEY_READ(), Delimiter => q{/}};
my $key_name_software = 'HKEY_LOCAL_MACHINE/SOFTWARE/';
my $current_key = $key_name_software;
my $software = new Win32::TieRegistry $current_key, $open_params;
if (not $software) {
- print "* Cannot find or access registry key `$current_key'!\n"
- if $debug;
+ if ($log) {
+ print {$LogWrite} "* Cannot find or access registry key `$current_key'!\n";
+ }
return $found;
}
- print "* Search registry at `$current_key'.\n" if $debug;
+ if ($log) { print {$LogWrite} "* Search registry at `$current_key'.\n"; }
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 $debug;
+ if ($log) { print {$LogWrite} "* Registry entry found: $current_key\n"; }
my $key_gs = $software->Open($key_name_gs, $open_params);
if (not $key_gs) {
- print "* Cannot open registry key `$current_key'!\n" if $debug;
+ if ($log) { print {$LogWrite} "* Cannot open registry key `$current_key'!\n"; }
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 $debug;
+ if ($log) { print {$LogWrite} "* Registry entry found: $current_key\n"; }
if (not $key_name_version =~ /^(\d+)\.(\d+)$/) {
- print " The sub key is not a version number!\n" if $debug;
+ if ($log) { print {$LogWrite} " The sub key is not a version number!\n"; }
next;
}
my $version_main = $1;
@@ -206,13 +555,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 $debug;
+ if ($log) { print {$LogWrite} "* Cannot open registry key `$current_key'!\n"; }
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 $debug;
+ if ($log) { print {$LogWrite} " GS_DLL = $value\n"; }
$value =~ s|([\\/])([^\\/]+\.dll)$|$1gswin32c.exe|i;
my $value64 = $value;
$value64 =~ s/gswin32c\.exe$/gswin64c.exe/;
@@ -220,10 +569,10 @@ sub SearchRegistry () {
$value = $value64;
}
if (-f $value) {
- print "EXE found: $value\n" if $debug;
+ if ($log) { print {$LogWrite} "EXE found: $value\n"; }
}
else {
- print "EXE not found!\n" if $debug;
+ if ($log) { print {$LogWrite} "EXE not found!\n"; }
next;
}
my $sortkey = sprintf '%02d.%03d %s',
@@ -231,183 +580,118 @@ sub SearchRegistry () {
$list{$sortkey} = $value;
}
else {
- print "Missing key `GS_DLL' with type `REG_SZ'!\n" if $debug;
+ if ($log) { print {$LogWrite} "Missing key `GS_DLL' with type `REG_SZ'!\n"; }
}
}
}
foreach my $entry (reverse sort keys %list) {
$gscmd = $list{$entry};
- print "* Found (via registry): $gscmd\n" if $debug;
+ if ($log) { print {$LogWrite} "* Found (via registry): $gscmd\n"; }
$found = 1;
last;
}
return $found;
-} # end GS search
+} # end GS search registry
-### If windows
-if ($Win and $gscmd =~ /\s/) { $gscmd = "\"$gscmd\"";}
+### This part is only necessary if you're using Git on windows and don't
+### have gs configured in PATH. Git for windows don't have a Win32::TieRegistry
+### module for perl (is not supported in the current versions of msys).
+sub Searchbyregquery {
+ my $found = 0;
+ my $gs_regkey;
+ my $opt_reg = '//s //v';
+ if ($log) { print {$LogWrite} "* Search Ghostscript in Windows registry under mingw/msys:\n";}
+ $gs_regkey = qx{reg query "HKLM\\Software\\GPL Ghostscript" $opt_reg GS_DLL};
+ if ($? == 0) {
+ if ($log) { print {$LogWrite} "* Registry entry found for GS_DLL (64 bits version)\n";}
+ }
+ else {
+ $gs_regkey = qx{reg query "HKLM\\Software\\Wow6432Node\\GPL Ghostscript" $opt_reg GS_DLL};
+ if ($? == 0) {
+ if ($log) { print {$LogWrite} "* Registry entry found for GS_DLL (32 bits version)\n";}
+ }
+ }
+ my ($gs_find) = $gs_regkey =~ m/(?:\s* GS_DLL \s* REG_SZ \s*) (.+?)(?:\.dll.+?\R)/s;
+ if ($gs_find) {
+ my ($gs_vol, $gs_path, $gs_ver) = $gs_find =~ m/
+ (\w{1})(?:\:) # volumen
+ (.+?) # path to executable
+ (?:\\gsdll) # LIB
+ (\d{2}) # Version
+ /xs;
+ # Adjust
+ $gs_vol = lc($gs_vol);
+ $gs_path = '/'.$gs_vol.$gs_path;
+ $gs_path =~ s|\\|/|gmsxi;
+ # Add to PATH
+ if ($log) { print {$LogWrite} "* Add $gs_path to PATH for current session\n"; }
+ $PATH .= ":$gs_path";
+ # Set executable
+ $gscmd = 'gswin'.$gs_ver.'c';
+ if ($log) { print {$LogWrite} "* Found (via reg query): $gscmd\n"; }
+ $found = 1;
+ }
+ if ($@) {
+ if ($log) {
+ print {$LogWrite} "* Registry lookup for Ghostscript by reg query failed:\n";
+ my $msg = $@;
+ $msg =~ s/\s+$//;
+ foreach (split /\r?\n/, $msg) {
+ print {$LogWrite} " $_\n";
+ }
+ }
+ return $found;
+ }
+ return $found;
+}
### Call GS
find_ghostscript();
-### Program identification, options and help for command line
-
-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 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 $usage = <<"END_OF_USAGE";
-${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
+### Windows need suport space in path
+if ($Win and $gscmd =~ /\s/) { $gscmd = "\"$gscmd\"";}
-** 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]
---zip Compress files generated in .zip format [off]
---tar Compress files generated in .tar.gz format [off]
--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]
+### Help
+if (defined $opts_cmd{internal}{help}) {
+ usage(1);
+ exit 0;
+}
-** 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
+### Version
+if (defined $opts_cmd{internal}{version}) {
+ print $title;
+ exit 0;
+}
- 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>.
+### Check <input file> from command line
+@ARGV > 0 or errorUsage('Input filename missing');
+@ARGV < 2 or errorUsage('Unknown option or too many input files');
-** Documentation **
- For extended documentation use:
- \$ texdoc ltximg
-END_OF_USAGE
+### Check <input file> extention
+my @SuffixList = ('.tex', '.ltx');
+my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
+if ($ext eq '.tex' or $ext eq '.ltx') {
+ $ext = $ext;
+}
+else {
+ errorUsage('Invalid or empty extention for input file');
+}
-### Error in command line
-sub errorUsage { die "@_ (try ltximg --help for more information)\n"; }
+### Read <input file> in memory, need [:crlf] for old windows files
+Log("Read input file $name$ext in memory");
+open my $INPUTfile, '<:crlf', "$name$ext";
+ my $ltxfile;
+ {
+ local $/;
+ $ltxfile = <$INPUTfile>;
+ }
+close $INPUTfile;
-### Getopt::Long configuration for command line
-my %opts_cmd;
+### Set tmp random number for <name-fig-tmp> and others
+my $tmp = int(rand(10000));
-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
- 'zip' => \$zip, # zip images dir
- 'tar' => \$tar, # tar images dir
-# 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;
+### Identification message in terminal
+print $title;
### Remove white space and '=' in array captured from command line
s/^\s*(\=):?|\s*//mg foreach @extr_env_tmp;
@@ -417,149 +701,426 @@ 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 argument for --extrenv option";
+@extr_env_tmp = split /,/,join q{},@extr_env_tmp;
+@skip_env_tmp = split /,/,join q{},@skip_env_tmp;
+@verb_env_tmp = split /,/,join q{},@verb_env_tmp;
+@verw_env_tmp = split /,/,join q{},@verw_env_tmp;
+@delt_env_tmp = split /,/,join q{},@delt_env_tmp;
+
+### Validate environments options from comand line
+if (grep /(^\-|^\.).*?/, @extr_env_tmp) {
+ Log('Error!!: Invalid argument for --extrenv, some argument from list begin with -');
+ errorUsage('Invalid argument for --extrenv option');
}
-if (grep( /(^\-|^\.).*?/, @skip_env_tmp )) {
- die errorUsage "Invalid argument for --skipenv option";
+if (grep /(^\-|^\.).*?/, @skip_env_tmp) {
+ Log('Error!!: Invalid argument for --skipenv, some argument from list begin with -');
+ errorUsage('Invalid argument for --skipenv option');
}
-if (grep( /(^\-|^\.).*?/, @verb_env_tmp )) {
- die errorUsage "Invalid argument for --verbenv option";
+if (grep /(^\-|^\.).*?/, @verb_env_tmp) {
+ Log('Error!!: Invalid argument for --verbenv, some argument from list begin with -');
+ errorUsage('Invalid argument for --verbenv option');
}
-if (grep( /(^\-|^\.).*?/, @verw_env_tmp )) {
- die errorUsage "Invalid argument for --writenv option";
+if (grep /(^\-|^\.).*?/, @verw_env_tmp) {
+ Log('Error!!: Invalid argument for --writenv, some argument from list begin with -');
+ errorUsage('Invalid argument for --writenv option');
}
-if (grep( /(^\-|^\.).*?/, @delt_env_tmp )) {
- die errorUsage "Invalid argument for --deltenv option";
+if (grep /(^\-|^\.).*?/, @delt_env_tmp) {
+ Log('Error!!: Invalid argument for --deltenv, some argument from list begin with -');
+ errorUsage('Invalid argument for --deltenv option');
}
-### Help
-if (defined $opts_cmd{help}) {
- find_ghostscript();
- print $usage;
- exit(0);
+### Default environment to extract
+my @extr_tmp = qw (
+ preview postscript tikzpicture pgfpicture pspicture psgraph PSTexample
+ );
+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 (
+ scontents filecontents tcboutputlisting tcbexternal tcbwritetmp extcolorbox extikzpicture
+ VerbatimOut verbatimwrite filecontentsdef filecontentshere filecontentsdefmacro
+ filecontentsdefstarred filecontentsgdef filecontentsdefmacro filecontentsgdefmacro
+ );
+push @verw_env_tmp, @verbw_tmp;
+
+########################################################################
+# One problem that can arise is the filecontents environment, this can #
+# contain a complete document and be anywhere, before dividing we will #
+# make some replacements for this and comment lines #
+########################################################################
+
+### Create a Regex for verbatim write environment
+@verw_env_tmp = uniq(@verw_env_tmp);
+my $tmpverbw = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verw_env_tmp;
+$tmpverbw = qr/$tmpverbw/x;
+my $tmp_verbw = qr {
+ (
+ (?:
+ \\begin\{$tmpverbw\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$tmpverbw\*?\})
+ (?!end\{$tmpverbw\*?\})|
+ (?-1)
+ )*
+ \\end\{$tmpverbw\*?\}
+ )
+ )
+ }x;
+
+### A pre-regex for comment lines
+my $tmpcomment = qr/^ \s* \%+ .+? $ /mx;
+
+### Hash for replace in verbatim's and comment lines
+my %document = (
+ '\begin{document}' => '\BEGIN{document}',
+ '\end{document}' => '\END{document}',
+ '\documentclass' => '\DOCUMENTCLASS',
+ '\pagestyle{' => '\PAGESTYLE{',
+ '\thispagestyle{' => '\THISPAGESTYLE{',
+ );
+
+### Changes in <input file> for verbatim write and comment lines
+while ($ltxfile =~ / $tmp_verbw | $tmpcomment /pgmx) {
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ while (my($busco, $cambio) = each %document) {
+ $encontrado =~ s/\Q$busco\E/$cambio/g;
+ }
+ substr $ltxfile, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($ltxfile) = $pos_inicial + length $encontrado;
}
-### Version
-if (defined $opts_cmd{version}) {
- print $title;
- exit(0);
+### Now, split input file in $atbegindoc and contain % ltximg : <argument>
+my ($atbegindoc, $document) = $ltxfile =~ m/\A (\s* .*? \s*) (\\documentclass.*)\z/msx;
+
+### Capture options in preamble of <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, ... , booleans}
+
+my $readoptfile = qr/
+ ^ %+ \s* ltximg (?&SEPARADOR) (?<clave>(?&CLAVE)) (?&SEPARADOR) \{ (?<argumentos>(?&ARGUMENTOS)) \}
+ (?(DEFINE)
+ (?<CLAVE> \w+ )
+ (?<ARGUMENTOS> .+? )
+ (?<SEPARADOR> \s* : \s* )
+ )
+/mx;
+
+### Search options in <input file> and store in %opts_file
+my %opts_file;
+while ($atbegindoc =~ /$readoptfile/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'};
+ }
+ else {
+ $opts_file{$clave}{$argumento} = 1;
+ }
+ }
+ }
+ else {
+ push @{ $opts_file{ $clave } }, @argumentos;
+ }
}
-### Licence
-if (defined $opts_cmd{license}) {
- print $licensetxt;
- exit(0);
+### Process options from <input file>
+if(%opts_file) {
+ Infocolor('Warning', "Found options for script in $name$ext");
+ # Search and extract options from <input file>
+ Log("Searching options for script in $name$ext");
+ if (exists $opts_file{extrenv}) {
+ Log("Found \% ltximg\: extrenv\: \{...\} in $name$ext");
+ if (grep /(^\-|^\.).*?/, @{$opts_file{extrenv}}) {
+ Log('Error!!: Invalid argument for % ltximg: extrenv: {...}, some argument from list begin with -');
+ errorUsage('Invalid argument in % ltximg: extrenv: {...}');
+ }
+ Logarray(\@{$opts_file{extrenv}});
+ push @extr_env_tmp, @{$opts_file{extrenv}};
+ }
+ # Add skipenv options from <input file>
+ if (exists $opts_file{skipenv}) {
+ Log("Found \% ltximg\: skipenv\: \{...\} in $name$ext");
+ if (grep /(^\-|^\.).*?/, @{$opts_file{skipenv}}) {
+ Log('Error!!: Invalid argument for % ltximg: skipenv: {...}, some argument from list begin with -');
+ errorUsage('Invalid argument in % ltximg: skipenv: {...}');
+ }
+ Logarray(\@{$opts_file{skipenv}});
+ push @skip_env_tmp, @{$opts_file{skipenv}};
+ }
+ # Add verbenv options from <input file>
+ if (exists $opts_file{verbenv}) {
+ Log("Found \% ltximg\: verbenv\: \{...} in $name$ext");
+ if (grep /(^\-|^\.).*?/, @{$opts_file{verbenv}}) {
+ Log('Error!!: Invalid argument for % ltximg: verbenv: {...}, some argument from list begin with -');
+ errorUsage('Invalid argument in % ltximg: verbenv: {...}');
+ }
+ Logarray(\@{ $opts_file{verbenv}});
+ push @verb_env_tmp, @{$opts_file{verbenv}};
+ }
+ # Add writenv options from <input file>
+ if (exists $opts_file{writenv}) {
+ Log("Found \% ltximg\: writenv\: \{...\} in $name$ext");
+ if (grep /(^\-|^\.).*?/, @{ $opts_file{writenv}}) {
+ Log('Error!!: Invalid argument for % ltximg: writenv: {...}, some argument from list begin with -');
+ errorUsage('Invalid argument in % ltximg: writenv: {...}');
+ }
+ Logarray(\@{ $opts_file{writenv}});
+ push @verw_env_tmp, @{$opts_file{writenv}};
+ }
+ # Add deltenv options from <input file>
+ if (exists $opts_file{deltenv}) {
+ Log("Found \% ltximg\: deltenv\: \{...\} in $name$ext");
+ if (grep /(^\-|^\.).*?/, @{$opts_file{deltenv}}) {
+ Log('Error!!: Invalid argument for % ltximg: deltenv: {...}, some argument from list begin with -');
+ errorUsage('Invalid argument in % ltximg: deltenv: {...}');
+ }
+ Logarray(\@{ $opts_file{deltenv}});
+ push @delt_env_tmp, @{$opts_file{deltenv}};
+ }
+ # Add all other options from <input file>
+ if (exists $opts_file{options}) {
+ Log("Found \% ltximg\: options\: \{...\} in $name$ext");
+ # Add compilers from <input file>
+ for my $opt (qw(arara xetex luatex latex dvips dvipdf dvilua latexmk)) {
+ if (exists $opts_file{options}{$opt}) {
+ Log("Found [$opt] compiler option in $name$ext");
+ $opts_cmd{compiler}{$opt} = 1;
+ }
+ }
+ # Add image options
+ for my $opt (qw(eps ppm svg png jpg bmp tif)) {
+ if (exists $opts_file{options}{$opt}) {
+ Log("Found [$opt] image option in $name$ext");
+ $opts_cmd{image}{$opt} = 1;
+ }
+ }
+ # Add boolean options
+ for my $opt (qw(shell nopdf norun nocrop srcenv subenv zip tar gray force noprew)) {
+ if (exists $opts_file{options}{$opt}) {
+ Log("Found [$opt] option in $name$ext");
+ $opts_cmd{boolean}{$opt} = 1;
+ }
+ }
+ # Add string options
+ for my $opt (qw(dpi myverb margins prefix imgdir output runs)) {
+ if (exists $opts_file{options}{$opt}) {
+ Log("Found [$opt = $opts_file{options}{$opt}] in $name$ext");
+ $opts_cmd{string}{$opt} = $opts_file{options}{$opt};
+ }
+ }
+ # Add clean option
+ for my $opt (qw(doc off pst tkz all)) {
+ if ($opts_file{options}{clean} eq "$opt" ) {
+ Log("Found [clean = $opt] in $name$ext");
+ $opts_cmd{clean} = $opt;
+ }
+ }
+ }
}
-### Set tmp random name for name-fig-tmp (temp files)
-my $tmp = "$$";
+### Validate --dpi
+if( $opts_cmd{string}{dpi} <= 0 or $opts_cmd{string}{dpi} >= 2500) {
+ Log('Error!!: Invalid argument for --dpi, argument out of range');
+ errorUsage('Invalid argument for --dpi option');
+}
-### Check --srcenv and --subenv option from command line
-if ($srcenv && $subenv) {
- die errorUsage "--srcenv and --subenv options are mutually exclusive";
+### Validate --runs
+if( $opts_cmd{string}{runs} <= 0 or $opts_cmd{string}{runs} >= 3) {
+ Log('Error!!: Invalid argument for --runs, argument out of range');
+ errorUsage('Invalid argument for --runs option');
}
-### 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 --arara and others compilers
+if ($opts_cmd{compiler}{arara}) {
+ # Search others compilers options
+ for my $opt (qw(xetex luatex latex dvips dvipdf dvilua latexmk)) {
+ if (defined $opts_cmd{compiler}{$opt}) {
+ Log("Error!!: Options --arara and --$opt are mutually exclusive");
+ errorUsage("Options --arara and --$opt are mutually exclusive");
+ }
+ }
+}
-### Check input file extention
-my @SuffixList = ('.tex', '', '.ltx'); # posibles
-my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
-$ext = '.tex' if not $ext;
+### Check --srcenv and --subenv option
+if ($opts_cmd{boolean}{srcenv} && $opts_cmd{boolean}{subenv}) {
+ Log('Error!!: Options --srcenv and --subenv are mutually exclusive');
+ errorUsage('Options --srcenv and --subenv are mutually exclusive');
+}
-### Read input file in memory (slurp), need :crlf for windows/linux
-open my $INPUTfile, '<:crlf', "$name$ext";
-my $ltxfile;
- {
- local $/;
- $ltxfile = <$INPUTfile>;
- }
-close $INPUTfile;
+### If --srcenv or --subenv option are OK activate write <sub files>
+if ($opts_cmd{boolean}{srcenv}) {
+ $outsrc = 1;
+ $opts_cmd{boolean}{subenv} = undef;
+}
+if ($opts_cmd{boolean}{subenv}) {
+ $outsrc = 1;
+ $opts_cmd{boolean}{srcenv} = undef;
+}
-### Funtion uniq
-sub uniq {
- my %seen;
- grep !$seen{$_}++, @_;
+### Add pdf image format if --nopdf
+if (!$opts_cmd{boolean}{nopdf}) {
+ $opts_cmd{image}{pdf} = 1;
}
-### Funtion array_minus
-sub array_minus(\@\@) {
- my %e = map{ $_ => undef } @{$_[1]};
- return grep( ! exists( $e{$_} ), @{$_[0]} );
+### Store defined image formats in $format
+my $format = join q{, },grep { defined $opts_cmd{image}{$_} } keys %{$opts_cmd{image}};
+
+### Write defined image format in log file
+if (!$opts_cmd{boolean}{norun}) {
+ Log("Defined image formats for creating: $format");
}
-### 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;
+### Check --norun and no images type
+if (!$opts_cmd{boolean}{norun} and $format eq q{}) {
+ Log('Error!!: Option --nopdf need --norun or an image option');
+ errorUsage('Option --nopdf need --norun or an image option');
}
-### Default environment to extract
-my @extr_tmp = qw (
- postscript tikzpicture pgfpicture pspicture psgraph
- );
+### Check --dvips and no eps image type
+if ($opts_cmd{compiler}{dvips} and !$opts_cmd{image}{eps} and !$opts_cmd{boolean}{norun}) {
+ Log('Error!!: Option --dvips need --eps');
+ errorUsage('Option --dvips need --eps');
+}
-push (@extr_env_tmp, @extr_tmp);
+### Validate myverb = macro option
+if (defined $opts_cmd{string}{myverb}) {
+ if ($opts_cmd{string}{myverb} =~ /^(?:\\|\-).+?/) {
+ Log('Error!!: Invalid argument for --myverb option, argument begin with - or \ ');
+ errorUsage('Invalid argument for --myverb');
+ }
+ else { Log("Set myverb = $opts_cmd{string}{myverb}"); }
+}
-### 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
- );
+### Validate imgdir = string option
+if (defined $opts_cmd{string}{imgdir}) {
+ if ($opts_cmd{string}{imgdir} =~ /^(?:\\|\-).+?/) {
+ Log('Error!!: Invalid argument for --imgdir option, argument begin with -, \ or /');
+ errorUsage('Invalid argument for --imgdir');
+ }
+ else { Log("Set imgdir = $opts_cmd{string}{imgdir}"); }
+}
-push (@verb_env_tmp, @verb_tmp);
+### Validate clean
+my %clean = map { $_ => 1 } @clean;
+$clean{doc} = 1; # by default clean = doc
-### Default verbatim write environment
-my @verbw_tmp = qw (
- scontents filecontents tcboutputlisting tcbexternal tcbwritetmp extcolorbox extikzpicture
- VerbatimOut verbatimwrite PSTexample filecontentsdef filecontentshere filecontentsdefmacro
- );
+### Pass $opts_cmd{clean} to $clean{$opt}
+for my $opt (qw(doc off pst tkz all)) {
+ if ($opts_cmd{clean} eq "$opt") {
+ $clean{$opt} = 1;
+ push @currentopt, "--clean=$opt";
+ }
+}
+
+### Activate clean options for script
+if ($clean{pst} or $clean{tkz}) { $clean{doc} = 1; }
+if ($clean{all}) { @clean{qw(pst doc tkz)} = (1) x 3; }
+if ($clean{off}) { undef %clean; }
+
+### Validating the <output file> name and save extension
+my $outext;
+if (defined $opts_cmd{string}{output}) {
+ Log('Validating name and extension for output file');
+ # Capture and split
+ my ($outname, $outpath, $tmpext) = fileparse($opts_cmd{string}{output}, @SuffixList);
+ if ($outname =~ /(^\-|^\.).*?/) {
+ Log('The name of output file begin with dash -');
+ errorUsage("$opts_cmd{string}{output} it is not a valid name for output file");
+ }
+ if ($tmpext eq q{}) { # Check and set extension
+ Log("Set extension for output file to $ext");
+ $outext = $ext;
+ }
+ else {
+ Log("Set extension for output file to $tmpext");
+ $outext = $tmpext;
+ }
+ if ($outname eq $name) { # Check name
+ Log("The name of the output file must be different that $name");
+ Infoline("Changing the output file name to $name-out");
+ $opts_cmd{string}{output} = "$name-out";
+ }
+ else {
+ Log("Set name of the output file to $outname");
+ $opts_cmd{string}{output} = $outname;
+ }
+ # If output name are ok, then $outfile = 1
+ $outfile = 1;
+}
+
+### Storing the current options of script in array for ltximg.log file
+my @allopt = qw (arara xetex luatex latex dvips dvipdf dvilua latexmk
+ shell nopdf norun nocrop srcenv subenv zip tar gray force
+ noprew eps ppm svg png jpg bmp tif dpi myverb margins
+ prefix imgdir output runs
+ );
+
+for my $opt (@allopt) {
+ if (defined $opts_cmd{boolean}{$opt}) {
+ push @currentopt, "--$opt";
+ }
+ if (defined $opts_cmd{compiler}{$opt}) {
+ push @currentopt, "--$opt";
+ }
+ if (defined $opts_cmd{image}{$opt}) {
+ push @currentopt, "--$opt";
+ }
+ if (defined $opts_cmd{string}{$opt}) {
+ push @currentopt, "--$opt=$opts_cmd{string}{$opt}"
+ }
+}
-push (@verw_env_tmp, @verbw_tmp);
+### Write all options in ltximg.log file
+@currentopt = sort { length $a <=> length $b } @currentopt;
+Log('The script will execute the following options:');
+Logarray(\@currentopt);
-### Rules to capture in regex
+### Rules to capture for regex
my $braces = qr/ (?:\{)(.+?)(?:\}) /msx;
my $braquet = qr/ (?:\[)(.+?)(?:\]) /msx;
my $no_corchete = qr/ (?:\[ .*? \])? /msx;
-### Capture new verbatim environments defined in input file
+### Array for capture new verbatim environments defined in input file
my @new_verb = qw (
- newtcblisting DeclareTCBListing ProvideTCBListing NewTCBListing
- lstnewenvironment NewListingEnvironment NewProgram specialcomment
- includecomment DefineVerbatimEnvironment newverbatim newtabverbatim
- );
+ 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;
+my $newverbenv = join q{|}, 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
+### Array for capture new verbatim write environments defined in input file
my @new_verb_write = qw (
- renewtcbexternalizetcolorbox renewtcbexternalizeenvironment
- newtcbexternalizeenvironment newtcbexternalizetcolorbox
- );
+ renewtcbexternalizetcolorbox renewtcbexternalizeenvironment
+ newtcbexternalizeenvironment newtcbexternalizetcolorbox newenvsc
+ );
### 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;
+my $newverbwrt = join q{|}, 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;
@@ -569,297 +1130,139 @@ 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
+### Filter input file, now $ltxfile is pass to $filecheck
+Log("Filter $name$ext \(remove % and comments\)");
my @filecheck = $ltxfile;
-s/%.*\n//mg foreach @filecheck; # del comments
+s/%.*\n//mg foreach @filecheck; # del comments
s/^\s*|\s*//mg foreach @filecheck; # del white space
-my $filecheck = join '', @filecheck;
+my $filecheck = join q{}, @filecheck;
-### Capture \newverbatim write names in input file
-my @newv_write = $filecheck =~ m/$newverbwrt/xg;
-
-### Add @newv_write defined in input file to @verw_env_tmp
-push (@verw_env_tmp, @newv_write);
+### Search verbatim and verbatim write environments <input file>
+Log("Search verbatim and verbatim write environments in $name$ext");
-### Capture \newminted{$mintdenv}{options} (for)
-my @mint_denv = $filecheck =~ m/$mintdenv/xg;
-
-### Capture \newminted[$mintcenv]{lang} (for)
-my @mint_cenv = $filecheck =~ m/$mintcenv/xg;
-
-### Capture \newmint{$mintdshrt}{options} (while)
-my @mint_dshrt = $filecheck =~ m/$mintdshrt/xg;
-
-### Capture \newmint[$mintcshrt]{lang}{options} (while)
-my @mint_cshrt = $filecheck =~ m/$mintcshrt/xg;
-
-### Capture \newmintinline{$mintdline}{options} (while)
-my @mint_dline = $filecheck =~ m/$mintdline/xg;
-
-### Capture \newmintinline[$mintcline]{lang}{options} (while)
-my @mint_cline = $filecheck =~ m/$mintcline/xg;
+### Search new verbatim write names in <input file>
+my @newv_write = $filecheck =~ m/$newverbwrt/xg;
+if (@newv_write) {
+ Log("Found new verbatim write environments in $name$ext");
+ Logarray(\@newv_write);
+ push @verw_env_tmp, @newv_write;
+}
-### Capture \newverbatim environments in input file (for)
+### Search new verbatim environments in <input file> (for)
my @verb_input = $filecheck =~ m/$newverbenv/xg;
+if (@verb_input) {
+ Log("Found new verbatim environments in $name$ext");
+ Logarray(\@verb_input);
+ push @verb_env_tmp, @verb_input;
+}
-### 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) {
+### Search \newminted{$mintdenv}{options} in <input file>, need add "code" (for)
+my @mint_denv = $filecheck =~ m/$mintdenv/xg;
+if (@mint_denv) {
+ Log("Found \\newminted\{envname\} in $name$ext");
+ # Append "code"
$mintdenv = join "\n", map { qq/$_\Qcode\E/ } @mint_denv;
@mint_denv = split /\n/, $mintdenv;
+ Logarray(\@mint_denv);
+ push @verb_env_tmp, @mint_denv;
}
-### Append "inline" (minted)
-if (!@mint_dline == 0) {
- $mintdline = join "\n", map { qq/$_\Qinline\E/ } @mint_dline;
- @mint_dline = split /\n/, $mintdline;
+### Search \newminted[$mintcenv]{lang} in <input file> (for)
+my @mint_cenv = $filecheck =~ m/$mintcenv/xg;
+if (@mint_cenv) {
+ Log("Found \\newminted\[envname\] in $name$ext");
+ Logarray(\@mint_cenv);
+ push @verb_env_tmp, @mint_cenv;
}
-### 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 $readoptfile, %opt_from_file;
-my $readoptfile = qr/
- ^ %+ \s* ltximg (?&SEPARADOR) (?<clave>(?&CLAVE)) (?&SEPARADOR) \{ (?<argumentos>(?&ARGUMENTOS)) \}
- (?(DEFINE)
- (?<CLAVE> \w+ )
- (?<ARGUMENTOS> .+? )
- (?<SEPARADOR> \s* : \s* )
- )
-/mx;
-
-### Split input file, $atbegindoc contain % ltximg : <argument>
-my ($atbegindoc, $document) = $ltxfile =~ m/\A (\s* .*? \s*) (\\documentclass.*)\z/msx;
-
-### Process options from input file
-my %opts_file;
-
-while ($atbegindoc =~ /$readoptfile/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 ($clean{all}) { @clean{qw(pst doc tkz)} = (1) x 3; }
-if ($clean{off}) { undef %clean; }
+### Remove repetead again :)
+@verb_env_tmp = uniq(@verb_env_tmp);
-### Add extract options from input file
-if (exists $opts_file{extract}) {
- push @extr_env_tmp, @{ $opts_file{extract} };
-}
+### Capture verbatim inline macros in input file
+Log("Search verbatim macros in $name$ext");
-### Add skipenv options from input file
-if (exists $opts_file{skipenv}) {
- push @skip_env_tmp, @{ $opts_file{skipenv} };
-}
+### Store all minted inline/short in @mintline
+my @mintline;
-### Add verbenv options from input file
-if (exists $opts_file{verbenv}) {
- push @verb_env_tmp, @{ $opts_file{verbenv} };
+### Search \newmint{$mintdshrt}{options} in <input file> (while)
+my @mint_dshrt = $filecheck =~ m/$mintdshrt/xg;
+if (@mint_dshrt) {
+ Log("Found \\newmint\{macroname\} (short) in $name$ext");
+ Logarray(\@mint_dshrt);
+ push @mintline, @mint_dshrt;
}
-### Add writenv options from input file
-if (exists $opts_file{writenv}) {
- push @verw_env_tmp, @{ $opts_file{writenv} };
+### Search \newmint[$mintcshrt]{lang}{options} in <input file> (while)
+my @mint_cshrt = $filecheck =~ m/$mintcshrt/xg;
+if (@mint_cshrt) {
+ Log("Found \\newmint\[macroname\] (short) in $name$ext");
+ Logarray(\@mint_cshrt);
+ push @mintline, @mint_cshrt;
}
-### Add deltenv options from input file
-if (exists $opts_file{deltenv}) {
- push @delt_env_tmp, @{ $opts_file{deltenv} };
+### Search \newmintinline{$mintdline}{options} in <input file> (while)
+my @mint_dline = $filecheck =~ m/$mintdline/xg;
+if (@mint_dline) {
+ Log("Found \\newmintinline\{macroname\} in $name$ext");
+ # Append "inline"
+ $mintdline = join "\n", map { qq/$_\Qinline\E/ } @mint_dline;
+ @mint_dline = split /\n/, $mintdline;
+ Logarray(\@mint_dline);
+ push @mintline, @mint_dline;
}
-### Set \myverb|<code>| options from input file
-if (exists $opts_file{options}{verbcmd}) {
- $verbcmd = $opts_file{options}{verbcmd};
+### Search \newmintinline[$mintcline]{lang}{options} in <input file> (while)
+my @mint_cline = $filecheck =~ m/$mintcline/xg;
+if (@mint_cline) {
+ Log("Found \\newmintinline\[macroname\] in $name$ext");
+ Logarray(\@mint_cline);
+ push @mintline, @mint_cline;
}
-### 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);
+### Add standart mint, mintinline and lstinline
+my @mint_tmp = qw(mint mintinline lstinline);
-### 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);
+### Join all inline verbatim macros captured
+push @mintline, @mint_tmp;
+@mintline = uniq(@mintline);
-### 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);
+### Create a regex using @mintline
+my $mintline = join q{|}, map { quotemeta } sort { length $a <=> length $b } @mintline;
+$mintline = qr/\b(?:$mintline)/x;
### 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
- '\pspicture' => '\TRICKS',
- '\endpspicture' => '\ENDTRICKS',
-# pgfpicture
- '\pgfpicture' => '\PGFTRICKS',
- '\endpgfpicture' => '\ENDPGFTRICKS',
-# tikzpicture
- '\tikzpicture' => '\TKZTRICKS',
- '\endtikzpicture' => '\ENDTKZTRICKS',
-# psgraph
- '\psgraph' => '\PSGRAPHTRICKS',
- '\endpsgraph' => '\ENDPSGRAPHTRICKS',
-# some reserved
- '\usepackage' => '\USEPACKAGE',
- '{graphicx}' => '{GRAPHICX}',
- '\graphicspath{' => '\GRAPHICSPATH{',
+ '%<*ltximg>' => '%<*LTXIMG>',
+ '%</ltximg>' => '%</LTXIMG>',
+ '%<*noltximg>' => '%<*NOLTXIMG>',
+ '%</noltximg>' => '%</NOLTXIMG>',
+ '%<*remove>' => '%<*REMOVE>',
+ '%</remove>' => '%</REMOVE>',
+ '\psset' => '\PSSET',
+ '\tikzset' => '\TIKZSET',
+ '\pspicture' => '\TRICKS',
+ '\endpspicture' => '\ENDTRICKS',
+ '\pgfpicture' => '\PGFTRICKS',
+ '\endpgfpicture' => '\ENDPGFTRICKS',
+ '\tikzpicture' => '\TKZTRICKS',
+ '\endtikzpicture' => '\ENDTKZTRICKS',
+ '\psgraph' => '\PSGRAPHTRICKS',
+ '\endpsgraph' => '\ENDPSGRAPHTRICKS',
+ '\usepackage' => '\USEPACKAGE',
+ '{graphicx}' => '{GRAPHICX}',
+ '\graphicspath{' => '\GRAPHICSPATH{',
);
-### Changues \begin... \end in verbatim inline
+### Hash to replace \begin and \end in verbatim inline
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}',
- );
+### Join changes in new hash (while) for verbatim inline
+my %cambios = (%changes_in,%init_end);
-### 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
- '\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 and constantes
my $no_del = "\0";
my $del = $no_del;
@@ -867,10 +1270,9 @@ my $del = $no_del;
my $llaves = qr/\{ .+? \} /x;
my $no_llaves = qr/(?: $llaves )? /x;
my $corchetes = qr/\[ .+? \] /x;
-my $nestedbr = qr/(\{(?>[^\{\}\\]++|\\.|(?R))*+\}) /x;
my $delimitador = qr/\{ (?<del>.+?) \} /x;
my $scontents = qr/Scontents [*]? $no_corchete /ix;
-my $verb = qr/(?:((spv|(?:q|f)?v|V)erb|$verbcmd)[*]?) /ix;
+my $verb = qr/(?:((spv|(?:q|f)?v|V)erb|$opts_cmd{string}{myverb})[*]?) /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;
@@ -879,7 +1281,9 @@ my $comentario = qr/^ \s* \%+ .+? $
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)
+Log('Making changes to inline/multiline verbatim before extraction');
+
+### Changes in input file for verbatim inline/multiline
while ($document =~
/ $marca
| $comentario
@@ -898,917 +1302,1671 @@ while ($document =~
}
else {
while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/g;
- } # close while
+ $encontrado =~ s/\Q$busco\E/$cambio/g;
+ }
substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
pos ($document) = $pos_inicial + length $encontrado;
}
}
-### Regex for verbatim inline whit braces {...}
+### Change "escaped braces" to <LTXSB.> (this label is not the one in the document)
+$document =~ s/\\[{]/<LTXSBO>/g;
+$document =~ s/\\[}]/<LTXSBC>/g;
+
+### Regex for verbatim inline/multiline with braces {...}
+my $nestedbr = qr / ( [{] (?: [^{}]++ | (?-1) )*+ [}] ) /x;
my $fvextra = qr /\\ (?: (Save|Esc)Verb [*]?) $no_corchete /x;
my $mintedbr = qr /\\ (?:$mintline|pygment) (?!\*) $no_corchete $no_llaves /x;
-my $tcbxverb = qr /\\ (?: tcboxverb [*]?| Scontents [*]? |$verbcmd [*]?|lstinline) $no_corchete /x;
-my $verb_brace = qr / (?:$tcbxverb|$mintedbr|$fvextra) (?:\s*)? $nestedbr /x;
+my $tcbxverb = qr /\\ (?: tcboxverb [*]?| Scontents [*]? |$opts_cmd{string}{myverb} [*]?|lstinline) $no_corchete /x;
+my $verb_brace = qr / (?:$tcbxverb|$mintedbr|$fvextra) (?:\s*)? $nestedbr /x;
-### Changue \verb*{code} for verbatim inline
+### Change \verb*{code} for verbatim inline/multiline
while ($document =~ /$verb_brace/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 $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
-} # close while
-
-### Changue <*TAGS> to <*tags>
-my $ltxtags = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %reverse_tag;
- $document =~ s/^($ltxtags)/$reverse_tag{$1}/gmsx;
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ while (my($busco, $cambio) = each %cambios) {
+ $encontrado =~ s/\Q$busco\E/$cambio/g;
+ }
+ substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($document) = $pos_inicial + length $encontrado;
+}
-### Define environments Verbatim standart
-my $verbatim = join "|", map quotemeta, sort { length $a <=> length $b } @verbatim;
- $verbatim = qr/$verbatim/x;
+### We recovered the escaped braces
+$document =~ s/<LTXSBO>/\\{/g;
+$document =~ s/<LTXSBC>/\\}/g;
-### Define environments Verbatim write
-my $verbatim_w = join "|", map quotemeta, sort { length $a <=> length $b } @verbatim_w;
- $verbatim_w = qr/$verbatim_w/x;
+### Reverse changes for extract and output file
+my %changes_out = (
+ '\PSSET' => '\psset',
+ '\TIKZSET' => '\tikzset',
+ '\TRICKS' => '\pspicture',
+ '\ENDTRICKS' => '\endpspicture',
+ '\PGFTRICKS' => '\pgfpicture',
+ '\ENDPGFTRICKS' => '\endpgfpicture',
+ '\TKZTRICKS' => '\tikzpicture',
+ '\ENDTKZTRICKS' => '\endtikzpicture',
+ '\PSGRAPHTRICKS' => '\psgraph',
+ '\ENDPSGRAPHTRICKS' => '\endpsgraph',
+ '\USEPACKAGE' => '\usepackage',
+ '{GRAPHICX}' => '{graphicx}',
+ '\GRAPHICSPATH{' => '\graphicspath{',
+ '\BEGIN{' => '\begin{',
+ '\END{' => '\end{',
+ '\DOCUMENTCLASS' => '\documentclass',
+ '\PAGESTYLE{' => '\pagestyle{',
+ '\THISPAGESTYLE{' => '\thispagestyle{',
+ );
-### Define environments to skip
-my $skipenv = join "|", map quotemeta, sort { length $a <=> length $b } @skipped;
- $skipenv = qr/$skipenv/x;
+### Reverse tags, need back in all file to extract
+my %reverse_tag = (
+ '%<*LTXIMG>' => '%<*ltximg>',
+ '%</LTXIMG>' => '%</ltximg>',
+ '%<*NOLTXIMG>' => '%<*noltximg>',
+ '%</NOLTXIMG>' => '%</noltximg>',
+ '%<*REMOVE>' => '%<*remove>',
+ '%</REMOVE>' => '%</remove>',
+ );
-### Define environments to extract
-my $environ = join "|", map quotemeta, sort { length $a <=> length $b } @extract;
- $environ = qr/$environ/x;
+### First we do some security checks to ensure that they are verbatim and
+### verbatim write environments are unique and disjointed
+@verb_env_tmp = array_minus(@verb_env_tmp, @verw_env_tmp); #disjointed
+my @verbatim = uniq(@verb_env_tmp);
+my %verbatim = crearhash(@verbatim);
-### Define environments to delete
-my $delenv = join "|", map quotemeta, sort { length $a <=> length $b } @delt_env_tmp;
- $delenv = qr/$delenv/x;
+Log('The environments that are considered verbatim:');
+Logarray(\@verbatim);
-### Split file by lines
-my @lineas = split /\n/, $document;
+### Create a Regex for verbatim standart environment
+my $verbatim = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verbatim;
+$verbatim = qr/$verbatim/x;
+my $verb_std = qr {
+ (
+ (?:
+ \\begin\{$verbatim\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim\*?\})
+ (?!end\{$verbatim\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim\*?\}
+ )
+ )
+ }x;
-### 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;
+### Verbatim write
+@verw_env_tmp = array_minus(@verw_env_tmp, @verb_env_tmp); #disjointed
+my @verbatim_w = uniq(@verw_env_tmp);
+my %verbatim_w = crearhash(@verbatim_w);
-### Change in $verbatim and $verbatim_w
-my $DEL;
-for (@lineas) {
- if (/\\begin\{($verbatim\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- s/($find)/$replace{$1}/g; }
- 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 $document
-$document = join("\n", @lineas);
-
-### Split input file
-my ($preamble,$bodydoc,$enddoc) = $document =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
+Log('The environments that are considered verbatim write:');
+Logarray(\@verbatim_w);
-### Regex for delete environment
-my $delt_env = qr /
- (
- (?:
- \\begin\{$delenv\*?\}
+### Create a Regex for verbatim write environment
+my $verbatim_w = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verbatim_w;
+$verbatim_w = qr/$verbatim_w/x;
+my $verb_wrt = qr {
+ (
(?:
- (?>[^\\]+)|
- \\
- (?!begin\{$delenv\*?\})
- (?!end\{$delenv\*?\})|
- (?-1)
- )*
- \\end\{$delenv\*?\}
+ \\begin\{$verbatim_w\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim_w\*?\})
+ (?!end\{$verbatim_w\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim_w\*?\}
+ )
)
- )
- /x;
+ }x;
+
+### Check skip environments
+my @skipped;
+if (@skip_env_tmp) {
+ my %envcheck = map { $_ => 1 } @skip_env_tmp;
+ if (exists $envcheck{PSTexample}) {
+ Log('The [PSTexample] environment is not allowed for skipping');
+ @skip_env_tmp = grep !/PSTexample/, @skip_env_tmp;
+ }
+ if (exists $envcheck{preview}) {
+ Log('The [preview] environment is not allowed for skipping');
+ @skip_env_tmp = grep !/preview/, @skip_env_tmp;
+ }
+ # Valid environments for skip
+ for my $skip (qw(pspicture tikzpicture pgfpicture psgraph postscript)) {
+ if (exists $envcheck{$skip}) {
+ push @skipped,$skip;
+ }
+ }
+}
-### Regex for verbatim write environment
-my $verb_wrt = qr /
- (
- (?:
- \\begin\{$verbatim_w\*?\}
+### List of environments to be skiped from extraction
+@skipped = uniq(@skip_env_tmp);
+Log('The environments that will be skiped for extraction:');
+Logarray(\@skipped);
+
+### Create a Regex for skip environment
+my $skipenv = join q{|}, map { quotemeta } sort { length $a <=> length $b } @skipped;
+$skipenv = qr/$skipenv/x;
+my $skip_env = qr {
+ (
(?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim_w\*?\})
- (?!end\{$verbatim_w\*?\})|
- (?-1)
- )*
- \\end\{$verbatim_w\*?\}
+ \\begin\{$skipenv\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$skipenv\*?\})
+ (?!end\{$skipenv\*?\})|
+ (?-1)
+ )*
+ \\end\{$skipenv\*?\}
+ )
)
- )
- /x;
+ }x;
-### Pass $verb_wrt to %<*ltximgverw> ... %</ltximgverw>
-$bodydoc =~ s/($verb_wrt)/\%<\*ltximgverw>\n$1\n\%<\/ltximgverw>/gmsx;
+### Check reserved environments
+my %envcheck = map { $_ => 1 } @extr_env_tmp;
-### Regex for skip environment
-my $skip_env = qr /
- (
- (?:
- \\begin\{$skipenv\*?\}
+if (exists $envcheck{document}) {
+ Log('The [document] environment is allowed for extraction');
+ @extr_env_tmp = grep !/document/, @extr_env_tmp;
+}
+if (exists $envcheck{nopreview}) {
+ Log('The [nopreview] environment is allowed for extraction');
+ @extr_env_tmp = grep !/nopreview/, @extr_env_tmp;
+}
+
+### An array with all environments to extract, including nopreview
+my @extract_env = qw(nopreview);
+push @extract_env,@extr_env_tmp;
+
+### Some oprations for skip environments
+@extract_env = array_minus(@extract_env, @skip_env_tmp);
+@extract_env = uniq(@extract_env);
+
+### Hash for regex
+my %extract_env = crearhash(@extract_env);
+
+Log('The environments that will be searched for extraction:');
+my @real_extract_env = grep !/nopreview/, @extract_env;
+Logarray(\@real_extract_env);
+
+### Create a regex to extract environments
+my $environ = join q{|}, map { quotemeta } sort { length $a <=> length $b } @extract_env;
+$environ = qr/$environ/x;
+my $extr_tmp = qr {
+ (
(?:
- (?>[^\\]+)|
- \\
- (?!begin\{$skipenv\*?\})
- (?!end\{$skipenv\*?\})|
- (?-1)
- )*
- \\end\{$skipenv\*?\}
+ \\begin\{$environ\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$environ\*?\})
+ (?!end\{$environ\*?\})|
+ (?-1)
+ )*
+ \\end\{$environ\*?\}
+ )
)
- )
- /x;
+ }x;
+
+### Check delete environments
+if (@delt_env_tmp) {
+ my %envcheck = map { $_ => 1 } @delt_env_tmp;
+ if (exists $envcheck{document}) {
+ Log('The [document] environment is not allowed for delete');
+ @delt_env_tmp = grep !/document/, @delt_env_tmp;
+ }
+}
-### Pass %<*noltximg> ... %</noltximg> to \begin{nopreview} ... \end{nopreview}
-$bodydoc =~ s/^\%<\*$skiptag>(.+?)\%<\/$skiptag>/\\begin\{nopreview\}$1\\end\{nopreview\}/gmsx;
+### An array of environments to be removed in <output file>
+my @delete_env = uniq(@delt_env_tmp);
+my %delete_env = crearhash(@delete_env);
-### Pass $skip_env to \begin{nopreview} .+? \end{nopreview}
-$bodydoc =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- ($skip_env)/\\begin\{nopreview\}\n$1\n\\end\{nopreview\}\n/gmsx;
+Log('The environments that will be removed in output file:');
+Logarray(\@delete_env);
-### Regex to extract environments
-my $extr_env = qr /
- (
- (?:
- \\begin\{$environ\*?\}
+### Create a Regex for delete environment in <output file>
+my $delenv = join q{|}, map { quotemeta } sort { length $a <=> length $b } @delete_env;
+$delenv = qr/$delenv/x;
+my $delt_env = qr {
+ (
(?:
- (?>[^\\]+)|
- \\
- (?!begin\{$environ\*?\})
- (?!end\{$environ\*?\})|
- (?-1)
- )*
- \\end\{$environ\*?\}
+ \\begin\{$delenv\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$delenv\*?\})
+ (?!end\{$delenv\*?\})|
+ (?-1)
+ )*
+ \\end\{$delenv\*?\}
+ )
)
- )
- /x;
-
-### Set bolean options from input file
-$zip = 1 if exists $opts_file{options}{zip};
-$tar = 1 if exists $opts_file{options}{tar};
-$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};
+ }x;
-### Check plain TeX syntax
-my %special = map { $_ => 1 } @extract; # anon hash
-### Convert \pspicture to LaTeX syntax
-if (exists($special{pspicture})) {
- $bodydoc =~ s/
- \\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
+########################################################################
+# In this first part the script only detects verbatim environments and #
+# verbatim write don't distinguish between which ones are extracted, #
+# that's done in a second pass. #
+########################################################################
+
+Log('Making changes to verbatim and verbatim write environments before extraction');
+
+### First, revert %<*TAGS> to %<*tags> in all document
+my $ltxtags = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %reverse_tag;
+$document =~ s/^($ltxtags)/$reverse_tag{$1}/gmsx;
+
+### Create an array with the temporary extraction list, no verbatim environments
+my @extract_tmp = array_minus(@extract_env, @verb_env_tmp);
+@extract_tmp = array_minus(@extract_tmp, @verw_env_tmp);
+@extract_tmp = uniq(@extract_tmp);
+my %extract_tmp = crearhash(@extract_tmp);
+
+### Hash and Regex for changes, this "regex" is re-used in ALL script
+my %replace = (%verbatim, %extract_tmp, %changes_in, %document); # revert tags again :)
+my $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
+
+### We go line by line and make the changes in verbatim's envoronments (/p for ${^MATCH})
+while ($document =~ /$verb_wrt | $verb_std /pgmx) {
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ if ($encontrado =~ /$verb_wrt/) {
+ $encontrado =~ s/($find)/$replace{$1}/g;
+ substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($document) = $pos_inicial + length $encontrado;
+ }
+ if ($encontrado =~ /$verb_std/) {
+ %replace = (%verbatim_w, %extract_tmp, %changes_in, %document);
+ $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
+ $encontrado =~ s/($find)/$replace{$1}/g;
+ substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($document) = $pos_inicial + length $encontrado;
+ }
+}
+
+### Now split document
+my ($preamble,$bodydoc,$enddoc) = $document =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
+
+### Internal <dtxtag> for mark verbatim and verbatim write environments
+my $dtxverb = "verbatim$tmp";
+
+### Match <dtxtags>, if they're matched, we turn them :)
+my @tag_extract = $bodydoc =~ m/(?:^\%<\*ltximg>.+?\%<\/ltximg>)/gmsx;
+my @tag_noextract = $bodydoc =~ m/(?:^\%<\*noltximg>.+?\%<\/noltximg>)/gmsx;
+
+if (@tag_extract) {
+ Log('Pass extract tags %<*ltximg> ... %</ltximg> to \begin{preview} ... \end{preview}');
+ $bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ^\%<\*$extrtag>(.+?)\%<\/$extrtag>/\\begin\{preview\}$1\\end\{preview\}/gmsx;
+}
+if (@tag_noextract) {
+ Log('Pass no extract tags %<*noltximg> ... %</noltximg> to \begin{nopreview} ... \end{nopreview}');
+ $bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ^\%<\*$skiptag>(.+?)\%<\/$skiptag>/\\begin\{nopreview\}$1\\end\{nopreview\}/gmsx;
}
-### Convert \psgraph to LaTeX syntax
-if (exists($special{psgraph})) {
- $bodydoc =~ s/
- \\psgraph(\*)?(.+?)\\endpsgraph/\\begin{psgraph$1}$2\\end{psgraph$1}/gmsx;
+########################################################################
+# We now make the real changes for environment extraction. Since we #
+# don't know what kind of environments are passed, need to redefine #
+# all regex to make the changes. #
+########################################################################
+
+my @new_verb_tmp = array_minus(@verbatim, @extract_env);
+$verbatim = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verb_tmp;
+$verbatim = qr/$verbatim/x;
+$verb_std = qr {
+ (
+ (?:
+ \\begin\{$verbatim\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim\*?\})
+ (?!end\{$verbatim\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim\*?\}
+ )
+ )
+ }x;
+
+my @new_verbw_tmp = array_minus(@verbatim_w, @extract_env);
+$verbatim_w = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verbw_tmp;
+$verbatim_w = qr/$verbatim_w/x;
+$verb_wrt = qr {
+ (
+ (?:
+ \\begin\{$verbatim_w\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim_w\*?\})
+ (?!end\{$verbatim_w\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim_w\*?\}
+ )
+ )
+ }x;
+
+### Regex using hash
+%replace = (%extract_env);
+$find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
+
+### We go line by line and make the changes (/p for ${^MATCH})
+while ($bodydoc =~ /$verb_wrt | $verb_std /pgmx) {
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ $encontrado =~ s/($find)/$replace{$1}/g;
+ substr $bodydoc, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($bodydoc) = $pos_inicial + length $encontrado;
+}
+
+### Now put a internal dtxmark in no extraction/replace environments
+Log("Pass verbatim write environments to %<*$dtxverb> ... %</$dtxverb>");
+$bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ($verb_wrt)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
+$preamble =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ($verb_wrt)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
+
+Log("Pass verbatim environments to %<*$dtxverb> ... %</$dtxverb>");
+$bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ($verb_std)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
+$preamble =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ($verb_std)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
+
+### Check plain TeX syntax
+my %plainsyntax = map { $_ => 1 } @extract_env; # anon hash
+
+if (exists $plainsyntax{pspicture}) {
+ Log('Convert plain \pspicture to LaTeX syntax [skip in PSTexample]');
+ $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
+ \\pspicture(\*)?(.+?)\\endpspicture/\\begin\{pspicture$1\}$2\\end\{pspicture$1\}/gmsx;
+}
+
+if (exists $plainsyntax{psgraph}) {
+ Log('Convert plain \psgraph to LaTeX syntax [skip in PSTexample]');
+ $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
+ \\psgraph(\*)?(.+?)\\endpsgraph/\\begin\{psgraph$1\}$2\\end\{psgraph$1\}/gmsx;
}
-### Convert \tikzpicture to LaTeX syntax
-if (exists($special{tikzpicture})) {
- $bodydoc =~ s/
+if (exists $plainsyntax{tikzpicture}) {
+ Log('Convert plain \tikzpicture to LaTeX syntax');
+ $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
\\tikzpicture(.+?)\\endtikzpicture/\\begin{tikzpicture}$1\\end{tikzpicture}/gmsx;
}
-### Convert \pgfpicture to LaTeX syntax
-if (exists($special{pgfpicture})) {
- $bodydoc =~ s/
+if (exists $plainsyntax{pgfpicture}) {
+ Log('Convert plain \pgfpicture to LaTeX syntax');
+ $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
\\pgfpicture(.+?)\\endpgfpicture/\\begin{pgfpicture}$1\\end{pgfpicture}/gmsx;
}
-### Pass %<*ltximg> (.+?) %</ltximg> to \begin{preview} (.+?) \end{preview}
-$bodydoc =~ s/^\%<\*$extrtag>(.+?)\%<\/$extrtag>/\\begin\{preview\}$1\\end\{preview\}/gmsx;
+### Force mode for pstricks/psgraph/tikzpiture
+if ($opts_cmd{boolean}{force}) {
+ if (exists $plainsyntax{pspicture} or exists $plainsyntax{psgraph}) {
+ Log('Try to capture \psset{...} for pstricks environments [force mode]');
+ $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
+ \\begin\{postscript\}.+?\\end\{postscript\}(*SKIP)(*F)|
+ (?<code>
+ (?:\\psset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
+ \\begin\{(?<env> pspicture\*?| psgraph)\} .+? \\end\{\k<env>\}
+ )
+ /\\begin\{preview\}$+{code}\\end\{preview\}/gmsx;
+ }
+ if (exists $plainsyntax{tikzpicture}) {
+ Log('Try to capture \tikzset{...} for tikzpicture environments [force mode]');
+ $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*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\}$+{code}\\end\{preview\}/gmsx;
+ }
+}
-### $force mode for pstricks/psgraph/tikzpiture
-if ($force) {
-if (exists($special{pspicture}) or exists($special{psgraph})) { # pspicture or psgraph found
-$bodydoc =~ 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
-if (exists($special{tikzpicture})) {# tikzpicture found
-$bodydoc =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+Log('Pass skip environments to \begin{nopreview} ... \end{nopreview}');
+$bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*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}
-$bodydoc =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
+ \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
+ ($skip_env)/\\begin\{nopreview\}$1\\end\{nopreview\}/gmsx;
+
+### Pass all captured environments in body \begin{preview} ... \end{preview}
+Log('Pass all captured environments to \begin{preview} ... \end{preview}');
+$bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*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 words to original
-%replace = (%changes_out,%reverse_tag);
- $find = join "|", map {quotemeta} sort { length($a)<=>length($b) } keys %replace;
-
-### Split $preamble by lines
-@lineas = split /\n/, $preamble;
-
-### Changues in verbatim write
+ ($extr_tmp)/\\begin\{preview\}$1\\end\{preview\}/gmsx;
+
+########################################################################
+# All environments are now classified: #
+# Extraction -> \begin{preview} ... \end{preview} #
+# No Extraction -> \begin{nopreview} ... \end{nopreview} #
+# Verbatim's -> %<\*$dtxverb> ... <\/$dtxverb> #
+########################################################################
+
+### The %<*remove> ... %</remove> tags need a special treatment :)
+$bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ^(\%<(?:\*|\/))(remove)(\>)/$1$2$tmp$3/gmsx;
+$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ^(\%<(?:\*|\/))(remove)(\>)/$1$2$tmp$3/gmsx;
+$atbegindoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
+ ^(\%<(?:\*|\/))(remove)(\>)/$1$2$tmp$3/gmsx;
+
+### Pass \begin{preview} ... \end{preview} to \START{preview} ... \STOP{preview}
+### Pass \begin{nopreview} ... \end{nopreview} to \START{nopreview} ... \STOP{nopreview}
+$bodydoc =~ s/\\begin\{((no)?preview)\}/\\START\{$1\}/gmsx;
+$bodydoc =~ s/\\end\{((no)?preview)\}/\\STOP\{$1\}/gmsx;
+
+### We restore the changes of all environments in body
+my @lineas = split /\n/, $bodydoc;
+my $NEWDEL;
for (@lineas) {
- if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- s/($find)/$replace{$1}/g; }
-} # close for
-
-### Join lines in $preamble
-$preamble = join("\n", @lineas);
-
-### Change back betwen \begin{preview} ... \end{preview}
-@lineas = split /\n/, $bodydoc;
-
-for (@lineas) {
- if (/\\begin\{(preview)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) { # range operator
- s/($find)/$replace{$1}/g; }
- if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
- s/($find)/$replace{$1}/g; }
-} # close for
-
-### Join lines in $bodydoc
-$bodydoc = join("\n", @lineas);
+ %replace = (%changes_out);
+ $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
+ if (/\\START\{((no)?preview)(?{ $NEWDEL = "\Q$^N" })\}/ .. /\\STOP\{$NEWDEL\}/) {
+ s/($find)/$replace{$1}/msgx;
+ }
+ if (/\%<\*($dtxverb)(?{ $NEWDEL = "\Q$^N" })>/ .. /\%<\/$NEWDEL>/) {
+ s/($find)/$replace{$1}/msgx;
+ }
+}
+$bodydoc = join "\n", @lineas;
-### preview environment for extract
-my $BP = '\\\\begin\{preview\}';
-my $EP = '\\\\end\{preview\}';
+### We restore the changes of all environments in preamble
+while ($preamble =~ /\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/pgmsx) {
+ %cambios = (%changes_out);
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ while (my($busco, $cambio) = each %cambios) {
+ $encontrado =~ s/\Q$busco\E/$cambio/msxg;
+ }
+ substr $preamble, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($preamble) = $pos_inicial + length $encontrado;
+}
-my @env_extract = $bodydoc =~ m/(?<=$BP)(.+?)(?=$EP)/gms;
-my $envNo = scalar @env_extract;
+### Set wraped environments for extraction
+my $wrapping = "$scriptname$tmp";
+Log("Set up the environment [$wrapping] to encapsulate the extraction");
-### PSTexample environment for extract
+### Set vars for match/regex
+my $BP = "\\\\begin\{$wrapping\}";
+my $EP = "\\\\end\{$wrapping\}";
my $BE = '\\\\begin\{PSTexample\}';
my $EE = '\\\\end\{PSTexample\}';
-my @exa_extract = $bodydoc =~ m/(?<=$BE)(.+?)(?=$EE)/gms;
-my $exaNo = scalar @exa_extract;
+### Wrap environments for extraction
+Log("Pass all captured environments to \\begin{$wrapping} ... \\end{$wrapping}");
+$bodydoc =~ s/\\START\{preview\}
+ (?<code>.+? )
+ \\STOP\{preview\}
+ /\\begin\{$wrapping\}$+{code}\\end\{$wrapping\}/gmsx;
-### Check if PSTexample environment found, 1 = run script
-if ($exaNo!=0) { $PSTexa = 1; }
+$bodydoc =~ s/\\START\{nopreview\}
+ (?<code>.+? )
+ \\STOP\{nopreview\}
+ /\\begin\{nopreview\}\%$tmp$+{code}\\end\{nopreview\}\%$tmp/gmsx;
-### Check if standart environment found, , 1 = run script
-if ($envNo!=0) { $STDenv=1; }
+### We put back ltximg tags :)
+$bodydoc =~ s/($ltxtags)/$reverse_tag{$1}/gmsx;
+$preamble =~ s/($ltxtags)/$reverse_tag{$1}/gmsx;
-### PSTexample environment suport
-if ($PSTexa) { # append [graphic={[...]...}]
-$exaNo = 1;
-while ($bodydoc =~ /\\begin\{PSTexample\}(\[.+?\])?/gsm) {
- my $swpl_grap = "graphic=\{\[scale=1\]$imageDir/$name-$prefix-exa";
- my $corchetes = $1;
- my ($pos_inicial, $pos_final) = ($-[1], $+[1]);
+### First search PSTexample environments for extract
+my @exa_extract = $bodydoc =~ m/(?:\\begin\{$wrapping\})($BE.+?$EE)(?:\\end\{$wrapping\})/gmsx;
+my $exaNo = scalar @exa_extract;
+
+### Set vars for log and print in terminal
+my $envEXA = $exaNo > 1 ? 'PSTexample environments' : 'PSTexample environment';
+my $fileEXA = $exaNo > 1 ? 'files' : 'file';
+
+### Check if PSTexample environment found
+if ($exaNo!=0) {
+ $PSTexa = 1;
+ Log("Found $exaNo $envEXA in $name$ext");
+ my $figNo = 1;
+ for my $item (@exa_extract) {
+ Logline("%##### PSTexample environment captured number $figNo ######%");
+ Logline($item);
+ $figNo++;
+ }
+ # Add [graphic={[...]...}] to \begin{PSTexample}[...]
+ Log('Append [graphic={[...]...}] to \begin{PSTexample}[...]');
+ $figNo = 1;
+ while ($bodydoc =~ /\\begin\{$wrapping\}(\s*)?\\begin\{PSTexample\}(\[.+?\])?/gsm) {
+ my $swpl_grap = "graphic=\{\[scale=1\]$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa";
+ my $corchetes = $1;
+ my ($pos_inicial, $pos_final) = ($-[1], $+[1]);
if (not $corchetes) { $pos_inicial = $pos_final = $+[0]; }
if (not $corchetes or $corchetes =~ /\[\s*\]/) {
- $corchetes = "[$swpl_grap-$exaNo}]";
+ $corchetes = "[$swpl_grap-$figNo}]";
}
- else { $corchetes =~ s/\]/,$swpl_grap-$exaNo}]/; }
- substr($bodydoc, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
- pos($bodydoc) = $pos_inicial + length $corchetes;
-} # close while
-continue { $exaNo++; } # increment counter
-
-### Pass PSTexample to nopreview environment
-$bodydoc =~ s/\%<\*ltximgverw>\n
- (?<code>
- \\begin\{PSTexample\} .+? \\end\{PSTexample\}
- )
- \n\%<\/ltximgverw>
- /\\begin\{nopreview\}\n$+{code}\n\\end\{nopreview\}/gmsx;
-} # close PSTexa
-
-### Command line script identification
-print "$program $nv $copyright" ;
-
-### 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";
- }
-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"; }
-
-### Set output file name from input file
-if (exists $opts_file{options}{output}){
- $output = $opts_file{options}{output};
+ else { $corchetes =~ s/\]/,$swpl_grap-$figNo}]/; }
+ substr($bodydoc, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
+ pos($bodydoc) = $pos_inicial + length $corchetes;
+ }
+ continue { $figNo++; }
+ Log('Pass PSTexample environments to \begin{nopreview} ... \end{nopreview}');
+ $bodydoc =~ s/\\begin\{$wrapping\}
+ (?<code>\\begin\{PSTexample\} .+? \\end\{PSTexample\})
+ \\end\{$wrapping\}
+ /\\begin\{nopreview\}\%$tmp$+{code}\\end\{nopreview\}\%$tmp/gmsx;
}
-### 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";
+### Second search standart environments for extract
+my @env_extract = $bodydoc =~ m/(?<=$BP)(.+?)(?=$EP)/gms;
+my $envNo = scalar @env_extract;
+
+### Set vars for log and print in terminal
+my $envSTD = $envNo > 1 ? 'standard environments' : 'standard environment';
+my $fileSTD = $envNo > 1 ? 'files' : 'file';
+
+### If any standard environments found
+if ($envNo!=0) {
+ $STDenv = 1;
+ Log("Found $envNo $envSTD in $name$ext");
+ my $figNo = 1;
+ for my $item (@env_extract) {
+ Logline("%##### Standard environment captured number $figNo ######%");
+ Logline($item);
+ $figNo++;
+ }
}
-# The name of the output file must be different that $name
-if ($output eq "$name") { $output = "$name-out$ext"; }
-# The name of the output file must be different that $name.ext
-if ($output eq "$name$ext") { $output = "$name-out$ext"; }
+### Run script process only if any enviroment found in <input file>
+if ($envNo == 0 and $exaNo == 0) {
+ errorUsage("$scriptname can not find any environment to extract in $name$ext");
+}
-# Remove .ltx or .tex extension
-if ($output =~ /.*?$ext/) { $output =~ s/(.+?)$ext/$1/gms;}
-} # close check
+### Set directory to save generated files, need full path for goog log :)
+my $imgdirpath = File::Spec->rel2abs($opts_cmd{string}{imgdir});
-### If output name are ok, then $outfile = 1
-if (defined($output)) { $outfile = 1; }
+if (-e $opts_cmd{string}{imgdir}) {
+ Infoline("The generated files will be saved in $imgdirpath");
+}
+else {
+ Infoline("Creating the directory $imgdirpath to save the generated files");
+ Infocolor('Running', "mkdir $imgdirpath");
+ Logline("[perl] mkdir($opts_cmd{string}{imgdir},0744)");
+ mkdir $opts_cmd{string}{imgdir},0744 or errorUsage("Can't create the directory $opts_cmd{string}{imgdir}");
+}
-### If --srcenv or --subenv option are OK then execute script
-if ($srcenv) { $outsrc = 1; $subenv = 0; }
-if ($subenv) { $outsrc = 1; $srcenv = 0; }
+### Set compiler
+my $compiler = $opts_cmd{compiler}{xetex} ? 'xelatex'
+ : $opts_cmd{compiler}{luatex} ? 'lualatex'
+ : $opts_cmd{compiler}{latex} ? 'latex'
+ : $opts_cmd{compiler}{dvips} ? 'latex'
+ : $opts_cmd{compiler}{dvilua} ? 'dvilualatex'
+ : $opts_cmd{compiler}{dvipdf} ? 'latex'
+ : $opts_cmd{compiler}{arara} ? 'arara'
+ : 'pdflatex'
+ ;
-### Set imgdir name from input file
-if (exists $opts_file{options}{imgdir}) {
- $imageDir = $opts_file{options}{imgdir};
+if (!$opts_cmd{boolean}{norun}) {
+ if ($compiler eq 'arara') {
+ Log("The file will be processed using $compiler, no ducks will be harmed in this process");
+ }
+ else { Log("The file will be processed using $compiler"); }
}
-### Set prefix name from input file
-if (exists $opts_file{options}{prefix}) {
- $prefix = $opts_file{options}{prefix};
+### Set option for pdfcrop (last version of pdfcrop https://github.com/ho-tex/pdfcrop)
+my $opt_crop = $opts_cmd{compiler}{xetex} ? "--xetex --margins $opts_cmd{string}{margin}"
+ : $opts_cmd{compiler}{luatex} ? "--luatex --margins $opts_cmd{string}{margin}"
+ : $opts_cmd{compiler}{latex} ? "--margins $opts_cmd{string}{margin}"
+ : "--pdftex --margins $opts_cmd{string}{margin}"
+ ;
+
+### Set options for preview packpage
+my $opt_prew = $opts_cmd{compiler}{xetex} ? 'xetex,'
+ : $opts_cmd{compiler}{latex} ? q{}
+ : $opts_cmd{compiler}{dvipdf} ? q{}
+ : $opts_cmd{compiler}{dvips} ? q{}
+ : $opts_cmd{compiler}{dvilua} ? q{}
+ : 'pdftex,'
+ ;
+
+########################################################################
+# One problem with using arara is that we don't know what the file is #
+# really compiled with, this affects [preview] and [pdfcrop]. #
+########################################################################
+
+### Try to capture arara:compiler in preamble of <input file>
+my @arara_engines = qw (latex pdflatex lualatex xelatex luahbtex);
+my $arara_engines = join q{|}, map { quotemeta} sort { length $a <=> length $b } @arara_engines;
+$arara_engines = qr/\b(?:$arara_engines)/x;
+my $arara_rule = qr /^(?:\%\s{1}arara[:]\s{1}) ($arara_engines) /msx;
+
+### Set options for [compiler], [preview] and [pdfcrop]
+if ($compiler eq 'arara') {
+ Log('Trying to detect some suported [engine] in the rules of arara');
+ my @engine = $atbegindoc =~ m/$arara_rule/msx;
+ my %engine = map { $_ => 1 } @engine; # anon hash
+ if (exists $engine{latex}) {
+ Log('The [latex] engine was found in arara rule');
+ # Set options for [preview] and [pdfcrop]
+ $opt_crop = "--margins $opts_cmd{string}{margin}";
+ $opt_prew = q{};
+ }
+ elsif (exists $engine{lualatex} or exists $engine{luahbtex}) {
+ Log('The [lualatex] engine was found in arara rule');
+ # Set options for [preview] and [pdfcrop]
+ $opt_crop = "--luatex --margins $opts_cmd{string}{margin}";
+ $opt_prew = 'pdftex,';
+ }
+ elsif (exists $engine{xelatex}) {
+ Log('The [xelatex] engine was found in arara rule');
+ # Set options for [preview] and [pdfcrop]
+ $opt_crop = "--xetex --margins $opts_cmd{string}{margin}";
+ $opt_prew = 'xetex,';
+ }
+ elsif (exists($engine{pdflatex})) {
+ Log('The [pdflatex] engine was found in arara rule');
+ # Set options for [preview] and [pdfcrop]
+ $opt_crop = "--pdftex --margins $opts_cmd{string}{margin}";
+ $opt_prew = 'pdftex,';
+ }
+ else {
+ Log('No supported [engine] could be detected, default values will be used');
+ # Set options for [preview] and [pdfcrop]
+ $opt_crop = "--pdftex --margins $opts_cmd{string}{margin}";
+ $opt_prew = 'pdftex,';
+ }
}
-### Set pdfcrop margins from input file
-if (exists $opts_file{options}{margins}) {
- $margins = $opts_file{options}{margins};
+### Message in command line for compiler
+my $msg_compiler = $opts_cmd{compiler}{xetex} ? 'xelatex'
+ : $opts_cmd{compiler}{luatex} ? 'lualatex'
+ : $opts_cmd{compiler}{latex} ? 'latex>dvips>ps2pdf'
+ : $opts_cmd{compiler}{dvips} ? 'latex>dvips>ps2pdf'
+ : $opts_cmd{compiler}{dvilua} ? 'dvilualatex>dvips>ps2pdf'
+ : $opts_cmd{compiler}{dvipdf} ? 'latex>dvipdfmx'
+ : $opts_cmd{compiler}{arara} ? 'arara'
+ : 'pdflatex'
+ ;
+
+### Set write18 for compiler
+if ($opts_cmd{boolean}{shell}) {
+ $write18 = '-shell-escape';
+ $write18 = '--enable-write18' if defined $ENV{'TEXSYSTEM'} and $ENV{'TEXSYSTEM'} =~ /miktex/i;
+}
+else {
+ $write18 = '-no-shell-escape';
+ $write18 = '--disable-write18' if defined $ENV{'TEXSYSTEM'} and $ENV{'TEXSYSTEM'} =~ /miktex/i;
}
-### Set DPI resolution for images from input file
-if (exists $opts_file{options}{dpi}) {
- $DPI = $opts_file{options}{dpi};
+### Set options for compiler
+my $opt_compiler = $opts_cmd{compiler}{arara} ? '--log'
+ : "$write18 -interaction=nonstopmode -recorder"
+ ;
+
+if (!$opts_cmd{boolean}{norun}) {
+ Log("The options '$opt_compiler' will be passed to [$compiler]");
}
-### Create /images dir to save image and source code
--e $imageDir or mkdir($imageDir,0744) or die "Can't create $imageDir: $!\n";
+### Set -q for system command line (gs, poppler-utils, dvips, dvipdfmx)
+my $quiet = $verbose ? q{}
+ : '-q'
+ ;
-### Options for \pagestyle{empty} ($crop)
-my $opt_page = $crop ? "\n\\pagestyle\{empty\}\n\\begin\{document\}"
- : "\n\\begin\{document\}"
- ;
+### Set options for ghostscript in command line
+my %opt_gs_dev = (
+ pdf => '-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite',
+ gray => '-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -sProcessColorModel=DeviceGray',
+ png => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -r$opts_cmd{string}{dpi}",
+ bmp => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=bmp32b -r$opts_cmd{string}{dpi}",
+ jpg => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=jpeg -r$opts_cmd{string}{dpi} -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4",
+ tif => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=tiff32nc -r$opts_cmd{string}{dpi}",
+ );
-### Add options to preamble for subfiles
-my $sub_prea = "$atbegindoc$preamble$opt_page";
+### Set executable from poppler-utils
+my %cmd_poppler = (
+ eps => "pdftops",
+ ppm => "pdftoppm",
+ svg => "pdftocairo",
+ );
-### Delete <*remove> ... </remove> in $sub_prea
-$sub_prea =~ s/^\%<\*remove>\s*(.+?)\s*\%<\/remove>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+### Set options for poppler-utils
+my %opt_poppler = (
+ eps => "$quiet -eps",
+ ppm => "$quiet -r $opts_cmd{string}{dpi}",
+ svg => "$quiet -svg",
+ );
-### Options for preview packpage
-my $opt_prew = $xetex ? 'xetex,'
- : $latex ? ''
- : 'pdftex,'
- ;
+### Copy preamble and body for temp file with all environments
+my $atbeginout = $atbegindoc;
+my $preamout = $preamble;
+my $tmpbodydoc = $bodydoc;
+
+### Match \pagestyle and \thispagestyle in preamble
+my $style_page = qr /(?:\\)(?:this)?(?:pagestyle\{) (.+?) (?:\})/x;
+my @style_page = $preamout =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)| $style_page/gmsx;
+my %style_page = map { $_ => 1 } @style_page; # anon hash
+
+### Seting \pagestyle{empty} for subfiles and process
+if (@style_page) {
+ if (!exists $style_page{empty}) {
+ Log("Replacing page style for generated files");
+ $preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ (\\(this)?pagestyle)(?:\{.+?\})/$1\{empty\}/gmsx;
+ }
+}
+else {
+ Log('Add \pagestyle{empty} for generated files');
+ $preamout = $preamout."\\pagestyle\{empty\}\n";
+}
+
+#### Remove wraped postscript environments provide by pst-pdf, auto-pst-pdf, auto-pst-pdf-lua pkgs
+Log("Convert postscript environments to \\begin\{$wrapping\} ... \\end\{$wrapping\} for standalone files");
+$tmpbodydoc =~ s/(?:$BP)(?:\\begin\{postscript\})(?:\s*\[ [^]]*? \])?
+ (?<code>.+?)
+ (?:\\end\{postscript\})
+ (?:$EP)
+ /\\begin\{$wrapping\}$+{code}\\end\{$wrapping\}/gmsx;
+
+### We created a preamble for standalone files
+my $sub_prea = "$atbeginout$preamout".'\begin{document}';
+
+### Revert changes
+$sub_prea =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
+%replace = (%changes_out);
+$find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
+$sub_prea =~ s/($find)/$replace{$1}/g;
+$sub_prea =~ s/(remove$tmp)/remove/g;
+
+### Write standalone files for environments
+if ($outsrc) {
+ my $src_name = "$name-$opts_cmd{string}{prefix}-";
+ my $srcNo = 1;
+ if ($opts_cmd{boolean}{srcenv}) {
+ Log('Extract source code of all captured environments without preamble');
+ if ($STDenv) {
+ if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-1$ext") {
+ Log("Recreating $envNo $fileSTD [$ext] with source code for $envSTD in $imgdirpath");
+ print "Recreating $envNo $fileSTD ", color('magenta'), "[$ext]",
+ color('reset'), " with source code for $envSTD\r\n";
+ }
+ else {
+ Log("Creating $envNo $fileSTD [$ext] with source code for $envSTD in $imgdirpath");
+ print "Creating $envNo $fileSTD ", color('magenta'), "[$ext]",
+ color('reset'), " with source code for $envSTD\r\n";
+ }
+ # Write files
+ while ($tmpbodydoc =~ m/$BP\s*(?<env_src>.+?)\s*$EP/gms) {
+ open my $outexasrc, '>', "$opts_cmd{string}{imgdir}/$src_name$srcNo$ext";
+ print {$outexasrc} $+{'env_src'};
+ close $outexasrc;
+ }
+ continue { $srcNo++; }
+ }
+ if ($PSTexa) {
+ if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-1$ext") {
+ Log("Recreating $exaNo $fileEXA [$ext] with source code for $envEXA in $imgdirpath");
+ print "Recreating $exaNo $fileEXA ", color('magenta'), "[$ext]",
+ color('reset'), " with source code for $envEXA\r\n";
+ }
+ else {
+ Log("Creating $exaNo $fileEXA [$ext] with source code for $envEXA in $imgdirpath");
+ print "Creating $exaNo $fileEXA ", color('magenta'), "[$ext]",
+ color('reset'), " with source code for $envEXA\r\n";
+ }
+ # Write files
+ while ($tmpbodydoc =~ m/$BE\[.+?(?<pst_exa_name>$opts_cmd{string}{imgdir}\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
+ open my $outstdsrc, '>', "$+{'pst_exa_name'}$ext";
+ print {$outstdsrc} $+{'exa_src'};
+ close $outstdsrc;
+ }
+ }
+ }
+ if ($opts_cmd{boolean}{subenv}) {
+ Log('Extract source code of all captured environments with preamble');
+ if ($STDenv) {
+ if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-1$ext") {
+ Log("Recreating a $envNo standalone $fileSTD [$ext] for $envSTD in $imgdirpath");
+ print "Recreating a $envNo standalone $fileSTD ", color('magenta'), "[$ext]",
+ color('reset'), " for $envSTD\r\n";
+ }
+ else {
+ Log("Creating a $envNo standalone $fileSTD [$ext] for $envSTD in $imgdirpath");
+ print "Creating a $envNo standalone $fileSTD ", color('magenta'), "[$ext]",
+ color('reset'), " for $envSTD\r\n";
+ }
+ # Write files
+ while ($tmpbodydoc =~ m/$BP(?:\s*)?(?<env_src>.+?)(?:\s*)?$EP/gms) {
+ open my $outstdfile, '>', "$opts_cmd{string}{imgdir}/$src_name$srcNo$ext";
+ print {$outstdfile} "$sub_prea\n$+{'env_src'}\n\\end\{document\}";
+ close $outstdfile;
+ }
+ continue { $srcNo++; }
+ }
+ if ($PSTexa) {
+ if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-1$ext") {
+ Log("Recreating a $exaNo standalone $fileEXA [$ext] for $envEXA in $imgdirpath");
+ print "Recreating a $exaNo standalone $fileEXA ", color('magenta'), "[$ext]",
+ color('reset'), " for $envEXA\r\n";
+ }
+ else {
+ Log("Creating a $exaNo standalone $fileEXA [$ext] for $envEXA in $imgdirpath");
+ print "Creating a $exaNo standalone $fileEXA ", color('magenta'), "[$ext]",
+ color('reset'), " for $envEXA\r\n";
+ }
+ # Write files
+ while ($tmpbodydoc =~ m/$BE\[.+?(?<pst_exa_name>$opts_cmd{string}{imgdir}\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
+ open my $outexafile, '>', "$+{'pst_exa_name'}$ext";
+ print {$outexafile} "$sub_prea\n$+{'exa_src'}\n\\end\{document\}";
+ close $outexafile;
+ }
+ }
+ }
+}
-### Lines to add at begin input file
-my $preview = <<"EXTRA";
+### Store options for preview and pst-pdf (add at begin document)
+my $previewpkg = <<"EXTRA";
+\\PassOptionsToPackage\{inactive\}\{pst-pdf\}%
\\AtBeginDocument\{%
+\\RequirePackage\[inactive\]\{pst-pdf\}%
\\RequirePackage\[${opt_prew}active,tightpage\]\{preview\}%
\\renewcommand\\PreviewBbAdjust\{-60pt -60pt 60pt 60pt\}\}%
EXTRA
-### Extract source $outsrc
-if ($outsrc) {
-my $src_name = "$name-$prefix-";
-my $srcNo = 1;
-
-### Source file whitout preamble for standart environment
-if ($srcenv) {
-if ($STDenv) { # extract standard environments in individual files
- say "Creating $envNo files with source code for all environments";
- while ($bodydoc =~ 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++; } # increment counter
-} # close STDenv
-if ($PSTexa) { # extract PSTexample environments in individual files
- say "Creating $exaNo files with source code for all PSTexample environments";
- while ($bodydoc =~ 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) {
-if ($STDenv) { # extract standard environments (with preamble) in individual files
-say "Creating a $envNo files whit source code and preamble for all environments";
-while ($bodydoc =~ m/(?<=$BP)(?<env_src>.+?)(?=$EP)/gms) { # search $bodydoc
-open my $OUTsub, '>', "$imageDir/$src_name$srcNo$ext";
-print $OUTsub <<"EOC";
-$sub_prea$+{'env_src'}\\end\{document\}
-EOC
-close $OUTsub;
- } # close while
-continue { $srcNo++; }
-} # close STDenv
-if ($PSTexa) { # extract PSTexample environments (with preamble) in individual files
-say "Creating a $exaNo files whit source code and preamble for all PSTexample environments";
-while ($bodydoc =~ 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
+### Store options for pst-pdf (add at begin document)
+my $pstpdfpkg = <<'EXTRA';
+\PassOptionsToPackage{inactive}{pst-pdf}
+\AtBeginDocument{%
+\RequirePackage[inactive]{pst-pdf}}%
+EXTRA
-### Create a one file with "all" PSTexample environments extracted
-if ($PSTexa) {
-say "Creating the temporary file $name-$prefix-exa-$tmp$ext whit $exaNo PSTexample environments extracted";
-@exa_extract = undef;
- while ( $bodydoc =~ m/$BE\[.+? $imageDir\/.+?-\d+\}\](?<exa_src>.+?)$EE/gmsx ) { # search $bodydoc
- push @exa_extract, $+{exa_src}."\n\\newpage\n";
- open my $OUTfig, '>', "$name-$prefix-exa-$tmp$ext";
- print $OUTfig "$atbegindoc"."$preamble"."$opt_page"."@exa_extract\n"."\\end\{document\}";
- close $OUTfig;
- }# close while
-if (!$run) { # Move and rename tmp-exa-rand file to /image dir
-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");
- }
-}# close $PSTexa
-
-### Create a one file whit "all" standard environments extracted
-if ($STDenv) {
-open my $OUTfig, '>', "$name-$prefix-$tmp$ext";
- if ($noprew) { # $noprew option
- say "Creating the temporary file $name-$prefix-$tmp$ext whit $envNo environments extracted";
- my @env_extract;
- while ( $bodydoc =~ m/(?<=$BP)(?<env_src>.+?)(?=$EP)/gms ) { # search $bodydoc
- push @env_extract, $+{env_src}."\n\\newpage\n";
- } # close while
- print $OUTfig "$atbegindoc"."$preamble"."$opt_page"."@env_extract\n"."\\end{document}";
- } # close $noprew
- else { # default
- say "Creating the temporary file $name-$prefix-$tmp$ext whit $envNo environment extracted using preview package";
- print $OUTfig $atbegindoc.$preview.$preamble."\n".$bodydoc."\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");
- }
-} # 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"
- ;
+### First match preview package in preamble (prevent option clash)
+my $REQPACK = quotemeta'\RequirePackage';
+my $USEPACK = quotemeta'\usepackage';
+my $CORCHETES = qr/\[ [^]]*? \]/x;
-### Define $silence
-my $silence = $verbose ? ''
- : ">$null"
- ;
+my $PALABRAS = qr/\b (?: preview )/x;
+my $FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
-### Append -q to gs and poppler for system command line
-my $quiet = $verbose ? ''
- : '-q'
+Log('Remove preview package (if found) in preamble [memory]');
+$preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
+$preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
+$preamout =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
+
+### Remove %<*$dtxverb> ... %</$dtxverb> in tmpbodydoc and preamout
+$tmpbodydoc =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
+$preamout =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
+
+### Adjust nopreview environments
+$tmpbodydoc =~ s/\\begin\{nopreview\}\%$tmp
+ (?<code> .+?)
+ \\end\{nopreview\}\%$tmp
+ /\\begin\{nopreview\}\n$+{code}\n\\end\{nopreview\}\n/gmsx;
+
+### Adjust $wrapping environments (need \n after close for some environments, like a Verbatim)
+$tmpbodydoc =~ s/\\begin\{$wrapping\}
+ (?<code>.+?)
+ \\end\{$wrapping\}
+ /\\begin\{$wrapping\}\n$+{code}\n\\end\{$wrapping\}/gmsx;
+
+### Reverse changes for temporary file with all env (no in -exa file)
+$tmpbodydoc =~ s/($find)/$replace{$1}/g;
+$tmpbodydoc =~ s/(\%$tmp)//g;
+$tmpbodydoc =~ s/(remove$tmp)/remove/g;
+$preamout =~ s/($find)/$replace{$1}/g;
+$atbeginout =~ s/(remove$tmp)/remove/g;
+$atbeginout =~ s/($find)/$replace{$1}/g;
+
+### We created a preamble for individual files with all environments
+$sub_prea = $opts_cmd{boolean}{noprew} ? "$atbeginout$pstpdfpkg$preamout".'\begin{document}'
+ : "$atbeginout$previewpkg$preamout"
;
-### 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",
- );
-
-### 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 (/(?<name>$name-$prefix(-exa)?)(?<type>-$tmp$ext)/) {
- system("$compiler $+{name}$+{type} $silence");
- say "Compiling the file $+{name}$+{type} using $msg_compiler";
-
-### Compiling file using latex>dvips>ps2pdf
-if ($dvips or $latex) {
- system("dvips -q -Ppdf -o $+{name}-$tmp.ps $+{name}-$tmp.dvi");
- system("ps2pdf -dPDFSETTINGS=/prepress -dAutoRotatePages=/None $+{name}-$tmp.ps $+{name}-$tmp.pdf");
-} # close latex
-
-### Compiling file using latex>dvipdfmx
-if ($dvipdf) { system("dvipdfmx -q $+{name}-$tmp.dvi"); }
-
-### If option gray
-if ($gray) {
- say "Moving the file $+{name}-$tmp.pdf to $tempDir/$+{name}-all.pdf (gray scale)";
- system("$opt_gs_dev{gray} -o $tempDir/$+{name}-all.pdf $workdir/$+{name}-$tmp.pdf");
- move("$workdir/$+{name}-$tmp.pdf","$tempDir/$+{name}-$tmp.pdf");
- }
-else {
- say "Moving the file $+{name}-$tmp.pdf to $tempDir/$+{name}-all.pdf";
- move("$workdir/$+{name}-$tmp.pdf", "$tempDir/$+{name}-all.pdf");
+### Create a one file with "all" PSTexample environments extracted
+if ($PSTexa) {
+ @exa_extract = undef;
+ Log("Adding packages to $name-$opts_cmd{string}{prefix}-exa-$tmp$ext");
+ Logline($pstpdfpkg);
+ Log('Convert plain Tex syntax for pspicture and psgraph to LaTeX syntax in PSTexample environments');
+ while ($tmpbodydoc =~ m/$BE\[.+? $opts_cmd{string}{imgdir}\/.+?-\d+\}\] .+?$EE/pgsmx ) { # search
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ $encontrado =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin\{pspicture$1\}$2\\end\{pspicture$1\}/gmsx;
+ $encontrado =~ s/\\psgraph(\*)?(.+?)\\endpsgraph/\\begin\{psgraph$1\}$2\\end\{psgraph$1\}/gmsx;
+ substr $tmpbodydoc, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($tmpbodydoc) = $pos_inicial + length $encontrado;
+ }
+ # Write files
+ Infoline("Creating $name-$opts_cmd{string}{prefix}-exa-$tmp$ext with $exaNo $envEXA extracted");
+ while ($tmpbodydoc =~ m/$BE\[.+? $opts_cmd{string}{imgdir}\/.+?-\d+\}\](?<exa_src>.+?)$EE/gmsx ) { # search
+ push @exa_extract, $+{'exa_src'}."\\newpage\n";
+ open my $allexaenv, '>', "$name-$opts_cmd{string}{prefix}-exa-$tmp$ext";
+ print {$allexaenv} "$atbeginout$pstpdfpkg$preamout".'\begin{document}'."@exa_extract"."\\end\{document\}";
+ close $allexaenv;
+ }
+ # Remove [graphic={...}] in PSTexample example environments
+ $tmpbodydoc =~ s/($BE)(?:\[graphic=\{\[scale=1\]$opts_cmd{string}{imgdir}\/.+?-\d+\}\])/$1/gmsx;
+ $tmpbodydoc =~ s/($BE\[.+?)(?:,graphic=\{\[scale=1\]$opts_cmd{string}{imgdir}\/.+?-\d+\})(\])/$1$2/gmsx;
+ # Moving and renaming
+ if ($opts_cmd{boolean}{norun}) {
+ Infoline("Moving and renaming $name-$opts_cmd{string}{prefix}-exa-$tmp$ext to $name-$opts_cmd{string}{prefix}-exa-all$ext");
+ if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext") {
+ Infocolor('Warning', "The file [$name-$opts_cmd{string}{prefix}-exa-all$ext] already exists and will be rewritten");
+ Log("Rewriting the file $name-$opts_cmd{string}{prefix}-exa-all$ext in $imgdirpath");
+ }
+ else {
+ Log("Writing the file $name-$opts_cmd{string}{prefix}-exa-all$ext in $imgdirpath");
+ }
+ if ($verbose) {
+ Infocolor('Running', "mv $workdir/$name-$opts_cmd{string}{prefix}-exa-$tmp$ext $imgdirpath/$name-$opts_cmd{string}{prefix}-exa-all$ext");
+ }
+ else {
+ Infocolor('Running', "mv $name-$opts_cmd{string}{prefix}-exa-$tmp$ext ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext");
+ }
+ Logline("[perl] move($workdir/$name-$opts_cmd{string}{prefix}-exa-$tmp$ext, $imgdirpath/$name-$opts_cmd{string}{prefix}-exa-all$ext)");
+ move("$workdir/$name-$opts_cmd{string}{prefix}-exa-$tmp$ext", "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext")
+ or die "* Error!!: Couldn't be renamed $name-$opts_cmd{string}{prefix}-exa-$tmp$ext to ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext";
+ }
}
-### Crop generate file
-if ($crop) {
- say "The file $+{name}-all.pdf need a crop, using pdfcrop $opt_crop";
- system("pdfcrop $opt_crop $tempDir/$+{name}-all.pdf $tempDir/$+{name}-all.pdf $silence");
+### Create a one file with "all" standard environments extracted
+if ($STDenv) {
+ if ($opts_cmd{boolean}{noprew}) {
+ Log("Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted [no preview]");
+ print "Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted",
+ color('magenta'), " [no preview]\r\n",color('reset');
+ }
+ else {
+ Log("Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted [preview]");
+ print "Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted",
+ color('magenta'), " [preview]\r\n",color('reset');
+ }
+ open my $allstdenv, '>', "$name-$opts_cmd{string}{prefix}-$tmp$ext";
+ if ($opts_cmd{boolean}{noprew}) {
+ my @env_extract;
+ while ($tmpbodydoc =~ m/(?:$BP)(?<env_src>.+?)(?:$EP)/gms) {
+ push @env_extract, $+{'env_src'}."\\newpage\n";
+ }
+ Log("Adding packages to $name-$opts_cmd{string}{prefix}-$tmp$ext");
+ Logline($pstpdfpkg);
+ print {$allstdenv} $sub_prea."@env_extract"."\\end{document}";
+ }
+ else {
+ Log("Adding packages to $name-$opts_cmd{string}{prefix}-$tmp$ext");
+ Logline($previewpkg);
+ Log("Convert $wrapping to preview environments in $name-$opts_cmd{string}{prefix}-$tmp$ext");
+ # Convert $wrapping to preview environments
+ $tmpbodydoc =~ s/\\begin\{$wrapping\}(?<code>.+?)\\end\{$wrapping\}
+ /\\begin\{preview\}$+{code}\\end\{preview\}\n/gmsx;
+ print {$allstdenv} $sub_prea.$tmpbodydoc."\n\\end{document}";
+ }
+ close $allstdenv;
+ if ($opts_cmd{boolean}{norun}) {
+ # Moving and renaming
+ Infoline("Moving and renaming $name-$opts_cmd{string}{prefix}-$tmp$ext to $name-$opts_cmd{string}{prefix}-all$ext");
+ if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext") {
+ Infocolor('Warning', "The file [$name-$opts_cmd{string}{prefix}-all$ext] already exists and will be rewritten");
+ Log("Rewriting the file $name-$opts_cmd{string}{prefix}-all$ext in $imgdirpath");
+ }
+ else {
+ Log("Writing the file $name-$opts_cmd{string}{prefix}-all$ext in $imgdirpath");
+ }
+ if ($verbose) {
+ Infocolor('Running', "mv $workdir/$name-$opts_cmd{string}{prefix}-$tmp$ext $imgdirpath/$name-$opts_cmd{string}{prefix}-all$ext");
+ }
+ else {
+ Infocolor('Running', "mv $name-$opts_cmd{string}{prefix}-$tmp$ext ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext");
+ }
+ Logline("[perl] move($workdir/$name-$opts_cmd{string}{prefix}-$tmp$ext, $imgdirpath/$name-$opts_cmd{string}{prefix}-all$ext)");
+ move("$workdir/$name-$opts_cmd{string}{prefix}-$tmp$ext", "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext")
+ or die "* Error!!: Couldn't be renamed $name-$opts_cmd{string}{prefix}-$tmp$ext to ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext";
+ }
}
-### Move tmp-rand.tex file whit all source code for environments to /images dir
-move("$workdir/$+{name}$+{type}", "$imageDir/$+{name}-all$ext");
- } # close if m/.../
- } # close while
+### Compiler and generate PDF files
+if (!$opts_cmd{boolean}{norun}) {
+Log('Generate a PDF file with all captured environments');
+my @compiler = (1..$opts_cmd{string}{runs});
+opendir (my $DIR, $workdir);
+ while (readdir $DIR) {
+ if (/(?<name>$name-$opts_cmd{string}{prefix}(-exa)?)(?<type>-$tmp$ext)/) {
+ Log("Compiling the file $+{name}$+{type} using [$msg_compiler]");
+ print "Compiling the file $+{name}$+{type} using ", color('magenta'), "[$msg_compiler]\r\n",color('reset');
+ for (@compiler){
+ RUNOSCMD("$compiler $opt_compiler","$+{name}$+{type}",'show');
+ }
+ # Compiling file using latex>dvips>ps2pdf
+ if ($compiler eq 'dvips' or $compiler eq 'latex' or $compiler eq 'dvilualatex') {
+ RUNOSCMD("dvips $quiet -Ppdf", "-o $+{name}-$tmp.ps $+{name}-$tmp.dvi",'show');
+ RUNOSCMD("ps2pdf -sPDFSETTINGS=prepress -sAutoRotatePages=None", "$+{name}-$tmp.ps $+{name}-$tmp.pdf",'show');
+ }
+ # Compiling file using latex>dvipdfmx
+ if ($compiler eq 'dvipdf') {
+ RUNOSCMD("dvipdfmx $quiet", "$+{name}-$tmp.dvi",'show');
+ }
+ # Moving and renaming temp files with source code
+ Infoline("Moving and renaming $+{name}$+{type} to $+{name}-all$ext");
+ if (-e "$opts_cmd{string}{imgdir}/$+{name}-all$ext") {
+ Infocolor('Warning', "The file [$+{name}-all$ext] already exists and will be rewritten");
+ Log("Rewriting the file $+{name}-all$ext with all source for environments in $imgdirpath");
+ }
+ else {
+ Log("Writing the file $+{name}-all$ext with all source for environments in $imgdirpath");
+ }
+ if ($verbose){
+ Infocolor('Running', "mv $workdir/$+{name}$+{type} $imgdirpath/$+{name}-all$ext");
+ }
+ else {
+ Infocolor('Running', "mv $+{name}$+{type} ./$opts_cmd{string}{imgdir}/$+{name}-all$ext");
+ }
+ Logline("[perl] move($workdir/$+{name}$+{type}, $imgdirpath/$+{name}-all$ext)");
+ move("$workdir/$+{name}$+{type}", "$opts_cmd{string}{imgdir}/$+{name}-all$ext")
+ or die "* Error!!: Couldn't be renamed $+{name}$+{type} to $opts_cmd{string}{imgdir}/$+{name}-all$ext";
+ # pdfcrop
+ if (!$opts_cmd{boolean}{nocrop}) {
+ Infoline("Cropping the file $+{name}-$tmp.pdf");
+ RUNOSCMD("pdfcrop $opt_crop", "$+{name}-$tmp.pdf $+{name}-$tmp.pdf",'show');
+ }
+ # gray
+ if ($opts_cmd{boolean}{gray}) {
+ Infoline("Creating the file $+{name}-all.pdf [gray] in $tempDir");
+ RUNOSCMD("$gscmd $quiet $opt_gs_dev{gray} ","-o $tempDir/$+{name}-all.pdf $workdir/$+{name}-$tmp.pdf",'show');
+ }
+ else {
+ Infoline("Creating the file $+{name}-all.pdf in $tempDir");
+ if ($verbose){
+ Infocolor('Running', "mv $workdir/$+{name}-$tmp.pdf $tempDir/$+{name}-all.pdf");
+ }
+ else { Infocolor('Running', "mv $+{name}-$tmp.pdf $tempDir/$+{name}-all.pdf"); }
+ # Renaming pdf file
+ Logline("[perl] move($workdir/$+{name}-$tmp.pdf, $tempDir/$+{name}-all.pdf)");
+ move("$workdir/$+{name}-$tmp.pdf", "$tempDir/$+{name}-all.pdf")
+ or die "* Error!!: Couldn't be renamed $+{name}-$tmp.pdf to $tempDir/$+{name}-all.pdf";
+ }
+ }
+ }
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 (/(?<name>$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/$+{name}-%1d.$var $tempDir/$+{name}$+{type}";
- system("$ghostcmd");
- print "Create a $var image format: runing command $opt_gs_dev{$var} in $+{name}$+{type}\r\n";
- } # close defined for ghostscript
- }# close for
-} # close if m/.../
-
-### EPS/PPM/SVG format suported by poppler-utils
-if (/(?<name>$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/$+{name}$+{type} $workdir/$imageDir/$+{name}-$epsNo.$var";
-system("$poppler");
- } # close for C style
-print "Create a $var image format: runing command $opt_poppler{$var} in $+{name}$+{type}\r\n";
- } # close defined
- } # close for my $var
-} # close if m/.../
-
-### EPS/PPM/SVG for pst-exa package
-if (/(?<name>$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/$+{name}$+{type} $workdir/$imageDir/$+{name}-$epsNo.$var";
-system("$poppler");
- } # close for C style
-print "Create a $var image format: runing command $opt_poppler{$var} in $+{name}$+{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);
+if (!$opts_cmd{boolean}{norun}) {
+ Log("Creating the image formats: $format, working on $tempDir");
+ opendir(my $DIR, $tempDir);
while (readdir $DIR) {
- if (/(?<name>$name-fig(-exa)?-\d+\.ppm)(?<sep>-\d+)(?<ppm>\.ppm)/) {
- move("$imageDir/$+{name}$+{sep}$+{ppm}", "$imageDir/$+{name}");
- } # close if m/.../
+ # PDF/PNG/JPG/BMP/TIFF format suported by ghostscript
+ if (/(?<name>$name-$opts_cmd{string}{prefix}(-exa)?)(?<type>-all\.pdf)/) {
+ for my $var (qw(pdf png jpg bmp tif)) {
+ if (defined $opts_cmd{image}{$var}) {
+ Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $gscmd");
+ print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
+ RUNOSCMD("$gscmd $quiet $opt_gs_dev{$var} ", "-o $workdir/$opts_cmd{string}{imgdir}/$+{name}-%1d.$var $tempDir/$+{name}$+{type}",'show');
+ }
+ }
+ }
+ # EPS/PPM/SVG format suported by poppler-utils
+ if (/(?<name>$name-$opts_cmd{string}{prefix}-exa)(?<type>-all\.pdf)/) { # pst-exa package
+ for my $var (qw(eps ppm svg)) {
+ if (defined $opts_cmd{image}{$var}) {
+ Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $cmd_poppler{$var}");
+ print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
+ if (!$verbose){
+ Infocolor('Running', "$cmd_poppler{$var} $opt_poppler{$var}");
+ }
+ for (my $epsNo = 1; $epsNo <= $exaNo; $epsNo++) {
+ RUNOSCMD("$cmd_poppler{$var} $opt_poppler{$var}", "-f $epsNo -l $epsNo $tempDir/$+{name}$+{type} $workdir/$opts_cmd{string}{imgdir}/$+{name}-$epsNo.$var",'only');
+ }
+ }
+ }
+ }
+ if (/(?<name>$name-$opts_cmd{string}{prefix})(?<type>-all\.pdf)/) {
+ for my $var (qw(eps ppm svg)) {
+ if (defined $opts_cmd{image}{$var}) {
+ Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $cmd_poppler{$var}");
+ print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
+ if (!$verbose){
+ Infocolor('Running', "$cmd_poppler{$var} $opt_poppler{$var}");
+ }
+ for (my $epsNo = 1; $epsNo <= $envNo; $epsNo++) {
+ RUNOSCMD("$cmd_poppler{$var} $opt_poppler{$var}", "-f $epsNo -l $epsNo $tempDir/$+{name}$+{type} $workdir/$opts_cmd{string}{imgdir}/$+{name}-$epsNo.$var",'only');
+ }
+ }
+ }
+ }
} # close while
closedir $DIR;
- } # close renaming PPM
+ # Renaming PPM image files
+ if (defined $opts_cmd{image}{ppm}) {
+ Log("Renaming [ppm] images in $imgdirpath");
+ if ($verbose){
+ print 'Renaming', color('blue'), " [ppm] ", color('reset'),"images in $imgdirpath\r\n";
+ }
+ opendir(my $DIR, $opts_cmd{string}{imgdir});
+ while (readdir $DIR) {
+ if (/(?<name>$name-$opts_cmd{string}{prefix}(-exa)?-\d+\.ppm)(?<sep>-\d+)(?<ppm>\.ppm)/) {
+ if ($verbose){
+ Infocolor('Running', "mv $+{name}$+{sep}$+{ppm} $+{name}");
+ }
+ Logline("[perl] move($imgdirpath/$+{name}$+{sep}$+{ppm}, $imgdirpath/$+{name})");
+ move("$opts_cmd{string}{imgdir}/$+{name}$+{sep}$+{ppm}", "$opts_cmd{string}{imgdir}/$+{name}")
+ or die "* Error!!: Couldn't be renamed $+{name}$+{sep}$+{ppm} to $+{name}";
+ }
+ }
+ closedir $DIR;
+ }
} # close run
-### Create a output file
-if ($outfile) {
-say "Creating the file $output$ext, convert extracted environments to \\includegraphics";
-
-### Convert extracted environments to \includegraphics
-my $grap = "\\includegraphics[scale=1]{$name-$prefix-";
-my $close = '}';
-my $imgNo = 1;
-$bodydoc =~ s/$BP.+?$EP/$grap@{[$imgNo++]}$close/msg; # changes
-
### Constant
-my $USEPACK = quotemeta('\usepackage');
-my $GRAPHICPATH = quotemeta('\graphicspath{');
-
-### Precompiled regex
-my $CORCHETES = qr/\[ [^]]*? \]/x;
-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) = $preamble =~ m/$graphix/x;
-
-### Remove graphix package
-$preamble =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
- ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
+my $findgraphicx = 'true';
+
+### pst-exa package
+my $pstexa = qr/(?:\\ usepackage) \[\s*(.+?)\s*\] (?:\{\s*(pst-exa)\s*\} ) /x;
+my @pst_exa;
+my %pst_exa;
+
+### Possible packages that load graphicx
+my @pkgcandidates = qw (
+ rotating epsfig lyluatex xunicode parsa xepersian-hm gregoriotex teixmlslides
+ teixml fotex hvfloat pgfplots grfpaste gmbase hep-paper postage schulealt
+ schule utfsym cachepic abc doclicense rotating epsfig semtrans mgltex
+ graphviz revquantum mpostinl cmpj cmpj2 cmpj3 chemschemex register papercdcase
+ flipbook wallpaper asyprocess draftwatermark rutitlepage dccpaper-base
+ nbwp-manual mandi fmp toptesi isorot pinlabel cmll graphicx-psmin ptmxcomp
+ countriesofeurope iodhbwm-templates fgruler combinedgraphics pax pdfpagediff
+ psfragx epsdice perfectcut upmethodology-fmt ftc-notebook tabvar vtable
+ teubner pas-cv gcard table-fct pdfpages keyfloat pdfscreen showexpl simplecd
+ ifmslide grffile reflectgraphics markdown bclogo tikz-page pst-uml realboxes
+ musikui csbulobalka lwarp mathtools sympytex mpgraphics miniplot.sty:77
+ dottex pdftricks2 feupphdteses tex4ebook axodraw2 hagenberg-thesis dlfltxb
+ hu-berlin-bundle draftfigure quicktype endofproofwd euflag othelloboard
+ pdftricks unswcover breqn pdfswitch latex-make figlatex repltext etsvthor
+ cyber xcookybooky xfrac mercatormap chs-physics-report tikzscale ditaa
+ pst-poker gmp CJKvert asypictureb hletter tikz-network powerdot-fuberlin
+ skeyval gnuplottex plantslabels fancytooltips ieeepes pst-vectorian
+ phfnote overpic xtuformat stubs graphbox ucs pdfwin metalogo mwe
+ inline-images asymptote UNAMThesis authorarchive amscdx pst-pdf adjustbox
+ trimclip fixmetodonotes incgraph scanpages pst-layout alertmessage
+ svg quiz2socrative realhats autopdf egplot decorule figsize tikzexternal
+ pgfcore frontespizio textglos graphicx tikz tcolorbox pst-exa
+ );
-### Comment \graphicspath for order and future use
-$preamble =~s /\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
- ^ ($GRAPHICPATH) /%$1/msxg;
+my $pkgcandidates = join q{|}, map { quotemeta } sort { length $a <=> length $b } @pkgcandidates;
+$pkgcandidates = qr/$pkgcandidates/x;
+my @graphicxpkg;
-### Regex to capture [options] for pst-exa package
-my $pstexa = qr/(?:\\ usepackage) \[\s*(.+?)\s*\] (?:\{\s*(pst-exa)\s*\} ) /x;
+### \graphicspath
+my $graphicspath= qr/\\ graphicspath \{ ((?: $llaves )+) \}/ix;
+my @graphicspath;
-### Capture [option] for pst-exa package
-my (@pst_exa) = $preamble =~ m/$pstexa/xg;
+### Replacing the extracted environments with \\includegraphics
+if ($outfile) {
+ Log("Convert standard extracted environments to \\includegraphics for $opts_cmd{string}{output}$outext");
+ my $grap = "\\includegraphics[scale=1]{$name-$opts_cmd{string}{prefix}-";
+ my $close = '}';
+ my $imgNo = 1;
+ $bodydoc =~ s/$BP.+?$EP/$grap@{[$imgNo++]}$close/msg;
+ $preamble = "$atbegindoc$preamble";
+ my @tag_remove_preamble = $preamble =~ m/(?:^\%<\*remove$tmp>.+?\%<\/remove$tmp>)/gmsx;
+ if (@tag_remove_preamble) {
+ Log("Removing the content between <*remove> ... </remove> tags in preamble for $opts_cmd{string}{output}$outext");
+ $preamble =~ s/^\%<\*remove$tmp>\s*(.+?)\s*\%<\/remove$tmp>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+ }
+ # To be sure that the package is in the main document and not in a
+ # verbatim write environment we make the changes using the hash and
+ # range operator in a copy
+ my %tmpreplace = (
+ 'graphicx' => 'TMPGRAPHICXTMP',
+ 'pst-exa' => 'TMPPSTEXATMP',
+ 'graphicspath' => 'TMPGRAPHICSPATHTMP',
+ );
+ my $findtmp = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %tmpreplace;
+ my $preambletmp = $preamble;
+ my @lineas = split /\n/, $preambletmp;
+ # We remove the commented lines
+ s/\%.*(?:[\t ]*(?:\r?\n|\r))?+//msg foreach @lineas;
+ # We make the changes in the environments verbatim write
+ my $DEL;
+ for (@lineas) {
+ if (/\\begin\{($verbatim_w\*?)(?{ $DEL = "\Q$^N" })\}/ .. /\\end\{$DEL\}/) {
+ s/($findtmp)/$tmpreplace{$1}/g;
+ }
+ }
+ $preambletmp = join "\n", @lineas; # Join lines in $preambletmp
+ $preambletmp =~ s/^(?:[\t ]*(?:\r?\n|\r))?+//gmsx; # We removed the blank lines
+ # Now we're trying to capture
+ @graphicxpkg = $preambletmp =~ m/($pkgcandidates)/gmsx;
+ if (@graphicxpkg) {
+ Log("Found graphicx package in preamble for $opts_cmd{string}{output}$outext");
+ $findgraphicx = 'false';
+ }
+ # Second search graphicspath
+ @graphicspath = $preambletmp =~ m/graphicspath/msx;
+ if (@graphicspath) {
+ Log("Found \\graphicspath in preamble for $opts_cmd{string}{output}$outext");
+ $findgraphicx = 'false';
+ while ($preamble =~ /$graphicspath /pgmx) {
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ if ($encontrado =~ /$graphicspath/) {
+ my $argumento = $1;
+ if ($argumento !~ /\{$opts_cmd{string}{imgdir}\/\}/) {
+ $argumento .= "\{$opts_cmd{string}{imgdir}/\}";
+ my $cambio = "\\graphicspath{$argumento}";
+ substr $preamble, $pos_inicial, $pos_final-$pos_inicial, $cambio;
+ pos($preamble) = $pos_inicial + length $cambio;
+ }
+ }
+ }
+ }
+ # Third search pst-exa
+ @pst_exa = $preambletmp =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|$pstexa/xg;
+ %pst_exa = map { $_ => 1 } @pst_exa;
+ if (@pst_exa) {
+ Log("Comment pst-exa package in preamble for $opts_cmd{string}{output}$outext");
+ $findgraphicx = 'false';
+ $preamble =~ s/(\\usepackage\[)\s*(swpl|tcb)\s*(\]\{pst-exa\})/\%$1$2,pdf$3/msxg;
+ }
+ if (exists $pst_exa{tcb}) {
+ Log("Suport for \\usepackage[tcb,pdf]\{pst-exa\} for $opts_cmd{string}{output}$outext");
+ $bodydoc =~ s/(graphic=\{)\[(scale=\d*)\]($opts_cmd{string}{imgdir}\/$name-$opts_cmd{string}{prefix}-exa-\d*)\}/$1$2\}\{$3\}/gsmx;
+ }
+}
-### Search [option] in pst-exa package
-my %pst_exa = map { $_ => 1 } @pst_exa;
+### Capture graphicx.sty in .log of LaTeX file
+if ($findgraphicx eq 'true' and $outfile) {
+ Log("Couldn't capture the graphicx package for $opts_cmd{string}{output}$ext in preamble");
+ my $ltxlog;
+ my @graphicx;
+ my $null = devnull();
+ Log("Creating $name-$opts_cmd{string}{prefix}-$tmp$ext [only preamble]");
+ if ($verbose) { say "Creating [$name-$opts_cmd{string}{prefix}-$tmp$ext] with only preamble"; }
+ open my $OUTfile, '>', "$name-$opts_cmd{string}{prefix}-$tmp$ext";
+ print {$OUTfile} "$preamble\n\\stop";
+ close $OUTfile;
+ # Set compiler
+ if ($opts_cmd{compiler}{arara}) {
+ my @engine = $preamble =~ m/$arara_rule/msx;
+ my %engine = map { $_ => 1 } @engine;
+ if (%engine) {
+ for my $var (@arara_engines) {
+ if (defined $engine{$var}) {
+ $compiler = $var;
+ }
+ }
+ }
+ else { $compiler = 'pdflatex'; }
+ }
+ if ($opts_cmd{compiler}{latex}) { $compiler = 'pdflatex'; }
+ if ($opts_cmd{compiler}{dvilua}) { $compiler = 'lualatex'; }
+ # Compiling file
+ RUNOSCMD("$compiler $write18 -interaction=batchmode", "$name-$opts_cmd{string}{prefix}-$tmp$ext >$null", 'only');
+ # Restore arara compiler
+ if ($opts_cmd{compiler}{arara}) { $compiler = 'arara'; }
+ Log("Search graphicx package in $name-$opts_cmd{string}{prefix}-$tmp.log");
+ open my $LaTeXlog, '<', "$name-$opts_cmd{string}{prefix}-$tmp.log";
+ {
+ local $/;
+ $ltxlog = <$LaTeXlog>;
+ }
+ close $LaTeXlog;
+ # Try to capture graphicx
+ @graphicx = $ltxlog =~ m/.+? (graphicx\.sty)/xg;
+ if (@graphicx) {
+ Log("Found graphicx package in $name-$opts_cmd{string}{prefix}-$tmp.log");
+ }
+ else {
+ Log("Not found graphicx package in $name-$opts_cmd{string}{prefix}-$tmp.log");
+ Log("Add \\usepackage\{graphicx\} to preamble of $opts_cmd{string}{output}$outext");
+ $preamble= "$preamble\n\\usepackage\{graphicx\}";
+ }
+}
-### Clean file (pst/tags)
-if ($clean{pst}) {
-$PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add )? | psfrag |psgo |vaucanson-g| auto-pst-pdf )/x;
+### Regex for clean file (pst) in preamble
+$PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add | -pdf )? | psfrag |psgo |vaucanson-g| auto-pst-pdf(?: -lua )? )/x;
$FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
-### Remove pst packages lines
-$preamble =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
- ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
-
-### Delete package words
-$preamble =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
-(?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
-
-### Delete \psset
-$preamble =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
- \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
-
-### Delete \SpecialCoor
-$preamble =~ s/\%<\*ltximgverw> .+?\%<\/ltximgverw>(*SKIP)(*F)|
- \\SpecialCoor(?:[\t ]*(?:\r?\n|\r))+//gmsx;
-} # close clean{pst}
-
-### Delete empty package line \usepackage{}
-$preamble =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
+if ($clean{pst}) {
+ Log("Remove pstricks packages in preamble for $opts_cmd{string}{output}$outext");
+ $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
+ $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
+ $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+ $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
+ \\SpecialCoor(?:[\t ]*(?:\r?\n|\r))+//gmsx;
+ $preamble =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
+}
-### Append graphicx to end of preamble
-if (!@graphix == 0) {
-$preamble .= <<"EXTRA";
-@graphix
-EXTRA
- } else {
-$preamble .= <<"EXTRA";
-\\usepackage{graphicx}
-EXTRA
+if (@pst_exa) {
+ Log("Uncomment pst-exa package in preamble for $opts_cmd{string}{output}$outext");
+ $preamble =~ s/(?:\%)(\\usepackage\[\s*)(swpl|tcb)(,pdf\s*\]\{pst-exa\})/$1$2$3/msxg;
}
-### Regex to capture \graphicspath
-my $graphicspath= qr/\\ graphicspath \{ ((?: $llaves )+) \}/ix;
+### Add last lines
+if ($outfile) {
+ if (!@graphicspath) {
+ Log("Not found \\graphicspath in preamble for $opts_cmd{string}{output}$outext");
+ Log("Add \\graphicspath\{\{$opts_cmd{string}{imgdir}/\}\} to preamble for $opts_cmd{string}{output}$ext");
+ $preamble= "$preamble\n\\graphicspath\{\{$opts_cmd{string}{imgdir}/\}\}";
+ }
+ Log("Add \\usepackage\{grfext\} to preamble for $opts_cmd{string}{output}$ext");
+ $preamble = "$preamble\n\\usepackage\{grfext\}";
+ Log("Add \\PrependGraphicsExtensions\*\{\.pdf\} to preamble for $opts_cmd{string}{output}$ext");
+ $preamble = "$preamble\n\\PrependGraphicsExtensions\*\{\.pdf\}";
+ $preamble =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
+ $preamble =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
+ $preamble =~ s/^(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+}
-### If preamble contain \graphicspath
-if ($preamble =~ m/($graphicspath)/m) {
- while ($preamble =~ /$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 $preamble, $pos_inicial, $pos_final-$pos_inicial, $cambio;
- pos($preamble) = $pos_inicial + length $cambio;
- }
- }
- } #close while
-
-### Regex to capture
-my ($GraphicsPath) = $preamble =~ m/($graphicspath)/msx;
-
-### Append \graphicspath to end of preamble
-$preamble .= <<"EXTRA";
-$GraphicsPath
-\\usepackage{grfext}
-\\PrependGraphicsExtensions*{.pdf}
-EXTRA
- } # close if ($preamble)
-else {
-### If preamble not contain graphicspath, append to premble
-my $GraphicsPath = "\\graphicspath\{\{$imageDir/\}\}";
-
-### Append graphicspath to end of preamble
-$preamble .= <<"EXTRA";
-$GraphicsPath
-\\usepackage{grfext}
-\\PrependGraphicsExtensions*{.pdf}
-EXTRA
-} # close graphicspath
+### We remove environments from the output file
+if (%delete_env and $outfile) {
+ Log("Remove environments in body of $opts_cmd{string}{output}$ext");
+ %replace = (%delete_env);
+ $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
+ # We must prevent eliminating somewhere wrong
+ # We re-create the regular expressions to make the changes
+ my @new_verb_tmp = array_minus(@verbatim, @delete_env);
+ $verbatim = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verb_tmp;
+ $verbatim = qr/$verbatim/x;
+ $verb_std = qr {
+ (
+ (?:
+ \\begin\{$verbatim\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim\*?\})
+ (?!end\{$verbatim\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim\*?\}
+ )
+ )
+ }x;
+
+ my @new_verbw_tmp = array_minus(@verbatim_w, @delete_env);
+ $verbatim_w = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verbw_tmp;
+ $verbatim_w = qr/$verbatim_w/x;
+ $verb_wrt = qr {
+ (
+ (?:
+ \\begin\{$verbatim_w\*?\}
+ (?:
+ (?>[^\\]+)|
+ \\
+ (?!begin\{$verbatim_w\*?\})
+ (?!end\{$verbatim_w\*?\})|
+ (?-1)
+ )*
+ \\end\{$verbatim_w\*?\}
+ )
+ )
+ }x;
+ while ($bodydoc =~ /$verb_wrt | $verb_std /pgmx) {
+ my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
+ my $encontrado = ${^MATCH};
+ $encontrado =~ s/($find)/$replace{$1}/g;
+ substr $bodydoc, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
+ pos ($bodydoc) = $pos_inicial + length $encontrado;
+ }
+ # Now remove
+ $bodydoc =~ s/($delt_env)(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+}
-### Suport for \usepackage[swpl]{pst-exa}
-if (exists($pst_exa{swpl})) {
-$preamble .= <<'EXTRA';
-\usepackage[swpl,pdf]{pst-exa}
-EXTRA
+### Create a <output file>
+if ($outfile) {
+ # Options for out_file (add $end to outfile)
+ my $out_file = $clean{doc} ? "$preamble\n$bodydoc\n\\end\{document\}"
+ : "$preamble\n$bodydoc\n$enddoc"
+ ;
+ # Clean \psset content in output file
+ if ($clean{pst}) {
+ $out_file =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \%<\*$dtxverb> .+? \%<\/$dtxverb>(*SKIP)(*F)|
+ \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+ }
+ # Clean \tikzset content in output file
+ if ($clean{tkz}) {
+ $out_file =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
+ \%<\*$dtxverb> .+? \%<\/$dtxverb>(*SKIP)(*F)|
+ \\tikzset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+ }
+ # Revert all changes in outfile
+ $out_file =~ s/\\begin\{nopreview\}\%$tmp\s*(.+?)\s*\\end\{nopreview\}\%$tmp/$1/gmsx;
+ my @tag_remove_outfile = $out_file =~ m/(?:^\%<\*remove$tmp>.+?\%<\/remove$tmp>)/gmsx;
+ if (@tag_remove_outfile) {
+ Log("Removing the content between <*remove> ... </remove> tags in all $opts_cmd{string}{output}$outext");
+ $out_file =~ s/^\%<\*remove$tmp>\s*(.+?)\s*\%<\/remove$tmp>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
+ }
+ # Remove internal mark for verbatim and verbatim write environments
+ $out_file =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
+ %replace = (%changes_out);
+ $find = join q{|}, map {quotemeta} sort { length $a <=> length $b } keys %replace;
+ $out_file =~ s/($find)/$replace{$1}/g;
+ if (-e "$opts_cmd{string}{output}$outext") {
+ Log("Rewriting the file $opts_cmd{string}{output}$outext in $workdir");
+ Infocolor('Warning', "The file [$opts_cmd{string}{output}$outext] already exists and will be rewritten");
+ }
+ else{
+ Infoline("Creating the file $opts_cmd{string}{output}$outext");
+ Log("Write the file $opts_cmd{string}{output}$outext in $workdir");
+ }
+ # Write <output file>
+ open my $OUTfile, '>', "$opts_cmd{string}{output}$outext";
+ print {$OUTfile} $out_file;
+ close $OUTfile;
}
-### Suport for \usepackage[tcb]{pst-exa}
-if (exists($pst_exa{tcb})) {
-$preamble .= <<'EXTRA';
-\usepackage[tcb,pdf]{pst-exa}
-EXTRA
-### Regex
-$bodydoc =~ s/(graphic=\{)\[(scale=\d*)\]($imageDir\/$name-$prefix-exa-\d*)\}/$1$2\}\{$3\}/gsmx;
-} # close if
+### Set compiler for process <output file>
+$compiler = $opts_cmd{compiler}{xetex} ? 'xelatex'
+ : $opts_cmd{compiler}{luatex} ? 'lualatex'
+ : $opts_cmd{compiler}{dvips} ? 'latex'
+ : $opts_cmd{compiler}{dvilua} ? 'lualatex'
+ : $opts_cmd{compiler}{dvipdf} ? 'latex'
+ : $opts_cmd{compiler}{arara} ? 'arara'
+ : $opts_cmd{compiler}{latexmk} ? 'latexmk'
+ : 'pdflatex'
+ ;
-### Options for out_file (add $end to outfile)
-my $out_file = $clean{doc} ? "$atbegindoc$preamble$bodydoc\n\\end\{document\}"
- : "$atbegindoc$preamble$bodydoc\n$enddoc"
+### Set options for latexmk
+my $ltxmkopt = $opts_cmd{compiler}{xetex} ? "-pdfxe -silent -xelatex=\"xelatex $write18 -recorder %O %S\""
+ : $opts_cmd{compiler}{luatex} ? "-pdflua -silent -lualatex=\"lualatex $write18 -recorder %O %S\""
+ : $opts_cmd{compiler}{dvilua} ? "-pdflua -silent -lualatex=\"lualatex $write18 -recorder %O %S\""
+ : $opts_cmd{compiler}{dvips} ? "-pdfps -silent -latex=\"latex $write18 -recorder %O %S\""
+ : $opts_cmd{compiler}{dvipdf} ? "-pdfdvi -silent -latex=\"latex $write18 -recorder %O %S\""
+ : "-pdf -silent -pdflatex=\"pdflatex $write18 -recorder %O %S\""
;
-### 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
-
-### Revert 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 run
-} # close outfile file
+### Set options for compiler <output file>
+$opt_compiler = $opts_cmd{compiler}{arara} ? '--log'
+ : $opts_cmd{compiler}{latexmk} ? "$ltxmkopt"
+ : "$write18 -interaction=nonstopmode -recorder"
+ ;
+
+### Now set latexmk
+if ($opts_cmd{compiler}{latexmk}) {
+ $compiler = $msg_compiler = 'latexmk';
+}
+
+### Compiling <output file>
+if (!$opts_cmd{boolean}{norun} and $outfile) {
+ Log("Compiling the file $opts_cmd{string}{output}$outext using [$msg_compiler]");
+ print "Compiling the file $opts_cmd{string}{output}$outext using ", color('magenta'), "[$msg_compiler]\r\n",color('reset');
+ RUNOSCMD("$compiler $opt_compiler", "$opts_cmd{string}{output}$outext",'show');
+ # Compiling <output file> using dvips>ps2pdf
+ if ($opts_cmd{compiler}{dvips}) {
+ RUNOSCMD("dvips $quiet -Ppdf", "$opts_cmd{string}{output}.dvi",'show');
+ RUNOSCMD("ps2pdf -sPDFSETTINGS=prepress -sAutoRotatePages=None", "$opts_cmd{string}{output}.ps $opts_cmd{string}{output}.pdf", 'show');
+ }
+ # Compiling <output file> using latex>dvipdfmx
+ if ($opts_cmd{compiler}{dvipdf}) {
+ RUNOSCMD("dvipdfmx $quiet", "$opts_cmd{string}{output}.dvi", 'show');
+ }
+}
### Remove temporary files
-if ($run) {
-say "Deleting (most) temporary files created during the process";
+my @tmpfiles;
my @protected = qw();
-push (@protected,"$output$ext","$output.pdf") if defined $output;
-
-my $flsline = "OUTPUT";
+my $flsline = 'OUTPUT';
my @flsfile;
-if ($PSTexa) { push @flsfile,"$name-$prefix-exa-$tmp.fls"; }
-if ($STDenv) { push @flsfile,"$name-$prefix-$tmp.fls"; }
-push (@flsfile,"$output.fls") if defined $output;
+### Protect generated files
+if (defined $opts_cmd{string}{output}) {
+ push @protected, "$opts_cmd{string}{output}$outext", "$opts_cmd{string}{output}.pdf";
+}
-my @tmpfiles;
+### Find files
+find(\&aux_files, $workdir);
+sub aux_files{
+ my $findtmpfiles = $_;
+ if (-f $findtmpfiles && $findtmpfiles =~ m/$name-$opts_cmd{string}{prefix}(-exa)?-$tmp.+?$/) { # search
+ push @tmpfiles, $_;
+ }
+ return;
+}
+
+### Add if exists
+if (-e 'arara.log') {
+ push @flsfile, 'arara.log';
+}
+if (-e "$name-$opts_cmd{string}{prefix}-$tmp.fls") {
+ push @flsfile, "$name-$opts_cmd{string}{prefix}-$tmp.fls";
+}
+if (-e "$name-$opts_cmd{string}{prefix}-exa-$tmp.fls") {
+ push @flsfile, "$name-$opts_cmd{string}{prefix}-exa-$tmp.fls";
+}
+if (-e "$opts_cmd{string}{output}.fls") {
+ push @flsfile, "$opts_cmd{string}{output}.fls";
+}
+
+### Read .fls file
for my $filename(@flsfile){
- open my $RECtmp, '<', "$filename";
+ 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
-
-### Compress images dir whit generated files
-if ($zip or $tar) {
-my $stamp = strftime "%F", localtime;
-my $archivetar = "$imageDir-$stamp";
-
-my @savetozt;
-find(\&zip_tar, $imageDir);
-sub zip_tar{
- my $filesto = $_;
- if (-f $filesto && $filesto =~ m/$name-$prefix-.+?$/) { # buscamos
- push @savetozt, $File::Find::name;
+push @tmpfiles, @flsfile;
+@tmpfiles = uniq(@tmpfiles);
+@tmpfiles = array_minus(@tmpfiles, @protected);
+
+Log('The files that will be deleted are:');
+Logarray(\@tmpfiles);
+
+### Remove only if exist
+if (@tmpfiles) {
+ Infoline("Remove temporary files created in $workdir");
+ foreach my $tmpfiles (@tmpfiles) {
+ move($tmpfiles, $tempDir);
}
}
-# Write compressed zip file
-if ($zip) {
- say "Creating a file $workdir/$archivetar.zip";
- zip \@savetozt => "$archivetar.zip";
+
+### Find dirs created by minted
+my @deldirs;
+my $mintdir = "\_minted\-$name-$opts_cmd{string}{prefix}-$tmp";
+my $mintdirexa = "\_minted\-$name-$opts_cmd{string}{prefix}-exa-$tmp";
+if (-e $mintdir) { push @deldirs, $mintdir; }
+if (-e $mintdirexa) { push @deldirs, $mintdirexa; }
+
+Log('The directory that will be deleted are:');
+Logarray(\@deldirs);
+
+### Remove only if exist
+if (@deldirs) {
+ Infoline("Remove temporary directories created by minted in $workdir");
+ foreach my $deldirs (@deldirs) {
+ remove_tree($deldirs);
}
+}
-# Write compressed tar.gz file
-if ($tar) {
- say "Creating a file $workdir/$archivetar.tar.gz";
- my $imgdirtar = Archive::Tar->new();
- $imgdirtar->add_files( @savetozt );
- $imgdirtar->write( "$archivetar.tar.gz" , 9 );
+### Compress ./images with all generated files
+my $archivetar;
+if ($opts_cmd{boolean}{zip} or $opts_cmd{boolean}{tar}) {
+ my $stamp = strftime("%Y-%m-%d", localtime);
+ $archivetar = "$opts_cmd{string}{imgdir}-$stamp";
+
+ my @savetozt;
+ find(\&zip_tar, $opts_cmd{string}{imgdir});
+ sub zip_tar{
+ my $filesto = $_;
+ if (-f $filesto && $filesto =~ m/$name-$opts_cmd{string}{prefix}-.+?$/) { # search
+ push @savetozt, $File::Find::name;
+ }
+ return;
}
-} #close compress
+ Log("The files are compress found in $imgdirpath are:");
+ Logarray(\@savetozt);
+ if ($opts_cmd{boolean}{zip}) {
+ if (-e "$archivetar.zip") {
+ Infocolor('Warning', "The file [$archivetar.zip] already exists and will be rewritten");
+ Log("Rewriting the file $archivetar.zip in $workdir");
+ }
+ else{
+ print "Creating the file ", color('magenta'), "[$archivetar.zip]",
+ color('reset'), " with generate files in ./$opts_cmd{string}{imgdir}\r\n";
+ Log("Writen the file $archivetar.tar.gz in $workdir");
+ }
+ zip \@savetozt => "$archivetar.zip";
+ }
+ if ($opts_cmd{boolean}{tar}) {
+ if (-e "$archivetar.tar.gz") {
+ Infocolor('Warning', "The file [$archivetar.tar.gz] already exists and will be rewritten");
+ Log("Rewriting the file $archivetar.tar.gz in $workdir");
+ }
+ else{
+ print "Creating the file ", color('magenta'), "[$archivetar.tar.gz]",
+ color('reset'), " with generate files in ./$opts_cmd{string}{imgdir}\r\n";
+ Log("Writen the file $archivetar.tar.gz in $workdir");
+ }
+ my $imgdirtar = Archive::Tar->new();
+ $imgdirtar->add_files(@savetozt);
+ $imgdirtar->write( "$archivetar.tar.gz" , 9 );
+ }
+}
+
+### End script process
+if (!$opts_cmd{boolean}{norun} and ($opts_cmd{boolean}{srcenv} or $opts_cmd{boolean}{subenv})) {
+ Log("The image files: $format and generated files are in $imgdirpath");
+}
+if (!$opts_cmd{boolean}{norun} and (!$opts_cmd{boolean}{srcenv} and !$opts_cmd{boolean}{subenv})) {
+ Log("The image files: $format are in $imgdirpath");
+}
+if ($opts_cmd{boolean}{norun} and ($opts_cmd{boolean}{srcenv} or $opts_cmd{boolean}{subenv})) {
+ Log("The generated files are in $imgdirpath");
+}
+if ($outfile) { Log("The file $opts_cmd{string}{output}$ext are in $workdir"); }
+
+Infocolor('Finish', "The execution of $scriptname has been successfully completed");
-### End of script process
-if ($run) { say "Finish, image formats: $format are in $workdir/$imageDir/"; }
- else { say "Done"; }
+Log("The execution of $scriptname has been successfully completed");
__END__