Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

When using texdef to learn the definitions of environments sometimes not all the relevant lines are shown. I guess this has do with how the definitions are written. It seems that when environments are defined as

\def\environmentname{A}
\def\endenvironmentname{B}

or as

\def\environmentname{A}
\let\endenvironmentname B

then texdef returns only A (and not B). Is it possible to make texdef return both A and B? This would make sense because someone who wants to look up a definition of an environment would like to know the definition of the whole environment, i.e. both the beginning and the end.

For example texdef -t latex equation returns

\equation:
macro:->$$\refstepcounter {equation}

when the relevant lines are

\def\equation{$$\refstepcounter{equation}}
\def\endequation{\eqno \hbox{\@eqnnum}$$\@ignoretrue}

Another example is that texdef -t latex enumerate returns

\enumerate:
macro:->\ifnum \@enumdepth >\thr@@ \@toodeep \else \advance \@enumdepth \@ne \edef \@enumctr {enum\romannumeral \the \@enumdepth }\expandafter \list \csname label\@enumctr \endcsname {\usecounter \@enumctr \def \makelabel ##1{\hss \llap {##1}}}\fi

when the relevant lines are

\def\enumerate{%
  \ifnum \@enumdepth >\thr@@\@toodeep\else
    \advance\@enumdepth\@ne
    \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
      \expandafter
      \list
        \csname label\@enumctr\endcsname
        {\usecounter\@enumctr\def\makelabel##1{\hss\llap{##1}}}%
  \fi}
\let\endenumerate =\endlist
share|improve this question
    
The routine could be improved to show also \endfoo if not undefined (or equivalent to \relax). –  egreg Jan 30 '12 at 19:01
add comment

2 Answers 2

up vote 6 down vote accepted

As stated by egreg environments like foo are built by the macros \foo and \endfoo. texdef prints normally the definition of \foo if you use texdef foo. It does so by using the TeX primitive \show, which shows the internal definition, not the original source code. You need to use texdef foo endfoo manually to get the definition of both the begin and end code of an environment.

However, starting from texdef v1.5 from 2012/04/29 there is now a --source / -s option which will try to show the original source code of the definition. This is done by first locating the file holding the (first) definition of the macro using the --find/-f option and then scanning the file for the definition. This works well with most macro definitions both in LaTeX and TeX form, but is not yet implemented for \newenvironment etc. and will not/never work with any definitions which change the usual catcodes, i.e. verbatim related macros.

Using this option you can get now get the exact location and source code of e.g. of enumerate:

$ ./texdef -t latex -s enumerate
% latex.ltx, line 4545:
\def\enumerate{%
  \ifnum \@enumdepth >\thr@@\@toodeep\else
    \advance\@enumdepth\@ne
    \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
      \expandafter
      \list
        \csname label\@enumctr\endcsname
        {\usecounter\@enumctr\def\makelabel##1{\hss\llap{##1}}}%
  \fi}

This works because \def and not \newenvironment was used. Definitions done with \let etc. are not supported. The full file path is given if the -F option is used in addition.

Note that at the moment --source/-s will return nothing if the source is not found. You have to manually remove this option to get the unformatted definition. I will try to improve on this in future versions.


Update 2011/05/02:

I now released texdef v1.6 which supports \newenvironment and follows \let with the -s option. Also, there is now a -E option which tells the script that you are asking for an environment. If the -s option is used and no LaTeX environment definition is found, or without -s, for every <command> given as argument an end<command> is automatically added.

Examples:

$ texdef -t latex -s -E enumerate 
% latex.ltx, line 4545:
\def\enumerate{%
  \ifnum \@enumdepth >\thr@@\@toodeep\else
    \advance\@enumdepth\@ne
    \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
      \expandafter
      \list
        \csname label\@enumctr\endcsname
        {\usecounter\@enumctr\def\makelabel##1{\hss\llap{##1}}}%
  \fi}

% latex.ltx, line 4554:
\let\endenumerate =\endlist

% latex.ltx, line 4422:
\def\endlist{%
  \global\advance\@listdepth\m@ne
  \endtrivlist}
$ texdef -t latex -s abstract
% article.cls, line 376:
  \newenvironment{abstract}{%
      \titlepage
      \null\vfil
      \@beginparpenalty\@lowpenalty
      \begin{center}%
        \bfseries \abstractname
        \@endparpenalty\@M
      \end{center}}%
     {\par\vfil\null\endtitlepage}

Here is -E option is not required because of -s and \newenvironment. It doesn't hurt adding it, however.

share|improve this answer
add comment

texdef works by feeding the requested macro to TeX with the appropriate format (LaTeX if called with the -t latex option). The foo environment is actually obtained by defining \foo and \endfoo, so asking

texdef -t latex foo

shows the definition of \foo. I believe it's feasible that, when the format is LaTeX, texdef shows also \endfoo if defined. However this might reveal problematic. It's not so difficult to call

texdef -t latex foo endfoo

(any number of commands can be requested in the command line).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.