Source for file jResponseLatexToPdf.class.php

Documentation is available at jResponseLatexToPdf.class.php

  1. <?php
  2. /**
  3. @package     jelix
  4. @subpackage  core_response
  5. @author      Aubanel MONNIER
  6. @contributor Laurent Jouanneau
  7. @contributor johannb
  8. @copyright   2007 Aubanel MONNIER
  9. @link        http://aubanel.info
  10. @licence     GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  11. */
  12.  
  13. /**
  14. * pdf response, generated from a latex content
  15. @package  jelix
  16. @subpackage core_response
  17. @since 1.0b2
  18. */
  19. class jResponseLatexToPdf extends jResponse {
  20.     /**
  21.     * @var string 
  22.     */
  23.     protected $_type = 'ltx2pdf';
  24.     /**
  25.      * selector of the main template file
  26.      * This template should contains the body content, and is used by the $body template engine
  27.      * @var string 
  28.      */
  29.     public $bodyTpl = '';
  30.     /**
  31.      * The template engine used to generate the content
  32.      * @var jTpl 
  33.      */
  34.     public $body = null;
  35.     /**
  36.      * Authors of the document
  37.      * @var array 
  38.      */
  39.     public $authors = array();
  40.     /**
  41.      * Document title
  42.      * @var string 
  43.      */
  44.     public $title = '';
  45.  
  46.     /**
  47.      * Contains the list of commands to write in the preamble.
  48.      * @var array 
  49.      */
  50.     protected $_commands=array();
  51.  
  52.     /**
  53.      * complete path to the pdflatex executable
  54.      * @var string 
  55.      */
  56.     public $pdflatexPath='pdflatex';
  57.  
  58.     /**
  59.      * path to the cache directory.
  60.      * default is directory responseLatexToPdf in temp directory
  61.      * @since 1.0
  62.      */
  63.     public $cachePath'';
  64.  
  65.     /**
  66.      * constructor;
  67.      * setup the template engine
  68.      */
  69.     function __construct (){
  70.         $this->cachePath = JELIX_APP_TEMP_PATH.'responseLatexToPdf/';
  71.         $this->body = new jTpl();
  72.         parent::__construct();
  73.     }
  74.  
  75.     /**
  76.      * Add a command to the preamble, e.g. \documentclass[a4,11pt]{article}
  77.      * @param string $command name of the command to add
  78.      * @param string $argument argument of the command to add
  79.      * @param array $options options of the command to add
  80.      */
  81.     public function addCommand($command$argument$options=array()){
  82.         $cmd '\\'.$command;
  83.         if (count($options)) 
  84.             $cmd.='['.join(',',$options).']';
  85.         $this->_commands []$cmd.'{'.$argument.'}';
  86.     }
  87.  
  88.     /**
  89.      * A list of commands that can be safely used as default, or as a template for the _commonProcess function
  90.      * Tis function is called if the command stack is empty (useful to get quicly started)
  91.      */
  92.     public function addDefaultCommands(){
  93.         $this->addCommand('documentclass''article'array('a4''11pt'));
  94.         $this->addCommand('usepackage''fontenc'array('T1'));
  95.         $this->addCommand('usepackage''graphicx');
  96.         $this->addCommand('usepackage''geometry'array('pdftex'));
  97.         $this->addCommand('geometry''hmargin=1cm, vmargin=1cm');
  98.     }
  99.  
  100.     /**
  101.      * output the pdf content
  102.      *
  103.      * @return boolean    true if the generated content is ok
  104.      */
  105.     function output(){
  106.         $this->_commonProcess();
  107.         if (count($this->_commands<= 0//No commands, likewise we need some...
  108.             $this->addDefaultCommands();
  109.  
  110.         $data =  join("\n"$this->_commands).'
  111. \begin{document}
  112. \title{'.$this->title.'}
  113. \author{';
  114.         foreach ($this->authors as $a
  115.             $data.= $a.'\\\\'."\n";
  116.         $data.= '}
  117. \date{\today}
  118. \maketitle
  119. ';
  120.         $data.=$this->body->fetch($this->bodyTpl);
  121.         $data.= '
  122.  
  123. \end{document}';
  124.  
  125.         $fbase='cache-'.md5($data);
  126.  
  127.         $texFile=$this->cachePath.$fbase.'.tex';
  128.         $pdfFile=$this->cachePath.$fbase.'.pdf';
  129.  
  130.         if (file_exists($pdfFile)){
  131.             // Naïve cache: we have an md5 on the content of the tex file. If the pdf 
  132.             // corresponding to this content already exists, just serve it. 
  133.             // No managment of cache deletion :o/
  134.             jFile::write($texFile$data);
  135.             $output=array();
  136.             $retVal=1;    
  137.                 exec('
  138.             TEXMFOUTPUT='.$this->cachePath.' && export TEXMFOUTPUT && TEXINPUTS=:'.$this->cachePath.' && export TEXINPUTS &&
  139.             '.$this->pdflatexPath.' --interaction=batchmode '.$texFile$output$retVal);
  140.             if ($retVal!=0{
  141.                 $outputStr=implode('<br />',$output);
  142.                 throw new jException('jelix~errors.ltx2pdf.exec',array($this->pdflatexPath$outputStr));
  143.             }
  144.         }
  145.  
  146.         $this->_httpHeaders['Content-Type']='application/pdf';
  147.         $this->_httpHeaders['Content-length']=@filesize($pdfFile);
  148.         $this->_httpHeaders['Content-Disposition']='attachment; filename='.$this->title.'.pdf';
  149.         $this->sendHttpHeaders();
  150.  
  151.         readfile($pdfFile);
  152.         return true;
  153.     }
  154.  
  155.     /**
  156.      * The method you can overload in your inherited response
  157.      * overload it if you want to add processes (additionnal commands, content etc..)
  158.      * for all actions
  159.      */
  160.     protected function _commonProcess(){
  161.  
  162.     }
  163.  
  164.     /**
  165.      * Clears the cache directory
  166.      */
  167.     public function clearCache(){
  168.         jFile::removeDir($this->cachePathfalse);
  169.     }
  170.  
  171.     /**
  172.      * output errors
  173.      */
  174.     public function outputErrors(){
  175.         global $gJConfig;
  176.         header("HTTP/1.0 500 Internal Server Error");
  177.         header('Content-Type: text/plain;charset='.$gJConfig->charset);
  178.         if($this->hasErrors()){
  179.             foreach$GLOBALS['gJCoord']->errorMessages  as $e){
  180.                 echo '['.$e[0].' '.$e[1].'] '.$e[2]." \t".$e[3]." \t".$e[4]."\n";
  181.             }
  182.         }else{
  183.             echo "[unknown error]\n";
  184.         }
  185.     }
  186. }
  187. ?>

Documentation generated on Wed, 07 Sep 2011 13:47:46 +0200 by phpDocumentor 1.4.3