LaTeX 文档的静态分析?

LaTeX 文档的静态分析?

C对于诸如、、C++等编程语言,C#总是Java存在某种静态分析器、工具来检查源代码中是否存在无法访问的代码、未使用的变量、内存泄漏和其他与编译无关的东西(因此编译器根本不会报告或注意到它)。

有没有类似的 LaTeX 工具?

当然,有些软件包,例如onlyamsmathnag可以检查过期的宏或软件包,并refcheck检查未使用的标签。但是,是否有软件包和/或工具可以检查或提示

  • 无法到达的代码:\if\else\fi一条或多条路径永远无法到达的构造?
  • 低效的循环,像\foreach可以简化的一样?
  • 未使用的宏定义?
  • \newcommand*建议在适当的地方使用代替\newcommand
  • 缺少可能的括号或空格?例如:
    1. a^b c- 清除
    2. a^{bc}- 清除
    3. a^bc- 可疑:渲染效果与 1 类似,但也许是 2 是故意的?
  • 可疑的空行(段落)?例如文本和公式之间?
  • 可疑或失踪结束行注释
  • 您还能想到什么通常对人眼来说是错误的、低效的或不清楚的呢?

答案1

简短的回答是,这是不可能的。

有些工具可以做一些事情,但它们无法真正分析乳胶文档,因此它们提供的任何建议都只能作为提示,它可能是错误的。

LaTeX 与您提到的 C 和 Java 等语言之间的最大区别在于,LaTeX 的语法无法分析,甚至输入的基本词汇分析和标记化也依赖于运行时行为。

\section[abc}

看起来这可能是一个语法错误,你可能希望静态分析能够发现它,但文档可能

\documentclass{article}

\ifodd\time\catcode`[1\fi
\begin{document}

\section[abc}

aa
\end{document}

这意味着它是否是有效文档取决于自午夜以来的分钟数。这显然是一个极端情况,但并不像您想象的那么极端。许多软件包都会做类似的事情来改变文档的分析,例如 babel 简写。可以通过检查前言来静态检测 babel 是否已加载,但要确定在任何时候哪种语言有效,实际上需要运行完整的 LaTeX 解释器。

即使可能,我也会质疑您的某些物品是否真的应该被标记。

  • 无法到达的代码:\if\else\fi一条或多条路径永远无法到达的构造?

这里的难点在于确定哪些标记实际上是测试,大多数情况下您看不到 Tex 基元,例如\if 通过定义的 But 标记\newif,这些标记很难被检查器识别。也许可以假设每个标记开头\if..都是这个意义上的 if 标记,但例如 LaTeX\ifthenelse以 开头,\if....但语法却大不相同。

  • 低效的循环,像\foreach可以简化的一样?

\foreach只是一个宏,因此几乎根据定义,它的任何特定用途都可以通过扩展宏来简化。但这可能不被视为简化……

  • 未使用的宏定义?

LaTeX 及其所有包都是宏定义,并且大多数文档并不使用定义的大多数命令,因此任何给定的文档中通常都有数千个未使用的宏。

  • \newcommand*建议在适当的地方使用代替\newcommand

我不确定如何做到这一点,除非你记录给定文档中宏的每次使用,并注意它在这种情况下永远不会发生。

  • 缺少可能的括号或空格?例如:
    1. a^b c- 清除
    2. a^{bc}- 清除
    3. a^bc- 可疑:渲染效果与 1 类似,但也许是 2 是故意的?

我不同意这个检查。2. 是标准的 latex 语法。如果你决定允许 1.,那么你也应该允许 3,无需注释。TeX 数学模式语法设计的核心部分是,除了终止命令名称之外,空格并不重要。

  • 可疑的空行(段落)?例如文本和公式之间?

TeX 会费些力气来区分显示后的文本是否是新段落,而 LaTeX 会在其所有列表环境中模拟此行为。因此,除非静态分析器正在解释句子并建议它不应该是段落的开头,否则它不应该在空白行上进行注释。

  • 可疑或者缺少[结束行注释][1]?

是的,只要它能够识别 latex3 语法的开始或者类似的包,改变规则和平均值%是没有必要的。

  • 您还能想到什么通常对人眼来说是错误的、低效的或不清楚的呢?

让人类来校对文档是一个好主意,人眼在这方面仍然比机器更好:-)

答案2

虽然接受的答案提出了许多好的观点,但执行 LaTeX 静态分析的软件确实存在。正如预期的那样,它们并不像 Python 等语言的 linters 那样全面。

最值得注意的 linter 是查克特克斯。它还加拿大运输安全局并且是TeX 直播(自从2010)。

相关内容