developer.jelix.org is not used any more and exists only for history. Post new tickets on the Github account.
developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.

Ticket #1070: jResponseLatexToPdf.class.php

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