%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
%                                                                          %
% This is file 'ltxtools-trace.sty', version 0.0.1, December 2011.         %
%                                                                          %
% This package and accompanying files may be distributed and/or            %
% modified under the conditions of the LaTeX Project Public License,       %
% either version 1.3 of this license or 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 2005/12/01 or later.                                             %
%                                                                          %
% The LPPL maintenance status of this software is 'author-maintained'.     %
%                                                                          %
% This software is provided 'as it is', without warranty of any kind,      %
% either expressed or implied, including, but not limited to, the          %
% implied warranties of merchantability and fitness for a particular       %
% purpose.                                                                 %
%                                                                          %
% Copyright (c) 2011 Ahmed Musa (amusa22@gmail.com).                       %
%                                                                          %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
%                            COMMENTS                                      %
% The 'trace' package must be loaded last among all loaded packages,       %
% to avoid problems that might arise if some of the LaTeX commands it      %
% redefines are later redefined by other packages. In contrast, the        %
% 'ltxtools-trace' package can be loaded any time. Also, the counter       %
% \tracinggrade can be changed dynamically to enable or disable            %
% \tracingonline and \tracingifs.                                          %
%                                                                          %
% \tracinggrade (default = 3) accepts the following user values:           %
% <=1 -> no tracing online, no tracing ifs;                                %
% >1  -> tracing ifs                                                       %
% >2  -> tracing online                                                    %
%                                                                          %
% Package option 'tracingall' will trace even font selections.             %
%                                                                          %
% '\ltsbegingroup ... \ltsendgroup' can be used to trace group mismatch.   %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\ProvidesPackage{ltxtools-trace}[2011/12/12 v0.0.1 Tracing LaTeX code]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
\edef\reserved@a{%
  \noexpand\AtEndOfPackage{\catcode\number`\&=\number\catcode`\&}%
}
\reserved@a
\newcommand*\LTS@defcmds{}
\catcode`\&=3
\protected\def\LTS@defcmds#1#2{%
  \begingroup
  \toks@{}%
  \def\reserved@e##1 &{\reserved@f##1&}%
  \def\reserved@f##1&##2{%
    \unexpanded\expandafter{\romannumeral-`\q\noexpand##1}%
  }%
  \edef\LTS@tempa{\reserved@e#1& &}%
  \def\reserved@a{if}%
  \edef\LTS@tempb{\ifx\LTS@tempa\reserved@a if\fi}%
  \def\do##1,{%
    \ifnot@nil{##1}{%
      \edef\LTS@tempc{\reserved@e##1& &}%
      \edef\reserved@a{\expandafter\expandafter\expandafter
        \@car\expandafter\string\LTS@tempc\@nil}%
      \ifx\reserved@a\@backslashchar
        \@latex@error{'\detokenize{##1}' isn't a command name}\@ehc
      \fi
      \expandafter\@ifdefinable\csname\LTS@tempb\LTS@tempc\endcsname{%
        \ifx\LTS@tempa\@empty\else
          \def\reserved@a{cmd}%
          \ifx\LTS@tempa\reserved@a\else
            \toks@\expandafter{\the\expandafter\toks
              \expandafter0\expandafter\noexpand
              \csname new\LTS@tempa\expandafter\endcsname\csname
              \LTS@tempb\LTS@tempc\endcsname
            }%
          \fi
        \fi
      }%
      \do
    }%
  }%
  \do#2,\@nil,%
  \expandafter\endgroup\the\toks@
}
\LTS@defcmds{if}{LTS@tracesw,LTS@tracingall}
\LTS@defcmds{count}{LTS@grouplevel,LTS@grouptype,tracinggrade,
  LTS@tracedepth}
\LTS@defcmds{cmd}{ltsbegingroup,ltsendgroup,trace,
  LTS@traceon,LTS@traceoff,LTS@tracedefs,showcsn,
  starttracingall,stoptracingall}
\let\starttracingall\LTS@tracingalltrue
\let\stoptracingall\LTS@tracingallfalse
\DeclareOption{logonly}{\tracinggrade\tw@}
\DeclareOption{notraceifs}{\tracinggrade\@ne}
\DeclareOption{traceall}{\LTS@tracingalltrue}
\DeclareOption{tracingall}{\LTS@tracingalltrue}
\tracinggrade\thr@@
\ProcessOptions\relax

\protected\def\ltsbegingroup{%
  \begingroup
  \LTS@grouplevel\currentgrouplevel
  \LTS@grouptype\currentgrouptype
}
\protected\def\ltsendgroup{%
  \ifnum\LTS@grouptype=\currentgrouptype
    \ifnum\LTS@grouplevel=\currentgrouplevel\else
      \LTS@err{There is a group level mismatch}\@ehc
      \aftergroup\showgroups
    \fi
  \else
    \LTS@err{There is a group type mismatch}\@ehc
    \aftergroup\showgroups
  \fi
  \endgroup
}
\protected\def\LTS@traceon{%
  \tracingstats2
  \tracingpages1
  \tracinglostchars1
  \tracingparagraphs1
  \errorcontextlines\maxdimen
  \tracingoutput1
  \showboxbreadth\maxdimen
  \showboxdepth\maxdimen
  \errorstopmode
  \tracingrestores1
  \tracingonline\ifnum\tracinggrade>2 1 \else0 \fi
  \tracinggroups1
  \tracingifs\ifnum\tracinggrade>1 1 \else0 \fi
  \tracingassigns1
  \tracingmacros2
  \tracingcommands2
}
\protected\def\LTS@traceoff{%
  \tracingassigns0
  \tracingcommands0
  \tracingmacros0
  \tracingrestores0
  \tracingpages0
  \tracingoutput0
  \showboxbreadth-1
  \showboxdepth-1
  \tracingstats1
  \tracingparagraphs0
  \tracingifs0
  \tracinggroups0
}
\protected\def\LTS@tracedefs{%
  % Tracing 'fp' evaluations may lead to stack overflow.
  % Hence, they shouldn't be traced:
  \def\FPeval##1##2{%
    \ifLTS@tracesw\LTS@traceoff\fi
    \FP@eval{##1}{##2}%
    \ifLTS@tracesw\LTS@traceon\fi
  }
  \def\calc@open({%
    \begingroup
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceoff\fi
    \fi
    \aftergroup\calc@initB
    \begingroup\aftergroup\calc@initB
    \calc@pre@scan
  }%
  \def\define@newfont{%
    \begingroup
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceoff\fi
    \fi
    \let\typeout\@font@info
    \escapechar-1
    \expandafter\expandafter\expandafter\split@name
      \expandafter\string\font@name\@nil
    \try@load@fontshape
    \expandafter\ifx\csname\curr@fontshape\endcsname\relax
      \wrong@fontshape\else\extract@font\fi
    \endgroup
  }%
  \frozen@everymath={%
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceoff\fi
    \fi
    \check@mathfonts
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceon\fi
    \fi
    \the\everymath
  }%
  \frozen@everydisplay={%
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceoff\fi
    \fi
    \check@mathfonts
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceon\fi
    \fi
    \the\everydisplay
  }%
  \def\maybe@ic@{%
    \ifdim\fontdimen\@ne\font>\z@
    \else
      \ifLTS@tracingall\else
        \ifLTS@tracesw\LTS@traceoff\fi
      \fi
      \@tempswatrue
      \expandafter\@tfor\expandafter\reserved@a
        \expandafter:\expandafter=\nocorrlist\do\t@st@ic
      \if@tempswa\sw@slant\fi
      \ifLTS@tracingall\else
        \ifLTS@tracesw\LTS@traceon\fi
      \fi
    \fi
  }%
  \protected\def\selectfont{%
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceoff\fi
    \fi
    \ifx\f@linespread\baselinestretch\else
      \set@fontsize\baselinestretch\f@size\f@baselineskip
    \fi
    \xdef\font@name{%
      \csname\curr@fontshape/\f@size\endcsname
    }%
    \pickup@font
    \font@name
    \size@update
    \enc@update
    \ifLTS@tracingall\else
      \ifLTS@tracesw\LTS@traceon\fi
    \fi
  }%
}
\def\LTS@tracestack{}
\def\LTS@tracepush{%
  \global\advance\LTS@tracedepth\@ne
  \def\reserved@a{\romannumeral\LTS@tracedepth\endcsname}%
  \expandafter\let\csname ifLTS@tracesw@\reserved@a\ifLTS@tracesw
  \expandafter\let\csname ifLTS@tracest@\reserved@a\ifLTS@tracest
  \edef\LTS@tracestack{%
    \let\noexpand\ifLTS@tracesw\expandafter\noexpand
      \csname ifLTS@tracesw@\reserved@a
    \let\noexpand\ifLTS@tracest\expandafter\noexpand
      \csname ifLTS@tracest@\reserved@a
    {\unexpanded\expandafter{\LTS@tracestack}}%
  }%
}
\def\LTS@tracepop{%
  \def\reserved@a##1##{##1\gdef\LTS@tracestack}%
  \expandafter\reserved@a\LTS@tracestack
  \global\advance\LTS@tracedepth-1
}
\newcommand*\trace{}
% \begin{trace}*...\end{trace}.
% Star (*) -> stop run at end of trace.
\protected\def\trace{%
  \@ifstar{\let\ifLTS@tracest\iftrue\LTS@trace}
    {\let\ifLTS@tracest\iffalse\LTS@trace}%
}
\protected\def\LTS@trace{%
  \LTS@tracepush
  \ifLTS@tracesw
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {%
    \typeout{^^J+++++++++ Tracing start +++++++++
    ^^J\@spaces Ignore the next 5 lines:}%
    \LTS@traceswtrue
    \LTS@tracedefs
    \LTS@traceon
  }%
}
\protected\def\endtrace{%
  \LTS@traceoff
  \LTS@traceswfalse
  \ifLTS@tracest\expandafter\stop\fi
  \LTS@tracepop
}
\protected\def\showcsn#1{\expandafter\show\csname#1\endcsname}

\endinput