summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-04-04 23:15:53 +0000
committerKarl Berry <karl@freefriends.org>2011-04-04 23:15:53 +0000
commitd44f7912c87e36c92464c167338b2809ed486602 (patch)
tree5102268b802a77991a19ffef4f2409ca653d2014 /Master/texmf-dist/scripts
parent2665e437bbe1c3e6652fcc4319d38482a387a9b8 (diff)
texdef 1.3 (4apr11)
git-svn-id: svn://tug.org/texlive/trunk@21965 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts')
-rwxr-xr-xMaster/texmf-dist/scripts/texdef/texdef.pl194
1 files changed, 178 insertions, 16 deletions
diff --git a/Master/texmf-dist/scripts/texdef/texdef.pl b/Master/texmf-dist/scripts/texdef/texdef.pl
index 2cba8798b72..8ccc2ece4ae 100755
--- a/Master/texmf-dist/scripts/texdef/texdef.pl
+++ b/Master/texmf-dist/scripts/texdef/texdef.pl
@@ -35,14 +35,61 @@ my @PACKAGES = ();
my @OTHERDEFS = ();
my $INPREAMBLE = 0;
my $SHOWVALUE = 0;
+my $FINDDEF = 0;
+my $LISTCMD = 0;
+my $LISTCMDDEF = 0;
my $BEFORECLASS = 0;
my @ENVCODE = ();
+my %DEFS;
+my $LISTSTR = '@TEXDEF@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
+
+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@token @gtempa @filelist @filef@und
+ @declaredoptions @currnamestack @currname @currext
+ @ifdefinable default@ds ds@ @curroptions
+ filename@area filename@base filename@ext
+);
+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;
@@ -53,7 +100,7 @@ my $ENDENVSTR = '%s';
sub usage {
print << 'EOT';
texdef -- Show definitions of TeX commands
-Version 1.1 -- 2011/03/16
+Version 1.3 -- 2011/04/03
Copyright (C) 2011 Martin Scharrer <martin@scharrer-online.de>
This program comes with ABSOLUTELY NO WARRANTY;
This is free software, and you are welcome to redistribute it under certain conditions;
@@ -65,12 +112,12 @@ Usage:
Other program names are possible. See the 'tex' option. Command names do not need to start with `\`.
Options:
- --tex <flv>, -t <flv> : Use given flavour 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.
- --value, -v : Show value of command instead (i.e. \the\command).
- --preamble, -P : Show definition of the command inside the preamble.
- --beforeclass, -B : Show definition of the command before \documentclass.
+ --tex <flv>, -t <flv> : Use given flavour 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.
+ --value, -v : Show value of command instead (i.e. \the\command).
+ --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>}`.
@@ -84,12 +131,20 @@ Options:
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).
+ --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)
--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'):
@@ -112,6 +167,10 @@ Show definition of TikZ's '\draw' inside a node, inside a 'beamer' frame in 'han
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 (1);
}
@@ -126,6 +185,17 @@ sub envcode {
Getopt::Long::Configure ("bundling");
GetOptions (
'value|v!' => \$SHOWVALUE,
+ 'find|f!' => \$FINDDEF,
+ '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,
@@ -158,15 +228,21 @@ $CLASS =~ /^(?:\[(.*)\])?{?(.*?)}?$/;
$CLASS = $2;
my $CLASSOPTIONS = $1 || '';
+if ($FINDDEF && !$ISLATEX) { die "Error: The --find / -f option is only implemented for LaTeX!\n"; }
my $cwd = getcwd();
$ENV{TEXINPUTS} = $cwd . ':' . ($ENV{TEXINPUTS} || '');
-my $TMPDIR = tempdir( 'texdef_XXXXXX', CLEANUP => 1, TMPDIR => 1 );
+my $TMPDIR = 'temp';#tempdir( 'texdef_XXXXXX', CLEANUP => 1, TMPDIR => 1 );
chdir $TMPDIR or die;
my $TMPFILE = 'texdef.tex';
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);
+}
sub testdef {
my $cmd = shift;
@@ -246,9 +322,36 @@ select $tmpfile;
print "\\nonstopmode\n";
if ($ISLATEX) {
- print "\\nofiles\n";
+ #print "\\nofiles\n";
+ if ($FINDDEF || $LISTCMD) {
+ # Load the 'filehook' and 'currfile' packages without 'kvoptions' by providing dummy definitions for the 'currfile' options:
+ print '\makeatletter\expandafter\def\csname ver@kvoptions.sty\endcsname{0000/00/00}\let\SetupKeyvalOptions\@gobble\newcommand\DeclareBoolOption[2][]{}\let\DeclareStringOption\DeclareBoolOption';
+ print '\let\DeclareVoidOption\@gobbletwo\def\ProcessKeyvalOptions{\@ifstar{}{}}';
+ print '\def\currfile@mainext{tex}\def\currfile@maindir{\@currdir}\let\ifcurrfile@fink\iffalse\makeatother';
+ print "\\RequirePackage{filehook}\n";
+ print "\\RequirePackage{currfile}\n";
+ print '\makeatletter\expandafter\let\csname ver@kvoptions.sty\endcsname\relax\let\SetupKeyvalOptions\@undefined\let\DeclareBoolOption\@undefined\let\DeclareStringOption\@undefined';
+ print '\let\DeclareVoidOption\@undefined\let\ProcessKeyvalOptions\@undefined\makeatother';
+ }
+ if ($FINDDEF) {
+ print '{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname' . "\n";
+ print '\AtEndOfFiles{{{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname\else' . "\n";
+ 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 =~ /^(?:\[(.*)\])?{?(.*?)}?$/;
@@ -259,7 +362,17 @@ if ($ISLATEX) {
local $, = "\n";
print @OTHERDEFS, '';
}
- print "\\begin{document}\n" unless $inpreamble || $INPREAMBLE;
+ unless ($inpreamble || $INPREAMBLE) {
+ 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) {
@@ -275,7 +388,7 @@ elsif ($ISCONTEXT) {
}
elsif ($ISTEX) {
foreach my $pkgname (@PACKAGES) {
- print "\\input $pkgname.tex \n";
+ print "\\input $pkgname \n";
}
{
local $, = "\n";
@@ -294,6 +407,8 @@ foreach my $envc (@ENVCODE) {
}
}
+if (!$LISTCMD) {
+
print '\immediate\write0{==============================================================================}%'."\n";
if (length ($cmd) > 1) {
if ($showvalue || $SHOWVALUE) {
@@ -320,6 +435,8 @@ if ($showvalue || $SHOWVALUE) {
}
print '\immediate\write0{==============================================================================}%'."\n";
+}
+
foreach my $envc (reverse @ENVCODE) {
my ($envtype,$env) = @$envc;
if ($envtype eq 'environment') {
@@ -332,7 +449,11 @@ foreach my $envc (reverse @ENVCODE) {
if ($ISLATEX) {
print "\\documentclass[$CLASSOPTIONS]{$CLASS}\n" if $BEFORECLASS;
- print "\\begin{document}\n" if $inpreamble || $INPREAMBLE || $BEFORECLASS;
+ if ($inpreamble || $INPREAMBLE || $BEFORECLASS) {
+ print '\tracingonline=0\relax'. "\n";
+ print '\tracingassigns=0\relax'. "\n";
+ print "\\begin{document}\n"
+ }
print "\\end{document}\n";
}
elsif ($ISCONTEXT) {
@@ -354,6 +475,31 @@ my $definition = '';
my $errormsg = '';
while (<$texpipe>) {
+ print "$1\n" if /^::\s*(.*)/;
+ 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;
@@ -407,9 +553,25 @@ if ($error) {
next;
}
-print "\n(in preamble)" if $inpreamble;
-print "\n$name:\n$definition\n\n";
-
+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";
+ }
+ }
+} else {
+ print "\n(in preamble)" if $inpreamble;
+ print "\n$name:\n$definition\n\n";
+}
testdef($origcmd,$definition);