texlive[45132] Master/texmf-dist/scripts/texdef: copy texdef.pl ->

commits+karl at tug.org commits+karl at tug.org
Sat Aug 26 01:00:43 CEST 2017


Revision: 45132
          http://tug.org/svn/texlive?view=revision&revision=45132
Author:   karl
Date:     2017-08-26 01:00:43 +0200 (Sat, 26 Aug 2017)
Log Message:
-----------
copy texdef.pl -> latexdef.pl for Windows, per Akira

Added Paths:
-----------
    trunk/Master/texmf-dist/scripts/texdef/README.TEXLIVE
    trunk/Master/texmf-dist/scripts/texdef/latexdef.pl

Added: trunk/Master/texmf-dist/scripts/texdef/README.TEXLIVE
===================================================================
--- trunk/Master/texmf-dist/scripts/texdef/README.TEXLIVE	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/texdef/README.TEXLIVE	2017-08-25 23:00:43 UTC (rev 45132)
@@ -0,0 +1 @@
+latexdef.pl only used by Windows latexdef.exe wrapper


Property changes on: trunk/Master/texmf-dist/scripts/texdef/README.TEXLIVE
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/texdef/latexdef.pl
===================================================================
--- trunk/Master/texmf-dist/scripts/texdef/latexdef.pl	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/texdef/latexdef.pl	2017-08-25 23:00:43 UTC (rev 45132)
@@ -0,0 +1,932 @@
+#!/usr/bin/env perl
+################################################################################
+#  texdef -- Show definitions of TeX commands
+#  Copyright (c) 2011-2012 Martin Scharrer <martin at scharrer-online.de>
+#
+#  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.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+################################################################################
+use strict;
+use warnings;
+use File::Temp qw/tempdir/; 
+use File::Basename;
+use Cwd;
+
+my ($scriptname) = fileparse($0, qw(\.pl \.perl));
+
+my $TEX = 'pdflatex';
+if ($scriptname =~ /^(.*)def$/) {
+    $TEX = $1;
+}
+my $TEXOPTIONS = " -interaction nonstopmode ";
+
+## Variables for options and settings
+my $CLASS      = undef;
+my $USERCLASS  = 0;
+my @PACKAGES   = ();
+my @OTHERDEFS  = ();
+my $INPREAMBLE = 0;
+my $PRINTVERSION = 0;
+my $TMPDIR     = '';
+my $SHOWVALUE  = 0;
+my $ISENVIRONMENT = 0;
+my $PRINTORIGDEF  = 0;
+my $FINDDEF    = 0;
+my $LISTCMD    = 0;
+my $LISTCMDDEF = 0;
+my $BEFORECLASS = 0;
+my $PGFKEYS      = 0;
+my $PGFKEYSPLAIN = 0;
+my $FAKECMD    = "\0FAKECOMMAND\0";
+my $EDIT = 0;
+my $EDITOR;
+my $EDITORCMDLN;
+my @ENVCODE = ();
+my %DEFS;
+my $LISTSTR = '@TEXDEF at LISTDEFS@'; # used as a dummy command to list definitions
+my @FILES; # List of files (sty, cls, ...)
+my @FILEORDER; # Order of files
+my %ALIAS; # list of aliases; required for registers
+my $currfile = ''; # current file name
+# Operating system:
+my $OS = $^O;
+my $WINDOWS = ($OS =~ /MSWin/);
+
+my @IGNOREDEFREG = (# List of definitions to be ignored. Can be a regex or string
+   qr/^ver\@.*\.(?:sty|cls)$/,
+   qr/^opt\@.*\.(?:sty|cls)$/,
+   qr/^reserved\@[a-z]$/,
+   qr/-h\@\@k$/,
+   qr/^catcode\d+$/,
+   qr/^l\@ngrel\@x$/,
+   qr/^\@temp/,
+   qr/^KV\@/,
+   qr/^KVO\@/,
+   qr/^KVOdyn\@/,
+   qr/^KVS\@/,
+   qr/^currfile/,
+   qr/^filehook\@atbegin\@/,
+   qr/^filehook\@atend\@/,
+   qr/^count\d+$/,
+   qr/^pgfk@\//
+);
+my %IGNOREDEF = map { $_ => 1 } qw(
+   usepackage RequirePackage documentclass LoadClass  @classoptionslist
+   CurrentOption tracingassigns in@@ escapechar
+   @unprocessedoptions @let at token @gtempa @filelist @filef at und 
+   @declaredoptions @currnamestack @currname @currext
+   @ifdefinable default at ds ds@ @curroptions
+   filename at area filename at base filename at ext
+);
+
+## Adds arguments to %IGNOREDEF
+sub addignore {
+  my $opt  = shift;
+  my $arg  = shift;
+  my @args = split (/,/, $arg);
+  if ($opt eq 'ignore-cmds') {
+    @IGNOREDEF{@args} = (1) x scalar @args;
+  }
+  else {
+    push @IGNOREDEFREG, map { qr/$_/ } @args;
+  }
+}
+
+use Getopt::Long;
+my $data = "file.dat";
+my $length = 24;
+my $verbose;
+
+my $ISLATEX = 0;
+my $ISTEX   = 0;
+my $ISCONTEXT = 0;
+
+my $BEGINENVSTR = '%s';
+my $ENDENVSTR   = '%s';
+
+my $VERSION = 'Version 1.7b -- 2012/05/15';
+sub usage {
+    my $option = shift;
+    my $ret    = ($option) ? 0 : 1;
+print << 'EOT';
+texdef -- Show definitions of TeX commands
+Version 1.7b -- 2012/05/15
+Copyright (C) 2011-2012  Martin Scharrer <martin at scharrer-online.de>
+This program comes with ABSOLUTELY NO WARRANTY;
+This is free software, and you are welcome to redistribute it under certain conditions;
+
+Usage:
+  texdef   [options] commandname [commandname ...]
+  latexdef [options] commandname [commandname ...]
+
+Other program names are possible. See the 'tex' option.  Command names do not need to start with `\`.
+
+Options:
+  --tex <format>, -t <format>   : Use given format of TeX: 'tex', 'latex', 'context'.
+                                  Variations of 'tex' and 'latex', like 'luatex', 'lualatex', 'xetex', 'xelatex' are supported.
+                                  The default is given by the used program name: 'texdef' -> 'tex', 'latexdef' -> 'latex', etc.
+  --source, -s                  : Try to show the original source code of the command definition (L).
+  --value, -v                   : Show value of command instead (i.e. \the\command).
+  --Environment, -E             : Every command name is taken as an environment name. This will show the definition of
+                                  both \Macro\foo and \Macro\endfoo if \texttt{foo} is used as command name (L).
+  --preamble, -P                : Show definition of the command inside the preamble.
+  --beforeclass, -B             : Show definition of the command before \documentclass.
+  --package <pkg>, -p <pkg>     : (M) Load given tex-file, package or module depending on whether '*tex', '*latex'
+                                  or 'context' is used. For LaTeX the <pkg> can start with `[<options>]` and end 
+                                  with `<pkgname>` or `{<pkgname>}`.
+  --class <class>, -c <class>   : (LaTeX only) Load given class instead of default ('article').
+                                  The <class> can start with `[<classs options>]` and end 
+                                  with `<classname>` or `{<classname>}`.
+  --environment <env>, -e <env> : (M) Show definition inside the given environment <env>.
+  --othercode <code>, -o <code> : (M) Add other code into the preamble before the definition is shown.
+                                  This can be used to e.g. load PGF/TikZ libraries.
+  --before <code>, -b <code>    : (M) Place <code> before definition is shown.
+                                  The <code> can be arbitray TeX code and doesn't need be be balanced.
+  --after  <code>, -a <code>    : (M) Place <code> after definition is shown.
+                                  The <code> can be arbitray TeX code and doesn't need be be balanced.
+  --find, -f                    : Find file where the command sequence was defined (L).
+  --Find, -F                    : Show full filepath of the file where the command sequence was defined (L).
+  --list, -l                    : List user level command sequences of the given packages (L).
+  --list-defs, -L               : List user level command sequences and their shorten definitions of the given packages (L).
+  --list-all, -ll               : List all command sequences of the given packages (L).
+  --list-defs-all, -LL          : List all command sequences and their shorten definitions of the given packages (L).
+  --ignore-cmds <cs,cs,..>,  -i : Ignore the following command sequence(s) in the above lists. (M)
+  --ignore-regex <regex,..>, -I : Ignore all command sequences in the above lists which match the given Perl regular expression(s). (M)
+  --pgf-keys, -k                : Takes commands as pgfkeys and displays their definitions. Keys must use the full path but the common '.\@cmd' prefix is applied.
+  --pgf-Keys, -K                : Takes commands as pgfkeys and displays their definitions. Keys must use the full path.
+  --version, -V                 : If used alone prints version of this script.
+                                  (L) Together with -p or -c prints version of LaTeX package(s) or class, respectively.
+  --edit                        : Opens the file holding the macro definition. Uses --Find and --source. (L)
+                                  If the source definition can not be found the definition is printed as normal instead.
+  --editor <editor>             : Can be used to set the used editor. If not used the environment variables TEXDEF_EDITOR, EDITOR and
+                                  SELECTED_EDITOR are read in this order. If none of these are set a list of default
+                                  editors are tried.  The <editor> string can include '%f' for the filename, '%n' for
+                                  the line number and '%%' for a literal '%'.  If no '%' is used '+%n %f' is added to
+                                  the given command.
+  --tempdir <directory>         : Use given existing directory for temporary files.
+  --help, -h                    : Print this help and quit.
+
+ Long option can be shorten as long the are still unique.  Short options can be combined.
+ If the option 'environment', 'before' and 'after' are used toegether the
+ produced code will be inserted in the given order (reversed order for 'after').
+ (M) = This option can be given multiple times.
+ (L) = LaTeX only. Requires the packages 'filehook' and 'currfile'.
+
+Examples:
+Show the definition of '\chapter' with different classes ('article' (default), 'book' and 'scrbook'):
+
+    latexdef chapter
+    latexdef -c book chapter
+    latexdef -c scrbook chapter
+
+Show value of `\textwidth` with different class options:
+
+    latexdef -c [a4paper]{book} -v paperwidth
+    latexdef -c [letter]{book}  -v paperwidth
+
+Show definition of TikZ's '\draw' outside and inside a 'tikzpicture' environment:
+
+    latexdef -p tikz draw
+    latexdef -p tikz --env tikzpicture draw
+
+Show definition of TikZ's '\draw' inside a node, inside a 'beamer' frame in 'handout' mode:
+
+    latexdef -c [handout]beamer -p tikz --env frame --env tikzpicture -b '\node {' -a '};' draw
+
+List all user level command sequences (macros) defined by the 'xspace' LaTeX package:
+
+    latexdef -l -p xspace
+
+EOT
+  exit ($ret);
+}
+
+sub envcode {
+  my $opt = shift;
+  my $arg = shift;
+  push @ENVCODE, [ $opt, $arg ];
+}
+
+## Define and process options
+Getopt::Long::Configure ("bundling");
+GetOptions (
+   'value|v!' => \$SHOWVALUE,
+   'Environment|E!' => \$ISENVIRONMENT,
+   'version|V!' => \$PRINTVERSION,
+   'tempdir=s' => \$TMPDIR,
+   'find|f!' => sub { $FINDDEF = 1 },
+   'Find|F!' => sub { $FINDDEF = 2 },
+   'source|s!' => \$PRINTORIGDEF,
+   'list|l' => sub { $LISTCMD++ },
+   'list-def|L' => sub { $LISTCMDDEF++ },
+   'list-all' => sub { $LISTCMD=2 },
+   'list-def-all' => sub { $LISTCMDDEF=2 },
+   'ignore-cmds|i=s' => \&addignore,
+   'ignore-regex|I=s' => \&addignore,
+   'no-list|no-l' => sub { $LISTCMD=0; $LISTCMDDEF=0; },
+   'no-list-def|no-L' => sub { $LISTCMDDEF=0 },
+   'no-list-all|no-ll' => sub { $LISTCMD=0; $LISTCMDDEF=0; },
+   'no-list-def-all|no-LL' => sub { $LISTCMDDEF=0 },
+   'preamble|P!' => \$INPREAMBLE,
+   'beforeclass|B!' => \$BEFORECLASS,
+   'class|c=s' => \$CLASS,
+   'package|p=s' => \@PACKAGES,
+   'otherdefs|o=s' => \@OTHERDEFS,
+   'environment|e=s' => \&envcode,
+   'before|b=s' => \&envcode,
+   'after|a=s' => \&envcode,
+   'tex|t=s' => \$TEX,
+   'help|h' => \&usage,
+   'pgf-keys|k' => \$PGFKEYS,
+   'pgf-Keys|K' => \$PGFKEYSPLAIN,
+   'edit!' => sub { $EDIT=1; $FINDDEF = 2; $PRINTORIGDEF = 1; },
+   'editor=s' => \$EDITOR,
+) || usage();
+
+# usage() unless @ARGV;
+
+if ($EDIT && !$EDITOR) {
+    $EDITOR = $ENV{'TEXDEF_EDITOR'} || $ENV{'EDITOR'} || $ENV{'SELECTED_EDITOR'};
+    if (!$EDITOR) {
+        if (!$WINDOWS && exists $ENV{HOME}) {
+        # Check ~/.selected_editor file (Ubuntu)
+        my $fn = "$ENV{HOME}/.selected_editor";
+        if (-r $fn) {
+            open (my $fh, '<', $fn);
+            while (<$fh>) {
+                s/#.*//;
+                if (/^\s*SELECTED_EDITOR=(["']?)(.*)\1/) {
+                    $EDITOR=$2;
+                }
+            }
+            close ($fh);
+        }
+        }
+    }
+    if (!$EDITOR) {
+        warn "No editor set. Using default!\n";
+        if ($WINDOWS) {
+            $EDITOR = 'texworks "%f"';
+        }
+        else {
+            for my $ed (qw(/usr/bin/vim /usr/bin/emacs /usr/bin/nano)) {
+                if (-x $ed) {
+                    $EDITOR = $ed;
+                    last;
+                }
+            }
+            if (!$EDITOR) {
+                for my $ed (qw(/usr/bin/editor /usr/bin/open /bin/open)) {
+                    if (-x $ed) {
+                        $EDITOR = "$ed \"%f\"";
+                        last;
+                    }
+                }
+            }
+        }
+    }
+    if (!$EDITOR) {
+        warn "No suitable editor found. Disable editing!\n";
+        $EDIT = 0;
+    }
+}
+
+## Format specific settings
+if ($TEX =~ /latex$/) {
+  $ISLATEX = 1;
+  $BEGINENVSTR = '\begin{%s}' . "\n";
+  $ENDENVSTR   = '\end{%s}'   . "\n";
+}
+elsif ($TEX =~ /tex$/) {
+  $ISTEX   = 1;
+  $BEGINENVSTR = '\%s' . "\n";
+  $ENDENVSTR   = '\end%s' . "\n";
+}
+elsif ($TEX =~ /context$/) {
+  $ISCONTEXT = 1;
+  $BEGINENVSTR = '\start%s' . "\n";
+  $ENDENVSTR   = '\stop%s'  . "\n";
+}
+
+$USERCLASS = $CLASS;
+$CLASS = 'article' if not $CLASS;
+$CLASS =~ /^(?:\[(.*)\])?{?(.*?)}?$/;
+$CLASS = $2;
+my $CLASSOPTIONS = $1 || '';
+
+if ($FINDDEF == 1 && !$ISLATEX) { die "Error: The --find / -f option is only implemented for LaTeX!\n"; }
+if ($FINDDEF == 2 && !$ISLATEX) { die "Error: The --Find / -F option is only implemented for LaTeX!\n"; }
+
+my @cmds = @ARGV;
+$LISTCMD = $LISTCMDDEF if $LISTCMDDEF;
+if ($LISTCMD && !$ISLATEX) { die "Error: Listing for commands is only implemented for LaTeX!\n"; }
+if ($LISTCMD) {
+    @cmds = ($LISTSTR);
+}
+
+if ($PRINTVERSION) {
+    if (!@PACKAGES && !$USERCLASS) {
+        print STDERR "texdef: $VERSION\n";
+        exit (0) if not @cmds;
+    }
+    elsif (!@cmds) {
+        @cmds = ($FAKECMD);
+    }
+}
+
+sub print_versions {
+    my @files = map { $_.'.sty' } @PACKAGES;
+    unshift @files, "$USERCLASS.cls" if $USERCLASS;
+
+    foreach my $file (@files) {
+        print "\\message{^^J:TEXDEF: $file: \\csname ver\@$file\\endcsname^^J}%\n";
+    }
+    $PRINTVERSION = 0;# only print it once
+}
+
+usage() if not @cmds;
+
+my $cwd = getcwd();
+my $DIRSEP;
+if ($WINDOWS) {
+    $DIRSEP = ';';
+} else {
+    $DIRSEP = ':';
+}
+$ENV{TEXINPUTS} = '.' . $DIRSEP . $cwd . $DIRSEP . ($ENV{TEXINPUTS} || '');
+
+if (!$TMPDIR) {
+   $TMPDIR = tempdir( 'texdef_XXXXXX', CLEANUP => 1, TMPDIR => 1 );
+}
+chdir $TMPDIR or die "Couldn't change into temporary directory '$TMPDIR'\n";
+my $TMPFILE = 'texdeftmp.tex';
+
+sub testdef {
+    my $cmd = shift;
+    my $def = shift;
+    if ($def eq 'macro:->\@latex at error {Can be used only in preamble}\@eha ' && $cmd ne '\@notprerr') {
+        unshift @cmds, '^' . $cmd;
+    }
+    elsif ($def =~ /^(?:\\[a-z]+ )?macro:.*?>(.*)/) {
+        my $macrodef = $1;
+        if ($macrodef =~ /^\\protect (.*?) ?$/) {
+            my $protectedmacro = $1;
+            unshift @cmds, $protectedmacro;
+        }
+        elsif ($macrodef =~ /^\\x\@protect (.*?) ?\\protect (.*?) ?$/) {
+            my $protectedmacro = $2;
+            unshift @cmds, $protectedmacro;
+        }
+        elsif ($macrodef =~ /^\\\@protected\@testopt {?\\.*? }? *(\\\\.*?) /) {
+            unshift @cmds, $1;
+        }
+        elsif ($macrodef =~ /^\\\@testopt {?(\\.*?) }?/) {
+            unshift @cmds, $1;
+        }
+    }
+    elsif ($def =~ /^\\(char|mathchar)|(dimen|skip|muskip|count)\d/) {
+        unshift @cmds, '#' . $cmd;
+    }
+}
+
+my $bschar = 0;
+my $pcchar = 0;
+my $lbchar = 0;
+my $rbchar = 0;
+
+sub special_chars {
+    return if (!$bschar && !$pcchar && !$lbchar && !$rbchar);
+    print '\begingroup'."\n";
+    if ($bschar) {
+        print '\lccode`.=92 \lowercase{\expandafter\gdef\csname @backslashchar\endcsname{.}}'."\n";
+    }
+    if ($pcchar) {
+        print '\lccode`.=37 \lowercase{\expandafter\gdef\csname @percentchar\endcsname{.}}'."\n";
+    }
+    if ($lbchar) {
+        print '\lccode`.=123 \lowercase{\expandafter\gdef\csname @charlb\endcsname{.}}'."\n";
+    }
+    if ($rbchar) {
+        print '\lccode`.=125 \lowercase{\expandafter\gdef\csname @charrb\endcsname{.}}'."\n";
+    }
+    print '\endgroup'."\n";
+}
+
+#######################################################################################################################
+##  Loop around given commands                                                                                       ##
+#######################################################################################################################
+while (my $cmd = shift @cmds) {
+
+next if $cmd eq '';
+my $origcmd = $cmd; 
+my $showvalue;
+my $inpreamble;
+if ($cmd ne $FAKECMD) {
+if ($PGFKEYS) {
+    $cmd = "pgfk\@$cmd/.\@cmd";
+    push @PACKAGES, "pgfkeys";
+}
+if ($PGFKEYSPLAIN) {
+    $cmd = "pgfk\@$cmd";
+    push @PACKAGES, "pgfkeys";
+}
+if (length ($cmd) > 1) {
+    $cmd =~ s/^([#^])?\\?//;
+    my $type = $1 || '';
+    $showvalue  = $type eq '#';
+    $inpreamble = $type eq '^';
+}
+$bschar = $cmd =~ s/\\/\\csname\0\@backslashchar\\endcsname\0/g;
+$pcchar = $cmd =~ s/\%/\\csname\0\@percentchar\\endcsname\0/g;
+$lbchar = $cmd =~ s/\{/\\csname\0\@charlb\\endcsname\0/g;
+$rbchar = $cmd =~ s/\}/\\csname\0\@charrb\\endcsname\0/g;
+$cmd =~ s/\s/\\space /g;
+$cmd =~ s/\0/ /g;
+}
+
+open (my $tmpfile, '>', $TMPFILE);
+select $tmpfile;
+
+print "\\nonstopmode\n";
+
+if ($ISLATEX) {
+    #print "\\nofiles\n";
+    if ($FINDDEF || $LISTCMD || $PRINTORIGDEF) {
+        # Load the 'filehook' and 'currfile' packages without 'kvoptions' by providing dummy definitions for the 'currfile' options:
+        print '\makeatletter\expandafter\def\csname ver at kvoptions.sty\endcsname{0000/00/00}\let\SetupKeyvalOptions\@gobble';
+        print '\newcommand\DeclareStringOption[2][]{}';
+        print '\newcommand\DeclareBoolOption[2][false]{\expandafter\newif\csname ifcurrfile@#2\endcsname\csname currfile@#2#1\endcsname}';
+        print '\let\DeclareVoidOption\@gobbletwo\def\ProcessKeyvalOptions{\@ifstar{}{}}';
+        print '\def\currfile at mainext{tex}\def\currfile at maindir{\@currdir}\let\ifcurrfile at fink\iffalse\makeatother';
+        print "\\RequirePackage{filehook}\n";
+        print "\\RequirePackage{currfile}\n";
+        print '\makeatletter\expandafter\let\csname ver at kvoptions.sty\endcsname\relax\let\SetupKeyvalOptions\@undefined\let\DeclareBoolOption\@undefined\let\DeclareStringOption\@undefined';
+        print '\let\DeclareVoidOption\@undefined\let\ProcessKeyvalOptions\@undefined\makeatother';
+    }
+    if ($FINDDEF || $PRINTORIGDEF) {
+        print '{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname' . "\n";
+        print '\AtBeginOfFiles{{{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname\else' . "\n";
+        print '  \ClearHook\AtBeginOfFiles{}\relax';
+        print '  \ClearHook\AtEndOfFiles{}\relax';
+        # Get parent filename
+        print '  \csname currfile at pop\endcsname';
+        print '  {\message{^^J:: \expandafter\string\csname '.$cmd.'\endcsname\space first defined in "\currfilename".^^J}}\fi}}', "\n";
+        print '  \csname currfile at push\endcsname';
+        print '\AtEndOfFiles{{{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname\else' . "\n";
+        print '  \ClearHook\AtBeginOfFiles{}\relax';
+        print '  \ClearHook\AtEndOfFiles{}\relax';
+        print '  {\message{^^J:: \expandafter\string\csname '.$cmd.'\endcsname\space first defined in "\currfilename".^^J}}\fi}}', "\n";
+        print '\else'. "\n";
+        print '  {\message{^^J:: \expandafter\string\csname '.$cmd.'\endcsname\space is defined by (La)TeX.^^J}}', "\n";
+        print '\fi'. "\n";
+    }
+    if ($LISTCMD) {
+        print '\AtBeginOfEveryFile{\message{^^J>> entering file "\currfilename"^^J}}'."\n";
+        print '\AtEndOfEveryFile{\message{^^J<< leaving file "\currfilename"^^J}}'."\n";
+    }
+    if (!$BEFORECLASS) {
+        print "\\documentclass[$CLASSOPTIONS]{$CLASS}\n";
+        if ($LISTCMD) {
+            print '\tracingonline=1\relax'. "\n";
+            print '\tracingassigns=1\relax'. "\n";
+        }
+
+        foreach my $pkg (@PACKAGES) {
+            $pkg =~ /^(?:\[(.*)\])?{?(.*?)}?$/;
+            my ($pkgname,$pkgoptions) = ($2, $1 || '');
+            print "\\usepackage[$pkgoptions]{$pkgname}\n";
+        }
+        {
+            local $, = "\n";
+            print @OTHERDEFS, '';
+        }
+        unless ($inpreamble || $INPREAMBLE) {
+            print_versions if $PRINTVERSION;
+            print '\tracingonline=0\relax'. "\n";
+            print '\tracingassigns=0\relax'. "\n";
+            print "\\begin{document}\n";
+        }
+    }
+    else {
+        if ($LISTCMD) {
+            print '\tracingonline=1\relax'. "\n";
+            print '\tracingassigns=1\relax'. "\n";
+        }
+    }
+}
+elsif ($ISCONTEXT) {
+    foreach my $pkgname (@PACKAGES) {
+        print "\\usemodule[$pkgname]\n";
+    }
+    {
+        local $, = "\n";
+        print @OTHERDEFS, '';
+    }
+    &special_chars();
+    print "\\starttext\n" unless $inpreamble || $INPREAMBLE;
+}
+elsif ($ISTEX) {
+    foreach my $pkgname (@PACKAGES) {
+        print "\\input $pkgname \n";
+    }
+    {
+        local $, = "\n";
+        print @OTHERDEFS, '';
+    }
+    &special_chars();
+}
+
+foreach my $envc (@ENVCODE) {
+    my ($envtype,$env) = @$envc;
+    if ($envtype eq 'environment') {
+        printf $BEGINENVSTR, $env;
+    }
+    elsif ($envtype eq 'before') {
+        print "$env\n";
+    }
+}
+
+if (!$LISTCMD && $cmd ne $FAKECMD) {
+
+print '\immediate\write0{==============================================================================}%'."\n";
+if (length ($cmd) > 1) {
+if ($showvalue || $SHOWVALUE) {
+    print '\immediate\write0{\string\the\expandafter\string\csname ', $cmd, '\endcsname}%'."\n";
+    print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
+    print '\immediate\write0{\expandafter\the\csname ', $cmd, '\endcsname}%'."\n";
+} else {
+    print '\begingroup';
+    print '\immediate\write0{\expandafter\string\csname ', $cmd, '\endcsname}%'."\n";
+    print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
+    print '\expandafter\endgroup\expandafter\immediate\expandafter\write\expandafter0\expandafter{\expandafter\meaning\csname ', $cmd, '\endcsname}%'."\n";
+}
+}
+else {
+if ($showvalue || $SHOWVALUE) {
+    print '\immediate\write0{\string\the\string\\', $cmd, '}%'."\n";
+    print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
+    print '\immediate\write0{\the\\', $cmd, '}%'."\n";
+} else {
+    print '\immediate\write0{\string\\', $cmd, '}%'."\n";
+    print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
+    print '\immediate\write0{\meaning\\', $cmd, '}%'."\n";
+}
+}
+print '\immediate\write0{==============================================================================}%'."\n";
+
+}
+
+foreach my $envc (reverse @ENVCODE) {
+    my ($envtype,$env) = @$envc;
+    if ($envtype eq 'environment') {
+        printf $ENDENVSTR, $env;
+    }
+    elsif ($envtype eq 'after') {
+        print "$env\n";
+    }
+}
+
+if ($ISLATEX) {
+    print "\\documentclass[$CLASSOPTIONS]{$CLASS}\n" if $BEFORECLASS;
+    if ($inpreamble || $INPREAMBLE || $BEFORECLASS) {
+        print_versions if $PRINTVERSION;
+        print '\tracingonline=0\relax'. "\n";
+        print '\tracingassigns=0\relax'. "\n";
+        print "\\begin{document}\n" 
+    }
+    print "\\end{document}\n";
+}
+elsif ($ISCONTEXT) {
+    print "\\starttext\n" if $inpreamble || $INPREAMBLE;
+    print "\\stoptext\n";
+}
+elsif ($ISTEX) {
+    print "\\bye\n";
+}
+
+close ($tmpfile);
+
+select STDOUT;
+
+# Removes all '{' and '}' characters which no real braces.
+sub remove_invalid_braces {
+    $_[0] =~ s/\\[\\%]//g; # remove \\ and \%
+    $_[0] =~ s/%.*$//;     # remove line comments
+    $_[0] =~ s/\\[{}]//g;  # remove \{ and \}
+}
+
+sub env_braces {
+    my $line = shift;
+    remove_invalid_braces $line;
+    my $level = shift || 0;
+    my $count = shift || 0;
+    for my $char (split //, $line) {
+        if ($char eq '{') {
+            $level++;
+        }
+        elsif ($char eq '}') {
+            $level--;
+            if ($level == 0) {
+                $count++;
+            }
+        }
+    }
+    return ($level, $count);
+}
+
+sub call_editor {
+    my $path = shift;
+    my $linenumber = shift;
+    print "Opening file '$path', line $linenumber.\n";
+    if ($EDITOR =~ /%/) {
+        $EDITOR =~ s/%%/\000/;
+        $EDITOR =~ s/%f/$path/;
+        $EDITOR =~ s/%n/$linenumber/;
+        $EDITOR =~ s/\000/%/;
+        system($EDITOR);
+    }
+    else {
+        system($EDITOR, "+$linenumber", $path);
+    }
+}
+
+sub print_orig_def {
+    my $rmacroname = shift;
+    my $file = shift;
+    my $path = shift;
+    my $linenumber;
+    my $found = 0;
+    open (my $fh, '<', $path) or return;
+    my $rmacrodef  = qr/
+        ^                                                        # Begin of line (no whitespaces!)
+        (
+        (?:(?:\\global|\\long|\\protected|\\outer)\s*)*       # Prefixes (maybe with whitespace between them)
+        )
+        \\(
+              (?:[gex]?def) \s* \\                               # TeX definitions
+            | (?:new|renew|provide)command\s* \*? \s* {? \s* \\  # LaTeX definitions
+            | (?:new|renew|provide)robustcmd\s* \*? \s* {? \s* \\  # etoolbox definitions
+            | (?:new(?:box|count|dimen|if|insert|read|skip|muskip|toks|write)) \s* \\ # TeX registers etc.
+            | (?:char|count|dimen|mathchar|skip|toks)def \s* \\  # TeX chardefs etc.
+            | \@namedef{?                                        # Definition by name only
+            | Declare[a-zA-z]+ \s* \*? \s* {? \s* \\             # Declare... definitions
+            | declare[a-zA-z]+ \s* \*? \s* {? \s* \\             # declare... definitions
+        )
+        $rmacroname                                              # Macro name without backslash
+        [^a-zA-Z@]
+        /xms;
+    my $rmacrolet  = qr/
+        ^                                                        # Begin of line (no whitespaces!)
+        (?:global\s*)?                                           # Prefixes (maybe with whitespace between them)
+        \\let \s* \\                                             # let
+        $rmacroname                                              # Macro name without backslash
+        \s* =?                                                   # Optional '='
+        \s* \\ ([a-zA-Z@]+)                                      # Second macro
+        /xms;
+    my $renvdef = qr/
+        ^                                                        # Begin of line (no whitespaces!)
+        \\(
+            (?:new|renew|provide)environment\s* { \s*            # LaTeX definitions
+        )
+        ($rmacroname)                                            # Environment names follow same rules as macro names
+        \s* }                                                    # closing brace
+        (.*)                                                     # Rest of line
+        /xms;
+    while (my $line = <$fh>) {
+        if ($line =~ $rmacrodef) {
+            my $defcmd = $1;
+            $found = 1;
+            $linenumber = $.;
+            if ($EDIT) {
+                call_editor($path, $linenumber);
+                last;
+            }
+            print "% $file, line $linenumber:\n";
+            print $line;
+            last if $defcmd =~ /^(?:new(?:box|count|dimen|if|insert|read|skip|muskip|toks|write))/;
+            last if $defcmd =~ /^(?:char|count|dimen|mathchar|skip|toks)def/;
+            remove_invalid_braces $line;
+            my $obrace = $line =~ tr/{/{/;
+            my $cbrace = $line =~ tr/}/}/;
+            while ($obrace != $cbrace) {
+                my $line = <$fh>;
+                print $line;
+                remove_invalid_braces $line;
+                $obrace += $line =~ tr/{/{/;
+                $cbrace += $line =~ tr/}/}/;
+            }
+            print "\n";
+            last;
+        }
+        elsif ($line =~ $rmacrolet) {
+            my $letcmd = $1;
+            $found = 1;
+            $linenumber = $.;
+            if ($EDIT) {
+                call_editor($path, $linenumber);
+                last;
+            }
+            print "% $file, line $linenumber:\n";
+            print $line;
+            print "\n";
+            unshift @cmds, $letcmd;
+            last;
+        }
+        elsif ($line =~ $renvdef) {
+            $found = 2;
+            $linenumber = $.;
+            if ($EDIT) {
+                call_editor($path, $linenumber);
+                last;
+            }
+            print "% $file, line $linenumber:\n";
+            print $line;
+            my ($level, $count) = env_braces $line;
+            while ($count < 3) {
+                my $line = <$fh>;
+                print $line;
+                ($level, $count) = env_braces $line, $level, $count;
+            }
+            print "\n";
+            last;
+        }
+    }
+    close($fh);
+    return $found;
+}
+
+open (my $texpipe, '-|', "$TEX $TEXOPTIONS \"$TMPFILE\" ");
+
+my $name = '';
+my $definition = '';
+my $errormsg = '';
+my $origdeffound = 0;
+
+while (<$texpipe>) {
+  if (/^::\s*(.*)/) {
+    my $line = $1;
+    if ($FINDDEF == 2) {
+        if ($line =~ /first defined in "(.*)"/) {
+            my $path = `kpsewhich "$1"`;
+            chomp $path;
+            $line =~ s/$1/$path/;
+        }
+    }
+    if ($PRINTORIGDEF) {
+        if ($line =~ /first defined in "(.*)"/) {
+            my $file = $1;
+            my $path = `kpsewhich "$file"`;
+            chomp $path;
+            $origdeffound = print_orig_def($cmd, $file, $path);
+        }
+        elsif ($line =~ /is defined by \(La\)TeX./) {
+            my $file = 'latex.ltx';
+            my $path = `kpsewhich "$file"`;
+            chomp $path;
+            $file = $path if $FINDDEF > 1;
+            $origdeffound = print_orig_def($cmd, $file, $path);
+        }
+        if (!$origdeffound) {
+            print "Source code definition of '$origcmd' could not be found.\n";
+            print "$line\n";
+        }
+    }
+    else {
+        print "$line\n";
+    }
+    next;
+  }
+  if (/^(:TEXDEF:\s*(.*))/) {
+    my $line = $1;
+    chomp ($line);
+    my $text = $2;
+    while (length $line >= 79) {
+        $line = <$texpipe>;
+        chomp ($line);
+        $text .= $line;
+    }
+    print "$text\n";
+    next;
+  }
+  if ($LISTCMD) {
+  if (/^>> entering file "(.*)"$/) {
+      push @FILES, $currfile;
+      $currfile = $1;
+      push @FILEORDER, $currfile if not exists $DEFS{$currfile};
+  }
+  elsif (/^<< leaving file "(.*)"$/) {
+      $currfile = pop @FILES;
+  }
+  elsif (/^{(?:into|reassigning) \s*(.*)}?$/) {
+    my ($cs, $def) = split (/=/, $1, 2);
+    $cs =~ s/^\\//;
+    $def =~ s/\}$//;
+    if ($LISTCMD > 1 || $cs !~ /[@ ]/) {
+        if ($def =~ /^\\((?:skip|count|toks|muskip|box|dimen)\d+)$/) {
+            $ALIAS{$1} = $cs;
+        }
+        elsif (exists $ALIAS{$cs}) {
+            $cs = $ALIAS{$cs}
+        }
+        $DEFS{$currfile}{$cs} = $def;
+    }
+  }
+  }
+  last if /^=+$/;
+  if ($_ =~ /^!\s*(.*)/ && !$errormsg) {
+    chomp;
+    my $line = $1;
+    $errormsg = $line;
+    while (length $line >= 79) {
+        $line = <$texpipe>;
+        chomp $line;
+        $errormsg .= $line;
+    }
+  }
+}
+while (<$texpipe>) {
+  last if /^-+$/;
+  next if /^$/;
+  chomp;
+  $name .= $_;
+}
+while (<$texpipe>) {
+  last if /^=+$/;
+  next if /^$/;
+  chomp;
+  $definition .= $_;
+  if ($_ =~ /^!\s*(.*)/ && !$errormsg) {
+    $errormsg = $1;
+  }
+}
+while (<$texpipe>) {
+  if ($_ =~ /^!\s*(.*)/ && !$errormsg) {
+    chomp;
+    my $line = $1;
+    $errormsg = $line;
+    while (length $line >= 79) {
+        $line = <$texpipe>;
+        chomp $line;
+        $errormsg .= $line;
+    }
+  }
+}
+close ($texpipe);
+
+my $error = $? >> 8;
+
+if ($error) {
+  if ( ($SHOWVALUE || $showvalue) && ($errormsg =~ /^You can't use `.*' after \\the\./) ) {
+    print STDERR "\n$name:\nError: Given command sequence does not contain a value.\n\n";
+  }
+  else {
+    print STDERR "\n$name:\nCompile error: $errormsg\n\n";
+  }
+  next;
+}
+
+#last if $PRINTORIGDEF && $origdeffound && $EDIT;
+
+next if $cmd eq $FAKECMD;
+if ($cmd eq $LISTSTR) {
+    foreach $currfile (@FILEORDER) {
+        next if not keys %{$DEFS{$currfile}};
+        print "\nDefined by file '$currfile':\n";
+        CMD:
+        foreach my $cmd (sort keys %{$DEFS{$currfile}}) {
+            next CMD if exists $IGNOREDEF{$cmd};
+            foreach my $pattern (@IGNOREDEFREG) {
+                next CMD if $cmd =~ $pattern;
+            }
+            print "\\$cmd";
+            print ": $DEFS{$currfile}{$cmd}" if ($LISTCMDDEF);
+            print "\n";
+        }
+    }
+} elsif (!$PRINTORIGDEF || !$origdeffound) {
+    print "\n(in preamble)" if $inpreamble;
+    print "\n$name:\n$definition\n\n";
+}
+
+if (!($PRINTORIGDEF && $origdeffound)) {
+    testdef($origcmd,$definition);
+}
+if ($ISENVIRONMENT && $origdeffound < 2 && $cmd !~ /^end/) {
+    unshift @cmds, 'end' . $cmd;
+}
+
+}
+
+chdir $cwd;
+__END__


Property changes on: trunk/Master/texmf-dist/scripts/texdef/latexdef.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property


More information about the tex-live-commits mailing list