It is a simpl开发者_开发问答e question to which I am not able to find the answer:
Given a LaTeX command, how do I find out what package(s) it belongs to or comes from?
For example, given the \qquad
horizontal spacing command, what package does it come from? Especially troublesome since it works without including any package!
Given a LaTeX command, how do I find out what package(s) it belongs to or comes from?
Consult your references:
- If it's in the index to the TeXbook, it's inherited from TeX, the engine that drives LaTeX.
- Otherwise, if it's in the index to the LaTeX manual, it's probably defined in
latex.ltx
or in one of the standard class files, not in a package. - Otherwise, if it's in the index to The LaTeX Companion, the page number probably tells you what package it's from.
- Otherwise, you could do some fancy grepping on the results of
find /usr/share/texmf -name '*.sty'
, but be prepared for a painful exercise. - Or, you could ask on http://stackoverflow.com. But then some idiot will respond by asking why you want to know...
You can search http://www.ctan.org/tex-archive/info/symbols/comprehensive/ for that information and more.
Remember that LaTeX is a macro language on top of TeX, and all the macros are made up of TeX which doesn't need to be imported. \qquad
is in that category.
As far as I know, there is no really good general answer to this. But there are a number of techniques you might try for any given command. In the case of \qquad
, it's part of basic TeX. Remember that you can always use TeX in interactive mode:
$ tex '\show\qquad' This is TeX, Version 3.141592 (Web2C 7.5.6) > \qquad=macro: ->\hskip 2em\relax . \show\qquad ? x No pages of output.
Some macros are added by LaTeX on top of TeX, such as \begin
:
$ tex '\show\begin' This is TeX, Version 3.141592 (Web2C 7.5.6) > \begin=undefined. \show\begin ? x No pages of output.
whereas
$ latex '\show\begin' This is pdfTeXk, Version 3.141592-1.40.3 (Web2C 7.5.6) %&-line parsing enabled. entering extended mode LaTeX2e Babel and hyphenation patterns for english, usenglishmax, dumylang, noh yphenation, greek, monogreek, ancientgreek, ibycus, pinyin, loaded. > \begin=macro: #1->\@ifundefined {#1}{\def \reserved@a {\@latex@error {Environment #1 undefine d}\@eha }}{\def \reserved@a {\def \@currenvir {#1}\edef \@currenvline {\on@line }\csname #1\endcsname }}\@ignorefalse \begingroup \@endpefalse \reserved@a . \show\begin ? x No pages of output.
Everything else comes from packages. If you really wanna know which package a macro comes from (other than by google or grepping your texmf tree), you can check after each package you load whether it's defined. Try defining this before any \usepackage
commands:
\let\oldusepackage\usepackage \renewcommand\usepackage[1]{ \oldusepackage{#1} \ifcsname includegraphics\endcsname \message{^^Jincludegraphics is defined in #1^^J} \let\usepackage\oldusepackage \fi}
Then when you run latex
on your .tex
file, look for a line in the output that says includegraphics is defined in graphicx
. It's not likely, but some devious packages might do bad things with \usepackage
so there's a chance this might not work. Another alternative would be to simply define the command you're interested in before loading any packages:
\newcommand\includegraphics{}
Then you might get an error message when the package that defines the command is loading. This is actually less reliable than the former approach, since many packages use \def
and \let
to define their macros rather than \newcommand
, bypassing the "already-defined" check. You could also just insert a check by hand in between each load:
\ifcsname includegraphics\endcsname\message{^^Jdefined after graphicx^^J}\fi
Due to lack of reputation I cannot comment on Steve's answer, which was very helpful to me, but I would like to extend it a bit.
First, in his second approach (fiddling with usepackage
) the case where usepackage
has optional arguments is not dealt with. Secondly, packages are often loaded by other packages via RequirePackage
which makes it hard to find the actual place of definition of a command. So my refinement of Steve's answer is:
\usepackage{xargs}
\let\oldusepackage\usepackage
\let\oldRequirePackage\RequirePackage
\renewcommandx{\usepackage}[3][1,3]{
\oldusepackage[#1]{#2}[#3]
\ifcsname includegraphics\endcsname
\message{^^Jincludegraphics is defined in #2^^J}
\let\usepackage\oldusepackage
\let\RequirePackage\oldRequirePackage
\fi}
\renewcommandx{\RequirePackage}[3][1,3]{
\oldRequirePackage[#1]{#2}[#3]
\ifcsname includegraphics\endcsname
\message{^^Jincludegraphics is defined in #2^^J}
\let\usepackage\oldusepackage
\let\RequirePackage\oldRequirePackage
\fi}
The xargs
package is used here to get the unusual options of usepackage
right (first and third parameter are optional).
Putting this directly after documentclass
should tell where includegraphics
is defined.
精彩评论