LaTeX 文件修复 | Aspose.TeX for Java
如何检查和修复 LaTeX 文件
如果您不确定一个文本文件是否为 LaTeX 文件且希望对其进行排版,可以使用 Aspose.TeX for Java API 提供的 LaTeX 检查和修复功能。在下面的示例中,我们将检查并修复来自 Aspose.TeX for Java 示例项目的示例文件 invalid-latex.tex。
首先,需要注意的是,该示例文件似乎使用了 TeX 语法,但缺少 LaTeX 所需的结构。正如您所知,LaTeX 文件必须包含以 \documentclass 命令开头的导言区,以及位于 document 环境中的主体,即介于 \begin{document} 和 \end{document} 之间。
将 inputFile 设置为 invalid-latex.tex 的完整路径,将 outputDirectory 设置为现有输出文件夹,将 packagesDirectory 设置为包含 fancyhdr.sty 及其依赖文件的文件夹。将下面的回调连同 import 语句保存为 PackageGuesser.java,并在修复前创建 PackageGuesser packageGuesser = new PackageGuesser()。导入所用的 Aspose.TeX 类,处理或声明异常,并按照
许可指南应用许可证。输入和输出目录在修复结束前保持打开,随后关闭。
1// Repair the LaTeX structure and infer packages for undefined commands.
2// inputFile is the full invalid LaTeX path; packagesDirectory contains fancyhdr.sty.
3// outputDirectory is an existing output folder; packageGuesser is a PackageGuesser instance.
4LaTeXRepairerOptions options = new LaTeXRepairerOptions();
5OutputFileSystemDirectory output = new OutputFileSystemDirectory(outputDirectory);
6InputFileSystemDirectory packages = new InputFileSystemDirectory(packagesDirectory);
7options.setOutputWorkingDirectory(output);
8options.setRequiredInputDirectory(packages);
9options.setGuessPackageCallback(packageGuesser);
10TeXJobResult result;
11try {
12 result = new LaTeXRepairer(inputFile, options).run();
13} finally {
14 output.close();
15 packages.close();
16}类似于普通的 TeX 作业,我们首先创建一个对象来保存即将运行的过程的选项。这些选项大多与普通 TeX 作业相同。实际上,调用 setInputWorkingDirectory() 方法时,我们指定输入文件应读取的目录。然而在本例中我们并未使用它,因为我们在文件系统中提供了主输入文件的完整路径,并且主输入文件中不需要包含任何自定义文件。接下来,调用 setOutputWorkingDirectory() 方法以指定输出文件应写入的目录。如果调用了 setRequiredInputDirectory() 方法,则选项会指向您可以存放未嵌入 Aspose.TeX 库的 LaTeX 包的目录。最后,将在后文讨论 setGuessPackageCallback() 方法。
一旦选项分配完成,我们即可继续运行该过程。
那么,检查和修复过程是怎样的呢?它首先让 API 在输入文件中搜索 \documentclass 的出现。如果未找到,API 会假设应在文件开头插入 \documentclass{article}。此信息会记录在修复报告文件(.log)中。
接下来,过程从头开始扫描已调整的输入文件。配备 LaTeX 格式的 TeX 引擎可能在某个时刻抛出错误,指示在应已存在的情况下仍未找到 \begin{document}。于是确定了必须插入 \begin{document} 的位置,并在报告中体现。
在进一步扫描文件时,引擎可能会遇到未定义的命令或环境。在这种情况下,API 可以对一些最常见的命令和环境作出关于
embedded required packages(这些包定义了在未包含相应包时未定义的命令和环境)的假设。然而,也可以通过实现
IGuessPackageCallback 接口的类在外部作出此类假设。开发好此类后,应通过调用 setGuessPackageCallback() 方法将其实例传递给过程。
此示例将 \lhead 命令映射到 fancyhdr 包。回调接收不含开头反斜杠的命令名,并为未知命令和环境返回空字符串:
1import com.aspose.tex.features.IGuessPackageCallback;
2
3// Save as PackageGuesser.java and assign an instance with setGuessPackageCallback().
4public class PackageGuesser implements IGuessPackageCallback {
5 @Override
6 public String guessPackage(String commandName, boolean isEnvironment) {
7 // The command name has no leading backslash.
8 if (!isEnvironment && "lhead".equals(commandName)) {
9 return "fancyhdr";
10 }
11 // Empty means that this callback cannot identify a package.
12 return "";
13 }
14}对于示例文件,引擎首先遇到 \chapter 命令,该命令在 article 文档类中未定义,但在 book 文档类中定义。API 会调整文档类,使修复后文件的最终版本以 \documentclass{book} 开头。随后,引擎发现前述的 \lhead 命令,并确定必须在导言区插入 \usepackage{fancyhdr}。文件后续出现的 \href 和 \includegraphics 命令导致 Repairer 分别在导言区插入 \usepackage{hyperref} 和 \usepackage{graphicx}。这些决定基于 API 的内部映射。与之前一样,所有这些修复都会记录在报告文件中。
最后,由于缺少 LaTeX 文档的正确结束,引擎异常终止。于是 Repairer 在文件末尾追加 \end{document},并将此信息写入报告。
修复后,Repairer 运行 TeX 作业进行最终验证。本例的最终报告没有关键错误。run() 的返回值可能反映原始扫描的状态,因此请检查修复报告和修复后的 .tex 文件。修复不会提供缺失的外部资源。例如,示例引用的 Figures/uet_logo.pdf 必须另行提供才能完成排版。
以下是完整的报告:
1正在尝试修复原始文件...
2--------------------------------------------------------------------------------
3原始文件中缺少 `\documentclass`。已将其插入到文件开头。
4原始文件中缺少 `\begin{document}`。已将其插入到第 3 行,位置 0。
5第 3 行,位置 0 的命令 `\chapter` 未定义。请考虑在导言区使用 `\usepackage{package_name}`,
6其中 `'package_name'` 是定义此命令的宏包的名称。
7第 5 行,位置 0 的命令 `\lhead` 未定义。已在导言区插入 `\usepackage{fancyhdr}`,
8因为 `fancyhdr` 宏包应该定义了该命令。
9第 8 行,位置 0 的命令 `\href` 未定义。已在导言区插入 `\usepackage{hyperref}`,
10因为 `hyperref` 宏包应该定义了该命令。
11第 17 行第 0 列的命令 `\href` 未定义。在导言区插入了 `\usepackage{hyperref}`,
12因为 `hyperref` 宏包应该定义了该命令。
13第 20 行第 0 列的命令 `\href` 未定义。在导言区插入了 `\usepackage{hyperref}`,
14因为 `hyperref` 宏包应该定义了该命令。
15第 27 行第 0 列的命令 `\href` 未定义。在导言区插入了 `\usepackage{hyperref}`,
16因为 `hyperref` 宏包应该定义了该命令。
17第 32 行第 0 列的命令 `\href` 未定义。在导言区插入了 `\usepackage{hyperref}`,
18因为 `hyperref` 宏包应该定义了该命令。
19第 54 行第 2 列的命令 `\includegraphics` 未定义。导言区插入了 `\usepackage{graphicx}`
20因为 `graphicx` 宏包定义了该命令。
21第 67 行第 0 列的命令 `\href` 未定义。导言区插入了 `\usepackage{hyperref}`
22因为 `hyperref` 宏包定义了该命令。
23第 95 行第 57 列的命令 `\href` 未定义。导言区插入了 `\usepackage{hyperref}`
24因为 `hyperref` 宏包定义了该命令。
25第 96 行第 0 列的命令 `\href` 未定义。导言区插入了 `\usepackage{hyperref}`
26因为 `hyperref` 宏包定义了该命令。
27第 98 行第 100 列的命令 `\href` 未定义。 \usepackage{hyperref} 已插入到导言区
28因为 `hyperref` 宏包定义了该命令。
29原始文件中缺少 \end{document}。已将其插入到文件末尾。
30正在检查修复后的文件……
31-------------------------------------------------------------------------------- 修复后的文件中没有严重错误。您还可以查看我们免费的
AI LaTeX Repairer 网页应用,该应用基于在
Aspose.TeX for .NET API 中实现的功能,并采用了更高级的 IGuessPackageCallback 接口实现。