如何设计一个查询内部所需包的命令?

如何设计一个查询内部所需包的命令?

如何定义一个文档命令,将声明的文档类内部所需的所有包以及用户在文档中加载的包的列表\FilesRequire写入(或输出控制台)?.log

例如,对于本文档

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

\FilesRequire

\begin{document}

test

\end{document}

输出内容如下

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].

该命令应该有一个可选参数,用于以逗号分隔列出要查询的包:

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

\FilesRequire[amsmath]

\begin{document}

test

\end{document}

将仅生成文档类别和的信息 amsmath

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

基本上,该命令必须生成在文档中使用的和文件中\RequirePackage找到的所有命令的参数列表。.cls.sty

我对外部脚本不感兴趣。

答案1

此原型探索了获取顶级包的依赖关系而不记录完整包依赖关系的想法。代码遵循 LaTeX 的包管理,并挂接到\@onefilewithoptions所有所需包和类的调用,即使包已加载(然后 LaTeX 仅检查包选项是否存在冲突)。

评论:

  • 根据要求,仅记录顶级类和包的依赖关系。
  • 如果依赖包需要某个包,则也会将其添加到依赖项中。但是,如果包及其依赖包之前未加载,则传递闭包才是完整的,请参见下面的示例。
  • 有些包还通过 加载其他包\AtBeginDocument,这些情况也会被捕获,请参阅示例。

实施说明:

  • 实现不应该使用其他包。否则,它会对分析包依赖关系的文件造成过多干扰。
  • 软件包列表通过以下方式提供\AtEndDocument,这是 vanilla LaTeX 为代码提供的唯一钩子前言。如果想要更早的时间,则可以签入\AtBeginDocument,前提是包etoolbox可以使用其钩子\AfterEndPreamble。或者可以在文档主体中手动触发包列表。

示例文件:

\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}

结果:

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)]
================

讨论:

  • 该示例捕获通过via加载的包nameref和。colorhyperref\AtBeginDocument
  • 该示例还显示了限制。包bookmark加载包hyperref。由于包hyperref已加载,.styLaTeX 不会读取该文件,也\RequirePackage不会看到命令。因此,包的列表bookmark缺少包的依赖项hyperref。因此,此原型的改进需要记录完整的包依赖项。

答案2

这是我按照 Bruno Le Floch 的建议解决的污垢问题。

\需要包必须打电话您想要了解的软件包。它会向输出控制台和文件 *.requiredpackages 报告。它不会告诉您有关文档类所需的软件包的任何信息。但可以作为起点。

\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}

命令\usepackage\RequirePackage已被挂钩,但 \LoadClass 没有,因此未报告其使用情况。

事实上,它产生了这个:

Package graphicx requires: keyval,graphics, trig.
Package amsmath requires: amstext, amsgen, amsbsy, amsgen, amsopn, amsgen.

相关内容