1 % \iffalse meta-comment
5 % The LaTeX3 Project and any individual authors listed elsewhere
8 % This file is part of the Standard LaTeX `Tools Bundle'.
9 % -------------------------------------------------------
11 % It may be distributed and/or modified under the
12 % conditions of the LaTeX Project Public License, either version 1.3c
13 % of this license or (at your option) any later version.
14 % The latest version of this license is in
15 % http://www.latex-project.org/lppl.txt
16 % and version 1.3c or later is part of all distributions of LaTeX
17 % version 2005/12/01 or later.
19 % The list of all files belonging to the LaTeX `Tools Bundle' is
20 % given in the file `manifest.txt'.
25 %% $Id: trace.dtx 5291 2003-06-29 14:44:49Z mittelba $
27 %% (C) Copyright 1999-2014 Frank Mittelbach
28 %% All rights reserved.
31 \ProvidesFile{trace.dtx}
33 %<package>\NeedsTeXFormat{LaTeX2e}
34 %<package>\ProvidesPackage{trace}
35 %<driver>\ProvidesFile{trace.drv}
37 % \ProvidesFile{trace.dtx}
38 [2014/10/28 v1.1d trace LaTeX code]
42 \documentclass{ltxdoc}
44 \setcounter{StandardModuleDepth}{1}
49 \DeclareRobustCommand\eTeX{\ensuremath{\varepsilon}-\kern-.125em\TeX}
59 % \GetFileInfo{trace.dtx}
61 % \title{The \textsf{trace} package\thanks{This file
62 % has version number \fileversion, last
63 % revised \filedate.}}
64 % \author{Frank Mittelbach}
66 % \MaintainedByLaTeXTeam{tools}
71 % \section{Introduction}
73 % When writing new macros one often finds that they do not work as
74 % expected (at least I do :-). If this happens and one can't
75 % immediately figure out why there is a problem one has to start doing
76 % some serious debugging. \TeX{} offers a lot of bells and whistles to
77 % control what is being traced but often enough I find myself applying
78 % the crude command |\tracingall| which essentially means ``give me
79 % whatever tracing information is available''.
81 % In fact I normally use \eTeX{} in such a case, since that \TeX{}
82 % extension offers me a number of additional tracing possibilities
83 % which I find extremely helpful. The most important ones are
84 % |\tracingassigns|, which will show you changes to register values
85 % and changes to control sequences when they happen, and
86 % |\tracinggroups|, which will tell you what groups are entered
87 % or left (very useful if your grouping got out of sync).
89 % So what I really write is
91 % \tracingassigns=1\tracinggroups=1\tracingall
93 % That in itself is already a nuisance (since it is a mouthful) but
94 % there is a worse catch: when using |\tracingall| you do get a awful
95 % lot of information and some of it is really useless.
97 % For example, if \LaTeX{} has to load a new font it enters some
98 % internal routines of NFSS which scan font definition tables etc.
99 % And 99.9\% of the time you are not at all interested in that part of the
100 % processing but in the two lines before and the five lines
101 % after. However, you have to scan through a few hundred lines of
102 % output to find the lines you need.
104 % Another example is the \texttt{calc} package. A simple statement
105 % like |\setlength| |\linewidth| |{1cm}| inside your macro will result
108 % \renewcommand\MacroFont{\fontencoding\encodingdefault
109 % \fontfamily\ttdefault
110 % \fontseries\mddefault
111 % \fontshape\updefault
114 % \setlength ->\protect \setlength
117 % \setlength ->\calc@assign@skip
119 % \calc@assign@skip ->\calc@assign@generic \calc@Askip \calc@Bskip
121 % \calc@assign@generic #1#2#3#4->\let \calc@A #1\let \calc@B #2\expandafter \calc
122 % @open \expandafter (#4!\global \calc@A \calc@B \endgroup #3\calc@B
132 % \calc@open (->\begingroup \aftergroup \calc@initB \begingroup \aftergroup \calc
133 % @initB \calc@pre@scan
139 % \calc@pre@scan #1->\ifx (#1\expandafter \calc@open \else \ifx \widthof #1\expan
140 % dafter \expandafter \expandafter \calc@textsize \else \calc@numeric \fi \fi #1
147 % \calc@numeric ->\afterassignment \calc@post@scan \global \calc@A
153 % \calc@post@scan #1->\ifx #1!\let \calc@next \endgroup \else \ifx #1+\let \calc@
154 % next \calc@add \else \ifx #1-\let \calc@next \calc@subtract \else \ifx #1*\let
155 % \calc@next \calc@multiplyx \else \ifx #1/\let \calc@next \calc@dividex \else \i
156 % fx #1)\let \calc@next \calc@close \else \calc@error #1\fi \fi \fi \fi \fi \fi \
164 % {restoring \calc@next=undefined}
166 % \calc@initB ->\calc@B \calc@A
170 % {restoring \skip44=0.0pt}
172 % \calc@initB ->\calc@B \calc@A
177 % \noindent Do you still remember what I was talking about?
179 % No? We're trying to find a problem in macro code without having to scan
180 % too many uninteresting lines. To make this possible we have to
181 % redefine a number of key commands to turn tracing off temporarily in
182 % the hope that this will reduce the amount of noise during the
183 % trace. For example, if we change one of the \texttt{calc} internals
184 % slightly, the above tracing output can be reduced to:
187 % \setlength ->\protect \setlength
190 % \setlength ->\calc@assign@skip
192 % \calc@assign@skip ->\calc@assign@generic \calc@Askip \calc@Bskip
194 % \calc@assign@generic #1#2#3#4->\let \calc@A #1\let \calc@B #2\expandafter \calc
195 % @open \expandafter (#4!\global \calc@A \calc@B \endgroup #3\calc@B
205 % \calc@open (->\begingroup \conditionally@traceoff \aftergroup \calc@initB \begi
206 % ngroup \aftergroup \calc@initB \calc@pre@scan
209 % \conditionally@traceoff ->\tracingrestores \z@ \tracingcommands \z@ \tracingpag
210 % es \z@ \tracingmacros \z@ \tracingparagraphs \z@
213 % {restoring \tracingrestores=1}
215 % \calc@initB ->\calc@B \calc@A
220 % \noindent\label{conttraceoffexample}
221 % Still a lot of noise but definitely preferable to the
224 % I redefined those internals that I found most annoyingly
225 % noisy. There are probably many others that could be treated in a
226 % similar fashion, so if you think you found one worth adding please
227 % drop me a short note.
229 % \[ * \quad * \quad * \]
231 % \DescribeMacro\traceon
232 % \DescribeMacro\traceoff
233 % The package defines the two macros |\traceon| and |\traceoff| to
234 % unconditionally turn tracing on or off, respectively. |\traceon| is
235 % like |\tracingall| but additionally adds |\tracingassigns| and
236 % |\tracinggroups| if the \eTeX{} program (in extended mode) is
237 % used. And |\traceoff| will turn tracing off again, a command which
238 % is already badly missing in plain \TeX{}, since it is often not
239 % desirable to restrict the tracing using extra groups in the
242 % \DescribeMacro\conditionally@traceon
243 % \DescribeMacro\conditionally@traceoff
244 % There are also two internal macros that turn tracing on and off, but
245 % only if the user requested tracing in the first place. These are the
246 % ones that are used internally within the code below.
248 % Since the package overwrites some internals of other packages you
249 % should load it as the last package in your preamble using
250 % |\usepackage{trace}|.
252 % The package offers the option \texttt{logonly} that suppresses
253 % terminal output during tracing (unless |\tracingall| is used). This
254 % is useful if the \TeX{} implementation used gets rather slow when
255 % writing a lot of information to the terminal.
257 % It also offers the option \texttt{full} in which case |\traceon|
258 % will trace all parts of the code, i.e., essentially work like
261 % \section{A sample file}
263 % The following small test file shows the benefits of the
264 % \texttt{trace} package. If one uncomments the line loading the
265 % package, the amount of tracing data will be drastically reduced.
266 % Without the \texttt{trace} package we get 6594 lines in the log
267 % file; adding the package will reduce this to 1618 lines.
270 % \documentclass{article}
272 % %\usepackage{trace} % uncomment to see difference
275 % \ifx\traceon\undefined \tracingall \else \traceon \fi
277 % \setlength\linewidth{1cm}
281 % \small \texttt{\$} \stop
286 % \section{Implementation}
288 % \renewcommand\MacroFont{\fontencoding\encodingdefault
289 % \fontfamily\ttdefault
290 % \fontseries\mddefault
291 % \fontshape\updefault
294 % This package is for use with \LaTeX{} (though something similar
295 % could be produced for other formats).
298 \NeedsTeXFormat{LaTeX2e}[1998/12/01]
301 % The package has a option that suppresses tracing on the
302 % terminal, i.e., if used will not set |\tracingonline| to
303 % one. This has been added in version 1.1a since some \TeX{}
304 % implementations get rather slow when outputting to a terminal.
306 \DeclareOption{logonly}
307 {\let\tracingonline@p\z@}
309 % The default is showing the tracing information on the terminal.
311 \let\tracingonline@p\@ne
314 % If the option |full| is selected then all code should be traced,
315 % i.e., the commands |\conditionally@traceoff| and
316 % |\conditionally@traceon| should do nothing. We set them to
317 % |\@empty| not |\relax| since the latter might produce a math ord
318 % in certain circumstances. We also have to make sure that
319 % |\traceon| (as defined further down) is not redefining
320 % |\conditionally@traceoff| again. To make this all work these
321 % redefinitions have to wait until the end of the package.
322 % \changes{v1.1c}{2003/04/30}{Option ``full'' added}
325 {\AtEndOfPackage{\let\conditionally@traceoff\@empty
326 \let\conditionally@traceon\@empty
332 \ProcessOptions\relax
337 % \begin{macro}{\if@tracing}
338 % We need a switch to determine if we want any tracing at
339 % all. Otherwise, if we use |\traceoff|\ldots|\traceon|
340 % internally, we would unconditionally turn on tracing even when no
341 % tracing was asked for in the first place.
347 % \begin{macro}{\traceon}
348 % This macro ensures that |\conditionally@traceoff| is actually
349 % turning off switches (since |\tracinall| might have disabled it)
350 % and then calls |\tr@ce@n| to setup tracing.
352 \def\traceon{\let\conditionally@traceoff\unconditionally@traceoff
357 % \begin{macro}{\tr@ce@n}
358 % \changes{v1.1c}{2003/04/30}{Macro added}
359 % \begin{macro}{\conditionally@traceoff}
360 % As stated in the introduction, the amount of tracing being done
361 % should depend on the formatter we use. So we first test if we are
362 % running with \eTeX{} in extended mode. In the latter case the command
363 % |\tracinggroups| is defined.\footnote{If some package writer has defined
364 % that command name for some reason---too bad---then we make the
365 % wrong deduction from this fact and as a result the package will fail.}
367 \ifx\tracinggroups\undefined
370 % If we are using standard \TeX{} then |\tr@ce@n| is more or less
371 % another name for |\tracingall|. The only differences are that we
372 % set the above |@tracing| switch to true and reorder the
373 % assignments within it somewhat so that it will output no tracing
374 % information about itself. In contrast, |\tracingall| itself produces
377 % \renewcommand\MacroFont{\fontencoding\encodingdefault
378 % \fontfamily\ttdefault
379 % \fontseries\mddefault
380 % \fontshape\updefault
383 % {vertical mode: \tracingstats}
385 % {\tracinglostchars}
387 % {\tracingparagraphs}
389 % {\errorcontextlines}
391 % \showoutput ->\tracingoutput \@ne \showboxbreadth \maxdimen \showboxdepth \maxd
392 % imen \errorstopmode \showoverfull
398 % \showoverfull ->\tracingonline \@ne
403 % \noindent Which is quite a lot given that none of it is of any
404 % help to the task at hand. In contrast |\tr@ce@n| will produce
405 % nothing whatsoever since the noise generating switches are set at
410 % We start by setting the |@tracing| switch to signal that tracing
411 % is asked for. This is then followed by setting the various
412 % tracing primitives of \TeX.
417 \tracinglostchars\@ne
418 \tracingparagraphs\@ne
419 \errorcontextlines\maxdimen
421 \showboxbreadth\maxdimen
422 \showboxdepth\maxdimen
428 % The setting of |\tracingonline| depends on the option
431 \tracingonline\tracingonline@p
435 % Now what should |\conditionally@traceoff| do in this case? Should
436 % it revert all settings changed by |\tr@ce@n|? It should not, since
437 % our goal is to shorten the trace output, thus setting all of the
438 % uninteresting values back makes the output unnecessarily
439 % longer. Therefore we restrict ourselves to those |\tracing...|
440 % internals that really contribute to listings like the above.
442 % And one additional point is worth mentioning. The order in which
443 % we turn the tracing internals off has effects on the output we
444 % see. So what needs to be turned off first? Either
445 % |\tracingrestores| or |\tracingcommands|; it makes no difference
446 % which, as long as they both come first. This is because those two
447 % are the only tracing switches that produce output while tracing
448 % the command |\conditionally@traceoff| itself (see example on
449 % page~\pageref{conttraceoffexample}).
451 % In principle we would need to test the |@tracing| switch to see
452 % if there is anything to turn off; after all, this is the
453 % conditional trace off. However this would lead to
454 % extra output if we are currently tracing so we skip the test and
455 % instead accept that in case we are not doing any tracing we
456 % unnecessarily set the tracing primitives back to zero (i.e., the
457 % value they already have).
458 % \changes{v1.1c}{2003/04/30}{Turn off \cs{tracingoutput}}
460 \def\conditionally@traceoff{%
465 \tracingparagraphs\z@
471 % As remarked above there are more tracing switches set by
472 % |\tr@ce@n|, however there is no point in resetting
473 % |\tracinglostchars| so we leave it alone.
474 % \changes{v1.1c}{2003/04/30}{Reset \cs{tracingstats} to one}
477 % \tracinglostchars\z@
479 % Since this is the command that only conditionally turns off
480 % tracing we do not touch the |@tracing| switch. This way a
481 % |\conditionally@traceon| will be able to turn the tracing on
487 % That covers the case for the standard \TeX{} program. If
488 % |\tracingsgroups| was defined we assume that we are running with
489 % \eTeX{} in extended mode.
494 % In that case |\tr@ce@n| does more than |\tracingall|: it also
495 % turns on tracing of assignments and tracing of
496 % grouping.\footnote{These are my personal preference settings;
497 % \eTeX{} does in fact offer some more tracing switches and perhaps
498 % one or or more of them should be added here as well.}
499 % To keep tracing at a minimum |\tracingassigns| should be turned
500 % on last (in fact like before we disassemble |\tracingall|
501 % and reorder it partially).
507 \tracinglostchars\@ne
508 \tracingparagraphs\@ne
509 \errorcontextlines\maxdimen
511 \showboxbreadth\maxdimen
512 \showboxdepth\maxdimen
519 \tracingonline\tracingonline@p
523 % When turning tracing off again we now also have to turn off those
524 % additional tracing switches. But what to turn off in what order?
525 % Since |\tracingassigns| is quite noisy (two lines of output per
526 % assignment) and the whole command expansion consists of
527 % assignments, we had best start with this switch and follow it again
528 % by |\tracingrestores| and |\tracingcommands|. The rest can be in
529 % any order, it doesn't make a difference.
531 % With the same reasoning as before we omit testing for the
532 % |@tracing| switch and always set the primitives back to zero.
533 % \changes{v1.1c}{2003/04/30}{Turn off \cs{tracingoutput}}
534 % \changes{v1.1c}{2003/04/30}{Reset \cs{tracingstats} to one}
536 \def\conditionally@traceoff{%
546 \tracingparagraphs\z@
551 % This concludes the part that depends on the formatter being
560 % \begin{macro}{\unconditionally@traceoff}
561 % \changes{v1.1c}{2003/04/30}{Macro added}
562 % A saved version of whatever |\conditionally@traceoff| was defined
563 % to be. We need this since the latter might get disabled by
564 % |\tracingall| or by the \texttt{full} option.
566 \let\unconditionally@traceoff\conditionally@traceoff
570 % \begin{macro}{\tracingall}
571 % \changes{v1.1c}{2003/04/30}{Macro added}
572 % We redefine |\tracingall| to trace the same stuff than |\tr@ce@n| (i.e.,
573 % more when \eTeX{} is being used) and ensure that everything gets
574 % traced by disabling |\conditionally@traceoff|. And, of course,
575 % |\tracingall| should always report on the terminal.
577 \def\tracingall{\let\conditionally@traceoff\@empty
578 \let\tracingonline@p\@ne
585 % \begin{macro}{\traceoff}
586 % \begin{macro}{\conditionally@traceon}
587 % Above we have defined |\conditionally@traceoff| and |\traceon| so
588 % now we have to define their counterparts.
590 % To stop tracing unconditionally we call
591 % |\unconditionally@traceoff| and then reset the |@tracing| switch
594 \def\traceoff{\unconditionally@traceoff \@tracingfalse}
597 % Now the |\conditionally@traceon| command will look at the
598 % |@tracing| switch and if it is true it will call |\traceon| to
599 % restart tracing (note that the latter command unnecessarily sets
600 % the switch to true as well). The reason for the |\expandafter| is
601 % to get rid of the |\fi| primitive which would otherwise show up in
602 % the tracing output (and perhaps puzzle somebody).
604 \def\conditionally@traceon{\if@tracing \expandafter \traceon \fi}
610 % The rest of the package now consists of redefinitions of certain
611 % commands to make use of |\conditionally@traceoff|.
613 % \subsection{Taming \texttt{calc}}
615 % \begin{macro}{\calc@open}
616 % Near the start of parsing a calc expression the macro |\calc@open|
617 % is called. Since it already involves a group it is perfectly
618 % suitable for our task---we don't even have to restart the tracing as
619 % this is done automatically for us.
621 \def\calc@open({\begingroup
622 \conditionally@traceoff
623 \aftergroup\calc@initB
624 \begingroup\aftergroup\calc@initB
630 % \subsection{Making NFSS less noisy}
632 % \begin{macro}{\define@newfont}
633 % Whenever NFSS determines that the font currently asked for is not
634 % already loaded, it will start looking through font definition
635 % files and then load the font. This results in a very large number
636 % of tracing lines which are not normally of interest (unless there
637 % is a bug in that area---something we hope should have been found
638 % by now). Again the code already contains its own group so we only
639 % have to turn the tracing off.
641 \def\define@newfont{%
643 \conditionally@traceoff
644 \let\typeout\@font@info
646 \expandafter\expandafter\expandafter
647 \split@name\expandafter\string\font@name\@nil
648 \try@load@fontshape % try always
650 \csname\curr@fontshape\endcsname \relax
651 \wrong@fontshape\else
657 % \begin{macro}{\frozen@everymath}
658 % \begin{macro}{\frozen@everydisplay}
659 % At the beginning of every math formula NFSS will check whether or
660 % not the math fonts are properly set up and if not will load
661 % whatever is needed. So we surround that part of the code
662 % with |\conditionally@traceoff| and |\conditionally@traceon|
663 % thereby avoiding all this uninteresting output.
666 {\conditionally@traceoff \check@mathfonts \conditionally@traceon
668 \frozen@everydisplay =
669 {\conditionally@traceoff \check@mathfonts \conditionally@traceon
677 % \section{Checking for italic corrections}
679 % \begin{macro}{\maybe@ic@}
680 % When executing |\textit| or its friends, \LaTeX{} looks ahead to
681 % determine whether or not to add an italic correction at the
682 % end. This involves looping through the |\nocorrlist| which
683 % outputs a lot of tracing lines we are normally not interested
684 % in. So we disable tracing for this part of the processing.
685 % \changes{v1.1d}{2014/04/21}{Use \cs{ifmaybe@ic} not
686 % \cs{if@tempswa} as the kernel does (pr/4200)}
689 \ifdim \fontdimen\@ne\font>\z@
691 \conditionally@traceoff
693 \expandafter\@tfor\expandafter\reserved@a\expandafter:\expandafter=%
696 \ifmaybe@ic \sw@slant \fi
697 \conditionally@traceon