开发者

LaTeX: How to find package(s) that a command belongs to?

开发者 https://www.devze.com 2022-12-23 07:44 出处:网络
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?

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:

  1. If it's in the index to the TeXbook, it's inherited from TeX, the engine that drives LaTeX.
  2. 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.
  3. Otherwise, if it's in the index to The LaTeX Companion, the page number probably tells you what package it's from.
  4. Otherwise, you could do some fancy grepping on the results of find /usr/share/texmf -name '*.sty', but be prepared for a painful exercise.
  5. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号