summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cmdtrack/cmdtrack.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/cmdtrack/cmdtrack.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/cmdtrack/cmdtrack.dtx')
-rw-r--r--macros/latex/contrib/cmdtrack/cmdtrack.dtx478
1 files changed, 478 insertions, 0 deletions
diff --git a/macros/latex/contrib/cmdtrack/cmdtrack.dtx b/macros/latex/contrib/cmdtrack/cmdtrack.dtx
new file mode 100644
index 0000000000..fe6668c740
--- /dev/null
+++ b/macros/latex/contrib/cmdtrack/cmdtrack.dtx
@@ -0,0 +1,478 @@
+%%% ====================================================================
+%%% @LaTeX-file{
+% filename = "cmdtrack.dtx",
+%%% filename = "cmdtrack.sty",
+%%% version = "1.06",
+%%% date = "2012/12/18",
+%%% author = "Michael John Downes",
+%%% copyright = "Copyright 1999 Michael John Downes.
+%%% Copyright 2012 TeX Users Group.
+%%% This work may be distributed and/or modified under the
+%%% conditions of the LaTeX Project Public License, either version 1
+%%% of this license or (at your option) any later version.
+%%% The latest version of this license is in
+%%% http://www.latex-project.org/lppl.txt
+%%% and version 1.3 or later is part of all distributions of LaTeX
+%%% version 2003/12/01 or later.
+%%% ",
+% keywords = "newcommand",
+% abstract = "This is a LaTeX package that aids in the task
+% of checking whether a command defined in a
+% document preamble is actually used somewhere
+% in the document.",
+%%% }
+%%% ====================================================================
+% \iffalse
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\documentclass{amsdtx}
+\begin{document}
+\title{The \pkg{cmdtrack} package}
+\author{Michael Downes}
+\date{Version \fileversion, \filedate}
+\hDocInput{cmdtrack.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \maketitle
+% \section{Introduction}
+% This package is released under the \LaTeX\ Project Public License.
+%
+% The \pkg{cmdtrack} package aids in the task of checking whether a
+% command defined in a document preamble is actually used somewhere
+% in the document. If you add a statement
+% \begin{verbatim}
+% \usepackage{cmdtrack}
+% \end{verbatim}
+% in the preamble of your document, all \cs{newcommand} and similar
+% statements between that point and \verb'\begin{document}' will be
+% marked for logging. At the end of the document a report of the
+% command usage will be printed in the \TeX{} log, for example:
+% \begin{verbatim}
+% "mdash" was used on line 25
+% "ndash" was never used
+% "gar " was used on line 26
+% "math character ?" was used on line 26
+% \end{verbatim}
+% In this list, a command \cn{foo} is normally listed as
+% \verb'"foo"'; however if it was defined with an optional argument,
+% it will be listed as \verb'"\foo"', and if defined with
+% \cn{DeclareRobustCommand} it will be listed as
+% \texttt{"foo\symbol{32}"} (with an extra space). This has to do
+% with the way \latex/ deals with such definitions behind the scenes.
+% Twiddling the behavior to get more consistent treatment of the
+% command names looked hard, so I didn't do it. If you can send
+% actual code to remedy this deficiency, it will be welcome. I do not
+% plan on trying to fix it myself until after I have dealt with all
+% the other, more interesting or more pressing, problems in my queue.
+%
+% Certain kinds of commands are inherently untrackable due to the way
+% they are used (counters, lengths, and other variables that may
+% appear on the right-hand of an assignment statement; commands whose
+% first use is in the argument of \cs{label}, and so on.) Tracking
+% for commands of this sort can be turned off by moving their
+% definitions earlier (before the load statement of the cmdtrack
+% package), or by listing them in the argument of an \cs{untrack}
+% statement at the end of your document preamble, for example:
+% \begin{verbatim}
+% \untrack{\foo,\bar,\blub,...}
+% \end{verbatim}
+%
+% \section{Limitations}
+% \begin{itemize}
+% \item Only commands defined with \cs{newcommand}, \cs{newenvironment},
+% \cs{newtheorem}, \cs{DeclareMathSymbol}, \cs{DeclareMathOperator},
+% and their variants are logged. Commands will not be logged if they
+% are defined with \cs{def} instead of \cs{newcommand},
+% \cs{mathchardef} instead of \cs{DeclareMathSymbol}, etc.
+%
+% \item \qq{Commands} defined with \cs{newlength}, \cs{newsavebox},
+% \cs{newcounter}, \cs{newcount}, \cs{newtoks}, etc., will not be
+% logged because it cannot be done without disrupting their normal
+% use.
+%
+% \item Commands defined with \cs{DeclareTextSymbol},
+% \cs{DeclareTextAccent}, \cs{DeclareMathRadical},
+% \cs{DeclareMathAlphabet}, and various other things will not be
+% logged because I was starting to doze off on the keyboard after
+% adding the support for \cs{DeclareMathSymbol}. Any volunteers?
+%
+% \item The definitions of the commands that are to be logged must fall
+% between \verb'\usepackage{cmdtrack}' and \verb'\begin{document}'.
+% For problem commands, try moving their definitions before the
+% \verb'\usepackage{cmdtrack}' line, or use the \cs{untrack} command
+% to cancel tracking for selected commands at the end of the
+% preamble.
+%
+% \item The \pkg{cmdtrack} package should be the last package loaded
+% (or, the later-loaded packages will have their commands tracked as
+% well, if that is what you want).
+%
+% \item A command definition starting with \cs{multicolumn} will cause
+% trouble (unless it is never used).
+%
+% \item Large number of \cs{newcommands} (200+, say) might lead to an
+% error message \qq{\TeX{} capacity exceeded (hash size \ldots)}.
+% Depends on the capacity of your \TeX{} system.
+%
+% \end{itemize}
+%
+% \StopEventually{}
+%
+% \section{Embedded documentation}
+%
+% The following material comes into play only when the \verb'?'
+% package option is used.
+%
+% \begin{macrocode}
+%% Self-documenting section
+\ifcat ?$\relax{\catcode37=7 \catcode127=9 \def\0{\@sanitize\catcode}\fi
+%%? \endlinechar125\catcode127=13\def%%?{\typeout}\037=7
+%%?{====================================================================
+%%?{ With the cmdtrack package, all commands and environments defined
+%%?{ between \usepackage{cmdtrack} and \begin{document} will be marked
+%%?{ for logging. A report on the usage of the marked commands will be
+%%?{ printed in the LaTeX log file. Standard LaTeX methods must be used
+%%?{ for defining the commands (things defined with \def, for example,
+%%?{ won't be logged). Use \untrack{\cmd,\othercmd,...} just before
+%%?{ \begin{document} to turn off tracking for selected commands.
+%%?{
+%%?{ Package options:
+%%?{
+%%?{ ? Causes this information to be shown on-screen.
+%%?{
+%%?{ morose Opposite of verbose: causes the brief message about the ?
+%%?{ option to be suppressed.
+%%?{
+%%?{ Support for the following is not [yet] provided:
+%%?{ \DeclareTextSymbol, \DeclareMathRadical, \DeclareMathAlphabet, and
+%%?{ some others.
+%%?{
+%%?{ More comprehensive documentation for cmdtrack.sty may be found in
+%%?{ cmdtrack.dtx.
+%%?{====================================================================
+%%?{}}\endinput\bgroup
+%%
+% \end{macrocode}
+%
+% \section{Implementation}
+% Standard declaration of package name and date.
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{cmdtrack}[2012/12/18 v1.06]
+% \end{macrocode}
+%
+% The \pkg{cmdtrack} package works by hooking into the internal
+% \LaTeX{} function \cs{@yargdef}. When processing something like
+% \verb'\newcommand{\foo}{...}', there is a point where \LaTeX{}
+% runs, essentially,
+% \begin{verbatim}
+% \def\foo{...}
+% \end{verbatim}
+% Just as \LaTeX{} is about to carry out that assignment, we jump
+% in and substitute a different control sequence in place of
+% \cs{foo}! Our substituted control sequence has the same name but
+% with an extra double-quote character \verb'"' added at the
+% beginning: i.e., \verb'\"foo' instead of \cs{foo}. Thus \cs{"foo}
+% gets the real definition, and we are free to give \cs{foo} some
+% other definition for logging purposes. Obviously it should end by
+% calling the real definition. And here is how we arrange that.
+%
+% \begin{enumerate}
+% \item \cs{foo} expands to \verb'\logcmd \"foo \foo'.
+%
+% \item \cs{logcmd} redefines \cs{foo} to take on the meaning of
+% \cs{"foo}.
+%
+% \item \cs{logcmd} adds \cs{"foo} to a used-commands list, and records
+% the current line number with it.
+% \end{enumerate}
+%
+% Then when we reach the end of our document, we need to find some
+% way of looking through all of our marked commands and reporting
+% which ones were used. During the processing of the preamble, the
+% marked commands were stored in a list \cs{commandlist}.
+% Furthermore, when \cs{logcmd} redefined \cs{"foo}, it put in a
+% special marker character along with the line number. Then when we
+% reach the end of our document, we can iterate over the command list
+% with a function that checks for that special character in the
+% \cs{meaning} of each command.
+%
+% Alternatively one could imagine adding the used commands to a
+% separate list. At one point I started doing that but it got a
+% little messy so I abandoned the idea. Besides, this way the report
+% comes out with the commands in the same order as they were defined
+% in the preamble (except that newtheorem commands gravitate toward
+% the end of the list).
+%
+% \begin{macrocode}
+\let\commandlist\@empty
+% \end{macrocode}
+%
+% \begin{macrocode}
+\AtEndDocument{\report@command@usage}
+% \end{macrocode}
+%
+% The \LaTeX{} kernel doesn't provide this.
+% \begin{macrocode}
+\edef\@quotechar{\string"}
+% \end{macrocode}
+%
+% The \cs{untrack} command could just redefine \cs{logcmd} and run
+% through its argument list, but if the user accidentally leaves in
+% some command that is no longer defined (or defined before the
+% \pkg{cmdtrack} package is loaded) then some kind of error is
+% likely. So we check specifically for the string \verb"\logcmd" at
+% the beginning of each command's \cs{meaning} string.
+% \begin{macrocode}
+\newcommand{\untrack}[1]{%
+ \begingroup
+ \def\logcmd##1##2{\global\let##1=##2%
+ \xdef##2{\@percentchar\the\inputlineno}%
+ }%
+ \untrack@a#1{,\@gobble}\endgroup
+}
+% \end{macrocode}
+%
+% \begin{macrocode}i
+\def\untrack@a#1{%
+ \ifx,#1\@gobbletwo\expandafter\@gobble
+ \else \expandafter\untrack@b\meaning#1\@nil#1%
+ \fi
+ \untrack@a
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\untrack@b#1->#2#3#4#5#6#7#8#9\@nil{%
+ \expandafter\ifx\csname #3#4#5@#6#7#8\endcsname\log@cmd
+ \else
+ \def\@tempa##1{%
+ \PackageWarningNoLine{cmdtrack}{%
+Command \protect##1 does not have tracking turned on}%
+ }%
+ \expandafter\@tempa
+ \fi
+}
+% \end{macrocode}
+%
+% One branch of providecommand processing uses \cs{reserved@a} in a
+% way that will fail unless we watch out for it.
+% \begin{macrocode}
+\def\@isreserved@a#1\reserved@a#2#3@{#2}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\let\@hash@\relax
+\def\log@cmd#1#2{%
+ \if\@isreserved@a#2T\reserved@a F@T%
+ \endgroup
+ \else
+ \toks@\expandafter{\commandlist#1}%
+ \xdef\commandlist{\the\toks@}%
+ \endgroup
+ \def#2{\logcmd#2#1}%
+ \fi
+ \let\@hash@##%
+ \l@ngrel@x\expandafter\def\expandafter#1\reserved@a
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\logcmd#1#2{%
+ \ifx\protect\@typeset@protect
+ \global\let#1#2%
+ \xdef#2{\@percentchar\the\inputlineno}%
+ \else
+ \expandafter\protect
+ \fi
+ #1%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\begingroup \catcode`\"=12
+\gdef\cmd@check#1->#2#3-#4\@nil#5{%
+ \if\@percentchar#2\typeout{\string#5" was used on line #3}%
+ \else\typeout{\string#5" was never used}%
+ \fi
+}
+\endgroup
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\report@command@usage{%
+ \def\@tempa{\typeout{=========================================}}%
+ \@tempa
+ \begingroup \escapechar\m@ne
+ \def\do##1{%
+ \ifx\advance##1\expandafter\@gobbletwo\fi
+ {\expandafter\cmd@check\meaning##1->@-\@nil##1}%
+ \do
+ }%
+ \expandafter\do\commandlist \advance\z@\z@
+ \endgroup
+ \@tempa
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\testthm#1{%
+ \expandafter\testthm@a\csname#1\expandafter\endcsname
+ \csname\@quotechar#1\endcsname
+}
+% \end{macrocode}
+%
+% In order to avoid figuring out how to read the optional arguments
+% of \cs{newtheorem}, we postpone the application of \cs{log@cmd}
+% (actually, a slight variation thereof) until
+% \verb'\begin{document}'.
+% \begin{macrocode}
+\let\old@newtheorem\newtheorem
+\def\newtheorem#1{%
+ \AtBeginDocument{\testthm{#1}}%
+ \old@newtheorem{#1}%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\testthm@a#1#2{%
+ \begingroup
+ \toks@\expandafter{\commandlist#2}%
+ \xdef\commandlist{\the\toks@}%
+ \endgroup
+ \let#2#1%
+ \def#1{\logcmd#1#2}%
+}
+% \end{macrocode}
+%
+% It would be unusual for a character to be defined as a math symbol
+% in a document preamble. But what hey, why not support it?
+% \begin{macrocode}
+\def\set@mathchar#1#2#3#4{%
+ \expandafter\set@mathchar@a
+ \csname\@quotechar math character \string#2\expandafter\endcsname
+ \expandafter{\number`#2}{#1}{#3}{#4}%
+}%
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\set@mathchar@a#1#2#3#4#5{%
+ \global\mathcode#2=\@quotechar 8000
+ \global\mathchardef#1\@quotechar\mathchar@type#4\hexnumber@#3#5\relax
+ \toks@\expandafter{\commandlist#1}%
+ \xdef\commandlist{\the\toks@}%
+ \begingroup \lccode`\.=#2\lccode`\~=#2\lowercase{\endgroup
+ \gdef~{\global\mathcode#2=#1\logcmd#1#1}}%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\set@mathsymbol#1#2#3#4{%
+ \begingroup \escapechar=`\"\relax
+ \global\expandafter\mathchardef
+ \csname\string#2\endcsname
+ \@quotechar\mathchar@type#3\hexnumber@#1#4\relax
+ \expandafter\log@cmd@a\csname\string#2\endcsname#2%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\set@mathaccent#1#2#3#4{%
+ \xdef#2{\mathaccent\@quotechar\mathchar@type#3\hexnumber@#1#4\relax}%
+ \begingroup \escapechar`\"\relax
+ \expandafter\log@cmd@a\csname\string#2\endcsname#2%
+}
+% \end{macrocode}
+%
+% Note the use of \cs{gdef}.
+% \begin{macrocode}
+\def\log@cmd@a#1#2{%
+ \toks@\expandafter{\commandlist#1}%
+ \xdef\commandlist{\the\toks@}%
+ \endgroup
+ \gdef#2{\logcmd#2#1}%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{?}{\AtEndOfPackage{\ShowPackageInfo{cmdtrack}}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{morose}{}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{simple}{%
+ \def\logcmd#1#2{%
+ \ifx\protect\@typeset@protect
+ \global\let#1#2%
+ \begingroup \escapechar\m@ne
+ \typeout{\string#2\string" was used on line \the\inputlineno}%
+ \endgroup
+ \else
+ \expandafter\protect
+ \fi
+ #1%
+ }%
+ \AtBeginDocument{\global\let\commandlist\@empty}%
+ \global\let\report@command@usage\relax
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProcessOptions\relax
+\begingroup
+\catcode`\%=9 \catcode`\&=14 \catcode`\"=12
+\@ifpackagewith{cmdtrack}{morose}{\catcode`\%=14 }{}
+\@ifpackagewith{cmdtrack}{?}{\catcode`\%=14 }{}
+%%\typeout{&
+%%Try "\string\usepackage[\string ?]{cmdtrack}"
+%%to see information on using this package^^J&
+%%[including how to turn off this "helpful" message].&
+%%}
+\endgroup
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcommand{\ShowPackageInfo}[1]{%
+ \begingroup \catcode`\?=3
+ \input{#1.\@pkgextension}%
+ \endgroup
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\let\@@yargdef\@yargdef
+% \end{macrocode}
+%
+% Restore \cs{@yargdef} to normal at beginning of document, so that uses of
+% \cs{newcommand} in \cs{maketitle} (e.g.\@) are ignored.
+% \begin{macrocode}
+\AtBeginDocument{\let\@yargdef\@@yargdef}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\let\@hash@\relax
+\def\@yargdef #1#2#3{%
+ \@tempcnta#3\relax \advance\@tempcnta\@ne \let\@hash@\relax
+ \edef\reserved@a{\ifx#2\tw@ [\@hash@ 1]\fi}%
+ \@tempcntb#2%
+ \@whilenum\@tempcntb<\@tempcnta\do{%
+ \edef\reserved@a{\reserved@a\@hash@\the\@tempcntb}%
+ \advance\@tempcntb\@ne
+ }%
+ \begingroup \escapechar=`\"\relax
+ \expandafter\log@cmd\csname\string#1\endcsname#1%
+}
+% \end{macrocode}
+%
+% The usual \cs{endinput} to ensure that random garbage at the end of
+% the file doesn't get copied by \fn{docstrip}.
+% \begin{macrocode}
+\endinput
+% \end{macrocode}
+%
+% \Finale