Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * This class handles the XML-based CezPDF markup language created to allow
4
 * templates for the PDFdefaultConverter
5
 *
6
 * phpDocumentor :: automatic documentation generator
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * Copyright (c) 2002-2006 Gregory Beaver
11
 *
12
 * LICENSE:
13
 *
14
 * This library is free software; you can redistribute it
15
 * and/or modify it under the terms of the GNU Lesser General
16
 * Public License as published by the Free Software Foundation;
17
 * either version 2.1 of the License, or (at your option) any
18
 * later version.
19
 *
20
 * This library is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
 * Lesser General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Lesser General Public
26
 * License along with this library; if not, write to the Free Software
27
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
 *
29
 * @package    Converters
30
 * @subpackage PDFdefault
31
 * @author     Greg Beaver <cellog@php.net>
32
 * @copyright  2002-2006 Gregory Beaver
33
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
34
 * @version    CVS: $Id: ParserPDF.inc 238276 2007-06-22 14:58:30Z ashnazg $
35
 * @filesource
36
 * @link       http://www.phpdoc.org
37
 * @link       http://pear.php.net/PhpDocumentor
38
 * @since      1.2
39
 */
40
/** when <text> is found in an ezText input */
41
define('PHPDOCUMENTOR_PDF_EVENT_TEXT', 600);
42
/** when <text> is found in an ezText input */
43
define('PHPDOCUMENTOR_PDF_STATE_TEXT', 700);
44
/** used for parsing stuff between <text> */
45
define('PHPDOCUMENTOR_PDF_EVENT_CONTENT', 601);
46
/** used for parsing stuff between <text> */
47
define('PHPDOCUMENTOR_PDF_STATE_CONTENT', 701);
48
/** when <font> is found in an ezText input */
49
define('PHPDOCUMENTOR_PDF_EVENT_FONT', 602);
50
/** when <font> is found in an ezText input */
51
define('PHPDOCUMENTOR_PDF_STATE_FONT', 702);
52
/** when <newpage/> is found in an ezText input */
53
define('PHPDOCUMENTOR_PDF_EVENT_NEWPAGE', 603);
54
/** when <newpage/> is found in an ezText input */
55
define('PHPDOCUMENTOR_PDF_STATE_NEWPAGE', 703);
56
/** when <pdffunction> is found in an ezText input */
57
define('PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION', 604);
58
/** when <pdffunction> is found in an ezText input */
59
define('PHPDOCUMENTOR_PDF_STATE_PDFFUNCTION', 704);
60
 
61
 
62
/**
63
 * @package Converters
64
 * @subpackage PDFdefault
65
 * @author Greg Beaver <cellog@php.net>
66
 * @since 1.2
67
 */
68
class PDFParser extends Parser
69
{
70
    /**
71
     * Mapping of event constants to events handler function names
72
     * @var array
73
     * @access private
74
     */
75
    var $eventHandlers
76
        = array(
77
            PHPDOCUMENTOR_PDF_EVENT_TEXT => 'handleText',
78
            PHPDOCUMENTOR_PDF_EVENT_FONT => 'handleFont',
79
            PHPDOCUMENTOR_PDF_EVENT_NEWPAGE => 'handleNewPage',
80
            PARSER_EVENT_QUOTE => 'handleQuote',
81
            PARSER_EVENT_NOEVENTS => 'defaultHandler',
82
            PHPDOCUMENTOR_PDF_EVENT_CONTENT => 'handleContent',
83
            PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION => 'handlePDFfunction',
84
            );
85
 
86
    /**
87
     * Sets up the wordparser for this class
88
     */
89
    function PDFParser()
90
    {
91
        $this->wp = new WordParser;
92
        $this->setupStates();
93
    }
94
    /**
95
     * Parse text for PDFParser XML tags, and add the text to the PDF file
96
     *
97
     * @param    string text to parse for PDFParser XML tags
98
     * @param    string full path to the font directory
99
     * @param    phpdocpdf
100
     * @param    boolean determines whether output is saved in a variable or
101
     *                   added directly to the output
102
     * @staticvar    integer    used for recursion limiting if a handler for an event is not found
103
     * @return    bool
104
     */
105
    function parse ($parse_data,$fontdir,&$pdf,$debug=false)
106
    {
107
        static $endrecur = 0;
108
        $this->_debug = $debug;
109
 
110
        // initialize variables so E_ALL error_reporting doesn't complain
111
        $pevent = 0;
112
        $word = 0;
113
        $this->p_vars['event_stack'] = new EventStack;
114
        $this->p_flags['reset_quote_data'] = true;
115
        $this->p_vars['options'] = false;
116
        $this->p_vars['font_dir'] = $fontdir;
117
        $this->p_vars['text_size'] = false;
118
        $this->p_vars['pdf'] = &$pdf;
119
 
120
        $this->wp->setup($parse_data);
121
        $this->wp->setWhitespace(true);
122
 
123
        do
124
        {
125
            $lpevent = $pevent;
126
            $pevent = $this->p_vars['event_stack']->getEvent();
127
            if ($lpevent != $pevent)
128
            {
129
                $this->p_vars['last_pevent'] = $lpevent;
130
            }
131
 
132
            if ($this->p_vars['last_pevent'] != $pevent)
133
            {
134
                // its a new event so the word parser needs to be reconfigured
135
                $this->configWordParser($pevent);
136
            }
137
 
138
 
139
            $this->p_vars['last_word'] = $word;
140
            $word = $this->wp->getWord();
141
 
142
            if (PHPDOCUMENTOR_DEBUG == true)
143
            {
144
                echo "----------------\n";
145
                echo "LAST: |" . $this->p_vars['last_word'] . "|\n";
146
//                echo "INDEX: ".$this->p_vars['curpar']."\n";
147
                echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";
148
                echo "LASTPEVENT: " . $this->getParserEventName($this->p_vars['last_pevent']) . "\n";
149
                echo $this->wp->getPos() . " WORD: |".$word."|\n\n";
150
            }
151
            if (isset($this->eventHandlers[$pevent]))
152
            {
153
                $handle = $this->eventHandlers[$pevent];
154
                $this->$handle($word, $pevent);
155
            } else
156
            {
157
                debug('WARNING: possible error, no ParserPDFParser handler for event number '.$pevent);
158
                if ($endrecur++ == 25)
159
                {
160
                    die("FATAL ERROR, recursion limit reached");
161
                }
162
            }
163
        } while (!($word === false));
164
        if (false) {
165
            $fp = fopen("C:/Documents and Settings/Owner/Desktop/pdfsource.txt", "a");
166
            fwrite($fp, $this->wp->data);
167
            fclose($fp);
168
        }
169
    }
170
 
171
    /**#@+
172
     * Event Handlers
173
     * @param string token
174
     * @param integer event constant
175
     * @access private
176
     */
177
    function defaultHandler($word, $pevent)
178
    {
179
        if ($this->checkEventPush($word, $pevent)) return;
180
    }
181
 
182
    /**
183
     * Handles <newpage />
184
     * @tutorial ParserPDF.cls#tags.newpage
185
     */
186
    function handleNewPage($word, $pevent)
187
    {
188
        $this->p_vars['event_stack']->popEvent();
189
        $this->p_vars['pdf']->ezNewPage($this->_debug);
190
    }
191
 
192
    /**
193
     * Handles <text></text>
194
     * @tutorial ParserPDF.cls#tags.text
195
     */
196
    function handleText($word, $pevent)
197
    {
198
        $e = $this->checkEventPush($word, $pevent);
199
        $e1 = $this->checkEventPop($word, $pevent);
200
        if ($e == PARSER_EVENT_QUOTE) return;
201
        if ($e1)
202
        {
203
            $this->p_flags['textcolor'] = false;
204
            if (($a = $this->p_vars['savecolor']) != $this->p_vars['pdf']->getColor())
205
            {
206
                $this->p_vars['pdf']->setColor($a['r'],$a['g'],$a['b']);
207
            }
208
        }
209
        if ($this->p_vars['last_word'] == '<text')
210
        {
211
            // set up flags
212
            $this->p_flags['paramval'] = false;
213
            $this->p_flags['textcolor'] = false;
214
            $this->p_vars['curparam'] = false;
215
            $this->p_vars['savecolor'] = $this->p_vars['pdf']->getColor();
216
            $this->p_vars['options'] = array();
217
            unset($this->p_vars['quote_data']);
218
        }
219
        if (!$this->p_flags['paramval'])
220
        {
221
            if ($e || $e1) return;
222
            if ($word == '=')
223
            {
224
//                debug('set paramval '.$this->p_vars['curparam']);
225
                $this->p_flags['paramval'] = true;
226
                return;
227
            }
228
            $this->p_vars['curparam'] = trim($word);
229
        } else
230
        {
231
            if ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE)
232
            {
233
                if ($this->p_vars['curparam'] == 'size')
234
                {
235
                    $this->p_vars['text_size'] = (int)$this->p_vars['quote_data'];
236
                    $this->p_flags['paramval'] = false;
237
                    $this->p_vars['curparam'] = false;
238
                    if (!$e && !$e1)
239
                    {
240
                        $this->p_vars['curparam'] = trim($word);
241
                    }
242
                    unset($this->p_vars['quote_data']);
243
                } elseif ($this->p_vars['curparam'] == 'color')
244
                {
245
                    if ($a = $this->p_vars['pdf']->validHTMLColor($this->p_vars['quote_data']))
246
                    {
247
                        $this->p_flags['textcolor'] = true;
248
                        $this->p_vars['pdf']->setHTMLColor($a);
249
                    }
250
                } else
251
                {
252
                    if ($this->p_vars['quote_data'] === (string)(int)$this->p_vars['quote_data']) $this->p_vars['quote_data'] = (int)$this->p_vars['quote_data'];
253
//                    debug('added '.$this->p_vars['curparam'].' = '.$this->p_vars['quote_data']);
254
                    $this->p_vars['options'][$this->p_vars['curparam']] = $this->p_vars['quote_data'];
255
                    $this->p_flags['paramval'] = false;
256
                    $this->p_vars['curparam'] = false;
257
                    if (!$e && !$e1)
258
                    {
259
                        $this->p_vars['curparam'] = trim($word);
260
                    }
261
                    unset($this->p_vars['quote_data']);
262
                }
263
            }
264
        }
265
    }
266
 
267
    /**
268
     * handles <font></font>
269
     * @tutorial ParserPDF.cls#tags.font
270
     */
271
    function handleFont($word, $pevent)
272
    {
273
        $e = $this->checkEventPush($word, $pevent);
274
        $e1 = $this->checkEventPop($word, $pevent);
275
        if ($e == PARSER_EVENT_QUOTE) return;
276
        if ($this->p_vars['last_word'] == '<font')
277
        {
278
            // set up flags
279
            $this->p_flags['paramval'] = false;
280
            $this->p_vars['curparam'] = false;
281
            unset($this->p_vars['quote_data']);
282
        }
283
        if (!$this->p_flags['paramval'])
284
        {
285
            if ($e || $e1) return;
286
            if ($word == '=')
287
            {
288
                //debug('set paramval '.$this->p_vars['curparam']);
289
                $this->p_flags['paramval'] = true;
290
                return;
291
            }
292
            $this->p_vars['curparam'] = trim($word);
293
        } else
294
        {
295
            if ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE)
296
            {
297
                if ($this->p_vars['curparam'] == 'face')
298
                {
299
                    //debug('set face to '.$this->p_vars['font_dir'] . $this->p_vars['quote_data'] . '.afm');
300
                    $this->p_vars['pdf']->selectFont($this->p_vars['font_dir'] . $this->p_vars['quote_data'] . '.afm');
301
                    $this->p_flags['paramval'] = false;
302
                    $this->p_vars['curparam'] = false;
303
                    unset($this->p_vars['quote_data']);
304
                }
305
            }
306
        }
307
    }
308
 
309
    /**
310
     * handles <pdffunction>
311
     * @tutorial ParserPDF.cls#tags.pdffunction
312
     */
313
    function handlePDFFunction($word, $pevent)
314
    {
315
        $e = $this->checkEventPush($word, $pevent);
316
        $e1 = $this->checkEventPop($word, $pevent);
317
        if ($e == PARSER_EVENT_QUOTE) return;
318
        if ($this->p_vars['last_word'] == '<pdffunction:')
319
        {
320
            // set up flags
321
            $this->p_flags['paramval'] = $this->p_flags['curparam'] = false;
322
            $this->p_flags['returnval'] = false;
323
            $this->p_vars['funcname'] = trim($word);
324
//            debug("funcname is $word");
325
            $this->p_vars['options'] = array();
326
            unset($this->p_vars['quote_data']);
327
            if ($e1) addErrorDie(PDERROR_PDFFUNCTION_NO_FUNC);
328
        }
329
        if (!$this->p_flags['paramval'])
330
        {
331
            if ($e1)
332
            { // call function, no parameters
333
                $func = $this->p_vars['funcname'];
334
                if (!$func) addErrorDie(PDERROR_PDFFUNCTION_NO_FUNC);
335
                if (method_exists($this->p_vars['pdf'],$func))
336
                {
337
                    if (count($this->p_vars['options']))
338
                    {
339
//                        fancy_debug("calling function $func",$this->p_vars['options']);
340
                        $a = call_user_func_array(array(&$this->p_vars['pdf'],$func), $this->p_vars['options']);
341
                    } else
342
                    {
343
//                        debug("calling function $func");
344
                        $a = $this->p_vars['pdf']->$func();
345
                    }
346
                    if ($this->p_flags['returnval'])
347
                    {
348
//                        debug("setting returnvar ".$this->p_vars['return_varname']);
349
                        $this->tempvars[$this->p_vars['return_varname']] = $a;
350
                    }
351
                } else
352
                {
353
                    addWarning(PDERROR_PDF_METHOD_DOESNT_EXIST,$func);
354
                }
355
                return;
356
            }
357
            if ($e) return;
358
            if ($word == '=')
359
            {
360
//                debug('set paramval '.$this->p_vars['curparam']);
361
                $this->p_flags['paramval'] = true;
362
                return;
363
            }
364
            $this->p_vars['curparam'] = trim($word);
365
        } else
366
        {
367
            if ($this->p_vars['last_word'] == '=')
368
            { // check to see if we should use a tempvar from a previous return
369
                if (substr(trim($word),0,1) == '$')
370
                {
371
                    if (substr(trim($word),0,7) == '$this->')
372
                    { // this is a pdf var
373
                        $a = substr(trim($word),7);
374
                        $a = $this->p_vars['pdf']->$a;
375
    //                    debug("set option to $word");
376
                        $this->p_vars['options'][] = $a;
377
                        $this->p_flags['paramval'] = false;
378
                        unset($this->p_vars['quote_data']);
379
                    } else
380
                    { // this is a tempvar
381
                        if (!isset($this->tempvars[substr(trim($word),1)]))
382
                        {
383
                            addErrorDie(PDERROR_PDF_TEMPVAR_DOESNT_EXIST,$this->p_vars['funcname'],trim($word),trim($word));
384
                        }
385
                        $a = $this->tempvars[substr(trim($word),1)];
386
    //                    debug("set option to $word");
387
                        $this->p_vars['options'][] = $a;
388
                        $this->p_flags['paramval'] = false;
389
                        unset($this->p_vars['quote_data']);
390
                    }
391
                }
392
            } else
393
            {
394
                if ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE)
395
                {
396
                    if ($this->p_vars['quote_data'] === (string)(int)$this->p_vars['quote_data'])
397
                    {
398
                        $this->p_vars['quote_data'] = (int)$this->p_vars['quote_data'];
399
                    }
400
                    if ($this->p_vars['curparam'] == 'return')
401
                    {
402
//                        debug("param is return");
403
                        $this->p_vars['return_varname'] = $this->p_vars['quote_data'];
404
                        $this->p_flags['returnval'] = true;
405
                    } else
406
                    {
407
//                        fancy_debug("set option to arg",$this->p_vars['quote_data']);
408
                        $this->p_vars['options'][] = $this->p_vars['quote_data'];
409
                    }
410
                    $this->p_flags['paramval'] = false;
411
                    unset($this->p_vars['quote_data']);
412
                }
413
            }
414
            if ($e1)
415
            { // call function, with parameters
416
                $func = $this->p_vars['funcname'];
417
                if (method_exists($this->p_vars['pdf'],$func))
418
                {
419
                    if (count($this->p_vars['options']))
420
                    {
421
//                        fancy_debug("calling function $func",$this->p_vars['options']);
422
                        if ($func == 'ezImage') {
423
                            // set padding to 5, width to 0, resize to none
424
                            $this->p_vars['options'][] = 5;
425
                            $this->p_vars['options'][] = 0;
426
                            $this->p_vars['options'][] = 'none';
427
                        }
428
                        $a = call_user_func_array(array(&$this->p_vars['pdf'],$func), $this->p_vars['options']);
429
                    } else
430
                    {
431
//                        debug("calling function $func");
432
                        $a = $this->p_vars['pdf']->$func();
433
                    }
434
                    if ($this->p_flags['returnval'])
435
                    {
436
//                        debug("setting returnvar ".$this->p_vars['return_varname']);
437
                        $this->tempvars[$this->p_vars['return_varname']] = $a;
438
                    }
439
                } else
440
                {
441
                    addWarning(PDERROR_PDF_METHOD_DOESNT_EXIST,$func);
442
                }
443
            }
444
        }
445
    }
446
 
447
    /**
448
     * Adds content to the <text> tag
449
     */
450
    function handleContent($word, $pevent)
451
    {
452
        if ($e = $this->checkEventPush($word, $pevent))
453
        {
454
            if ($e == PHPDOCUMENTOR_PDF_EVENT_FONT)
455
            { // flush content
456
                if (!isset($this->p_vars['content'])) return;
457
                $this->p_vars['pdf']->_ezText($this->p_vars['content'],$this->p_vars['text_size'],$this->p_vars['options']);
458
                unset($this->p_vars['content']);
459
            }
460
            return;
461
        }
462
        if ($this->checkEventPop($word, $pevent))
463
        {
464
            $this->wp->backupPos($word);
465
            if (!isset($this->p_vars['content'])) return;
466
            $this->p_vars['pdf']->_ezText($this->p_vars['content'],$this->p_vars['text_size'],$this->p_vars['options']);
467
            unset($this->p_vars['content']);
468
        } else
469
        {
470
            if (!isset($this->p_vars['content'])) $this->p_vars['content'] = '';
471
            if (isset($this->p_vars['quote_data']))
472
            {
473
                $this->p_vars['content'] .= $this->p_vars['quote_data'];
474
                unset($this->p_vars['quote_data']);
475
            }
476
            $this->p_vars['content'] .= $word;
477
        }
478
    }
479
    /**#@-*/
480
    /**
481
     * setup the parser tokens, and the pushEvent/popEvent arrays
482
     * @see $tokens, $pushEvent, $popEvent
483
     */
484
 
485
    function setupStates()
486
    {
487
        $this->tokens[STATE_NOEVENTS]            = array("<text","<font","<newpage />","<newpage/>",'<pdffunction:','"');
488
        $this->tokens[PHPDOCUMENTOR_PDF_STATE_TEXT]    = array(">","=",'"',"</text>");
489
        $this->tokens[PHPDOCUMENTOR_PDF_STATE_FONT] = array("/>","=",'"');
490
        $this->tokens[PHPDOCUMENTOR_PDF_STATE_CONTENT]    = array("<font",'<pdffunction:',"</text>");
491
        $this->tokens[PHPDOCUMENTOR_PDF_STATE_PDFFUNCTION]    = array('"',"/>","="," ");
492
        $this->tokens[STATE_QUOTE]            = array("\\\"","\\\\","\"");
493
        $this->tokens[STATE_ESCAPE]            = false;// this tells the word parser to just cycle
494
 
495
        // For each event word to event mapings
496
        $this->pushEvent[PARSER_EVENT_QUOTE] =
497
            array(
498
                "\\"    => PARSER_EVENT_ESCAPE
499
            );
500
        $this->popEvent[PARSER_EVENT_QUOTE] = array("\"");
501
##########################
502
        $this->pushEvent[PARSER_EVENT_NOEVENTS] =
503
            array(
504
                "<text"    => PHPDOCUMENTOR_PDF_EVENT_TEXT,
505
                "<font"    => PHPDOCUMENTOR_PDF_EVENT_FONT,
506
                "<newpage />" => PHPDOCUMENTOR_PDF_EVENT_NEWPAGE,
507
                "<newpage/>" => PHPDOCUMENTOR_PDF_EVENT_NEWPAGE,
508
                "<pdffunction:" => PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION,
509
                '"' => PARSER_EVENT_QUOTE,
510
            );
511
##########################
512
        $this->pushEvent[PHPDOCUMENTOR_PDF_EVENT_TEXT] =
513
            array(
514
                '"' => PARSER_EVENT_QUOTE,
515
                '>' => PHPDOCUMENTOR_PDF_EVENT_CONTENT,
516
            );
517
 
518
        $this->popEvent[PHPDOCUMENTOR_PDF_EVENT_TEXT] = array("</text>");
519
##########################
520
        $this->pushEvent[PHPDOCUMENTOR_PDF_EVENT_FONT] =
521
            array(
522
                '"' => PARSER_EVENT_QUOTE,
523
            );
524
 
525
        $this->popEvent[PHPDOCUMENTOR_PDF_EVENT_FONT] = array("/>");
526
##########################
527
        $this->pushEvent[PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION] =
528
            array(
529
                '"' => PARSER_EVENT_QUOTE,
530
            );
531
 
532
        $this->popEvent[PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION] = array("/>");
533
##########################
534
        $this->pushEvent[PHPDOCUMENTOR_PDF_EVENT_CONTENT] =
535
            array(
536
                "<font"    => PHPDOCUMENTOR_PDF_EVENT_FONT,
537
                "<newpage />" => PHPDOCUMENTOR_PDF_EVENT_NEWPAGE,
538
                "<newpage/>" => PHPDOCUMENTOR_PDF_EVENT_NEWPAGE,
539
                "<pdffunction:" => PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION,
540
            );
541
 
542
        $this->popEvent[PHPDOCUMENTOR_PDF_EVENT_CONTENT] = array("</text>");
543
    }
544
 
545
    /**
546
     * Return the name of the parser event
547
     * @param integer
548
     */
549
    function getParserEventName ($value)
550
    {
551
        $lookup = array(
552
            PARSER_EVENT_NOEVENTS         => "PARSER_EVENT_NOEVENTS",
553
            PARSER_EVENT_QUOTE        => "PARSER_EVENT_QUOTE",
554
            PHPDOCUMENTOR_PDF_EVENT_TEXT        => "PHPDOCUMENTOR_PDF_EVENT_TEXT",
555
            PHPDOCUMENTOR_PDF_EVENT_CONTENT        => "PHPDOCUMENTOR_PDF_EVENT_CONTENT",
556
            PHPDOCUMENTOR_PDF_EVENT_FONT    => "PHPDOCUMENTOR_PDF_EVENT_FONT",
557
            PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION    => "PHPDOCUMENTOR_PDF_EVENT_PDFFUNCTION",
558
        );
559
        if (isset($lookup[$value]))
560
        return $lookup[$value];
561
        else return $value;
562
    }
563
}
564
?>