How can java tex rendering happen?

311    Asked by MohitChoudhary in Java , Asked on Oct 11, 2022

 I want to render maths formulas in my Java GUI application. I am looking for a library made for computer use, not web use, which can render TeX. I have already tried jLatexMath, but it's very slow when I use it in my application.

If there are any other/better, could you point me in the right direction?


The LaTeX standalone package allows the creation of a PNG output file, the size of which exactly corresponds to the size of the formula or of the text.


So, we just have to call LaTeX from Java, and get the PNG output file.

1. Prerequisites

a) LaTeX shall be installed on the computer

... with all packages necessary for the formula (in the below example: amsfonts and amsmath)

... with standalone package

GhostScript shall be installed (necessary for standalone package)

The directory containing gswin32c.exe shall be added to PATH.

On my computer: C:Program Files (x86)gsgs9.10in

ImageMagick shall be installed (necessary for standalone package)

convert.exe shall be renamed as imgconvert.exe

The directory containing imgconvert.exe shall be added to PATH.

On my computer: C:Program Files (x86)ImageMagick-6.8.8-9

2. Check that LaTeX (with standalone package) succeeds in generating the PNG file (no Java at this stage).

Reference : Compile a LaTeX document into a PNG image that's as short as possible

LaTeX file, called New21.tex (for instance):

documentclass[border=0.50001bp,convert={convertexe={imgconvert},outext=.png}]{standalone}
usepackage{amsfonts}
usepackage{amsmath}
egin{document}
$egin{array}{l}
orall arepsiloninmathbb{R}_+^* existseta>0 |x-x_0|leqetaLongrightarrow|f(x)-f(x_0)|leq arepsilon\
detegin{bmatrix}a_{11}&a_{12}&cdots&a_{1n}\a_{21}&ddots&& dots\ dots&&ddots& dots\a_{n1}&cdots&cdots&a_{nn}end{bmatrix}overset{mathrm{def}}{=}sum_{sigmainmathfrak{S}_n} arepsilon(sigma)prod_{k=1}^n a_{ksigma(k)}\
{sideset{_lpha^eta}{_gamma^delta}{mathop{egin{pmatrix}a&b\c&dend{pmatrix}}}}\
int_0^infty{x^{2n} e^{-a x^2},dx} = rac{2n-1}{2a} int_0^infty{x^{2(n-1)} e^{-a x^2},dx} = rac{(2n-1)!!}{2^{n+1}} sqrt{ rac{pi}{a^{2n+1}}}\
int_a^b{f(x),dx} = (b - a) sumlimits_{n = 1}^infty {sumlimits_{m = 1}^{2^n - 1} {left( { - 1}
ight)^{m + 1} } } 2^{ - n} f(a + mleft( {b - a}
ight)2^{-n} )\
int_{-pi}^{pi} sin(lpha x) sin^n(eta x) dx = extstyle{left { egin{array}{cc} (-1)^{(n+1)/2} (-1)^m rac{2 pi}{2^n} inom{n}{m} & n mbox{ odd}, lpha = eta (2m-n) \ 0 & mbox{otherwise} \ end{array}
ight .}\
L = int_a^b sqrt{ left|sum_{i,j=1}^ng_{ij}(gamma(t))left( rac{d}{dt}x^icircgamma(t)
ight)left( rac{d}{dt}x^jcircgamma(t)
ight)
ight|},dt\
egin{array}{rl} s &= int_a^bleft| rac{d}{dt} ec{r},(u(t),v(t))
ight|,dt \ &= int_a^b sqrt{u'(t)^2, ec{r}_ucdot ec{r}_u + 2u'(t)v'(t), ec{r}_ucdot ec{r}_v+ v'(t)^2, ec{r}_vcdot ec{r}_v},,, dt. end{array}\
end{array}$
end{document}

Command line:

pdflatex -shell-escape New21.tex

Generation of the PNG file from Java, through a call to LaTeX

Code:

import java.awt.FlowLayout;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
class StreamPrinter implements Runnable {
    // Source: http://labs.excilys.com/2012/06/26/runtime-exec-pour-les-nuls-et-processbuilder/
    private final InputStream inputStream;
    private boolean print;
    StreamPrinter(InputStream inputStream, boolean print) {
        this.inputStream = inputStream;
        this.print = print;
    }
    private BufferedReader getBufferedReader(InputStream is) {
        return new BufferedReader(new InputStreamReader(is));
    }
    @Override
    public void run() {
        BufferedReader br = getBufferedReader(inputStream);
        String ligne = "";
        try {
            while ((ligne = br.readLine()) != null) {
                if (print) {
                    System.out.println(ligne);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class Exemple141_LaTeX_to_PNG_using_installed_LaTeX_distribution {
    public static void main(String[] args) {
        String TEMP_DIRECTORY = "D:\_tmp";
        String TEMP_TEX_FILE_NAME = "New22"; // for New22.tex
        // 1. Prepare the .tex file
        String newLineWithSeparation = System.getProperty("line.separator")+System.getProperty("line.separator");
        String math = "";
        math += "\documentclass[border=0.50001bp,convert={convertexe={imgconvert},outext=.png}]{standalone}" + newLineWithSeparation;
        math += "\usepackage{amsfonts}" + newLineWithSeparation;
        math += "\usepackage{amsmath}" + newLineWithSeparation;
        math += "\begin{document}" + newLineWithSeparation;
        math += "$\begin{array}{l}" + newLineWithSeparation;
        math += "\forall\varepsilon\in\mathbb{R}_+^*\ \exists\eta>0\ |x-x_0|\leq\eta\Longrightarrow|f(x)-f(x_0)|\leq\varepsilon\\" + newLineWithSeparation;
        math += "\det\begin{bmatrix}a_{11}&a_{12}&\cdots&a_{1n}\\a_{21}&\ddots&&\vdots\\\vdots&&\ddots&\vdots\\a_{n1}&\cdots&\cdots&a_{nn}\end{bmatrix}\overset{\mathrm{def}}{=}\sum_{\sigma\in\mathfrak{S}_n}\varepsilon(\sigma)\prod_{k=1}^n a_{k\sigma(k)}\\" + newLineWithSeparation;
        math += "{\sideset{_\alpha^\beta}{_\gamma^\delta}{\mathop{\begin{pmatrix}a&b\\c&d\end{pmatrix}}}}\\" + newLineWithSeparation;
        math += "\int_0^\infty{x^{2n} e^{-a x^2}\,dx} = \frac{2n-1}{2a} \int_0^\infty{x^{2(n-1)} e^{-a x^2}\,dx} = \frac{(2n-1)!!}{2^{n+1}} \sqrt{\frac{\pi}{a^{2n+1}}}\\" + newLineWithSeparation;
        math += "\int_a^b{f(x)\,dx} = (b - a) \sum\limits_{n = 1}^\infty {\sum\limits_{m = 1}^{2^n - 1} {\left( { - 1} \right)^{m + 1} } } 2^{ - n} f(a + m\left( {b - a} \right)2^{-n} )\\" + newLineWithSeparation;
        math += "\int_{-\pi}^{\pi} \sin(\alpha x) \sin^n(\beta x) dx = \textstyle{\left \{ \begin{array}{cc} (-1)^{(n+1)/2} (-1)^m \frac{2 \pi}{2^n} \binom{n}{m} & n \mbox{ odd},\ \alpha = \beta (2m-n) \\ 0 & \mbox{otherwise} \\ \end{array} \right .}\\" + newLineWithSeparation;
        math += "L = \int_a^b \sqrt{ \left|\sum_{i,j=1}^ng_{ij}(\gamma(t))\left(\frac{d}{dt}x^i\circ\gamma(t)\right)\left(\frac{d}{dt}x^j\circ\gamma(t)\right)\right|}\,dt\\" + newLineWithSeparation;
        math += "\begin{array}{rl} s &= \int_a^b\left\|\frac{d}{dt}\vec{r}\,(u(t),v(t))\right\|\,dt \\ &= \int_a^b \sqrt{u'(t)^2\,\vec{r}_u\cdot\vec{r}_u + 2u'(t)v'(t)\, \vec{r}_u\cdot\vec{r}_v+ v'(t)^2\,\vec{r}_v\cdot\vec{r}_v}\,\,\, dt. \end{array}\\" + newLineWithSeparation;
        math += "\end{array}$" + newLineWithSeparation;
        math += "\end{document}";
        // 2. Create the .tex file
        FileWriter writer = null;
        try {
            writer = new FileWriter(TEMP_DIRECTORY + "\" + TEMP_TEX_FILE_NAME + ".tex", false);
            writer.write(math, 0, math.length());
            writer.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        // 3. Execute LaTeX from command line to generate picture
        ProcessBuilder pb = new ProcessBuilder("pdflatex", "-shell-escape", TEMP_TEX_FILE_NAME + ".tex");
        pb.directory(new File(TEMP_DIRECTORY));
        try {
            Process p = pb.start();
            StreamPrinter fluxSortie = new StreamPrinter(p.getInputStream(), false);
            StreamPrinter fluxErreur = new StreamPrinter(p.getErrorStream(), false);
            new Thread(fluxSortie).start();
            new Thread(fluxErreur).start();
            p.waitFor();
        } catch (IOException | InterruptedException ex) {
            ex.printStackTrace();
        }
        // 4. Display picture
        JFrame maFrame = new JFrame();
        maFrame.setResizable(false);
        maFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        maFrame.setSize(400, 400);
        maFrame.getContentPane().setLayout(new FlowLayout());
        maFrame.getContentPane().add(new JLabel(new ImageIcon(TEMP_DIRECTORY + "\" + TEMP_TEX_FILE_NAME + ".png")));
        maFrame.pack();
        maFrame.setVisible(true);
        // 5. Delete files
        for (File file : (new File(TEMP_DIRECTORY).listFiles())) {
            if (file.getName().startsWith(TEMP_TEX_FILE_NAME + ".")) {
                file.delete();
            }
        }
    }
}


Your Answer

Interviews

Parent Categories