Search code examples
phpvariablesescapingshell-execpdflatex

How to pass LaTeX code through a variable to pdflatex in PHP?


I tried this: (.php file)

<?php
$texscript = "
\documentclass[12pt,a4paper]{article}
\usepackage{helvet}
\usepackage{times}
\usepackage{multido}
\usepackage{fancyhdr}
\usepackage[hmargin=.8cm,vmargin=1.5cm,nohead,nofoot]{geometry}
\renewcommand{\familydefault}{\sfdefault}
\begin{document}

\fancyhf{} % clear all header and footer fields
\renewcommand{\headrulewidth}{0pt}
\pagestyle{fancy}
%\rhead{{\large\bfseries\thepage}}
\rhead{{\fbox{\large\bfseries\thepage}}}
\setcounter{page}{1}
\multido{}{1383}{\vphantom{x}\newpage}
\end{document}
";

$pdflatex = shell_exec("echo \$PATH > myenv; pdflatex ".$texscript." ");
?>

and am getting an error:

pdflatex : This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) (preloaded format=pdflatex) restricted \write18 enabled. ** ! End of file on the terminal...

why?

Is the above given code the correct way to write LaTeX in PHP variables and pass it to pdflatex command?? If not, then plz suggest corrections! I don't want to call an external .tex file but write the LaTeX code in PHP file itself and run from there.


Solution

  • Escaping may be one part, another is calling the command pdflatex; I circumvented (first) by writing the file before and (second) by replacing comments and newline on the variable so pdflatex has no problem with it any longer…

    <?php
    
    error_reporting(E_ALL);
    ini_set('error_reporting', E_ALL);
    
    $texscript = '\documentclass[12pt,a4paper]{article}
    \usepackage{helvet}
    \usepackage{times}
    \usepackage{multido}
    \usepackage{fancyhdr}
    \usepackage[hmargin=.8cm,vmargin=1.5cm,nohead,nofoot]{geometry}
    \renewcommand{\familydefault}{\sfdefault}
    \begin{document}
    
    \fancyhf{} % clear all header and footer fields
    \renewcommand{\headrulewidth}{0pt}
    \pagestyle{fancy}
    %\rhead{{\large\bfseries\thepage}}
    \rhead{{\fbox{\large\bfseries\thepage}}}
    \setcounter{page}{1}
    \multido{}{1383}{\vphantom{x}\newpage}
    \end{document}
    ';
    
    //write code to file
    $fn="texfile.tex";
    $myfile = fopen($fn, "w");
    fwrite($myfile, $texscript);
    fclose($myfile);
    
    //then execute pdflatex with parameter
    //didnt need
    //echo $PATH > myenv;
    $pdflatex = shell_exec('pdflatex ' .$fn .'' );
    
    //var_dump( $pdflatex );
    //test for success
    if (!file_exists("texfile.pdf")){
        print_r( file_get_contents("texfile.log") );
    } else {
        echo "PDF crated from file\n";
    }
    
    //trying same without file
    //removed comments and newlines
    $texscript = preg_replace('/[ \t]*\%.*[ \t]*[\r\n]+/', '', $texscript);
    $texscript = preg_replace('/[\r\n]+/', '', $texscript);
    //ahve a look on the variable
    //var_dump($texscript);
    
    $pdflatex = shell_exec('pdflatex "' .$texscript.'"' );
    if (!file_exists("article.pdf")){
        print_r(  file_get_contents("article.log") );
    } else {
        echo "PDF created from String\n";
    }    
    
    ?>
    

    it shouldn't matter to write the tex-file as well as pdflatex will write files besides the desired PDF.

    also added regex for replacing comments/newline.

    I call the script with: php test.php on cli with GNU/Linux Debian 8

    this produces the output:

    PDF crated from file
    string(405) "\documentclass[12pt,a4paper]{article}\usepackage{helvet}\usepackage{times}\usepackage{multido}\usepackage{fancyhdr}\usepackage[hmargin=.8cm,vmargin=1.5cm,nohead,nofoot]{geometry}\renewcommand{\familydefault}{\sfdefault}\begin{document}\fancyhf{}\renewcommand{\headrulewidth}{0pt}\pagestyle{fancy}\rhead{{\fbox{\large\bfseries\thepage}}}\setcounter{page}{1}\multido{}{1}{\vphantom{x}\newpage}\end{document}"
    PDF created from String
    

    and the PDF files both work and have the same filesize:

    -rw-r--r-- 1 vv01f vv01f 3360 Mai  5 article.pdf
    -rw-r--r-- 1 vv01f vv01f 3360 Mai  5 texfile.pdf