Зовнішні пакети LaTeX | Aspose.TeX для Java
Зовнішні пакети LaTeX
До бібліотеки Aspose.TeX для Java включено кілька поширених пакетів LaTeX. Тому вам не потрібно піклуватися про те, як надати ці Пакети механізму 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. Такий пакет, на жаль, працювати точно не буде.