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} 之间。
现在让我们来看一下 Java 代码示例。
1// Create repair options.
2LaTeXRepairerOptions options = new LaTeXRepairerOptions();
3// Specify a file system working directory for the output.
4options.setOutputWorkingDirectory(new OutputFileSystemDirectory(Utils.getOutputDirectory()));
5// Specify a file system working directory for the required input.
6// The directory containing packages may be located anywhere.
7options.setRequiredInputDirectory(new InputFileSystemDirectory(Utils.getInputDirectory() + "packages"));
8// Specify the callback class to externally guess packages required for undefined commands or environments.
9options.setGuessPackageCallback(new PackageGuesser());
10
11// Run the repair process.
12new LaTeXRepairer(Utils.getInputDirectory() + "invalid-latex.tex", options).run();类似于普通的 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() 方法将其实例传递给过程。
下面是一个基本示例,它仅将 \head 命令映射到 fancyhdr 包:
1// The callback class to externally guess packages required for undefined commands or environments.
2public static class PackageGuesser implements IGuessPackageCallback
3{
4 private Map<String, String> _map = new HashMap<String, String>();
5
6 public PackageGuesser()
7 {
8 _map.put("lhead", "fancyhdr"); // Defines the mapping between the \lhead command and the fancyhdr package.
9 }
10
11 public String guessPackage(String commandName, boolean isEnvironment)
12 {
13 if (!isEnvironment)
14 {
15 String packageName = _map.get(commandName);
16 return packageName != null ? packageName : ""; // It's better to return an empty string to avoid consequent calls for the same command name.
17 }
18
19 // Some code for environments
20 // ...
21
22 return "";
23 }
24}对于示例文件,引擎首先遇到 \chapter 命令,该命令在 article 文档类中未定义,但在 book 文档类中定义。API 会调整文档类,使修复后文件的最终版本以 \documentclass{book} 开头。随后,引擎发现前述的 \lhead 命令,并确定必须在导言区插入 \usepackage{fancyhdr}。文件后续出现的 \href 和 \includegraphics 命令导致 Repairer 分别在导言区插入 \usepackage{hyperref} 和 \usepackage{graphics}。这些决定基于 API 的内部映射。与之前一样,所有这些修复都会记录在报告文件中。
最后,由于缺少 LaTeX 文档的正确结束,引擎异常终止。于是 Repairer 在文件末尾追加 \end{document},并将此信息写入报告。
在创建了原文件的修复版本后,Repairer 会对其执行一次 TeX 作业以进行最终验证。在我们的示例中,此次运行未检测到任何关键错误,因此修复后的版本基本可以按预期进行排版。
以下是完整的报告:
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 接口实现。