\subsection{The \emph{luadraw\_compile\_tex} module}

\textbf{Warning}: 
\begin{itemize}
    \item This module adds new graphics methods to the \emph{ld.graph} and \emph{ld.graph3d} classes, as well as several functions in the \emph{luadraw} namespace, but it does not return anything.

    \item This module has been tested under Linux, but not (yet) under Windows or macOS.

    \item This module requires that the following programs be installed on your system: \emph{pdflatex}, \emph{pdf2ps}, and \emph{pstoedit}.
\end{itemize}

The \cmd{ld.compile\_tex\_default(options)} function allows you to modify the default settings. These parameters are (with their default values):
\begin{itemize}
    \item \opt{pdflatexcmd=\val{"pdflatex"}},
    \item \opt{pstoeditcmd=\val{"pstoedit"}},
    \item \opt{pdf2pscmd=\val{"pdf2ps"}},
    \item \opt{preamble=}\verb|"\\documentclass[12pt]{article}\n"}|,
    \item \opt{usepackage=}\verb|"\\usepackage{amsmath,amssymb}\n\\usepackage{fourier}\n"|.
\end{itemize}

Depending on your operating system, you may need to modify these variables to add the program path, for example :
\codeln{ld.compile\_tex\_default( \{pstoeditcmd="/usr/bin/pstoedit"\} )}


This module allows you to:

\begin{enumerate}
\item compile a text fragment in TeX,
\item convert the resulting file into an \emph{eps} file containing \emph{flattened postscript},
\item read the content of the \emph{eps} file and return its content as a list of paths, with the line thickness at the beginning of each path, and the fill instruction at the end.
\item The list thus obtained can be:
    \begin{enumerate}
    \item drawn on the screen,
    \item converted into 3D paths in a given plane and drawn,
    \item converted into 3D polygonal lines in a given plane (the thickness and fill command are then lost) and drawn.
    \end{enumerate}
\end{enumerate}

\subsubsection{Part One: Compilation and Reading}

\paragraph{Warning}: This step requires compiling the document with the \emph{-shell-escape} or \emph{-enable-write18} option.
Without this option, the fragment will not be compiled, which is not a problem if the \emph{<filename>.eps} file already exists and you did not intend to modify it.

The first step is handled by the \cmd{ld.compile\_tex(text \fac{, filename, conv\_stroke})} function. The \argu{text} argument is a string; this is the fragment to be compiled. The optional \argu{filename} argument is also a string; this is the name of the file that will be created. This name must not contain \textbf{a path or an extension}. By default, this name is \emph{"tex2FlatPs"}. It is created in the current directory (but will then be deleted). The optional argument \argu{conv\_stroke} is a boolean that indicates whether polygonal lines (\emph{stroke} instructions) should be converted into filled strips with a \emph{fill}, or not (\false by default).

The process unfolds in several steps:

\begin{enumerate}
    \item Creation of the TeX file. This uses the parameters \opt{preamble} and \opt{usepackage}. Compilation is done with \emph{pdflatex}.

    \item The resulting file is converted to PostScript using the \emph{pdf2ps} utility.

    \item The resulting PS file is then converted using the \emph{pstoedit} utility into an EPS file in flattened PostScript (all content is in the form of paths).

    \item The resulting file \emph{<filename>.eps} is copied to the working directory of \luadrawenv (the name of this directory is in the global variable \varglob{ld.cachedir}), and all compilation remnants are erased.

    \item The contents of the file thus created are automatically read by the function \cmd{ld.read\_compiled\_tex(filename)}, which returns a list of paths. Each path is a list starting with the line thickness, followed by dots and instructions like a regular path, and ending with the fill command (\emph{"fill"}, \emph{"eofill"}, or \emph{"stroke"}).
\end{enumerate}


\subsubsection{Part Two: Using the Result}

\paragraph{In 2D} The result can be drawn using the method \cmd{g:Dcompiled\_tex(L, anchor, options)} where \argu{L} is the result returned by the function \cmd{compile\_tex()}. The \argu{anchor} argument is a complex number; it represents the center of the bounding box of the drawing contained in \argu{L}. \writeoptions:
\begin{itemize}
    \item \opt{pos="center"}, indicates the position of the content of \argu{L} relative to the anchor point, the possible values ​​are the same as for the \opt{pos} option of labels, that is: \val{"center"}, \val{"N"}, \val{"NE"}, \val{"E"}, \val{"SE"}, \val{"S"}, \val{"SW"}, \val{"W"}, \val{"NW"}.

    \item \opt{scale=1}, allows you to adjust the size of the drawing, this option can be a number or a table of two numbers: \emph{\{scaleX, scaleY\}},

    \item \opt{color=<current default color>},

    \item \opt{dir=nil}, writing direction (\nil means the usual direction). Generally, it is a table consisting of two vectors \opt{dir=\{v1, v2\}} indicating the writing direction,

    \item \opt{hollow=false}, enables or disables the filling of shapes. With the value \true, only the outlines are drawn, 

    \item \opt{drawbox=false}: allows you to draw or not draw the bounding box,

    \item \opt{draw\_options=""}: string containing the options that will be be passed directly to the \drawcmd command.
\end{itemize}

The result can also be transformed into a polygonal line using the function \cmd{ld.compiled\_tex2polyline(L \fac{, scale})} where \argu{L} is the result returned by the \cmd{ld.compile\_tex()} function. The optional argument \argu{scale} allows you to adjust the size; it can be a number or a table of two numbers: \emph{\{scaleX, scaleY\}}.

\begin{demo}{Example with \emph{compile\_tex} in 2D}
\begin{luadraw}{name=compile_tex2d}
local ld = luadraw
local cpx = ld.cpx
local Z = cpx.Z

local g = ld.graph:new{bbox=false}
require 'luadraw_compile_tex'
local i = cpx.I
local text = "\\[\\int_0^{+\\infty} e^{-\\frac{x^2}2}dx = \\frac{\\sqrt{2\\pi}}2\\]" -- text to compile
-- compile with -shell-escape the first time to create the file
local L = ld.compile_tex(text,"gauss_integral",true) -- with true the lines (strokes) are changed into strips
g:Shift(2*i) -- a first drawing
g:Dcompiled_tex(L,0,{scale=2,hollow=true, drawbox=true, draw_options="fill=pink", dir={1-i/4,i}}) -- we draw L

g:Shift(-4*i) -- a second drawing
L = ld.compiled_tex2polyline(L,{3,3}) --L is converted to a polygonal line
local f = function(z) return Z(z.re,z.im+math.sin(z.re*1.5)) end  -- this function produces sinusoidal waves
L = ld.ftransform(L,f) -- we apply f to L
g:Dpath( ld.polyline2path(L), 'draw=none,fill=blue') -- we draw L as a path
g:Show()
\end{luadraw}
\end{demo}


\paragraph{In 3D} The result can be converted to 3D using the method \cmd{g:Compiled\_tex2path3d(L, options)} where \argu{L} is the result returned by the function \cmd{ld.compile\_tex()}. \writeoptions:

\begin{itemize}
    \item \opt{scale=1}, allows you to adjust the size of the drawing, this option can be a number or a table of two numbers: \emph{\{scaleX, scaleY\}},

    \item \opt{anchor=pt3d.Origin}, 3D point which represents the center of the bounding box of the drawing,
    \opt{pos="center"}, indicates the position of the content of \argu{L} relative to the anchor point, the possible values ​​are the same as for the \opt{pos} option of labels, that is: \val{"center"}, \val{"N"}, \val{"NE"}, \val{"E"}, \val{"SE"}, \val{"S"}, \val{"SW"}, \val{"W"}, \val{"NW"},

    \item \opt{color=<current default color>},

    \item \opt{dir=\{pt3d.vecJ,pt3d.vecK\}}, basis of the plane in which the result will be located (this plane will also contain the \opt{anchor} point), these two vectors indicate the direction of writing,

    \item \opt{polyline=false}, with the value \true the returned result will be a list of lists of 3D points and can therefore be drawn with the method \cmd{g:Dpolyline3d()}, however, the information: line thickness and fill command, are lost. With the value \false the result is a list of paths, each path is a list starting with the line thickness, followed by 3D points and instructions like an ordinary 3D path, and ending with the fill command (\emph{"fill"}, or \emph{"eofill"} or \emph{"stroke"}).
\end{itemize}

With the option \opt{polyline=false} (default value), the output can be drawn using the method \cmd{g:Dcompiled\_tex3d(L, options)} where \argu{L} is the result of the method \cmd{g:Compiled\_tex2path3d()}. \writeoptions:

\begin{itemize}
    \item \opt{color=<default current color>},
    \item \opt{hollow=false}, enables or disables the filling of shapes. With the value \true, only the outlines are drawn. 
    \item \opt{drawbox=false}: allows you to draw or not draw the bounding box,
    \item \opt{draw\_options=""}: string containing the options that will be be passed directly to the \drawcmd command.
\end{itemize}

\begin{demo}{Write on a cylinder}
\begin{luadraw}{name=compile_tex3d}
local ld = luadraw
local cpx, pt3d = ld.cpx, ld.pt3d
local Origin, vecI, vecJ, vecK, M, Mc = pt3d.Origin, pt3d.vecI, pt3d.vecJ, pt3d.vecK, pt3d.M, pt3d.Mc

local g = ld.graph3d:new{ window={-3,3,-4,4}, margin={0,0,0,0}, size={10,10}, viewdir={-50,60}}
require 'luadraw_compile_tex'

function curve_on_cylinder(curve,cylinder,screenNormal) 
-- curve is a 3D polyline on a cylinder
-- cylinder = {A,r,B} estle cylindre
-- this function separate the visible part from the hidden part of the curve
    local A,r,B = table.unpack(cylinder)
    local U = B-A
    local visibility_function = function(N)
        local I = ld.dproj3d(N,{A,U})
        return (pt3d.dot(N-I,screenNormal) >= 0)
    end
    return ld.split_points_by_visibility(curve,visibility_function)
end

local A, r, B = -3*vecK, 2, 2.5*vecK -- the cylinder
local text = "Euler theorem: \\par \\(e^{i\\pi}=-1\\)"
local L = ld.compile_tex(text, "essai") -- compile with shell-escape the first time to create "essai.eps" file
local C = g:Compiled_tex2path3d(L,{scale=3, anchor=M(r,0,0), dir={vecJ,vecK}, polyline=true})
--C is the text converted into 3D polylines, in the plane passing through anchor and basic direction dir, with a scale of 3.

local f = function(A) return Mc(r,A.y/r,A.z) end -- returns the image of a point A on the cylinder by winding
C = ld.ftransform3d(C,f) -- plane curve -> cylindrical curve transformation
local Cv, Ch = curve_on_cylinder(C, {A,r,B}, g.Normal) -- visible part and hidden part of C, this may take some time
Ch = ld.polyline2path3d(Ch) -- hidden part, conversion to path
g:Dpath3d(Ch, "draw=none,fill=red!30")
g:Dcylinder(A,r,B,{color="blue",opacity=0.5})
Cv = ld.polyline2path3d(Cv) -- visible part, conversion to path
g:Dpath3d(Cv, "draw=none,fill=red")
g:Show()
\end{luadraw}
\end{demo}
