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.

How can I define a document command \FilesRequire that writes to the .log (or to the output console) a list of all packages internally required by the declared document class and by the packages that have been loaded by the user in a document?

For example, with this document

\documentclass{book}
\usepackage{graphicx}
\usepackage{amsmath}

\FilesRequire

\begin{document}

test

\end{document}

The output will be something like

Document class book: doesn't require additional packages.
Package graphicx requires: keyval, graphics.
Package amsmath requires: amstext[1995/01/25], amsbsy[1995/01/20],
amsopn[1995/01/20].

The command should have an optional argument for a comma separated list of the packages which will be inquired:

\documentclass{book}
\usepackage{graphicx}
\usepackage{amsmath}

\FilesRequire[amsmath]

\begin{document}

test

\end{document}

will produce just the information for the document class and for amsmath:

Document class book: doesn't require additional packages.
Package amsmath requires: amstext[1995/01/25], amsbsy[1995/01/20],
amsopn[1995/01/20].

Basically, the command must produce a list of the arguments for all \RequirePackage commands found inside the .cls and .sty files used in a document.

I am not interested in external scripts.

share|improve this question
    
What you are asking for is doable by using one of the various package that keeps track of the current file, and hooking into \LoadClass and \RequirePackage (and \usepackage, if the hooking is done after \documentclass). But it is not completely straightforward to get everything right. Maybe if you described your goal it would be possible to find an alternate solution (within TeX). –  Bruno Le Floch Jun 17 '13 at 9:20
    
@BrunoLeFloch my goal is described in the question or, at least, I thought it was :-); I'd like to have the command with the mentioned specifications. Do you need me to clarify something else? –  Gonzalo Medina Jun 17 '13 at 19:54
    
My question is to know why you want such a list. For instance, do you in fact want to know for all existing packages what packages they depend on, to build a dependency tree? There may be easier approaches than what you are asking for. –  Bruno Le Floch Jun 18 '13 at 11:48
    
@BrunoLeFloch no, I am not interested in a dependency tree. I want this command to quickly show me which packages are being loaded behind the scenes without going to the .sty or .cls files directly. –  Gonzalo Medina Jun 19 '13 at 2:08
1  
@BrunoLeFloch now that I re-read my previous answer to you in view of Frank's comment, perhaps I need to clarify: I don't want a full dependency tree (as I assumed you were suggesting with "all packages"), but I want the ability to know which/if some package(s) was(were) loaded internally by another one that I directly loaded in my document. I hope my intent is more clear now. –  Gonzalo Medina Jun 20 '13 at 2:19

2 Answers 2

up vote 20 down vote accepted
+100

This prototype explores the idea to get the dependencies of the top level packages without recording the full package dependencies. The code observes LaTeX's package management and hooks into \@onefilewithoptions that is called for all required packages and classes, even if a package is already loaded (then LaTeX only checks the package options for clashes).

Remarks:

  • As requested, only the dependencies of the top level classes and packages are recorded.
  • Also packages are added to the dependencies, if they are required by dependent packages. However, the transitive closure is only complete, if the package and its dependent packages are not loaded earlier, see the example below.
  • Some packages also loads other packages via \AtBeginDocument, these cases are also caught, see the example.

Implementation notes:

  • An implementation should not use other packages. Otherwise it would interfere too much with the file, whose package dependencies are analyzed.
  • The package list is given via \AtEndDocument, the only hook vanilla LaTeX provides for code after the preamble. If an earlier time is wanted, then it could be checked in \AtBeginDocument, if pacakage etoolbox is available for using its hook \AfterEndPreamble. Or the package listings could be manually triggered in the document body.

Example file:

\makeatletter
\let\req@onefilewithoptions\@onefilewithoptions
\def\@onefilewithoptions#1[#2][#3]#4{%
  \req@push{#1.#4}%
  \req@onefilewithoptions{#1}[{#2}][{#3}]{#4}%
  \req@pop
}

\let\req@list\@empty
\let\req@item\relax
\let\req@top\relax
\newcounter{req@count}
\def\req@push#1{%
  % \typeout{*** [#1]}% debug
  \ifcase\value{req@count}%
    \@ifundefined{req@#1}{%the file, whose package dependencies 
      \global\expandafter
      \let\csname req@#1\endcsname\@empty
      \xdef\req@list{%
        \req@list
        \req@item{#1}%
      }%
    }{}%
    \xdef\req@top{#1}%
    \edef\req@tmp{%
      \noexpand\AtBeginDocument{%
        \noexpand\stepcounter{req@count}%
        \xdef\noexpand\req@top{#1}%
      }%
    }%
    \req@tmp
  \else
    \expandafter\ifx\csname req@\req@top\endcsname\@empty
      \expandafter\xdef\csname req@\req@top\endcsname{#1}%
    \else
      \edef\req@tmp{%
        \noexpand\in@{,#1,}{,\csname req@\req@top\endcsname,}%
      }%
      \req@tmp
      \ifin@
      \else
        \expandafter\xdef\csname req@\req@top\endcsname{%
          \csname req@\req@top\endcsname
          ,#1%
        }%
      \fi
    \fi
  \fi
  \stepcounter{req@count}%
}
\def\req@pop{%
  \addtocounter{req@count}{-1}%
  \ifcase\value{req@count}%
    \global\let\req@top\relax
    \AtBeginDocument{%
      \addtocounter{req@count}{-1}%
      \global\let\req@top\relax
    }%
  \fi
}

\def\req@process{%
  \typeout{Requirement list}%
  \typeout{================}%
  \let\req@item\req@process@item
  \req@list 
  \typeout{================}%
}
\def\req@process@item#1{%
  \typeout{* #1\req@info{#1}}%
  \expandafter\@for\expandafter\req@tmp
  \expandafter:\expandafter=\csname req@#1\endcsname\do{%
    \typeout{ \space> \req@tmp\req@info{\req@tmp}}%
  }%
}
\def\req@info#1{%
  \@ifundefined{ver@#1}{}{ [\@nameuse{ver@#1}]}%
}
\AtEndDocument{\req@process}%
\makeatother

\documentclass{article}
\usepackage{amsmath}
\usepackage[colorlinks]{hyperref}
\usepackage{bookmark}
\begin{document}
\end{document}

Result:

Requirement list
================
* article.cls [2007/10/19 v1.4h Standard LaTeX document class]
* amsmath.sty [2013/01/14 v2.14 AMS math features]
  > amstext.sty [2000/06/29 v2.01]
  > amsgen.sty [1999/11/30 v2.0]
  > amsbsy.sty [1999/11/29 v1.2d]
  > amsopn.sty [1999/12/14 v2.01 operator names]
* hyperref.sty [2012/11/06 v6.83m Hypertext links for LaTeX]
  > hobsub-hyperref.sty [2013/02/08 v1.16 Bundle oberdiek, subset hyperref (HO)
]
  > hobsub-generic.sty [2013/02/08 v1.16 Bundle oberdiek, subset generic (HO)]
  > ltxcmds.sty [2013/02/08 v1.23 LaTeX kernel commands for general use (HO)]
  > infwarerr.sty [2013/02/08 v1.4 Providing info/warning/error messages (HO)]
  > ifluatex.sty [2013/02/08 v1.5 Provides the ifluatex switch (HO)]
  > etexcmds.sty [2013/02/07 v1.6 Avoid name clashes with e-TeX commands (HO)]
  > protecteddef.sty [2013/02/08 v1.1 Define protected commands (HO)]
  > ifpdf.sty [2013/02/08 v2.5 Provides the ifpdf switch (HO)]
  > pdftexcmds.sty [2013/02/08 v0.22 Utility functions of pdfTeX for LuaTeX (HO
)]
  > intcalc.sty [2013/02/08 v1.2 Expandable calculations with integers (HO)]
  > bigintcalc.sty [2013/02/07 v1.4 Expandable calculations on big integers (HO
)]
  > hopatch.sty [2013/01/24 v1.4 Wrapper for package hooks (HO)]
  > xcolor-patch.sty [2013/02/08 xcolor patch]
  > keyval.sty [1999/03/16 v1.13 key=value parser (DPC)]
  > kvsetkeys.sty [2013/02/08 v1.18 Key value parser (HO)]
  > kvdefinekeys.sty [2013/02/08 v2.1 Define keys (HO)]
  > pdfescape.sty [2013/02/08 v1.16 Implements pdfTeX's escape features (HO)]
  > ifvtex.sty [2013/02/08 v1.6 Detect VTeX and its facilities (HO)]
  > ifxetex.sty [2010/09/12 v0.6 Provides ifxetex conditional]
  > hycolor.sty [2013/02/08 v1.8 Color options for hyperref/bookmark (HO)]
  > letltxmacro.sty [2013/02/08 v1.5 Let assignment for LaTeX macros (HO)]
  > auxhook.sty [2013/02/07 v1.4 Hooks for auxiliary files (HO)]
  > kvoptions.sty [2013/02/08 v3.13 Key value format for package options (HO)]
  > url.sty [2006/04/12  ver 3.3  Verb mode for urls, etc.]
  > bitset.sty [2013/02/07 v1.2 Handle bit-vector datatype (HO)]
  > atbegshi.sty [2013/02/08 v2.1 At begin shipout hook (HO)]
  > atveryend.sty [2013/02/08 v1.10 Hooks at the very end of document (HO)]
  > rerunfilecheck.sty [2013/02/08 v1.8 Rerun checks for auxiliary files (HO)]
  > uniquecounter.sty [2013/02/08 v1.4 Provide unlimited unique counter (HO)]
  > color.sty [2005/11/14 v1.0j Standard LaTeX Color (DPC)]
  > nameref.sty [2012/10/27 v2.43 Cross-referencing by name of section]
  > refcount.sty [2013/02/08 v3.6 Data extraction from label references (HO)]
  > gettitlestring.sty [2013/02/08 v1.6 Cleanup title references (HO)]
* bookmark.sty [2013/02/07 v1.25 PDF bookmarks (HO)]
  > pdfescape.sty [2013/02/08 v1.16 Implements pdfTeX's escape features (HO)]
  > ifpdf.sty [2013/02/08 v2.5 Provides the ifpdf switch (HO)]
  > ifxetex.sty [2010/09/12 v0.6 Provides ifxetex conditional]
  > ifvtex.sty [2013/02/08 v1.6 Detect VTeX and its facilities (HO)]
  > ifluatex.sty [2013/02/08 v1.5 Provides the ifluatex switch (HO)]
  > pdftexcmds.sty [2013/02/08 v0.22 Utility functions of pdfTeX for LuaTeX (HO
)]
  > hyperref.sty [2012/11/06 v6.83m Hypertext links for LaTeX]
  > auxhook.sty [2013/02/07 v1.4 Hooks for auxiliary files (HO)]
  > kvsetkeys.sty [2013/02/08 v1.18 Key value parser (HO)]
  > kvoptions.sty [2013/02/08 v3.13 Key value format for package options (HO)]
  > hycolor.sty [2013/02/08 v1.8 Color options for hyperref/bookmark (HO)]
  > bitset.sty [2013/02/07 v1.2 Handle bit-vector datatype (HO)]
  > ltxcmds.sty [2013/02/08 v1.23 LaTeX kernel commands for general use (HO)]
================

Discussion:

  • The example catches the packages nameref and color that are loaded by hyperref via \AtBeginDocument.
  • The example also shows the limitation. Package bookmark loads package hyperref. Since package hyperref is already loaded, the .sty file is not read by LaTeX and the \RequirePackage commands are not seen. Thus the list for package bookmark misses the dependencies of package hyperref. Therefore a refinement of this prototype would need to record the full package dependencies.
share|improve this answer
1  
Now that's hooking! –  Caio Lopes Jul 5 '13 at 19:12

This is my dirt solution following Bruno Le Floch's suggestion.

The \RequirePackages have to be call before the packages you want to know about. It reports to the output console and to a file *.requiredpackages. It doesn't tell nothing about packages required by the document class. But could work as a starting point.

\documentclass{book}

\def\RequiredPackages{
   \newwrite\requiredpackagesfile
   \openout\requiredpackagesfile=\jobname.requiredpackages
   \newtoks\requiredpackages
   \newif\ifrequiredpackages

   \let\realusepackage=\usepackage
   \def\usepackage##1{%
      \requiredpackagesfalse
      \requiredpackages{}%
      \realusepackage{##1}%
      \ifrequiredpackages
         \edef\requiredpackagesreport{Package ##1 requires: \the\requiredpackages.}%
      \else
         \edef\requiredpackagesreport{Package ##1 doesn't require additional packages.}%
      \fi
      \expandafter\expandafter\expandafter\write\expandafter\requiredpackagesfile\expandafter{\requiredpackagesreport}%
      \message{\requiredpackagesreport}%
   }

   \let\realRequirePackage=\RequirePackage
   \def\RequirePackage##1{%
      \ifrequiredpackages
         \requiredpackages\expandafter{\the\requiredpackages, ##1}%
      \else
         \requiredpackagestrue
         \requiredpackages\expandafter{##1}%
      \fi
      \realRequirePackage{##1}%
   }
}
\RequiredPackages

\usepackage{graphicx}
\usepackage{amsmath}

\begin{document}

test

\end{document}

The commands \usepackage and \RequirePackage are hooked, but not \LoadClass, so its use is not reported.

As is, it produces this:

Package graphicx requires: keyval,graphics, trig.
Package amsmath requires: amstext, amsgen, amsbsy, amsgen, amsopn, amsgen.
share|improve this answer
5  
nice, except for one thing ... it can't report on packages preloaded ("required") by a document class. so if you replace book by amsbook, it reports Package amsmath doesn't require additional packages. since amsmath is preloaded by amsbook, which short circuits the additional loading. in fact, it would be really nice if this could report packages required by a document class, so people would know that amsbook already preloads amsmath and amsfonts. (it has amsthm built into the code, so it would be impossible to detect that.) –  barbara beeton Jun 30 '13 at 18:01
    
Thank you, Caio. This is definitely a big step towards the solution! –  Gonzalo Medina Jul 2 '13 at 15:01

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.