13

TeX of course knows at any time what control words and symbols are defined. Is it possible to access this information, for example at the end of a run?

Edit: the answer for pdfTeX is no, since the list of control sequence names is only stored in the string pool, which is not accessible from the TeX run. The answer for XeTeX is currently yes, because of a bug (see my answer). The answer in LuaTeX is probably yes, but it would be great to have an actual implementation.

I will thus have to do what I planned differently (for this, the cmdtrack package should help).

What I wanted to use the list of macros for is essentially a duplicate of this question: expanding some macros inside the LaTeXsource.

3 Answers3

11

The cmdtrack package attempts to keep track of what commands are defined (in order to tell you if and where you use the commands that you define). Perhaps you can get some inspiration from its methods.

Lev Bishop
  • 45,462
  • An other way might be to set \tracingcommands=1, and read the .log The only commands that are used are then primitives and those appearing in the .log This has at least one drawback for my application: if a macro only appears in conditional text that is skipped, it won't appear in the .log, and I will thus expand it. – Bruno Le Floch Jan 01 '11 at 06:17
  • @Bruno: Did you mean \tracingmacros? – Harald Hanche-Olsen Jan 01 '11 at 12:52
  • @Harald: yes, sorry, \tracingmacros=1 . – Bruno Le Floch Jan 01 '11 at 13:37
8

While the answers telling me that this is impossible are right, there happens to be a bug in XeTeX (fixed in the development branch, it seems), which lets us access all strings known to XeTeX, and in particular, control sequence names. This code is not meant for serious use, of course. It misses all single letter control sequences, which are treated differently by XeTeX. Because of this, and to avoid polluting the string pool with auxiliaries, I am using one-letter auxiliaries, within a group. \l increments \count0 and using \lowercase it builds a letter with character code outside the BMP (for which XeTeX is currently buggy). Then \s removes the letter from the meaning to get the string, and we then test with \ifcsname if the string correspond to a control sequence (it can also be an error message, a path, etc.). We stop when encountering \selfreferencingmacro, which marks the end of string that are allocated (that code should be tweaked if meant to be used several times).

\begingroup
  \edef\selfreferencingmacro{\detokenize{selfreferencingmacro}}
  \def\s#1 #2 {}
  \def\l{\advance\count0 1\lccode`a\count0
    \lowercase{\edef\x{\expandafter\s\meaning a}}%
    \ifx \x \selfreferencingmacro \else
      \ifcsname\x\endcsname \immediate\write16{\x}\fi
      \expandafter \l
    \fi
  }
  \count0="FFFF
  \l
\endgroup
\bye
2

Is your aim to strip the user defined macros from a file and replace them with their definitions for self-contained publication?

Maybe there is an easier way to do that. Though I guess you could always go crazy and reimplement TeX in TeX (it is Turing complete).

  • Yes. Though I don't really have any good reason to do it. I just saw the question mentionned somewhere and I thought I would try it. Reimplementing TeX in TeX's stomach crossed my mind (e.g., it would be cool to be able to change category codes and retokenize any string of letters with the new catcodes: chapter 8 of the TeXbook.) – Bruno Le Floch Jan 01 '11 at 22:20
  • Hmm, maybe using luatex you could do something fancy. I mean this sounds like a perfect application for reflection or a meta-circular Virtual Machine. Ideally luatex should provide reflection capabilities that let one reflectively spawn internal TeX contexts and manage the execution therein. If it doesn't it's an extremely useful trick someone should consider adding. – Peter Gerdes Jan 01 '11 at 22:45
  • That would be interesting. However, Monday is coming soon, and it will have to wait for a few months: I am working on some more useful project (regular expressions for delimiting arguments of TeX commands). And, well... grading. – Bruno Le Floch Jan 02 '11 at 17:40