Paquetes LaTeX externos | Java

Paquetes externos de LaTeX

Hay varios paquetes comunes de LaTeX incluidos en la biblioteca Aspose.TeX para Java. Por lo tanto, no tiene que preocuparse por cómo proporcionar estos paquetes al motor TeX de la biblioteca. Pero a veces (tal vez a menudo) su archivo LaTeX puede requerir un paquete más allá del “paquete” de paquetes admitido “de forma nativa”. En este caso, puede intentar proporcionar la entrada requerida, es decir, los archivos fuente del paquete requerido, utilizando el método setRequiredInputDirectory() de la instancia de clase TeXOptions. Veremos cómo funciona esto con dos ejemplos.

Entrada requerida desempaquetada (paquete fancybox)

Digamos que tenemos el siguiente archivo LaTeX simple, que es required-input-fs.tex de nuestra solución de ejemplo:

 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}

En la tercera línea, vemos que el archivo requiere el paquete fancybox, que no es compatible “de forma nativa”. También asumimos que tenemos el archivo fuente del paquete fancybox. Es un paquete simple, por lo que en realidad consta de un solo archivo. Podemos colocar este archivo en cualquier lugar de nuestro sistema de archivos y especificar la ruta del directorio de la siguiente manera:

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

Después de ejecutar un trabajo TeX con esta opción (no olvide ajustar las otras opciones según sea necesario), obtenemos el documento de salida (es decir, una imagen PNG).

Documento de salida

Aquí está el código fuente completo del ejemplo:

 1// Create conversion options for Object LaTeX format upon Object TeX engine extension.
 2TeXOptions options = TeXOptions.consoleAppOptions(TeXConfig.objectLaTeX());
 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// Initialize the options for saving in PNG format.
 9options.setSaveOptions(new PngSaveOptions());
10// Run LaTeX to PNG conversion.
11new TeXJob(Utils.getInputDirectory() + "required-input-fs.tex", new ImageDevice(), options).run();

Entrada requerida archivada (paquete pgfplots)

Supongamos ahora que tenemos el siguiente archivo LaTeX también bastante simple, que es required-input-zip.tex de nuestra solución de ejemplo:

 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}

En la tercera línea, vemos que el archivo requiere el paquete pgfplots, que tampoco es compatible de forma “nativa”. Nuevamente, asumimos que tenemos los archivos fuente del paquete pgfplots. Es un conjunto bastante grande de archivos que se dividen en dos ubicaciones si los encuentra en el directorio de instalación de cualquier aplicación de composición tipográfica LaTeX. Puede encontrar la carpeta pgfplots en las carpetas \tex\generic y \tex\latex. Y el contenido de ambas carpetas debe proporcionarse como entrada requerida para la biblioteca Aspose.TeX. Queremos que estos archivos fuente estén empaquetados en un archivo ZIP, así que aquí está el diseño del archivo:

diseño del archivo

Y así es como especificamos el acceso a estos archivos fuente:

1final Stream zipStream = File.Open("path-to-zip-with-pgfplots-sources"), FileMode.Open))
2try {
3    ...
4    options.setRequiredInputDirectory(new InputZipDirectory(zipStream));
5    ...
6} finally {
7    if (zipStream != null)
8        zipStream.close();
9}

Después de ejecutar un trabajo TeX con esta opción, obtenemos el documento de salida:

Documento de salida

Aquí está el código fuente completo del ejemplo:

 1// Create conversion options for Object LaTeX format upon Object TeX engine extension.
 2TeXOptions options = TeXOptions.consoleAppOptions(TeXConfig.objectLaTeX());
 3// Specify a file system working directory for the output.
 4options.setOutputWorkingDirectory(new OutputFileSystemDirectory(Utils.getOutputDirectory()));
 5// Initialize the options for saving in PNG format.
 6options.setSaveOptions(new PngSaveOptions());
 7// Create a file stream for the ZIP archive containing the required package.
 8// The ZIP archive may be located anywhere.
 9final InputStream stream = new FileInputStream(Utils.getInputDirectory() + "packages\\pgfplots.zip");
10try {
11    // Specify a ZIP working directory for the required input.
12    options.setRequiredInputDirectory(new InputZipDirectory(stream, ""));
13    
14    // Run LaTeX to PNG conversion.
15    new TeXJob(Utils.getInputDirectory() + "required-input-zip.tex", new ImageDevice(), options).run();
16} finally {
17    if (stream != null)
18        stream.close();
19}

NOTA: El resultado se verificó utilizando la versión 1.18.1 del paquete pgfplots. Mientras que la versión del paquete pfg incluida en la biblioteca Aspose.TeX es la 3.1.9a.

Usar paquetes de fuentes externos

Normalmente, las distribuciones de LaTeX vienen con una selección de fuentes predeterminadas que se pueden utilizar para la composición tipográfica. Además de estas fuentes, Aspose.TeX ofrece varios paquetes de fuentes no estándar, como amsfonts, eurosym y wasysym. Como se mencionó anteriormente, Aspose.TeX también admite el uso de paquetes externos, aunque nos hemos centrado principalmente en paquetes que no incluyen fuentes. La extensión del motor Object TeX en Aspose.TeX requiere mapas de fuentes, que son archivos de texto con la extensión .map que especifican las fuentes físicas correspondientes al nombre de fuente interna de cada TeX. Estos mapas de fuentes deben cargarse en la memoria de TeX durante la fase de inicialización y deben incluirse en los archivos del paquete. Dado que el motor no conoce los nombres de todos los mapas de fuentes, busca cualquier archivo con la extensión .map. Por lo tanto, la implementación de la interfaz IInputWorkingDirectory utilizada como valor de la opción RequiredInputDirectory debe proporcionar una forma de acceder a colecciones de nombres de archivos según su extensión. Específicamente, esta implementación también debe implementar la interfaz IFileCollector. Las implementaciones estándar, InputFileSystemDirectory e InputZipDirectory, ya cumplen este requisito.

A continuación, presentamos un ejemplo de un directorio de entrada requerido personalizado que también implementa la interfaz IFileCollector. Nuestro énfasis principal está en recopilar nombres de archivos según su extensión, y omitimos intencionalmente los detalles del almacenamiento y recuperación de archivos.

 1// This is an implementation of IInputWorkingDirectory that is suitable for the TeX job's RequiredInputDirectory option
 2// in case required input contains fonts provided by external packages.
 3// The class additionally implements IFileCollector, which provides access to file collections by extension.
 4// This is necessary to load external font maps, which are files (outside TeX syntax) that map TeX's
 5public class RequiredInputDirectory implements IInputWorkingDirectory, IFileCollector
 6{
 7    private Map<String, Map<String, String>> _fileNames = new HashMap<String, Map<String, String>>();
 8
 9    public RequiredInputDirectory()
10    { 
11    }
12
13    // This method should preliminarily be called for each file entry that is supposed to be located inside
14    // the required input directory. Inside is an example of how the dictionary of file names could be organized
15    // for easy collection of file names by extension.
16    // Here fileName is a full file name. This can be a file path on a file system, a URL, or whatever else (theoretically).
17    public void storeFileName(String fileName)
18    {
19        String extension = getExtension(fileName);
20        String name = getFileNameWithoutExtension(fileName);
21
22        Map<String, String> files = _fileNames.get(extension);
23        if (files == null)
24            _fileNames.put(extension, files = new HashMap<String, String>());
25
26        files.put(name, fileName);
27    }
28
29    // The IInputWorkingDirectory implementation.
30    public TeXInputStream getFile(String fileName, boolean searchSubdirectories)
31    {
32        return new TeXInputStream(null, fileName); // Here we actually return a stream for the file requested by its name.
33    }
34    
35    // Here is how we gather file collections by extension.
36    public String[] getFileNamesByExtension(String extension)
37    {
38    	return getFileNamesByExtension(extension, null);
39    }
40
41    // Here is how we gather file collections by extension.
42    public String[] getFileNamesByExtension(String extension, String path)
43    {
44        Map<String, String> files = _fileNames.get(extension);
45        if (files == null)
46            return new String[0];
47        
48        return files.values().toArray(new String[0]);
49    }
50    
51    private String getExtension(String fileName)
52    {
53    	int pos = fileName.indexOf('.');
54    	if (pos < 0)
55    		return "";
56    	
57    	return fileName.substring(pos);
58    }
59    
60    private String getFileNameWithoutExtension(String fileName)
61    {
62    	int pos = fileName.lastIndexOf('/');
63    	if (pos >= 0)
64    		fileName = fileName.substring(pos + 1);
65    	
66    	pos = fileName.indexOf('.');
67    	if (pos < 0)
68    		return fileName;
69    	
70    	return fileName.substring(0, pos);
71    }
72
73    public void close()
74    {
75        _fileNames.clear();
76    }
77}

Restricciones

Un paquete requerido por su archivo LaTeX puede desarrollarse bajo el kernel LaTeX3e. Lo más probable es que un paquete de este tipo no funcione con la biblioteca Aspose.TeX ya que esta última se basa en el kernel LaTeX2e.

Además, un paquete requerido por su archivo LaTeX puede llamar directamente a comandos primitivos dependientes del dispositivo que no son compatibles con el motor Object TeX de la biblioteca Aspose.TeX. Desafortunadamente, un paquete así no funcionará con seguridad.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.