外部 LaTeX 包 | Aspose.TeX for .NET

外部 LaTeX 包

Aspose.TeX 库已经包含了许多 常用 LaTeX 包。因此您无需担心如何向库的 TeX 引擎提供这些包。但有时(甚至经常)您的 LaTeX 文件可能需要超出“原生”支持的“捆绑”包。如果出现这种情况,您可以尝试通过 TeXOptions 类实例的 RequiredInputDirectory 选项提供所需的输入,即所需包的源文件。下面我们将通过两个示例来演示其工作方式。

已解压的必需输入(fancybox 包)

假设我们有下面这个简单的 LaTeX 文件,它来自我们的 示例解决方案中的 required-input-fs.tex

 1\documentclass{article}
 2\usepackage[a6paper,landscape]{geometry}
 3\usepackage{fancybox}
 4\begin{document}
 5Test: \fbox{
 6  \begin{Bitemize}[b]
 7  \item First item
 8  \item A second one\\ on two lines
 9  \item(2pt) A third with extra space
10  \end{Bitemize}
11}
12\par\bigskip
13Test: \fbox{
14  \begin{Beqnarray}[t]
15  y & = & x^2 \\
16  a^2 + 2ab + b^2 & = & (a + b)^2 \\
17  \int_0^\infty e^{-ax} dx & = & \frac{1}{a}
18  \end{Beqnarray}
19}
20\end{document}

在第 3 行可以看到文件需要 fancybox 包,而该包并未被“原生”支持。假设我们已经拥有 fancybox 包的源文件。它是一个简单的包,仅包含单个文件。我们可以将此文件放在文件系统的任意位置,并按如下方式指定目录路径:

1options.RequiredInputDirectory = new InputFileSystemDirectory("path-to-directory-where-fancybox.sty-located");

使用此选项运行 TeX 作业后(别忘了根据需要调整其他选项),我们得到输出文档(即 PNG 图像)。

Output Document

以下是该示例的完整源代码:

 1// External LaTeX packages from file system
 2
 3// Create conversion options for Object LaTeX format upon Object TeX engine extension.
 4TeXOptions options = TeXOptions.ConsoleAppOptions(TeXConfig.ObjectLaTeX);
 5// Specify a file system working directory for the output.
 6options.OutputWorkingDirectory = new OutputFileSystemDirectory(OutputDir);
 7// Specify a file system working directory for the required input.
 8// The directory containing packages may be located anywhere.
 9options.RequiredInputDirectory = new InputFileSystemDirectory(Path.Combine(DataDir, "packages"));
10// Initialize the options for saving in PNG format.
11options.SaveOptions = new PngSaveOptions();
12// Run LaTeX to PNG conversion.
13new TeXJob(Path.Combine(DataDir, "required-input-fs.tex"), new ImageDevice(), options).Run();

已归档的必需输入(pgfplots 包)

现在假设我们还有下面这个同样相当简单的 LaTeX 文件,它来自示例解决方案中的 required-input-zip.tex

 1\documentclass{article}
 2\usepackage[margin=0.25in]{geometry}
 3\usepackage{pgfplots}
 4\pgfplotsset{width=10cm,compat=1.18}
 5\begin{document}
 6
 7第一个示例是并排绘制的二维和三维数学表达式
 8
 9%Here begins the 2D plot
10\begin{tikzpicture}
11\begin{axis}
12\addplot[color=red]{exp(x)};
13\end{axis}
14\end{tikzpicture}
15%Here ends the 2D plot
16\hskip 5pt
17%Here begins the 3D plot
18\begin{tikzpicture}
19\begin{axis}
20\addplot3[
21    surf,
22]
23{exp(-x^2-y^2)*x};
24\end{axis}
25\end{tikzpicture}
26%Here ends the 3D plot
27
28\end{document}

在第 3 行可以看到文件需要 pgfplots 包,同样未被“原生”支持。再次假设我们已经拥有 pgfplots 包的源文件。该包文件数量较多,分布在两个位置:\tex\generic\tex\latex 文件夹中。必须将这两个文件夹的内容作为必需输入提供给 Aspose.TeX 库。我们希望将这些源文件打包成 ZIP 存档,存档的布局如下:

Archive’s Layout

下面演示如何指定对这些源文件的访问方式:

1using (Stream zipStream = File.Open("path-to-zip-with-pgfplots-sources", FileMode.Open))
2{
3    ...
4    options.RequiredInputDirectory = new InputZipDirectory(zipStream);
5    ...
6}

使用此选项运行 TeX 作业后,我们得到输出文档:

Output Document

以下是该示例的完整源代码:

 1// External LaTeX packages from ZIP archive
 2
 3// Create conversion options for Object LaTeX format upon Object TeX engine extension.
 4TeXOptions options = TeXOptions.ConsoleAppOptions(TeXConfig.ObjectLaTeX);
 5// Specify a file system working directory for the output.
 6options.OutputWorkingDirectory = new OutputFileSystemDirectory(OutputDir);
 7// Initialize the options for saving in PNG format.
 8options.SaveOptions = new PngSaveOptions();
 9// Create a file stream for the ZIP archive containing the required package.
10// The ZIP archive may be located anywhere.
11using (Stream zipStream = File.Open(Path.Combine(DataDir, "packages\\pgfplots.zip"), FileMode.Open))
12{
13    // Specify a ZIP working directory for the required input.
14    options.RequiredInputDirectory = new InputZipDirectory(zipStream, "");
15    
16    // Run LaTeX to PNG conversion.
17    new TeXJob(Path.Combine(DataDir, "required-input-zip.tex"), new ImageDevice(), options).Run();
18}

注意: 结果已使用 pgfplots 包版本 1.18.1 验证。Aspose.TeX 库中包含的 pfg 包版本为 3.1.9a。

使用外部字体包

通常,LaTeX 发行版会提供一套默认字体供排版使用。除这些字体外,Aspose.TeX 还包含若干非标准字体包,例如 amsfontseurosymwasysym。正如前文所述,Aspose.TeX 也允许使用外部包,但大多数情况下我们讨论的是不包含字体的包。

Aspose.TeXObject TeX 引擎扩展需要字体映射文件(即扩展名为 .map 的文本文件),以确定每个 TeX 内部字体名对应的实际字体。这些映射文件必须在初始化阶段加载到 TeX 的内存中,并且必须随您引入的包一起存在。由于引擎不知道所有字体映射的名称,它会搜索所有扩展名为 .map 的文件。因此,实现用于 RequiredInputDirectory 选项的 IInputWorkingDirectory 接口时,需要提供一种按扩展名访问文件名集合的方式。更具体地说,该实现还必须实现 IFileCollector 接口。标准实现—— InputFileSystemDirectoryInputZipDirectory——已经具备此功能。

下面提供一个自定义必需输入目录的示例,该示例同样实现了 IFileCollector 接口。示例侧重于按扩展名收集文件名,省略了文件存储和检索的细节。

 1// Custom implementation of IInputWorkingDirectory for external packages with fonts
 2
 3// This is an implementation of IInputWorkingDirectory that is suitable for the TeX job's RequiredInputDirectory option
 4// in case required input contains fonts provided by external packages.
 5// The class additionally implements IFileCollector, which provides access to file collections by extension.
 6// This is necessary to load external font maps, which are files (outside TeX syntax) that map TeX's
 7// internal font names to file names of physical fonts.
 8public class RequiredInputDirectory : IInputWorkingDirectory, IFileCollector
 9{
10    private Dictionary<string, Dictionary<string, string>> _fileNames =
11        new Dictionary<string, Dictionary<string, string>>();
12
13    public RequiredInputDirectory()
14    {
15    }
16
17    // This method should preliminarily be called for each file entry that is supposed to be located inside
18    // the required input directory. Inside is an example of how the dictionary of file names could be organized
19    // for easy collection of file names by extension.
20    // Here fileName is a full file name. This can be a file path on a file system, a URL, or whatever else (theoretically).
21    public void StoreFileName(string fileName)
22    {
23        string extension = Path.GetExtension(fileName);
24        string name = Path.GetFileNameWithoutExtension(fileName);
25        
26        Dictionary<string, string> files;
27        if (!_fileNames.TryGetValue(extension, out files))
28            _fileNames.Add(extension, files = new Dictionary<string, string>());
29
30        files[name] = fileName;
31    }
32
33    // The IInputWorkingDirectory implementation.
34    public NamedStream GetFile(string fileName, bool searchSubdirectories = false)
35    {
36        // Try to find the file in our stored files
37        foreach (var extFiles in _fileNames.Values)
38        {
39            foreach (var file in extFiles.Values)
40            {
41                if (file.EndsWith(fileName) || Path.GetFileName(file) == fileName)
42                {
43                    return new NamedStream(File.OpenRead(file), fileName);
44                }
45            }
46        }
47        // If not found in stored files, return null (file not available)
48        return new NamedStream(null, fileName);
49    }
50
51    // Here is how we gather file collections by extension.
52    public string[] GetFileNamesByExtension(string extension, string path = null)
53    {
54        Dictionary<string, string> files;
55        if (!_fileNames.TryGetValue(extension, out files))
56            return new string[0];
57
58        return new List<string>(files.Values).ToArray();
59    }
60
61    public void Dispose()
62    {
63        _fileNames.Clear();
64    }
65}

限制

如果您的 LaTeX 文件所需的包是基于 LaTeX3e 内核开发的,则该包很可能无法与 Aspose.TeX 库一起工作,因为后者基于 LaTeX2e 内核。

此外,如果您的 LaTeX 文件所需的包直接调用了 Aspose.TeXObject TeX 引擎不支持的设备相关原语命令,则该包肯定无法工作。

Have any questions about Aspose.TeX?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.