如何提取 (La)TeX 文档的部分内容?

如何提取 (La)TeX 文档的部分内容?

我想要针对这些 LaTeX 文档运行查询:

  1. 获取所有方程的列表,即使有人声明\def\be{\begin{equation}}并使用它;
  2. 获取某个命令 (例如\marginpar) 的所有参数的列表,该命令已在文档中使用(同样,即使有人声明\def\m\marginpar并调用这个宏);
  3. 得到具有给定反值的定理。

这个任务似乎需要完全编译所有的宏,但我想在不是扩展形式 --- 不是作为块和胶水,而是作为用户的输入(如果可能的话)。

我怎能做这样的事?

更新:理想情况下,我想使用“语义标记”来标记文档的各个部分并生成它们的不同视图。假设我有这样的内容:

\beginBlock{calculus}
\beginBlock{content}
... lectures...
\endBlock
\beginBlock{exam}
... problems...
  \beginBlock{comments}
  ... comments about criteria and how to evaluate typical mistakes...
  \endBlock
\endBlock[exam]
\endBlock[calculus]

和其他文件中的线性代数类似;我想生成一份包含微积分和线性代数部分的报告,其中仅包含考试问题,例如

答案1

让我们看看\marginpar。您想要重新定义此命令以将其参数保存在要打印的某个列表中,例如在文档末尾。

我们必须看一下 的定义\marginpar,发现它是不是带有参数的命令,它会执行一系列相当复杂的任务。因此,我们不能简单地向其中添加一些操作,而不详细检查所使用的宏。

一个好的策略是收集论据,然后将它们放回原来的地方\marginpar

\makeatletter
\let\saved@marginpar\marginpar
\renewcommand\marginpar[2][]{%
  \if\relax\detokenize{#1}\relax
    \let\saved@mp@optional\@empty
  \else
    \def\saved@mp@optional{[#1]}%
  \fi
  \def\saved@mp@mandatory{{#2}}%
  \saved@mp@add{\saved@mp@print{#1}{#2}}%
  \expandafter\expandafter\expandafter\saved@marginpar
    \expandafter\saved@mp@optional\saved@mp@mandatory}
\newtoks\saved@mp@toks
\def\saved@mp@add#1{\global\saved@mp@toks=\expandafter{\the\saved@mp@toks#1}}
\def\printmarginpars{\the\saved@mp@toks}
\def\saved@mp@print#1#2{\par\noindent Marginpar\\
  Optional: #1\\
  Mandatory: #2\par\medskip}
\makeatother

如果你说,此代码,

\newcommand{\mpx}{\marginpar}

那么它将起到同样的作用。

宏起什么作用?

  1. \marginpar在保存了原始命令的副本后,被重新定义为具有可选参数和强制参数。

  2. 如果可选参数为空,那么我们将其定义\saved@mp@optional\@empty,否则我们将其定义为扩展为括号中的可选参数。

  3. 类似地,我们定义\saved@mp@mandatory扩展为括号中的强制参数。

  4. 我们将参数的内容添加到我们分配的令牌列表中。

  5. 我们把参数放回后面\saved@marginpar,这样 LaTeX 就会像什么都没发生一样完成其正常工作。

例子

\documentclass{article}
\makeatletter
\let\saved@marginpar\marginpar
\renewcommand\marginpar[2][]{%
  \if\relax\detokenize{#1}\relax
    \let\saved@mp@optional\@empty
  \else
    \def\saved@mp@optional{[#1]}%
  \fi
  \def\saved@mp@mandatory{{#2}}%
  \saved@mp@add{\saved@mp@print{#1}{#2}}%
  \expandafter\expandafter\expandafter\saved@marginpar
    \expandafter\saved@mp@optional\saved@mp@mandatory}
\newtoks\saved@mp@toks
\def\saved@mp@add#1{\global\saved@mp@toks=\expandafter{\the\saved@mp@toks#1}}
\def\printmarginpars{\the\saved@mp@toks}
\def\saved@mp@print#1#2{\par\noindent Marginpar\\
  Optional: #1\\
  Mandatory: #2\par\medskip}
\makeatother

\newcommand{\mpx}{\marginpar}

\begin{document}
a\marginpar{xxx}
b\mpx[yyy]{zzz}

\printmarginpars
\end{document}

答案2

我认为您最好使用您最喜欢的语言(如python或)的外部脚本perl

如果您想使用 LaTeX 来完成此操作,则可采用一种方法,至少对于非环境的命令,将命令的内容保存在文件中或列表中。

我将演示如何使用“marginpars”。首先定义一个列表:

  \def\alist{}

然后定义宏添加到列表中:

  \def\addtolist#1#2{
    \lst@lAddTo\alist{#2}
  }

  \long\gdef\addmp#1#2{\addtolist\alist{#1,}}

  \def\AddMP#1#2{%
     \long\expandafter\gdef\csname#1\endcsname{\textbf{#1}: #2}
     \addmp{#1}{#2}\marginpar{#2}
  }

marginpar注意最后一个,您可以使用保存内容addmp,然后打印它。

完整 MWE:

\documentclass[11pt]{book}
\usepackage{lstdoc,lipsum}
\begin{document}
\makeatletter
\def\alist{}

\def\addtolist#1#2{
  \lst@lAddTo\alist{#2}
}

\long\gdef\addmp#1#2{\addtolist\alist{#1,}}

\def\AddMP#1#2{%
\long\expandafter\gdef\csname#1\endcsname{\textbf{#1}: #2}
\addmp{#1}{#2}\marginpar{#2}
}

\def\PrintMP{%
  \@for \i:=\alist\do{%
  \csname\i\endcsname}
}
%example
\AddMP{mp}{\lipsum[2]}
\AddMP{mp}{\lipsum[3]}
\AddMP{mp}{\lipsum[1]}
% print the marginpars
\Printmp
\makeatother
\end{document}

编辑

根据原帖作者提供的新信息,可以使用.dtx系统文件doc/docstrip。这样您就可以将文档的各个部分保存到不同的文件中。

答案3

好的,现在我理解得更清楚了。一个相当普遍的想法是有一个“主”文档,它会在不同的“模式”下产生不同的输出。

这意味着您将进行不同的“配置”,其中您提到的环境定义不同。通过激活一个具有特定环境定义的“配置”,您将获得不同版本的文档。一个“配置”可以是.tex包含环境定义的文件(其中一个是\input),也可以是代表不同环境定义的专用包的不同选项。

可能相关的软件包:评论选修的版本版本演绎标记

另一个非常复杂的大型包装可用于这种事情:AcroTeX 教育套件

可能相关的问题:

“单独”显示问题的解决方案

比较有助于排版练习和解决方案的软件包:练习 vs. 答案 vs. probsoln

注释掉大段内容

仅包括与条件表达式对应的文档部分

还有一个问题与此高度相关,但现在我找不到了。它涉及如何将不同的内容部分存储在一个公共文件中,并将它们组合成不同的文档。也许其他人还记得。

相关内容