Внешние пакеты LaTeX | Aspose.TeX для Java
Внешние пакеты LaTeX
Существует ряд общих пакетов LaTeX, включенных в библиотеку Aspose.TeX для Java. Таким образом, вам не нужно заботиться о том, как предоставить эти пакеты движку TeX библиотеки. Но иногда (возможно, часто) вашему файлу LaTeX может потребоваться пакет, выходящий за рамки «изначально» поддерживаемого «пакета» пакетов. В этом случае вы можете попытаться предоставить требуемые входные данные, то есть исходные файлы требуемого пакета, используя метод setRequiredInputDirectory() экземпляра класса TeXOptions. Мы увидим, как это работает, на двух примерах.
Укажите в inputFile полный путь к соответствующему документу LaTeX, а в outputDirectory — существующую папку вывода. Оба примера преобразования создают PNG с разрешением 150 DPI. Импортируйте классы Aspose.TeX из выбранного примера, com.aspose.tex.rendering.ImageDevice, com.aspose.tex.rendering.PngSaveOptions, а для ввода из ZIP — java.io.InputStream и java.nio.file.Files. Обрабатывайте или объявляйте исключения в вызывающем методе. Примените лицензию согласно
руководству по лицензированию.
Распакованный требуемый ввод (пакет «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}
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}Третья строка требует внешний пакет fancybox. Укажите в packagesDirectory локальную папку с fancybox.sty и его зависимостями. Полный пример ниже назначает эту папку параметру RequiredInputDirectory и создаёт изображение PNG. Устройство и рабочие папки остаются открытыми до завершения задания, затем освобождаются или закрываются.

Вот полный исходный код примера:
1// Render the fancybox document using external package sources from a local folder.
2// inputFile is the full TeX input path; packagesDirectory contains fancybox.sty.
3// outputDirectory is an existing output folder.
4TeXOptions options = TeXOptions.consoleAppOptions(TeXConfig.objectLaTeX());
5OutputFileSystemDirectory output = new OutputFileSystemDirectory(outputDirectory);
6InputFileSystemDirectory packages = new InputFileSystemDirectory(packagesDirectory);
7options.setOutputWorkingDirectory(output);
8options.setRequiredInputDirectory(packages);
9PngSaveOptions saving = new PngSaveOptions();
10saving.setResolution(150);
11options.setSaveOptions(saving);
12options.setInteraction(Interaction.NonstopMode);
13options.setTerminalOut(new OutputMemoryTerminal());
14ImageDevice device = new ImageDevice();
15TeXJobResult result;
16int pages;
17try {
18 result = new TeXJob(inputFile, device, options).run();
19 pages = device.getPageCount();
20} finally {
21 device.dispose();
22 output.close();
23 packages.close();
24}Заархивированные необходимые данные (пакет 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
7First example is 2D and 3D math expressions plotted side-by-side.
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}В третьей строке мы видим, что для файла требуется пакет pgfplots, который также не поддерживается «изначально». Опять же, мы предполагаем, что у нас есть исходные файлы пакета pgfplots. Это довольно большой набор файлов, которые разделены между двумя местами, если вы найдете их в каталоге установки любого приложения для набора текста LaTeX. Вы можете найти папку pgfplots в папках \tex\generic и \tex\latex. И содержимое обеих этих папок должно быть предоставлено в качестве входных данных для библиотеки Aspose.TeX. Мы хотим, чтобы эти исходные файлы были упакованы в ZIP-архив, поэтому вот макет архива:

Укажите в packagesZip значение java.nio.file.Path, указывающее на архив с generic- и LaTeX-исходниками пакета. Полный Java-пример ниже открывает его через Files.newInputStream(...) и назначает InputZipDirectory параметру RequiredInputDirectory. Пустой аргумент базового пути выбирает весь архив. Держите ZIP-поток и папку открытыми до завершения задания TeX, затем закройте их. Результат — изображение PNG с двумя графиками.

Вот полный исходный код примера:
1// Render the 2D/3D plots using pgfplots package sources from a ZIP archive.
2// inputFile is the full TeX input path; packagesZip is a java.nio.file.Path.
3// outputDirectory is an existing output folder; the ZIP includes generic and latex sources.
4TeXJobResult result;
5int pages;
6try (InputStream zipStream = Files.newInputStream(packagesZip)) {
7 TeXOptions options = TeXOptions.consoleAppOptions(TeXConfig.objectLaTeX());
8 OutputFileSystemDirectory output = new OutputFileSystemDirectory(outputDirectory);
9 InputZipDirectory packages = new InputZipDirectory(zipStream, "");
10 options.setOutputWorkingDirectory(output);
11 options.setRequiredInputDirectory(packages);
12 PngSaveOptions saving = new PngSaveOptions();
13 saving.setResolution(150);
14 options.setSaveOptions(saving);
15 options.setInteraction(Interaction.NonstopMode);
16 options.setTerminalOut(new OutputMemoryTerminal());
17 ImageDevice device = new ImageDevice();
18 try {
19 result = new TeXJob(inputFile, device, options).run();
20 pages = device.getPageCount();
21 } finally {
22 device.dispose();
23 output.close();
24 packages.close();
25 }
26}NOTE: The result was verified using the
pgfplotspackage version 1.18.1. While the version of thepfgpackage included in the Aspose.TeX library is 3.1.9a.
Использование внешних пакетов шрифтов
Обычно дистрибутивы LaTeX поставляются с набором шрифтов по умолчанию, которые можно использовать для набора текста. В дополнение к этим шрифтам Aspose.TeX предлагает несколько нестандартных пакетов шрифтов, таких как «amsfonts», «eurosym» и «wasysym». Как упоминалось ранее, Aspose.TeX также поддерживает использование внешних пакетов, хотя мы в основном фокусировались на пакетах, не включающих шрифты.
Расширение движка Object TeX в Aspose.TeX требует карт шрифтов, которые представляют собой текстовые файлы с расширением .map, которые определяют физические шрифты, соответствующие внутреннему имени шрифта каждого TeX. Эти карты шрифтов необходимо загрузить в память TeX на этапе инициализации и включить в файлы пакета. Поскольку движку неизвестны названия всех карт шрифтов, он ищет любые файлы с расширением .map. Следовательно, реализация интерфейса
IInputWorkingDirectory, используемого в качестве значения опции
RequiredInputDirectory, должна предоставлять способ доступа к коллекциям имен файлов на основе их расширения. В частности, эта реализация также должна реализовывать интерфейс
IFileCollector. Стандартные реализации
InputFileSystemDirectory и
InputZipDirectory уже удовлетворяют этому требованию.
Следующий пользовательский RequiredInputDirectory реализует оба интерфейса и читает явно зарегистрированные локальные файлы. Сохраните его как RequiredInputDirectory.java вместе с включёнными импортами. Зарегистрируйте каждый файл через storeFileName(...), назначьте экземпляр через options.setRequiredInputDirectory(...) и закройте его после задания. Это плоский реестр: имена файлов должны быть уникальными при запросе без полного пути. Расширения сравниваются без учёта регистра; необязательный путь сбора выбирает папку файловой системы. Зарегистрируйте все необходимые файлы пакета, карты шрифтов, метрики и физические файлы шрифтов. Сбор файлов делает карты доступными для обнаружения, но не предоставляет недостающие данные шрифтов.
1import com.aspose.tex.IInputWorkingDirectory;
2import com.aspose.tex.IFileCollector;
3import com.aspose.tex.TeXInputStream;
4import java.io.IOException;
5import java.io.UncheckedIOException;
6import java.nio.file.Files;
7import java.nio.file.Path;
8import java.nio.file.Paths;
9import java.util.ArrayList;
10import java.util.LinkedHashSet;
11import java.util.List;
12import java.util.Locale;
13import java.util.Set;
14
15// Register local package files explicitly, including font maps and their dependencies.
16// Save this class as RequiredInputDirectory.java and close it after the TeX job.
17public class RequiredInputDirectory implements IInputWorkingDirectory, IFileCollector {
18 private final Set<Path> files = new LinkedHashSet<Path>();
19 private final List<TeXInputStream> streams = new ArrayList<TeXInputStream>();
20
21 public void storeFileName(String fileName) {
22 Path file = Paths.get(fileName).toAbsolutePath().normalize();
23 if (!Files.isRegularFile(file)) {
24 throw new IllegalArgumentException("Package file does not exist: " + file);
25 }
26 files.add(file);
27 }
28
29 @Override
30 public TeXInputStream getFile(String fileName, boolean searchSubdirectories) {
31 // This registry is a flat virtual directory; only registered files are accessible.
32 for (Path file : files) {
33 if (file.toString().equals(fileName) || file.getFileName().toString().equals(fileName)) {
34 try {
35 TeXInputStream stream = new TeXInputStream(Files.newInputStream(file), file.toString());
36 streams.add(stream);
37 return stream;
38 } catch (IOException exception) {
39 throw new UncheckedIOException(exception);
40 }
41 }
42 }
43 return new TeXInputStream(null, fileName);
44 }
45
46 @Override
47 public String[] getFileNamesByExtension(String extension) {
48 return getFileNamesByExtension(extension, null);
49 }
50
51 @Override
52 public String[] getFileNamesByExtension(String extension, String path) {
53 String requested = extension.toLowerCase(Locale.ROOT);
54 if (!requested.isEmpty() && !requested.startsWith(".")) {
55 requested = "." + requested;
56 }
57 Path directory = path == null ? null : Paths.get(path).toAbsolutePath().normalize();
58 List<String> matches = new ArrayList<String>();
59 for (Path file : files) {
60 String name = file.getFileName().toString();
61 int dot = name.lastIndexOf('.');
62 String actual = dot < 0 ? "" : name.substring(dot).toLowerCase(Locale.ROOT);
63 if (actual.equals(requested) && (directory == null || file.getParent().equals(directory))) {
64 matches.add(file.toString());
65 }
66 }
67 return matches.toArray(new String[0]);
68 }
69
70 @Override
71 public void close() throws IOException {
72 IOException failure = null;
73 for (TeXInputStream stream : streams) {
74 try {
75 stream.close();
76 } catch (IOException exception) {
77 if (failure == null) { failure = exception; }
78 else { failure.addSuppressed(exception); }
79 }
80 }
81 streams.clear();
82 files.clear();
83 if (failure != null) { throw failure; }
84 }
85}Ограничения
Пакет, необходимый для вашего файла LaTeX, может быть разработан под ядром LaTeX3e. Такой пакет, скорее всего, не будет работать с библиотекой Aspose.TeX, поскольку последняя основана на ядре LaTeX2e.
Кроме того, пакет, необходимый для вашего файла LaTeX, может напрямую вызывать зависящие от устройства примитивные команды, которые не поддерживаются механизмом Object TeX библиотеки Aspose.TeX. Такой пакет, к сожалению, точно не подойдет.