Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * Source Code Highlighting
4
 *
5
 * The classes in this file are responsible for the dynamic @example, @filesource
6
 * and {@}source} tags output.  Using the phpDocumentor_HighlightWordParser,
7
 * the phpDocumentor_HighlightParser retrieves PHP tokens one by one from the
8
 * array generated by {@link phpDocumentorTWordParser} source retrieval functions
9
 * and then highlights them individually.
10
 *
11
 * It accomplishes this highlighting through the assistance of methods in
12
 * the output Converter passed to its parse() method, and then returns the
13
 * fully highlighted source as a string
14
 *
15
 * phpDocumentor :: automatic documentation generator
16
 *
17
 * PHP versions 4 and 5
18
 *
19
 * Copyright (c) 2002-2008 Gregory Beaver
20
 *
21
 * LICENSE:
22
 *
23
 * This library is free software; you can redistribute it
24
 * and/or modify it under the terms of the GNU Lesser General
25
 * Public License as published by the Free Software Foundation;
26
 * either version 2.1 of the License, or (at your option) any
27
 * later version.
28
 *
29
 * This library is distributed in the hope that it will be useful,
30
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32
 * Lesser General Public License for more details.
33
 *
34
 * You should have received a copy of the GNU Lesser General Public
35
 * License along with this library; if not, write to the Free Software
36
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37
 *
38
 * @category   ToolsAndUtilities
39
 * @package    phpDocumentor
40
 * @subpackage Parsers
41
 * @author     Gregory Beaver <cellog@php.net>
42
 * @copyright  2002-2008 Gregory Beaver
43
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
44
 * @version    CVS: $Id: HighlightParser.inc 253641 2008-02-24 02:35:44Z ashnazg $
45
 * @filesource
46
 * @link       http://www.phpdoc.org
47
 * @link       http://pear.php.net/PhpDocumentor
48
 * @tutorial   tags.example.pkg, tags.filesource.pkg, tags.inlinesource.pkg
49
 * @since      1.2.0beta3
50
 * @todo       CS cleanup - change package to PhpDocumentor
51
 */
52
 
53
/**
54
 * Retrieve tokens from an array of tokens organized by line numbers
55
 *
56
 * @category   ToolsAndUtilities
57
 * @package    phpDocumentor
58
 * @subpackage Parsers
59
 * @author     Gregory Beaver <cellog@php.net>
60
 * @copyright  2002-2008 Gregory Beaver
61
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
62
 * @version    Release: 1.4.3
63
 * @link       http://www.phpdoc.org
64
 * @link       http://pear.php.net/PhpDocumentor
65
 * @since      1.2.0beta3
66
 * @todo       CS cleanup - change package to PhpDocumentor
67
 * @todo       CS cleanup - change class name to PhpDocumentor_*
68
 */
69
class phpDocumentor_HighlightWordParser extends phpDocumentorTWordParser
70
{
71
    /**
72
     * Hash used to keep track of line numbers that have already been initialized
73
     * @var array
74
     * @access private
75
     */
76
    var $_listLineNums = array();
77
    /**
78
     * Initialize the parser object
79
     *
80
     * @param array                         &$input  the input
81
     * @param phpDocumentor_HighlightParser &$parser the parser
82
     *
83
     * @return void
84
     */
85
    function setup(&$input, &$parser)
86
    {
87
        $this->_parser     = &$parser;
88
        $this->data        = &$input;
89
        $this->_all        = $input;
90
        $this->_sourceline = 0;
91
        $this->pos         = 0;
92
        $this->linenum     = 0;
93
    }
94
 
95
    /**
96
     * debugging function
97
     *
98
     * @return void
99
     * @access private
100
     */
101
    function printState()
102
    {
103
        $linenum = $this->linenum;
104
        $pos     = $this->pos;
105
        if (!isset($this->_all[$this->linenum][$this->pos])) {
106
            $linenum++;
107
            $pos = 0;
108
        }
109
        $details = '';
110
        $token   = $this->_all[$linenum][$pos];
111
        if (is_array($token)) {
112
            $details = token_name($token[0]);
113
            $token   = htmlspecialchars($token[1]);
114
        } else {
115
            $token = htmlspecialchars($token);
116
        }
117
        debug('Next Token ' . $this->linenum . '-' . $this->pos . ':' . $details);
118
        var_dump($token);
119
    }
120
 
121
    /**
122
     * Retrieve the position of the next token that will be parsed
123
     * in the internal token array
124
     *
125
     * @return array format: array(line number, position)
126
     */
127
    function nextToken()
128
    {
129
        $linenum = $this->linenum;
130
        $pos     = $this->pos;
131
        if (!isset($this->_all[$this->linenum][$this->pos])) {
132
            $linenum++;
133
            $pos = 0;
134
        }
135
        if (!isset($this->_all[$linenum][$pos])) {
136
            return false;
137
        }
138
        return array($linenum, $pos);
139
    }
140
 
141
    /**
142
     * Retrieve the next token
143
     *
144
     * @return array|string either array(PHP token constant, token) or string
145
     *                      non-specific separator
146
     */
147
    function getWord()
148
    {
149
        if (!isset($this->_all[$this->linenum][$this->pos])) {
150
            $this->linenum++;
151
            $this->pos = 0;
152
            if (!isset($this->_all[$this->linenum])) {
153
                return false;
154
            }
155
            $this->_parser->newLineNum();
156
            return $this->getWord();
157
        }
158
        $word = $this->_all[$this->linenum][$this->pos++];
159
        return str_replace("\t", '    ', $word);
160
    }
161
 
162
    /**
163
     * back the word parser to the previous token as defined by $last_token
164
     *
165
     * @param array|string $last_token token, or output from {@link nextToken()}
166
     * @param bool         $is_pos     if true, backupPos interprets $last_token
167
     *                                 to be the position in the internal token
168
     *                                 array of the last token
169
     *
170
     * @return void
171
     */
172
    function backupPos($last_token, $is_pos = false)
173
    {
174
        if (!$last_token) {
175
            return;
176
        }
177
        if ($is_pos) {
178
            $this->linenum = $last_token[0];
179
            $this->pos     = $last_token[1];
180
            return;
181
        }
182
        if ($last_token === false) {
183
            return;
184
        }
185
 
186
        //fancy_debug('before', $this->linenum, $this->pos,
187
        //    token_name($this->_all[$this->linenum][$this->pos][0]),
188
        //    htmlentities($this->_all[$this->linenum][$this->pos][1]),
189
        //    $this->_all[$this->linenum]);
190
 
191
        do {
192
            $this->pos--;
193
            if ($this->pos < 0) {
194
                $this->linenum--;
195
                if ($this->linenum < 0) {
196
                    var_dump($last_token);
197
                    break;
198
                }
199
                $this->pos = count($this->_all[$this->linenum]) - 1;
200
            }
201
        } while (!$this->tokenEquals($last_token, str_replace("\t", '    ',
202
            $this->_all[$this->linenum][$this->pos])));
203
 
204
        //fancy_debug('after', $this->linenum, $this->pos,
205
        //    token_name($this->_all[$this->linenum][$this->pos][0]),
206
        //    htmlentities($this->_all[$this->linenum][$this->pos][1]));
207
    }
208
}
209
 
210
/**
211
 * Highlights source code using {@link parse()}
212
 *
213
 * @category   ToolsAndUtilities
214
 * @package    phpDocumentor
215
 * @subpackage Parsers
216
 * @author     Gregory Beaver <cellog@php.net>
217
 * @copyright  2002-2008 Gregory Beaver
218
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
219
 * @version    Release: 1.4.3
220
 * @link       http://www.phpdoc.org
221
 * @link       http://pear.php.net/PhpDocumentor
222
 * @since      1.2.0beta3
223
 * @todo       CS cleanup - change package to PhpDocumentor
224
 * @todo       CS cleanup - change class name to PhpDocumentor_*
225
 */
226
class phpDocumentor_HighlightParser extends phpDocumentorTParser
227
{
228
    /**#@+
229
     * @access private
230
     */
231
 
232
    /**
233
     * Highlighted source is built up in this string
234
     * @var string
235
     */
236
    var $_output;
237
 
238
    /**
239
     * contents of the current source code line as it is parsed
240
     * @var string
241
     */
242
    var $_line;
243
 
244
    /**
245
     * Used to retrieve highlighted tokens
246
     * @var Converter a descendant of Converter
247
     */
248
    var $_converter;
249
 
250
    /**
251
     * Path to file being highlighted, if this is from a @filesource tag
252
     * @var false|string full path
253
     */
254
    var $_filesourcepath;
255
 
256
    /**
257
     * @var array
258
     */
259
    var $eventHandlers = array(
260
        PARSER_EVENT_ARRAY                      => 'defaultHandler',
261
        PARSER_EVENT_CLASS                      => 'handleClass',
262
        PARSER_EVENT_COMMENT                    => 'handleComment',
263
        PARSER_EVENT_DOCBLOCK_TEMPLATE          => 'handleDocBlockTemplate',
264
        PARSER_EVENT_END_DOCBLOCK_TEMPLATE      => 'handleEndDocBlockTemplate',
265
        PARSER_EVENT_LOGICBLOCK                 => 'handleLogicBlock',
266
        PARSER_EVENT_METHOD_LOGICBLOCK          => 'handleMethodLogicBlock',
267
        PARSER_EVENT_NOEVENTS                   => 'defaultHandler',
268
        PARSER_EVENT_OUTPHP                     => 'defaultHandler',
269
        PARSER_EVENT_CLASS_MEMBER               => 'handleClassMember',
270
        PARSER_EVENT_DEFINE                     => 'defaultHandler',
271
        PARSER_EVENT_DEFINE_PARAMS              => 'defaultHandler',
272
        PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS  => 'defaultHandler',
273
        PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS => 'defaultHandler',
274
        PARSER_EVENT_DOCBLOCK                   => 'handleDocBlock',
275
        PARSER_EVENT_TAGS                       => 'handleTags',
276
        PARSER_EVENT_DESC                       => 'handleDesc',
277
        PARSER_EVENT_DOCKEYWORD                 => 'handleTag',
278
        PARSER_EVENT_DOCKEYWORD_EMAIL           => 'handleDockeywordEmail',
279
        PARSER_EVENT_EOFQUOTE                   => 'handleQuote',
280
        PARSER_EVENT_FUNCTION                   => 'handleFunction',
281
        PARSER_EVENT_METHOD                     => 'handleMethod',
282
        PARSER_EVENT_FUNCTION_PARAMS            => 'handleFunctionParams',
283
        PARSER_EVENT_FUNC_GLOBAL                => 'handleFuncGlobal',
284
        PARSER_EVENT_INLINE_DOCKEYWORD          => 'handleInlineDockeyword',
285
        PARSER_EVENT_INCLUDE                    => 'defaultHandler',
286
        PARSER_EVENT_INCLUDE_PARAMS             => 'defaultHandler',
287
        PARSER_EVENT_QUOTE                      => 'handleQuote',
288
        PARSER_EVENT_QUOTE_VAR                  => 'handleQuoteVar',
289
        PARSER_EVENT_PHPCODE                    => 'handlePhpCode',
290
        PARSER_EVENT_SINGLEQUOTE                => 'handleSingleQuote',
291
        PARSER_EVENT_STATIC_VAR                 => 'defaultHandler',
292
        PARSER_EVENT_STATIC_VAR_VALUE           => 'defaultHandler',
293
        PARSER_EVENT_VAR                        => 'handleVar',
294
    );
295
 
296
    /**
297
     * event handlers for @tags
298
     * @tutorial tags.pkg
299
     */
300
    var $tagHandlers = array(
301
        '*'              => 'defaultTagHandler',
302
        'abstract'       => 'coreTagHandler',
303
        'access'         => 'coreTagHandler',
304
        'author'         => 'coreTagHandler',
305
        'category'       => 'coreTagHandler',
306
        'copyright'      => 'coreTagHandler',
307
        'deprecated'     => 'coreTagHandler',
308
        'example'        => 'coreTagHandler',
309
        'filesource'     => 'coreTagHandler',
310
        'final'          => 'coreTagHandler',
311
        'global'         => 'globalTagHandler',
312
        'ignore'         => 'coreTagHandler',
313
        'license'        => 'coreTagHandler',
314
        'link'           => 'coreTagHandler',
315
        'name'           => 'coreTagHandler',
316
        'package'        => 'coreTagHandler',
317
        'param'          => 'paramTagHandler',
318
        'parameter'      => 'paramTagHandler',
319
        'see'            => 'coreTagHandler',
320
        'since'          => 'coreTagHandler',
321
        'subpackage'     => 'coreTagHandler',
322
        'internal'       => 'coreTagHandler',
323
        'return'         => 'returnTagHandler',
324
        'static'         => 'coreTagHandler',
325
        'staticvar'      => 'staticvarTagHandler',
326
        'throws'         => 'coreTagHandler',
327
        'todo'           => 'coreTagHandler',
328
        'tutorial'       => 'coreTagHandler',
329
        'uses'           => 'coreTagHandler',
330
        'var'            => 'varTagHandler',
331
        'version'        => 'coreTagHandler',
332
        'property'       => 'propertyTagHandler',
333
        'property-read'  => 'propertyTagHandler',
334
        'property-write' => 'propertyTagHandler',
335
        'method'         => 'propertyTagHandler'
336
    );
337
    /**#@-*/
338
 
339
    /**
340
     * wraps the current line (via the converter) and resets it to empty
341
     *
342
     * @return void
343
     * @uses Converter::SourceLine() encloses {@link $_line} in a
344
     *                               converter-specific format
345
     */
346
    function newLineNum()
347
    {
348
        if ($this->_pf_no_output_yet) {
349
            return;
350
        }
351
        $this->_flush_save();
352
        $this->_line   .= $this->_converter->flushHighlightCache();
353
        $this->_output .= $this->_converter->SourceLine($this->_wp->linenum,
354
            $this->_line, $this->_path);
355
        $this->_line    = '';
356
    }
357
 
358
    /**
359
     * Start the parsing at a certain line number
360
     *
361
     * @param int $num line number
362
     *
363
     * @return void
364
     */
365
    function setLineNum($num)
366
    {
367
        $this->_wp->linenum = $num;
368
    }
369
 
370
    /**
371
     * Parse a new file
372
     *
373
     * The parse() method is a do...while() loop that retrieves tokens one by
374
     * one from the {@link $_event_stack}, and uses the token event array set up
375
     * by the class constructor to call event handlers.
376
     *
377
     * The event handlers each process the tokens passed to them, and use the
378
     * {@link _addoutput()} method to append the processed tokens to the
379
     * {@link $_line} variable.  The word parser calls {@link newLineNum()}
380
     * every time a line is reached.
381
     *
382
     * In addition, the event handlers use special linking functions
383
     * {@link _link()} and its cousins (_classlink(), etc.) to create in-code
384
     * hyperlinks to the documentation for source code elements that are in the
385
     * source code.
386
     *
387
     * @param array         &$parse_data       the parse data
388
     * @param Converter     &$converter        the converter object
389
     * @param bool          $inlinesourceparse whether this data is from an
390
     *                                         inline {@}source} tag
391
     * @param string|false  $class             if a string, it is the name of the
392
     *                                         class whose method we are parsing
393
     *                                         containing a {@}source} tag
394
     * @param false|integer $linenum           starting line number from
395
     *                                         {@}source linenum}
396
     * @param false|string  $filesourcepath    full path to file with @filesource
397
     *                                         tag, if this is a @filesource parse
398
     *
399
     * @staticvar int used for recursion limiting if a handler for
400
     *                an event is not found
401
     * @return bool
402
     * @uses setupStates() initialize parser state variables
403
     * @uses configWordParser() pass $parse_data to prepare retrieval of tokens
404
     * @todo CS cleanup - rename tokenizer_ext constant to uppercase
405
     */
406
    function parse (&$parse_data, &$converter, $inlinesourceparse = false,
407
        $class = false, $linenum = false, $filesourcepath = false)
408
    {
409
        if (!tokenizer_ext) {
410
            if (is_array($parse_data)) {
411
                $parse_data = join($parse_data, '');
412
            }
413
            $parse_data    = explode("\n", $parse_data);
414
            $this->_output = '';
415
            foreach ($parse_data as $linenum => $line) {
416
                if ($linenum > 0) {
417
                    $this->_output .= $converter->SourceLine($linenum,
418
                        $line, $filesourcepath);
419
                }
420
            }
421
            return $converter->PreserveWhiteSpace($this->_output);
422
        }
423
        static $endrecur  = 0;
424
        $this->_converter = &$converter;
425
        $converter->startHighlight();
426
        $this->_path = $filesourcepath;
427
        $this->setupStates($inlinesourceparse, $class);
428
 
429
        $this->configWordParser($parse_data);
430
        if ($linenum !== false) {
431
            $this->setLineNum($linenum);
432
        }
433
        // initialize variables so E_ALL error_reporting doesn't complain
434
        $pevent = 0;
435
        $word   = 0;
436
 
437
        do {
438
            $lpevent = $pevent;
439
            $pevent  = $this->_event_stack->getEvent();
440
            if ($lpevent != $pevent) {
441
                $this->_last_pevent = $lpevent;
442
            }
443
 
444
            if ($pevent == PARSER_EVENT_CLASS_MEMBER) {
445
                $this->_wp->setWhitespace(true);
446
            } else {
447
                $this->_wp->setWhitespace(false);
448
            }
449
 
450
            if (!is_array($word)) {
451
                $lw = $word;
452
            }
453
            if (is_array($word) && $word[0] != T_WHITESPACE) {
454
                $lw = $word;
455
            }
456
            $dbg_linenum = $this->_wp->linenum;
457
            $dbg_pos     = $this->_wp->getPos();
458
            $word        = $this->_wp->getWord();
459
            if (is_array($word) && ($word[0] == T_WHITESPACE ||
460
                $word[0] == T_COMMENT) &&
461
                $pevent != PARSER_EVENT_CLASS_MEMBER
462
            ) {
463
                //debug("added " . $this->_wp->linenum . '-' . $this->_wp->pos);
464
                $this->_addoutput($word);
465
                continue;
466
            } else {
467
                $this->_pv_last_word = $lw;
468
            }
469
            if ($pevent != PARSER_EVENT_DOCBLOCK) {
470
                $this->_pv_last_next_word = $this->_pv_next_word;
471
                $this->_pv_next_word      = $this->_wp->nextToken();
472
            }
473
            // in wordparser, have to keep track of lines
474
            //$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWLINENUM,
475
            //    $this->_wp->linenum);
476
            if (PHPDOCUMENTOR_DEBUG == true) {
477
                echo "LAST: ";
478
                if (is_array($this->_pv_last_word)) {
479
                    echo token_name($this->_pv_last_word[0]) .
480
                        ' => |' .
481
                        htmlspecialchars($this->_pv_last_word[1]);
482
                } else {
483
                    echo "|" . $this->_pv_last_word;
484
                }
485
                echo "|\n";
486
                echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";
487
                echo "LASTPEVENT: " .
488
                    $this->getParserEventName($this->_last_pevent) . "\n";
489
                //echo "LINE: "   . $this->_line   . "\n";
490
                //echo "OUTPUT: " . $this->_output . "\n";
491
                echo $dbg_linenum . '-' . $dbg_pos . ": ";
492
                if (is_array($word)) {
493
                    echo token_name($word[0]) . ' => |' . htmlspecialchars($word[1]);
494
                } else {
495
                    echo '|'.htmlspecialchars($word);
496
                }
497
                echo "|\n";
498
                $this->_wp->printState();
499
                echo "NEXT TOKEN: ";
500
                $tok1 = $this->_pv_next_word;
501
                $tok  = $this->_wp->_all[$tok1[0]][$tok1[1]];
502
                if (is_array($tok)) {
503
                    echo token_name($tok[0]) . ' => ' . $tok1[0] . '-' . $tok1[1] .
504
                        '|' . htmlspecialchars($tok[1]);
505
                } else {
506
                    echo "|" . $tok;
507
                }
508
                echo "|\n";
509
                echo "-------------------\n\n\n";
510
                flush();
511
            }
512
            if ($word !== false && isset($this->eventHandlers[$pevent])) {
513
                $handle = $this->eventHandlers[$pevent];
514
                $this->$handle($word, $pevent);
515
            } elseif ($word !== false) {
516
                debug('WARNING: possible error, no handler for event number '
517
                     . $pevent);
518
                if ($endrecur++ == 25) {
519
                    die("FATAL ERROR, recursion limit reached");
520
                }
521
            }
522
        } while (!($word === false));
523
        if (strlen($this->_line)) {
524
            $this->newLineNum();
525
        }
526
        return $this->_output;
527
    }
528
 
529
    /**#@+
530
     * Event Handlers
531
     *
532
     * All Event Handlers use {@link checkEventPush()} and
533
     * {@link checkEventPop()} to set up the event stack and parser state.
534
     *
535
     * @param string|array $word   token value
536
     * @param int          $pevent parser event from {@link Parser.inc}
537
     *
538
     * @return void
539
     * @access private
540
     */
541
    /**
542
     * Most tokens only need highlighting, and this method handles them
543
     */
544
    function defaultHandler($word, $pevent)
545
    {
546
        $this->_addoutput($word);
547
        if ($this->checkEventPush($word, $pevent)) {
548
            return;
549
        }
550
        $this->checkEventPop($word, $pevent);
551
    }
552
 
553
    /**
554
     * Handles global declarations in a function, like:
555
     *
556
     * <code>
557
     * function foobar()
558
     * {
559
     *     global $_phpDocumentor_setting;
560
     * }
561
     * </code>
562
     *
563
     * @uses _globallink() instead of _addoutput(), to link to global variables
564
     *       if they are used in a function
565
     */
566
    function handleFuncGlobal($word, $pevent)
567
    {
568
        if ($this->checkEventPush($word, $pevent)) {
569
            return;
570
        }
571
        $this->_globallink($word);
572
        $this->checkEventPop($word, $pevent);
573
    }
574
 
575
    /**
576
     * Handles strings in quotation marks and heredoc
577
     *
578
     * Special handling is needed for strings that contain variables like:
579
     *
580
     * <code>$a = "$test string"</code>
581
     *
582
     * The tokenizer parses out tokens '"',array(T_VARIABLE,'$test'),' string',
583
     * and '"'.  Since it is possible to have $this->classvar in a string,
584
     * we save a variable name just in case the next token is -> to allow linking
585
     * to class members.  Otherwise, the string is simply highlighted.
586
     *
587
     * constant strings (with no $variables in them) are passed as a single
588
     * entity, and so will be saved in the last token parsed.  This means the
589
     * event handler must tell the word parser to re-retrieve the current token
590
     * so that the correct event handler can process it.
591
     */
592
    function handleQuote($word, $pevent)
593
    {
594
        if ($this->_pf_inmethod && is_array($word) && $word[0] == T_VARIABLE) {
595
            $this->_pv_lastvar = $word;
596
        }
597
        if ($this->checkEventPush($word, $pevent)) {
598
            $this->_addoutput($word);
599
            return;
600
        }
601
        if ($this->_pf_quote_active &&
602
            (($this->_pv_last_word == '"' &&
603
            $this->_last_pevent != PARSER_EVENT_QUOTE) ||
604
            (is_array($this->_pv_last_word) &&
605
            $this->_pv_last_word[0] == T_END_HEREDOC &&
606
            $this->_last_pevent != PARSER_EVENT_EOFQUOTE))
607
        ) {
608
            $this->_pf_quote_active = false;
609
            $this->_wp->backupPos($word);
610
            $this->_event_stack->popEvent();
611
            return;
612
        }
613
        if (!$this->_pf_quote_active &&
614
            (($this->_pv_last_word == '"' &&
615
            $this->_last_pevent != PARSER_EVENT_QUOTE) ||
616
            (is_array($this->_pv_last_word) &&
617
            $this->_pv_last_word[0] == T_END_HEREDOC &&
618
            $this->_last_pevent != PARSER_EVENT_EOFQUOTE))
619
        ) {
620
            if (is_array($word) && $word[0] == T_VARIABLE) {
621
                $this->_pv_lastvar = $word;
622
            }
623
            $this->_pf_quote_active      = true;
624
            $this->_save_highlight_state = $this->_converter->getHighlightState();
625
            $this->_converter->startHighlight();
626
            $this->_addoutput($word);
627
            $this->checkEventPop($word, $pevent);
628
            return;
629
        } elseif (is_array($this->_pv_last_word) &&
630
            $this->_pv_last_word[0] == T_CONSTANT_ENCAPSED_STRING
631
        ) {
632
            //$this->_pv_quote_data = $this->_pv_last_word[1];
633
            $this->_event_stack->popEvent();
634
            $this->_wp->backupPos($word);
635
            return;
636
        }
637
        if ($this->checkEventPop($word, $pevent)) {
638
            $this->_pf_quote_active = false;
639
        }
640
        $this->_addoutput($word);
641
    }
642
 
643
    /**
644
     * Handles {$variable} within a "quote"
645
     *
646
     * This is a simple handler, for a very complex
647
     * array of legal syntax.  It is legal to nest control structures
648
     * inside the {}, and other weird stuff.
649
     */
650
    function handleQuoteVar($word, $pevent)
651
    {
652
        if ($this->checkEventPop($word, $pevent)) {
653
            $this->_pf_quote_active = true;
654
            $this->_addoutput($word);
655
            return;
656
        }
657
        if ($this->_pf_inmethod && is_array($word) && $word[0] == T_VARIABLE) {
658
            $this->_pv_lastvar = $word;
659
        }
660
        if ($this->checkEventPush($word, $pevent)) {
661
            $this->_pf_quote_active = false;
662
            if (is_string($word) && ($word == '{' || $word == '"' || $word == "'")
663
            ) {
664
                $this->_pf_quote_active = true;
665
                $this->_pv_lastvar      = false;
666
            }
667
        }
668
        $this->_addoutput($word);
669
    }
670
 
671
    /**
672
     * Handles define() statements
673
     *
674
     * The only thing this handler cares about is retrieving the name of the
675
     * define variable, and the end of the define statement, so after the name
676
     * is found, it simply makes sure parentheses are matched as in this case:
677
     *
678
     * <code>
679
     * define("test",array("hello",6 => 4, 5 => array('there')));
680
     * </code>
681
     *
682
     * This handler and the DEFINE_PARAMS_PARENTHESIS handler (which is just
683
     * {@link defaultHandler()} in this version, as nothing fancy is needed)
684
     * work together to ensure proper parenthesis matching.
685
     *
686
     * If the define variable is documented, a link will be created to its
687
     * documentation using the Converter passed.
688
     */
689
    function handleDefine($word, $pevent)
690
    {
691
        static $token_save;
692
        if (!isset($token_save)) {
693
            $token_save = array();
694
        }
695
        $e = $this->checkEventPush($word, $pevent);
696
        if ($e && $e != PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS) {
697
            return;
698
        }
699
 
700
        if (!isset($this->_pv_define_params_data)) {
701
            $this->_pv_define_params_data = '';
702
        }
703
 
704
        if ($this->checkEventPop($word, $pevent)) {
705
            unset($token_save);
706
            $this->_addoutput($word);
707
        }
708
        if ($this->_pf_definename_isset) {
709
            $this->_addoutput($word);
710
        } else {
711
            if ($word != ",") {
712
                $token_save[] = $word;
713
                if (is_array($word)) {
714
                    $word = $word[1];
715
                }
716
                $this->_pv_define_params_data .= $word;
717
            } else {
718
                if (substr($this->_pv_define_params_data, 0, 1) ==
719
                    substr($this->_pv_define_params_data,
720
                        strlen($this->_pv_define_params_data) - 1) &&
721
                    in_array(substr($this->_pv_define_params_data, 0, 1),
722
                        array('"', "'"))
723
                ) {
724
                    // remove leading and ending quotation marks
725
                    // if there are only two
726
                    $a = substr($this->_pv_define_params_data, 0, 1);
727
                    $b = substr($this->_pv_define_params_data, 1,
728
                        strlen($this->_pv_define_params_data) - 2);
729
                    if (strpos($b, $a) === false) {
730
                        $this->_pv_define_params_data = $b;
731
                    }
732
                }
733
                $this->_pf_definename_isset = true;
734
 
735
                $link = $this->_converter->getLink($this->_pv_define_params_data);
736
                foreach ($token_save as $token) {
737
                    if (is_object($link)) {
738
                        if (is_array($token)) {
739
                            $token = $token[1];
740
                        }
741
                        $this->_addoutput($this->_converter->returnSee($link,
742
                            $token));
743
                    } else {
744
                        $this->_addoutput($save, $token);
745
                    }
746
                }
747
                $this->_pv_define_params_data = '';
748
            }
749
        }
750
    }
751
 
752
    /**
753
     * Handles normal global code.  Special consideration is taken for DocBlocks
754
     * as they need to retrieve the whole DocBlock before doing any output, so
755
     * the parser flag {@link $_pf_no_output_yet} is set to tell
756
     * {@link _addoutput()} not to spit anything out yet.
757
     *
758
     * @uses _link() make any global code that is a documentable element link
759
     *       to the php manual or its documentation
760
     */
761
    function handlePhpCode($word, $pevent)
762
    {
763
        $test = $this->checkEventPush($word, $pevent);
764
        if ($test == PARSER_EVENT_DOCBLOCK || $test == PARSER_EVENT_COMMENT) {
765
            if (substr($word[1], 0, 2) == '/*' && strpos($word[1], '*/')) {
766
                $this->_pv_last_word = $word;
767
                if ($word[1] == '/**#@-*/') {
768
                    $this->_pf_docblock_template = true;
769
                } else {
770
                    $this->_pf_docblock = true;
771
                }
772
                return $this->handleDocBlock($word, PARSER_EVENT_DOCBLOCK);
773
            }
774
            $this->_pf_no_output_yet = true;
775
            $this->_pv_saveline      = $this->_wp->linenum + 1;
776
            return;
777
        }
778
        if (is_array($word) && $word[0] == T_DOUBLE_COLON) {
779
            $this->_pf_colon_colon = true;
780
        }
781
        if (!$this->_pf_colon_colon && is_array($word) && $word[0] == T_STRING) {
782
            $this->_pv_last_string = $word;
783
        }
784
        $this->_link($word);
785
        $this->checkEventPop($word, $pevent);
786
    }
787
 
788
    /**
789
     * Handle the function declaration header
790
     *
791
     * This handler only sees the "function name" portion of the function
792
     * declaration.  Handling of the function parameters is by
793
     * {@link handleFunctionParams()}, and the function body is handled by
794
     * {@link handleLogicBlock()}
795
     */
796
    function handleFunction($word, $pevent)
797
    {
798
        if ($this->checkEventPush($word, $pevent)) {
799
            $this->_addoutput($word);
800
            return;
801
        }
802
        if ($this->checkEventPop($word, $pevent)) {
803
            return;
804
        }
805
        $this->_link($word);
806
    }
807
 
808
    /**
809
     * Handle the method declaration header
810
     *
811
     * This handler only sees the "function name" portion of the method
812
     * declaration.  Handling of the method parameters is by
813
     * {@link handleFunctionParams()}, and the method body is handled by
814
     * {@link handleMethodLogicBlock()}
815
     */
816
    function handleMethod($word, $pevent)
817
    {
818
        if ($this->checkEventPush($word, $pevent)) {
819
            $this->_addoutput($word);
820
            return;
821
        }
822
        if ($this->checkEventPop($word, $pevent)) {
823
            if ($word == ';') {
824
                $this->_addoutput($word);
825
            }
826
            return;
827
        }
828
        $this->_methodlink($word);
829
    }
830
 
831
    /**
832
     * Handler for the stuff between ( and ) in a function declaration
833
     *
834
     * <code>
835
     * function handles($only,$these,$parameters){...}
836
     * </code>
837
     */
838
    function handleFunctionParams($word, $pevent)
839
    {
840
        if ($this->checkEventPush($word, $pevent)) {
841
            $this->_addoutput($word);
842
            return;
843
        }
844
        $this->_addoutput($word);
845
        $this->checkEventPop($word, $pevent);
846
    }
847
 
848
    /**
849
     * Handler for function body.
850
     *
851
     * The function body is checked for php functions, documented constants,
852
     * functions, and indirectly for global statements.  It hyperlinks to the
853
     * documentation for detected elements is created.  Everything else is
854
     * highlighted normally.
855
     */
856
    function handleLogicBlock($word, $pevent)
857
    {
858
        if ($this->checkEventPush($word, $pevent)) {
859
            $this->_addoutput($word);
860
            return;
861
        }
862
        if (is_array($word) && $word[0] == T_DOUBLE_COLON) {
863
            $this->_pf_colon_colon = true;
864
        }
865
        if (!$this->_pf_colon_colon && is_array($word) && $word[0] == T_STRING) {
866
            $this->_pv_last_string = $word;
867
        }
868
        $this->_link($word);
869
        if ($this->checkEventPop($word, $pevent)) {
870
            $e = $this->_event_stack->popEvent();
871
            $this->_event_stack->pushEvent($e);
872
            if ($e == PARSER_EVENT_FUNCTION) {
873
                $this->_wp->backupPos($word);
874
            }
875
        }
876
    }
877
 
878
    /**
879
     * Handler for method body.
880
     *
881
     * Like functions, the method body is checked for php functions, documented
882
     * constants, functions, and indirectly for global statements.  It also
883
     * checks for "$this->XXXX" where XXXX is a class variable or method, and
884
     * links to the documentation for detected elements is created.  Everything
885
     * else is highlighted normally.
886
     */
887
    function handleMethodLogicBlock($word, $pevent)
888
    {
889
        if (isset($this->_pv_prev_var_type)) {
890
            //debug('prevtype is set');
891
            if (!is_array($word)) {
892
                unset($this->_pv_prev_var_type);
893
            } else {
894
                if ($word[0] != T_WHITESPACE &&
895
                    $word[0] != T_STRING && $word[0] != T_OBJECT_OPERATOR
896
                ) {
897
                    //fancy_debug('unset', $word);
898
                    unset($this->_pv_prev_var_type);
899
                }
900
            }
901
        }
902
        $this->_pf_inmethod = true;
903
        if ($e = $this->checkEventPush($word, $pevent)) {
904
            $this->_addoutput($word);
905
            if ($e == PARSER_EVENT_CLASS_MEMBER) {
906
                $this->_pf_no_output_yet = true;
907
            }
908
            return;
909
        }
910
        if (is_array($word) && $word[0] == T_DOUBLE_COLON) {
911
            $this->_pf_colon_colon = true;
912
        }
913
        if (!$this->_pf_colon_colon && is_array($word) && $word[0] == T_STRING) {
914
            $this->_pv_last_string = $word;
915
        }
916
        if (is_array($word) && $word[0] == T_VARIABLE) {
917
            $this->_pv_lastvar = $word;
918
        }
919
        $this->_link($word);
920
        if ($this->checkEventPop($word, $pevent)) {
921
            $this->_pf_inmethod = false;
922
            $e                  = $this->_event_stack->popEvent();
923
            $this->_event_stack->pushEvent($e);
924
            if ($e == PARSER_EVENT_METHOD) {
925
                $this->_wp->backupPos($word);
926
            }
927
        }
928
    }
929
 
930
    /**
931
     * Handles $obj->classmember in a method body
932
     *
933
     * This handler is responsible for linking to the documentation of a
934
     * class member when it is used directly in a method body.
935
     *
936
     * There are two methods of determining whether to link:
937
     * - $this->member
938
     * - $this->member->submember
939
     *
940
     * The first case is handled by the $_pv_lastvar variable, and the
941
     * second case is handled by the $_pv_prev_var_type variable.  $_pv_lastvar
942
     * is always set to the value of the last T_VARIABLE token, if and only if
943
     * no text has occurred between the variable and a T_OBJECT_OPERATOR token
944
     * "->".  handleClassMember will only link if the last variable encountered
945
     * was $this.
946
     *
947
     * When $this->variable is encountered, the variable is looked up to see
948
     * if it can be found, and if so, the contents of its @var tag are processed
949
     * to see if the member variable is defined to have 1 and only 1 class.
950
     * If so, the $_pv_prev_var_type variable is set to this classname.  When
951
     * submember is processed, the HighlightParser checks to see if
952
     * $_pv_prev_var_type::submember() or $_pv_prev_var_type::$submember exists,
953
     * and if it does, it is linked to.
954
     */
955
    function handleClassMember($word, $pevent)
956
    {
957
        if (!isset($this->_pv_lastvar) && !isset($this->_pv_prev_var_type)) {
958
            //fancy_debug('returned from', $word, $this->_pv_prev_var_type);
959
            $this->_pf_no_output_yet = false;
960
            $this->_event_stack->popEvent();
961
            return $this->defaultHandler($word, $pevent);
962
        }
963
        if (isset($this->_pv_cm_name)) {
964
            $this->_pf_obj_op = false;
965
            $name             = $this->_pv_cm_name;
966
            unset($this->_pv_cm_name);
967
            //debug('unset pvcmname');
968
            $this->_event_stack->popEvent();
969
            // control variable for _pv_prev_var_type
970
            $setnow = false;
971
            if ((isset($this->_pv_lastvar) && $this->_pv_lastvar[1] == '$this') ||
972
                isset($this->_pv_prev_var_type)
973
            ) {
974
                if (is_array($word) && $word[0] == T_WHITESPACE) {
975
                    // preserve value of _pv_prev_var_type
976
                    $setnow = true;
977
                    $save   = $this->_wp->nextToken();
978
                    $temp   = $this->_wp->getWord();
979
                    $this->_wp->backupPos($save, true);
980
                }
981
                if ((is_string($word) && $word == '(') || (isset($temp) &&
982
                    is_string($temp) && $temp == '(')
983
                ) {
984
                    // it's a function
985
                    $this->_pf_no_output_yet = false;
986
                    $this->_methodlink($name);
987
                    unset($this->_pv_prev_var_type);
988
                } else {
989
                    // it's a variable
990
                    //fancy_debug('name is ', $name);
991
                    $this->_pf_no_output_yet = false;
992
                    $this->_varlink($name, true);
993
                    $templink =
994
                        $this->_converter->getLink('object ' . $this->_pv_class);
995
                    $class    = false;
996
                    if (is_object($templink)) {
997
                        $class = $this->_converter->classes
998
                            ->getClass($templink->name, $templink->path);
999
                    }
1000
                    if ($class) {
1001
                        $varname = $name;
1002
                        if (is_array($varname)) {
1003
                            $varname = $name[1];
1004
                        }
1005
                        if ($varname{0} != '$') {
1006
                            $varname = '$'.$varname;
1007
                        }
1008
                        $var = $class->getVar($this->_converter, $varname);
1009
 
1010
                        if (is_object($var) && $var->docblock->var) {
1011
                            $type = $var->docblock->var->returnType;
1012
                        }
1013
                        if (isset($type)) {
1014
                            if (strpos($type, 'object') === false) {
1015
                                $type = 'object '.$type;
1016
                            }
1017
                            $type = $this->_converter->getLink($type);
1018
                            if (phpDocumentor_get_class($type) == 'classlink') {
1019
                                // the variable's type is a class,
1020
                                // save it for future ->
1021
                                //fancy_debug('set prev_var_type!', $type->name);
1022
                                $setnow                  = true;
1023
                                $this->_pv_prev_var_type = $type->name;
1024
                            } else {
1025
                                unset($this->_pv_prev_var_type);
1026
                            }
1027
                        } else {
1028
                            unset($this->_pv_prev_var_type);
1029
                        }
1030
                    } else {
1031
                        unset($this->_pv_prev_var_type);
1032
                    }
1033
                }
1034
            } else {
1035
                $this->_pf_no_output_yet = false;
1036
                // this does NewLinenum if necessary
1037
                $this->_wp->backupPos($word);
1038
                $this->_wp->getWord();
1039
                $this->_addoutput($name);
1040
            }
1041
            if (!$setnow) {
1042
                //debug('unset prevtype, no setnow');
1043
                unset($this->_pv_prev_var_type);
1044
            }
1045
            unset($this->_pv_lastvar);
1046
            $this->_pf_no_output_yet = false;
1047
            // this does NewLinenum if necessary
1048
            $this->_wp->backupPos($word);
1049
            $this->_wp->getWord();
1050
            if ($word[0] == T_OBJECT_OPERATOR) {
1051
                $this->_wp->backupPos($word);
1052
            } else {
1053
                $this->_addoutput($word);
1054
            }
1055
            return;
1056
        }
1057
        if (!$this->_pf_obj_op && is_array($this->_pv_last_word) &&
1058
            $this->_pv_last_word[0] == T_OBJECT_OPERATOR
1059
        ) {
1060
            if ((isset($this->_pv_lastvar) && $this->_pv_lastvar[1] == '$this') ||
1061
                isset($this->_pv_prev_var_type)
1062
            ) {
1063
                $this->_pf_obj_op = true;
1064
            } else {
1065
                $this->_pf_no_output_yet = false;
1066
                // this does NewLinenum if necessary
1067
                $this->_wp->backupPos($word);
1068
                $this->_wp->getWord();
1069
                $this->_addoutput($word);
1070
                $this->_event_stack->popEvent();
1071
            }
1072
        }
1073
        if (is_array($word) && $word == T_WHITESPACE) {
1074
            $this->_pf_no_output_yet = false;
1075
            // this does NewLinenum if necessary
1076
            $this->_wp->backupPos($word);
1077
            $this->_wp->getWord();
1078
            $this->_addoutput($word);
1079
            return;
1080
        }
1081
        if ($this->_pf_obj_op) {
1082
            if (!(is_array($word) && ($word[0] == T_STRING ||
1083
                $word[0] == T_WHITESPACE))
1084
            ) {
1085
                unset($this->_pv_lastvar);
1086
                //debug('unset lastvar');
1087
                $this->_event_stack->popEvent();
1088
                $this->_pf_no_output_yet = false;
1089
                // this does NewLinenum if necessary
1090
                $this->_wp->backupPos($word);
1091
                $this->_wp->getWord();
1092
                $this->_addoutput($word);
1093
                return;
1094
            }
1095
            if ($word[0] == T_STRING) {
1096
                //fancy_debug('set pvcmname to', $word);
1097
                $this->_pv_cm_name = $word;
1098
            } else {
1099
                $this->_pf_no_output_yet = false;
1100
                // this does NewLinenum if necessary
1101
                $this->_wp->backupPos($word);
1102
                $this->_wp->getWord();
1103
                $this->_addoutput($word);
1104
            }
1105
        }
1106
    }
1107
 
1108
    /**
1109
     * Handles comments
1110
     *
1111
     * Comments are almost always single-line tokens, and so will be
1112
     * in the last word.  This handler checks to see if the current token
1113
     * is in fact a comment, and if it isn't, it backs up and returns control
1114
     * to the parent event handler with that word.
1115
     */
1116
    function handleComment($word, $pevent)
1117
    {
1118
        $w = $this->_pv_last_word;
1119
        // don't perform this check if this is a normal comment.  Docblocks
1120
        // have the _pf_no_output_yet variable set to true
1121
        if ($this->_pf_no_output_yet && is_array($w) &&
1122
            (in_array($w[0], array(T_COMMENT, T_DOC_COMMENT)) &&
1123
            strpos($w[1], '/**') === 0)
1124
        ) {
1125
            $this->_event_stack->popEvent();
1126
            $this->_event_stack->pushEvent(PARSER_EVENT_DOCBLOCK);
1127
            return $this->handleDocBlock($word, PARSER_EVENT_DOCBLOCK);
1128
        }
1129
        if ($this->_pf_no_output_yet) {
1130
            $flag                    = 1;
1131
            $this->_pf_no_output_yet = false;
1132
            $this->_addoutput($this->_pv_last_word);
1133
        }
1134
        if (!is_array($word) ||
1135
            !in_array($word[0], array(T_COMMENT, T_DOC_COMMENT)) ||
1136
            (in_array($word[0], array(T_COMMENT, T_DOC_COMMENT)) &&
1137
            strpos($word[1], '/**') === 0)
1138
        ) {
1139
            $this->_event_stack->popEvent();
1140
            if (strpos($this->_pv_last_word[1], "\n") !== false) {
1141
                //$this->_wp->linenum++;
1142
                //$this->newLineNum();
1143
            }
1144
            $this->_wp->backupPos($this->_pv_last_word);
1145
            $this->_wp->getWord();
1146
            //var_dump($this->_wp->nextToken());
1147
            return;
1148
        } elseif (isset($flag)) {
1149
            $this->newLineNum();
1150
        }
1151
        $this->_addoutput($word);
1152
        $this->checkEventPop($word, $pevent);
1153
        if (strpos($word[1], '*/') === strlen($word[1]) - 2) {
1154
            $this->_event_stack->popEvent();
1155
        }
1156
    }
1157
 
1158
    /**
1159
     * Handle class declarations
1160
     *
1161
     * Handles the initial declaration line:
1162
     *
1163
     * <code>class X</code>
1164
     *
1165
     * or
1166
     *
1167
     * <code>class X extends Y implements I</code>
1168
     *
1169
     * @uses _classlink() to link to documentation for X and for Y class in
1170
     *                    "class X extends Y"
1171
     */
1172
    function handleClass($word, $pevent)
1173
    {
1174
        $this->_pf_in_class = true;
1175
        $a                  = $this->checkEventPush($word, $pevent);
1176
 
1177
        if (!isset($this->_pv_class) && is_array($word) && $word[0] == T_STRING) {
1178
            $this->_pv_class = $this->_converter->class = $word[1];
1179
            $this->_classlink($word);
1180
            return;
1181
        }
1182
 
1183
        if (is_array($word) &&
1184
            in_array($word[0], array(T_PRIVATE, T_PROTECTED, T_PUBLIC))
1185
        ) {
1186
            $starttok = $this->_wp->nextToken();
1187
            $test     = array(T_WHITESPACE);
1188
            while ($test && $test[0] == T_WHITESPACE) {
1189
                $tok  = $this->_wp->nextToken();
1190
                $test = $this->_wp->getWord();
1191
            } // while
1192
 
1193
            if (is_array($test) && $test[0] == T_VARIABLE) {
1194
                $this->_wp->backupPos($tok, true);
1195
                return;
1196
            }
1197
            $this->_wp->backupPos($starttok, true);
1198
        }
1199
 
1200
        if (@in_array($this->_pv_last_word[0],
1201
            array(T_PRIVATE, T_PROTECTED, T_PUBLIC))
1202
        ) {
1203
            if (is_array($word) && $word[0] == T_VARIABLE) {
1204
                $this->_wp->backupPos($this->_pv_last_word);
1205
                $this->_event_stack->pushEvent(PARSER_EVENT_VAR);
1206
                return;
1207
            }
1208
        }
1209
 
1210
        if ($this->_pf_extends_found && is_array($word) && $word[0] == T_STRING) {
1211
            $this->_classlink($word);
1212
            return;
1213
        }
1214
        if (is_array($word) && $word[0] == T_EXTENDS) {
1215
            $this->_pf_extends_found = true;
1216
        }
1217
        if ($a == PARSER_EVENT_DOCBLOCK) {
1218
            $this->_pf_no_output_yet = true;
1219
            $this->_pv_saveline      = $this->_wp->linenum + 1;
1220
            return;
1221
        }
1222
        $this->_addoutput($word);
1223
        if ($this->checkEventPop($word, $pevent)) {
1224
            $this->_pf_in_class = false;
1225
            unset($this->_pv_class);
1226
        }
1227
    }
1228
 
1229
    /**
1230
     * Handles class variable declaration
1231
     *
1232
     * <code>
1233
     * class X
1234
     * {
1235
     *     var $Y;
1236
     * }
1237
     * </code>
1238
     *
1239
     * @uses _varlink() make a link to $Y documentation in class variable
1240
     *                  declaration "var $Y;"
1241
     */
1242
    function handleVar($word, $pevent)
1243
    {
1244
        if ($this->checkEventPush($word, $pevent)) {
1245
            $this->_addoutput($word);
1246
            return;
1247
        }
1248
        if (is_array($word) && $word[0] == T_VARIABLE) {
1249
            return $this->_varlink($word);
1250
        }
1251
        $this->_addoutput($word);
1252
        $this->checkEventPop($word, $pevent);
1253
    }
1254
 
1255
    /**
1256
     * This handler is responsible for highlighting DocBlocks
1257
     *
1258
     * handleDocBlock determines whether the docblock is normal or a template,
1259
     * and gathers all the lines of the docblock together before doing any
1260
     * processing
1261
     *
1262
     * As it is not possible to distinguish any comment token from a docblock
1263
     * token, this handler is also called for comments, and will pass control
1264
     * to {@link handleComment()} if the comment is not a DocBlock
1265
     *
1266
     * @uses commonDocBlock() once all lines of the DocBlock have been retrieved
1267
     */
1268
    function handleDocBlock($word, $pevent)
1269
    {
1270
        if (!($this->_pf_docblock || $this->_pf_docblock_template)) {
1271
            if (strpos($this->_pv_last_word[1], '/**') !== 0) {
1272
                // not a docblock
1273
                $this->_wp->backupPos($this->_pv_last_word);
1274
                $this->_event_stack->popEvent();
1275
                $this->_event_stack->pushEvent(PARSER_EVENT_COMMENT);
1276
                $this->_pf_no_output_yet = false;
1277
                return;
1278
            } else {
1279
                $this->_pf_no_output_yet = true;
1280
                $this->_pv_db_lines      = array();
1281
            }
1282
        }
1283
        $last_word = $this->_pv_last_word[1];
1284
        $dtype     = '_pv_docblock';
1285
        if ($last_word == '/**#@-*/') {
1286
            // stop using docblock template
1287
            $this->_pf_no_output_yet = false;
1288
            $this->_addDocBlockoutput('closetemplate', $last_word);
1289
            if ($this->_pv_next_word !== false) {
1290
                $this->_wp->backupPos($this->_pv_next_word, true);
1291
            }
1292
            $this->_event_stack->popEvent();
1293
            return;
1294
        }
1295
        if (!($this->_pf_docblock || $this->_pf_docblock_template)) {
1296
            $this->_pv_db_lines = array();
1297
            if (strpos($last_word, '/**#@+') === 0) {
1298
                // docblock template definition
1299
                $this->_pf_docblock_template = true;
1300
            } else {
1301
                $this->_pf_docblock = true;
1302
            }
1303
            $this->_pv_db_lines[] = $last_word;
1304
            if (strpos($last_word, '*/') !== false) {
1305
                $this->commonDocBlock();
1306
                return;
1307
            }
1308
            $this->_pv_db_lines[] = $word[1];
1309
            if (strpos($word[1], '*/') !== false) {
1310
                $this->commonDocBlock();
1311
            }
1312
        } else {
1313
            $this->_pv_db_lines[] = $word[1];
1314
        }
1315
        if (($this->_pf_docblock || $this->_pf_docblock_template) &&
1316
            (strpos($word[1], '*/') !== false)
1317
        ) {
1318
            $this->commonDocBlock();
1319
        }
1320
    }
1321
    /**#@-*/
1322
 
1323
    /**
1324
     * This continuation of handleDocBlock splits DocBlock comments up into
1325
     * phpDocumentor tokens.  It highlights DocBlock templates in a different
1326
     * manner from regular DocBlocks, recognizes inline tags, regular tags,
1327
     * and distinguishes between standard core tags and other tags, and
1328
     * recognizes parameters to tags like @var.
1329
     *
1330
     * the type in "@var type description" will be highlighted as a php type,
1331
     * and the var in "@param type $var description" will be highlighted as a
1332
     * php variable.
1333
     *
1334
     * @return void
1335
     * @uses handleDesc() highlight inline tags in the description
1336
     * @uses handleTags() highlight all tags
1337
     * @access private
1338
     */
1339
    function commonDocBlock()
1340
    {
1341
        $this->_event_stack->popEvent();
1342
        $lines = $this->_pv_db_lines;
1343
        $go    = count($this->_pv_db_lines);
1344
        for ($i=0; $i < $go; $i++) {
1345
            if (substr(trim($lines[$i]), 0, 2) == '*/' ||
1346
                substr(trim($lines[$i]), 0, 1) != '*' &&
1347
                substr(trim($lines[$i]), 0, 3) != '/**'
1348
            ) {
1349
                $lines[$i] = array($lines[$i], false);
1350
            } elseif (substr(trim($lines[$i]), 0, 3) == '/**') {
1351
                $linesi = array();
1352
                // remove leading "/**"
1353
                $linesi[1] = substr(trim($lines[$i]), 3);
1354
                if (empty($linesi[1])) {
1355
                    $linesi[0] = $lines[$i];
1356
                } else {
1357
                    $linesi[0] =
1358
                        substr($lines[$i], 0, strpos($lines[$i], $linesi[1]));
1359
                }
1360
                $lines[$i] = $linesi;
1361
            } else {
1362
                $linesi = array();
1363
                // remove leading "* "
1364
                $linesi[1] = substr(trim($lines[$i]), 1);
1365
                if (empty($linesi[1])) {
1366
                    $linesi[0] = $lines[$i];
1367
                } else {
1368
                    $linesi[0] =
1369
                        substr($lines[$i], 0, strpos($lines[$i], $linesi[1]));
1370
                }
1371
                $lines[$i] = $linesi;
1372
            }
1373
        }
1374
        for ($i = 0; $i < count($lines); $i++) {
1375
            if ($lines[$i][1] === false) {
1376
                continue;
1377
            }
1378
            if (substr(trim($lines[$i][1]), 0, 1) == '@' &&
1379
                substr(trim($lines[$i][1]), 0, 2) != '@ '
1380
            ) {
1381
                $tagindex = $i;
1382
                $i        = count($lines);
1383
            }
1384
        }
1385
        if (isset($tagindex)) {
1386
            $tags = array_slice($lines, $tagindex);
1387
            $desc = array_slice($lines, 0, $tagindex);
1388
        } else {
1389
            $tags = array();
1390
            $desc = $lines;
1391
        }
1392
        //var_dump($desc, $tags);
1393
        $this->_pf_no_output_yet = false;
1394
        $save                    = $this->_wp->linenum;
1395
        $this->_wp->linenum      = $this->_pv_saveline;
1396
        $this->handleDesc($desc);
1397
        $this->handleTags($tags);
1398
        $this->_pv_db_lines = array();
1399
        $this->_wp->linenum = $save;
1400
        if (strpos($this->_pv_last_word[1], '*/') !== false) {
1401
            $this->_wp->backupPos($this->_pv_next_word, true);
1402
        }
1403
        $this->_pf_docblock = $this->_pf_docblock_template = false;
1404
    }
1405
 
1406
    /**
1407
     * Handle the description area of a DocBlock
1408
     *
1409
     * This method simply finds inline tags and highlights them
1410
     * separately from the rest of the description.
1411
     *
1412
     * @param mixed $desc the description piece(s)
1413
     *
1414
     * @return void
1415
     * @uses getInlineTags()
1416
     * @access private
1417
     */
1418
    function handleDesc($desc)
1419
    {
1420
        $dbtype  = 'docblock';
1421
        $dbtype .= ($this->_pf_docblock ? '' : 'template');
1422
        foreach ($desc as $line) {
1423
            $this->getInlineTags($line[0] . $line[1]);
1424
            if (strpos($line[0], '*/') === false &&
1425
                !(substr($line[0], 0, 2) == '/*' &&
1426
                strpos($line[1], '*/') !== false)
1427
            ) {
1428
                $this->newLineNum();
1429
                $this->_wp->linenum++;
1430
            }
1431
        }
1432
        if ($this->_pf_internal) {
1433
            $this->_pf_internal = false;
1434
        }
1435
    }
1436
 
1437
    /**
1438
     * Handle phpDocumentor tags in a DocBlock
1439
     *
1440
     * This method uses the {@link $tagHandlers} array to determine which
1441
     * method will handle tags found in the docblock, and passes the data to
1442
     * the individual handlers one by one
1443
     *
1444
     * @param array $tags array of tags to handle
1445
     *
1446
     * @return void
1447
     * @access private
1448
     */
1449
    function handleTags($tags)
1450
    {
1451
        $newtags = array();
1452
        $curtag  = array();
1453
        for ($i=0; $i < count($tags); $i++) {
1454
            $tagsi = trim($tags[$i][1]);
1455
            if (substr($tagsi, 0, 1) == '@' && substr($tagsi, 0, 2) != '@ ') {
1456
                // start a new tag
1457
                $tags[$i][1] = array(substr($tags[$i][1], 0,
1458
                    strpos($tags[$i][1], $tagsi)), $tagsi);
1459
                if (!empty($curtag)) {
1460
                    $newtags[] = $curtag;
1461
                    $curtag    = array();
1462
                }
1463
                $curtag[] = $tags[$i];
1464
            } else {
1465
                $curtag[] = $tags[$i];
1466
            }
1467
        }
1468
        if (!empty($curtag)) {
1469
            $newtags[] = $curtag;
1470
        }
1471
        foreach ($newtags as $tag) {
1472
            foreach ($tag as $i => $t) {
1473
                if ($t[1] === false) {
1474
                    continue;
1475
                }
1476
                if (is_array($t[1])) {
1477
                    $tag[$i][1][1]
1478
                        = explode(" ", str_replace("\t", '    ', $t[1][1]));
1479
                    $x = $tag[$i][1][1];
1480
                }
1481
            }
1482
            $tagname   = substr(array_shift($x), 1);
1483
            $restoftag = $tag;
1484
            if (isset($this->tagHandlers[$tagname])) {
1485
                $handle = $this->tagHandlers[$tagname];
1486
            } else {
1487
                $handle = $this->tagHandlers['*'];
1488
            }
1489
            $this->$handle($tagname, $restoftag);
1490
        }
1491
    }
1492
 
1493
    /**
1494
     * This handler recognizes all {@}inline} tags
1495
     *
1496
     * Normal inline tags are simply highlighted.  the {@}internal}} inline
1497
     * tag {@tutorial tags.inlineinternal.pkg} is highlighted differently
1498
     * to distinguish it from other inline tags.
1499
     *
1500
     * @param mixed $value       the tag value
1501
     * @param bool  $endinternal indicates the end of an @internal tag
1502
     *
1503
     * @return void
1504
     * @access private
1505
     */
1506
    function getInlineTags($value, $endinternal = false)
1507
    {
1508
        if (!$value) {
1509
            return;
1510
        }
1511
        if ($this->_pf_internal && !$endinternal) {
1512
            if (strpos($value, '}}') !== false) {
1513
                $x = strrpos($value, '}}');
1514
                // add the rest of internal
1515
                $this->getInlineTags(substr($value, 0, $x + 3), true);
1516
                // strip internal from value
1517
                $value = substr($value, strrpos($value, '}}') + 1);
1518
                // turn off internal
1519
                $this->_pf_internal = false;
1520
            }
1521
        }
1522
        if (!$value) {
1523
            return;
1524
        }
1525
        $dbtype  = 'docblock';
1526
        $dbtype .= ($this->_pf_docblock ? '' : 'template');
1527
        $save    = $value;
1528
        $value   = explode('{@', $value);
1529
        $newval  = array();
1530
        // everything before the first {@ is normal text
1531
        $this->_addDocBlockoutput($dbtype, $value[0]);
1532
        for ($i=1; $i < count($value); $i++) {
1533
            if (substr($value[$i], 0, 1) == '}') {
1534
                $this->_addDocBlockoutput($dbtype, '{@}' . substr($value[$i], 1));
1535
            } else {
1536
                $save      = $value[$i];
1537
                $value[$i] = str_replace("\t", "    ", $value[$i]);
1538
                $value[$i] = explode(" ", $value[$i]);
1539
                $word      = array_shift($value[$i]);
1540
                $val       = join(' ', $value[$i]);
1541
                if ($word == 'internal') {
1542
                    $this->_pf_internal = true;
1543
                    $this->_addDocBlockoutput($dbtype, '{@internal ');
1544
                    $value[$i] = substr($save, strlen('internal') + 1);
1545
                    // strip internal and cycle as if it were normal text.
1546
                    $this->_addDocBlockoutput($dbtype, $value[$i]);
1547
                    continue;
1548
                }
1549
                if (in_array(str_replace('}', '', $word), $this->allowableInlineTags)
1550
                ) {
1551
                    if (strpos($word, '}')) {
1552
                        $word = str_replace('}', '', $word);
1553
                        $val  = '} ' . $val;
1554
                    }
1555
                    $val = explode('}', $val);
1556
                    if (count($val) == 1) {
1557
                         //addError(PDERROR_UNTERMINATED_INLINE_TAG,
1558
                         //    $word, '', $save);
1559
                    }
1560
                    $rest = $val;
1561
                    $val  = array_shift($rest);
1562
                    if ($endinternal) {
1563
                        $rest = join('}', $rest);
1564
                    } else {
1565
                        $rest = join(' ', $rest);
1566
                    }
1567
                    if (isset($this->inlineTagHandlers[$word])) {
1568
                        $handle = $this->inlineTagHandlers[$word];
1569
                    } else {
1570
                        $handle = $this->inlineTagHandlers['*'];
1571
                    }
1572
                    $this->$handle($word, $val);
1573
                    $this->_addDocBlockoutput($dbtype, $rest);
1574
                } else {
1575
                    $val = $word . ' ' . $val;
1576
                    $this->_addDocBlockoutput($dbtype, '{@' . $val);
1577
                }
1578
            }
1579
        }
1580
    }
1581
 
1582
 
1583
    /**
1584
     * Handles all inline tags
1585
     *
1586
     * @param string $name  the tag name
1587
     * @param mixed  $value the tag value
1588
     *
1589
     * @return void
1590
     * @access private
1591
     */
1592
    function handleDefaultInlineTag($name, $value)
1593
    {
1594
        $this->_addDocBlockoutput('inlinetag', '{@' . $name . ' ' . $value . '}');
1595
    }
1596
 
1597
    /**#@+
1598
     * phpDocumentor DocBlock tag handlers
1599
     *
1600
     * @param string $name    tag name
1601
     * @param array  $value   array of lines contained in the tag description
1602
     *
1603
     * @return void
1604
     * @access private
1605
     */
1606
    /**
1607
     * Handle normal tags
1608
     *
1609
     * This handler adds to outpu all comment information before the tag begins
1610
     * as in " * " before "@todo" in " * @todo"
1611
     *
1612
     * Then, it highlights the tag as a regular or coretag based on $coretag.
1613
     * Finally, it uses getInlineTags to highlight the description
1614
     *
1615
     * @param bool $coretag whether this tag is a core tag or not
1616
     *
1617
     * @uses getInlineTags() highlight a tag description
1618
     */
1619
    function defaultTagHandler($name, $value, $coretag = false)
1620
    {
1621
        $dbtype  = 'docblock';
1622
        $dbtype .= ($this->_pf_docblock ? '' : 'template');
1623
        foreach ($value as $line) {
1624
            $this->_addDocBlockoutput($dbtype, $line[0]);
1625
            if ($line[1] === false) {
1626
                if (trim($line[0]) != '*/') {
1627
                    $this->newLineNum();
1628
                    $this->_wp->linenum++;
1629
                }
1630
                continue;
1631
            }
1632
            $this->_addDocBlockoutput($dbtype, $line[1][0]);
1633
            $stored = '';
1634
            if (is_array($line[1][1])) {
1635
                foreach ($line[1][1] as $i => $tpart) {
1636
                    if ($tpart == '@' . $name && $i == 0) {
1637
                        $tagname = 'tag';
1638
                        if ($coretag) {
1639
                            $tagname = 'coretag';
1640
                        }
1641
                        $this->_addDocBlockoutput($tagname, '@' . $name);
1642
                        continue;
1643
                    }
1644
                    $stored .= ' ' . $tpart;
1645
                }
1646
            } else {
1647
                $stored = $line[1];
1648
            }
1649
            $this->getInlineTags($stored);
1650
            if (strpos($stored, '*/') === false) {
1651
                $this->newLineNum();
1652
                $this->_wp->linenum++;
1653
            }
1654
        }
1655
    }
1656
 
1657
    /**
1658
     * main handler for "core" tags
1659
     *
1660
     * @see defaultTagHandler()
1661
     */
1662
    function coreTagHandler($name, $value)
1663
    {
1664
        return $this->defaultTagHandler($name, $value, true);
1665
    }
1666
 
1667
    /**
1668
     * Handles @global
1669
     *
1670
     * This handler works like {@link defaultTagHandler()} except it highlights
1671
     * the type and variable (if present) in "@global type $variable" or
1672
     * "@global type description"
1673
     */
1674
    function globalTagHandler($name, $value)
1675
    {
1676
        $this->paramTagHandler($name, $value);
1677
    }
1678
 
1679
    /**
1680
     * Handles @param
1681
     *
1682
     * This handler works like {@link defaultTagHandler()} except it highlights
1683
     * the type and variable (if present) in "@param type $variable description"
1684
     * or "@param type description"
1685
     *
1686
     * @param bool $checkforvar private parameter, checks for $var or not
1687
     */
1688
    function paramTagHandler($name, $value, $checkforvar = true)
1689
    {
1690
        $dbtype  = 'docblock';
1691
        $dbtype .= ($this->_pf_docblock ? '' : 'template');
1692
        $ret     = $this->retrieveType($value, 0, $checkforvar);
1693
        foreach ($value as $num => $line) {
1694
            $this->_addDocBlockoutput($dbtype, $line[0]);
1695
            if ($line[1] === false) {
1696
                if (trim($line[0]) != '*/') {
1697
                    $this->newLineNum();
1698
                    $this->_wp->linenum++;
1699
                }
1700
                continue;
1701
            }
1702
            $this->_addDocBlockoutput($dbtype, $line[1][0]);
1703
            $stored  = '';
1704
            $typeloc = 1;
1705
            $varloc  = 2;
1706
            if (is_array($line[1][1])) {
1707
                $this->_addDocBlockoutput('coretag', '@' . $name . ' ');
1708
                foreach ($ret[0] as $text) {
1709
                    if (is_string($text)) {
1710
                        $this->_addDocBlockoutput($dbtype, $text);
1711
                    }
1712
                    if (is_array($text)) {
1713
                        if ($text[0] != 'desc') {
1714
                            $this->_addDocBlockoutput($text[0], $text[1]);
1715
                        } else {
1716
                            $stored .= $text[1];
1717
                        }
1718
                    }
1719
                }
1720
            } else {
1721
                if (isset($ret[$num])) {
1722
                    foreach ($ret[$num] as $text) {
1723
                        if (is_string($text)) {
1724
                            $this->_addDocBlockoutput($dbtype, $text);
1725
                        }
1726
                        if (is_array($text)) {
1727
                            if ($text[0] != 'desc') {
1728
                                $this->_addDocBlockoutput($text[0], $text[1]);
1729
                            } else {
1730
                                $stored .= $text[1];
1731
                            }
1732
                        }
1733
                    }
1734
                } else {
1735
                    $stored = $line[1];
1736
                }
1737
            }
1738
            $this->getInlineTags($stored);
1739
            if (strpos($stored, '*/') === false) {
1740
                $this->newLineNum();
1741
                $this->_wp->linenum++;
1742
            }
1743
        }
1744
    }
1745
 
1746
    /**
1747
     * handles the @staticvar tag
1748
     *
1749
     * @see paramTagHandler()
1750
     */
1751
    function staticvarTagHandler($name, $value)
1752
    {
1753
        return $this->paramTagHandler($name, $value);
1754
    }
1755
 
1756
    /**
1757
     * handles the @var tag
1758
     *
1759
     * @see paramTagHandler()
1760
     */
1761
    function varTagHandler($name, $value)
1762
    {
1763
        return $this->paramTagHandler($name, $value);
1764
    }
1765
 
1766
    /**
1767
     * Handles @return
1768
     *
1769
     * This handler works like {@link defaultTagHandler()} except it highlights
1770
     * the type in "@return type description"
1771
     */
1772
    function returnTagHandler($name, $value)
1773
    {
1774
        $this->paramTagHandler($name, $value, false);
1775
    }
1776
 
1777
    /**
1778
     * Handles @property(-read or -write) and @method magic tags
1779
     */
1780
    function propertyTagHandler($name, $value)
1781
    {
1782
        return $this->paramTagHandler($name, $value, true);
1783
    }
1784
 
1785
    /**#@-*/
1786
 
1787
    /**
1788
     * Retrieve the type portion of a @tag type description
1789
     *
1790
     * Tags like @param, @return and @var all have a PHP type portion in their
1791
     * description.  Since the type may contain the expression "object blah"
1792
     * where blah is a classname, it makes parsing out the type field complex.
1793
     *
1794
     * Even more complicated is the case where a tag variable can contain
1795
     * multiple types, such as object blah|object blah2|false, and so this
1796
     * method handles these cases.
1797
     *
1798
     * @param array $value       array of words that were separated by spaces
1799
     * @param 0|1   $state       0 = find the type, 1 = find the var, if present
1800
     * @param bool  $checkforvar flag to determine whether to check for the end of a
1801
     *                           type is defined by a $varname
1802
     *
1803
     * @return array Format: array(state (0 [find type], 1 [var], 2 [done]),
1804
     * @access private
1805
     */
1806
    function retrieveType($value, $state = 0, $checkforvar = false)
1807
    {
1808
        $index  = 0;
1809
        $result = array();
1810
        do {
1811
            if (!isset($value[$index][1])) {
1812
                return $result;
1813
            }
1814
            $val = $value[$index][1];
1815
            if (empty($val)) {
1816
                return $result;
1817
            }
1818
            if ($index == 0) {
1819
                $val = $val[1];
1820
                array_shift($val);
1821
            } else {
1822
                $val = explode(' ', $val);
1823
            }
1824
            $ret              = $this->_retrieveType($val, $state, $checkforvar);
1825
            $state            = $ret[0];
1826
            $result[$index++] = $ret[1];
1827
        } while ((!$checkforvar && $state < 1) || ($state < 2 && $checkforvar));
1828
        return $result;
1829
    }
1830
 
1831
    /**
1832
     * used by {@link retrieveType()} in its work
1833
     *
1834
     * @param array $value       array of words that were separated by spaces
1835
     * @param 0|1   $state       0 = find the type, 1 = find the var, if present
1836
     * @param bool  $checkforvar flag to determine whether to check for the end of a
1837
     *                           type is defined by a $varname
1838
     *
1839
     * @return array
1840
     * @access private
1841
     */
1842
    function _retrieveType($value, $state, $checkforvar)
1843
    {
1844
        $result   = array();
1845
        $result[] = $this->_removeWhiteSpace($value, 0);
1846
        if ($state == 0) {
1847
            if (!count($value)) {
1848
                return array(2, $result);
1849
            }
1850
            $types = '';
1851
            $index = 0;
1852
            if (trim($value[0]) == 'object') {
1853
                $result[] = array('tagphptype', $value[0] . ' ');
1854
                $types   .= array_shift($value).' ';
1855
                $result[] = $this->_removeWhiteSpace($value, 0);
1856
                if (!count($value)) {
1857
                    // was just passed "object"
1858
                    return array(2, $result);
1859
                }
1860
                if ($value[0]{0} == '$' || substr($value[0], 0, 2) == '&$') {
1861
                    // was just passed "object"
1862
                    // and the next thing is a variable name
1863
                    if ($checkforvar) {
1864
                        $result[] = array('tagvarname' , $value[0] . ' ');
1865
                        array_shift($value);
1866
                    }
1867
                    $result[] = array('desc', join(' ', $value));
1868
                    return array(2, $result);
1869
                }
1870
            }
1871
            $done = false;
1872
            $loop = -1;
1873
            do {
1874
                // this loop checks for type|type|type and for
1875
                // type|object classname|type|object classname2
1876
                if (strpos($value[0], '|')) {
1877
                    $temptypes = explode('|', $value[0]);
1878
                    while (count($temptypes)) {
1879
                        $type     = array_shift($temptypes);
1880
                        $result[] = array('tagphptype', $type);
1881
                        if (count($temptypes)) {
1882
                            $result[] = '|';
1883
                        }
1884
                    }
1885
                    if (trim($type) == 'object') {
1886
                        $result[] = array('tagphptype', $types . ' ');
1887
                        $result[] = $this->_removeWhiteSpace($value, 0);
1888
                    } else {
1889
                        $done = true;
1890
                    }
1891
                    array_shift($value);
1892
                    if (count($value) && strlen($value[0]) && isset ($value[0]) &&
1893
                        ($value[0]{0} == '$' || substr($value[0], 0, 2) == '&$')
1894
                    ) {
1895
                        // was just passed "object"
1896
                        // and the next thing is a variable name
1897
                        $result[] = array('tagvarname' , $value[0] . ' ');
1898
                        array_shift($value);
1899
                        $result[] = array('desc', join(' ', $value));
1900
                        return array(2, $result);
1901
                    }
1902
                } else {
1903
                    $result[] = array('tagphptype', $value[0] . ' ');
1904
                    array_shift($value);
1905
                    $done = true;
1906
                }
1907
                $loop++;
1908
            } while (!$done && count($value));
1909
            if ($loop) {
1910
                $result[] = ' ';
1911
            }
1912
            // still searching for type
1913
            if (!$done && !count($value)) {
1914
                return array(0, $result);
1915
            }
1916
            // still searching for var
1917
            if ($done && !count($value)) {
1918
                return array(1, $result);
1919
            }
1920
        }
1921
        $result[] = $this->_removeWhiteSpace($value, 0);
1922
        $state    = 1;
1923
        if ($checkforvar) {
1924
            if (count($value)) {
1925
                $state = 2;
1926
                if (substr($value[0], 0, 1) == '$' ||
1927
                    substr($value[0], 0, 2) == '&$'
1928
                ) {
1929
                    $result[] = array('tagvarname' , $value[0] . ' ');
1930
                    array_shift($value);
1931
                }
1932
            } else {
1933
                $state = 1;
1934
            }
1935
        }
1936
        $result[] = array('desc', join(' ', $value));
1937
        return array($state, $result);
1938
    }
1939
 
1940
    /**
1941
     * captures trailing whitespace
1942
     *
1943
     * @param array &$value array of string
1944
     * @param int   $index  index to seek non-whitespace to
1945
     *
1946
     * @return string whitespace
1947
     * @access private
1948
     */
1949
    function _removeWhiteSpace(&$value, $index)
1950
    {
1951
        $result = '';
1952
        if (count($value) > $index && empty($value[$index])) {
1953
            $found = false;
1954
            for ($i = $index; $i < count($value) && !strlen($value[$i]); $i++) {
1955
                $result .= ' ';
1956
            }
1957
            array_splice($value, $index, $i - $index);
1958
        }
1959
        return $result;
1960
    }
1961
 
1962
    /**#@+
1963
     * Link generation methods
1964
     *
1965
     * @param string|array $word token to try to link
1966
     *
1967
     * @access private
1968
     */
1969
    /**
1970
     * Generate a link to documentation for an element
1971
     *
1972
     * This method tries to link to documentation for functions, methods,
1973
     * PHP functions, class names, and if found, adds the links to output
1974
     * instead of plain text
1975
     */
1976
    function _link($word)
1977
    {
1978
        if (is_array($word) && $word[0] == T_STRING) {
1979
            if ($this->_pf_colon_colon) {
1980
                $this->_pf_colon_colon = false;
1981
 
1982
                $combo = $this->_pv_last_string[1] . '::' . $word[1] . '()';
1983
                //debug('testing ' . $combo);
1984
                $link = $this->_converter->getLink($combo);
1985
                if (is_object($link)) {
1986
                    $this->_addoutput($this->_converter->returnSee($link,
1987
                        $word[1]), true);
1988
                    return;
1989
                }
1990
                $this->_addoutput($word);
1991
                return;
1992
            }
1993
            $link = $this->_converter->getLink($word[1] . '()');
1994
            if (is_object($link)) {
1995
                $this->_addoutput($this->_converter->returnSee($link,
1996
                    $word[1]), true);
1997
                return;
1998
            } elseif (is_string($link) && strpos($link, 'ttp://')) {
1999
                $this->_addoutput($this->_converter->returnLink($link,
2000
                    $word[1]), true);
2001
                return;
2002
            } else {
2003
                $link = $this->_converter->getLink($word[1]);
2004
                if (is_object($link)) {
2005
                    $word[1] = $this->_converter->returnSee($link, $word[1]);
2006
                }
2007
                $this->_addoutput($word, true);
2008
                return;
2009
            }
2010
        }
2011
        $this->_addoutput($word);
2012
    }
2013
 
2014
    /**
2015
     * Works like {@link _link()} except it only links to global variables
2016
     */
2017
    function _globallink($word)
2018
    {
2019
        if (!is_array($word)) {
2020
            return $this->_addoutput($word);
2021
        }
2022
        if ($word[0] != T_VARIABLE) {
2023
            return $this->_addoutput($word);
2024
        }
2025
        if (is_array($word) && $word[0] == T_VARIABLE) {
2026
            $link = $this->_converter->getLink('global ' . $word[1]);
2027
            if (is_object($link)) {
2028
                $this->_addoutput($this->_converter->returnSee($link,
2029
                    $word[1]), true);
2030
                return;
2031
            }
2032
        }
2033
        $this->_addoutput($word);
2034
    }
2035
 
2036
    /**
2037
     * Works like {@link _link()} except it only links to classes
2038
     */
2039
    function _classlink($word)
2040
    {
2041
        //debug("checking class " . $word[1]);
2042
        if (is_array($word) && $word[0] == T_STRING) {
2043
            $link = $this->_converter->getLink($word[1]);
2044
            if (is_object($link)) {
2045
                $this->_addoutput($this->_converter->returnSee($link,
2046
                    $word[1]), true);
2047
                return;
2048
            }
2049
        }
2050
        $this->_addoutput($word);
2051
    }
2052
 
2053
    /**
2054
     * Works like {@link _link()} except it only links to methods
2055
     */
2056
    function _methodlink($word)
2057
    {
2058
        if (is_array($word) && $word[0] == T_STRING) {
2059
            //debug("checking method " . $this->_pv_class . '::' . $word[1] . '()');
2060
            if (isset($this->_pv_prev_var_type)) {
2061
                $link = $this->_converter->getLink($this->_pv_prev_var_type . '::' .
2062
                    $word[1] . '()');
2063
            } else {
2064
                $link = $this->_converter->getLink($this->_pv_class . '::' .
2065
                    $word[1] . '()');
2066
            }
2067
            if (is_object($link)) {
2068
                $this->_addoutput($this->_converter->returnSee($link,
2069
                    $word[1]), true);
2070
                return;
2071
            }
2072
            if (isset($this->_pv_prev_var_type)) {
2073
                $this->_addoutput($word);
2074
                return;
2075
            }
2076
            //debug("checking method " . $word[1] . '()');
2077
            $link = $this->_converter->getLink($word[1] . '()');
2078
            if (is_object($link)) {
2079
                $this->_addoutput($this->_converter->returnSee($link,
2080
                    $word[1]), true);
2081
                return;
2082
            }
2083
        }
2084
        $this->_addoutput($word);
2085
    }
2086
 
2087
    /**
2088
     * Works like {@link _link()} except it only links to class variables
2089
     *
2090
     * @param bool $justastring true if the $word is only a string
2091
     */
2092
    function _varlink($word, $justastring=false)
2093
    {
2094
        if ($justastring) {
2095
            $word[0] = T_VARIABLE;
2096
        }
2097
        if (is_array($word) && $word[0] == T_VARIABLE) {
2098
            $x = ($justastring ? '$' : '');
2099
            //debug("checking var " . $this->_pv_class . '::' . $x . $word[1]);
2100
            if (isset($this->_pv_prev_var_type)) {
2101
                //debug("checking var " . $this->_pv_prev_var_type . '::' .
2102
                //    $x . $word[1]);
2103
                $link = $this->_converter->getLink($this->_pv_prev_var_type . '::' .
2104
                    $x . $word[1]);
2105
            } else {
2106
                $link = $this->_converter->getLink($this->_pv_class . '::' .
2107
                    $x . $word[1]);
2108
            }
2109
            if (is_object($link)) {
2110
                $this->_addoutput($this->_converter->returnSee($link,
2111
                    $word[1]), true);
2112
                return;
2113
            }
2114
            //debug("checking var " . $x . $word[1]);
2115
            if (isset($this->_pv_prev_var_type)) {
2116
                $this->_addoutput($word);
2117
                return;
2118
            }
2119
            $link = $this->_converter->getLink($x . $word[1]);
2120
            if (is_object($link)) {
2121
                $this->_addoutput($this->_converter->returnSee($link,
2122
                    $word[1]), true);
2123
                return;
2124
            }
2125
        }
2126
        $this->_addoutput($word);
2127
    }
2128
    /**#@-*/
2129
 
2130
    /**#@+
2131
     * Output Methods
2132
     * @access private
2133
     */
2134
    /**
2135
     * This method adds output to {@link $_line}
2136
     *
2137
     * If a string with variables like "$test this" is present, then special
2138
     * handling is used to allow processing of the variable in context.
2139
     *
2140
     * @param mixed $word         the string|array tag token and value
2141
     * @param bool  $preformatted whether or not the $word is already formatted
2142
     *
2143
     * @return void
2144
     * @see _flush_save()
2145
     */
2146
    function _addoutput($word, $preformatted = false)
2147
    {
2148
        if ($this->_pf_no_output_yet) {
2149
            return;
2150
        }
2151
        if ($this->_pf_quote_active) {
2152
            if (is_array($word)) {
2153
                $this->_save .= $this->_converter->highlightSource($word[0],
2154
                    $word[1]);
2155
            } else {
2156
                $this->_save .= $this->_converter->highlightSource(false,
2157
                    $word, true);
2158
            }
2159
        } else {
2160
            $this->_flush_save();
2161
            if (is_string($word) && trim($word) == '') {
2162
                $this->_line .= $this->_converter->postProcess($word);
2163
                return;
2164
            }
2165
            if (is_array($word) && trim($word[1]) == '') {
2166
                $this->_line .= $this->_converter->postProcess($word[1]);
2167
                return;
2168
            }
2169
            if (is_array($word)) {
2170
                $this->_line .= $this->_converter->highlightSource($word[0],
2171
                    $word[1], $preformatted);
2172
            } else {
2173
                $this->_line .= $this->_converter->highlightSource(false,
2174
                    $word, $preformatted);
2175
            }
2176
        }
2177
    }
2178
 
2179
    /**
2180
     * Like {@link _output()}, but for DocBlock highlighting
2181
     *
2182
     * @param mixed $dbtype       the docblock type
2183
     * @param mixed $word         the string|array tag token and value
2184
     * @param bool  $preformatted whether or not the $word is already formatted
2185
     *
2186
     * @return void
2187
     */
2188
    function _addDocBlockoutput($dbtype, $word, $preformatted = false)
2189
    {
2190
        if ($this->_pf_internal) {
2191
            $this->_line .= $this->_converter->highlightDocBlockSource('internal',
2192
                $word, $preformatted);
2193
        } else {
2194
            $this->_line .= $this->_converter->highlightDocBlockSource($dbtype,
2195
                $word, $preformatted);
2196
        }
2197
    }
2198
 
2199
    /**
2200
     * Flush a saved string variable highlighting
2201
     *
2202
     * {@source}
2203
     *
2204
     * @return void
2205
     * @todo CS cleanup - rename to _flushSave() for camelCase rule
2206
     */
2207
    function _flush_save()
2208
    {
2209
        if (!empty($this->_save)) {
2210
            $this->_save .= $this->_converter->flushHighlightCache();
2211
            // clear the existing cache, reset it to the old value
2212
            if (isset($this->_save_highlight_state)) {
2213
                $this->_converter->
2214
                    _setHighlightCache($this->_save_highlight_state[0],
2215
                         $this->_save_highlight_state[1]);
2216
            }
2217
            $this->_line .= $this->_converter->
2218
                highlightSource(T_CONSTANT_ENCAPSED_STRING, $this->_save, true);
2219
            $this->_save  = '';
2220
        }
2221
    }
2222
    /**#@-*/
2223
 
2224
    /**
2225
     * Give the word parser necessary data to begin a new parse
2226
     *
2227
     * @param array &$data all tokens separated by line number
2228
     *
2229
     * @return void
2230
     */
2231
    function configWordParser(&$data)
2232
    {
2233
        $this->_wp->setup($data, $this);
2234
        $this->_wp->setWhitespace(true);
2235
    }
2236
 
2237
    /**
2238
     * Initialize all parser state variables
2239
     *
2240
     * @param bool         $inlinesourceparse true if we are highlighting an inline
2241
     *                                        {@}source} tag's output
2242
     * @param false|string $class             name of class we are going
2243
     *                                        to start from
2244
     *
2245
     * @return void
2246
     * @uses $_wp sets to a new {@link phpDocumentor_HighlightWordParser}
2247
     */
2248
    function setupStates($inlinesourceparse, $class)
2249
    {
2250
        $this->_output = '';
2251
        $this->_line   = '';
2252
        unset($this->_wp);
2253
        $this->_wp          = new phpDocumentor_HighlightWordParser;
2254
        $this->_event_stack = new EventStack;
2255
        if ($inlinesourceparse) {
2256
            $this->_event_stack->pushEvent(PARSER_EVENT_PHPCODE);
2257
            if ($class) {
2258
                $this->_event_stack->pushEvent(PARSER_EVENT_CLASS);
2259
                $this->_pv_class = $class;
2260
            }
2261
        } else {
2262
            $this->_pv_class = null;
2263
        }
2264
 
2265
        $this->_pv_define              = null;
2266
        $this->_pv_define_name         = null;
2267
        $this->_pv_define_value        = null;
2268
        $this->_pv_define_params_data  = null;
2269
        $this->_pv_dtype               = null;
2270
        $this->_pv_docblock            = null;
2271
        $this->_pv_dtemplate           = null;
2272
        $this->_pv_func                = null;
2273
        $this->_pv_global_name         = null;
2274
        $this->_pv_global_val          = null;
2275
        $this->_pv_globals             = null;
2276
        $this->_pv_global_count        = null;
2277
        $this->_pv_include_params_data = null;
2278
        $this->_pv_include_name        = null;
2279
        $this->_pv_include_value       = null;
2280
        $this->_pv_linenum             = null;
2281
        $this->_pv_periodline          = null;
2282
        $this->_pv_paren_count         = 0;
2283
        $this->_pv_statics             = null;
2284
        $this->_pv_static_count        = null;
2285
        $this->_pv_static_val          = null;
2286
        $this->_pv_quote_data          = null;
2287
        $this->_pv_function_data       = null;
2288
        $this->_pv_var                 = null;
2289
        $this->_pv_varname             = null;
2290
        $this->_pf_definename_isset    = false;
2291
        $this->_pf_extends_found       = false;
2292
        $this->_pf_includename_isset   = false;
2293
        $this->_pf_get_source          = false;
2294
        $this->_pf_getting_source      = false;
2295
        $this->_pf_in_class            = false;
2296
        $this->_pf_in_define           = false;
2297
        $this->_pf_in_global           = false;
2298
        $this->_pf_in_include          = false;
2299
        $this->_pf_in_var              = false;
2300
        $this->_pf_funcparam_val       = false;
2301
        $this->_pf_quote_active        = false;
2302
        $this->_pf_reset_quote_data    = true;
2303
        $this->_pf_useperiod           = false;
2304
        $this->_pf_var_equals          = false;
2305
        $this->_pf_obj_op              = false;
2306
        $this->_pf_docblock            = false;
2307
        $this->_pf_docblock_template   = false;
2308
        $this->_pf_colon_colon         = false;
2309
        $this->_pv_last_string         = false;
2310
        $this->_pf_inmethod            = false;
2311
        $this->_pf_no_output_yet       = false;
2312
        $this->_pv_saveline            = 0;
2313
        $this->_pv_next_word           = false;
2314
        $this->_save                   = '';
2315
    }
2316
 
2317
    /**
2318
     * Initialize the {@link $tokenpushEvent, $wordpushEvent} arrays
2319
     *
2320
     * @return void
2321
     */
2322
    function phpDocumentor_HighlightParser()
2323
    {
2324
        if (!defined('T_INTERFACE')) {
2325
            define('T_INTERFACE', -1);
2326
        }
2327
        $this->allowableTags
2328
            = $GLOBALS['_phpDocumentor_tags_allowed'];
2329
        $this->allowableInlineTags
2330
            = $GLOBALS['_phpDocumentor_inline_doc_tags_allowed'];
2331
        $this->inlineTagHandlers
2332
            = array('*' => 'handleDefaultInlineTag');
2333
        /**************************************************************/
2334
 
2335
        $this->tokenpushEvent[PARSER_EVENT_NOEVENTS] =
2336
            array(
2337
                T_OPEN_TAG => PARSER_EVENT_PHPCODE,
2338
            );
2339
 
2340
        /**************************************************************/
2341
 
2342
        $this->tokenpushEvent[PARSER_EVENT_PHPCODE] =
2343
            array(
2344
                T_FUNCTION      => PARSER_EVENT_FUNCTION,
2345
                T_CLASS         => PARSER_EVENT_CLASS,
2346
                T_INTERFACE     => PARSER_EVENT_CLASS,
2347
                T_INCLUDE_ONCE  => PARSER_EVENT_INCLUDE,
2348
                T_INCLUDE       => PARSER_EVENT_INCLUDE,
2349
                T_START_HEREDOC => PARSER_EVENT_EOFQUOTE,
2350
                T_REQUIRE       => PARSER_EVENT_INCLUDE,
2351
                T_REQUIRE_ONCE  => PARSER_EVENT_INCLUDE,
2352
                T_COMMENT       => PARSER_EVENT_COMMENT,
2353
                T_DOC_COMMENT   => PARSER_EVENT_DOCBLOCK,
2354
            );
2355
        $this->wordpushEvent[PARSER_EVENT_PHPCODE]  =
2356
            array(
2357
                "define" => PARSER_EVENT_DEFINE,
2358
                '"'      => PARSER_EVENT_QUOTE,
2359
                '\''     => PARSER_EVENT_QUOTE,
2360
            );
2361
        /**************************************************************/
2362
 
2363
        $this->wordpushEvent[PARSER_EVENT_FUNCTION]  =
2364
            array(
2365
                '{' => PARSER_EVENT_LOGICBLOCK,
2366
                '(' => PARSER_EVENT_FUNCTION_PARAMS,
2367
            );
2368
        $this->tokenpushEvent[PARSER_EVENT_FUNCTION] =
2369
            array(
2370
                T_COMMENT     => PARSER_EVENT_COMMENT,
2371
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2372
            );
2373
        $this->wordpopEvent[PARSER_EVENT_FUNCTION]   = array("}");
2374
        /**************************************************************/
2375
 
2376
        $this->tokenpopEvent[PARSER_EVENT_EOFQUOTE] = array(T_END_HEREDOC);
2377
        /**************************************************************/
2378
 
2379
        $this->tokenpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
2380
            array(
2381
                T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
2382
                T_ARRAY                    => PARSER_EVENT_ARRAY,
2383
                T_COMMENT                  => PARSER_EVENT_COMMENT,
2384
                T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
2385
            );
2386
        $this->wordpushEvent[PARSER_EVENT_FUNCTION_PARAMS]  =
2387
            array(
2388
                '"' => PARSER_EVENT_QUOTE,
2389
                "'" => PARSER_EVENT_QUOTE,
2390
            );
2391
        $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS]   = array(")");
2392
        /**************************************************************/
2393
 
2394
        $this->wordpushEvent[PARSER_EVENT_LOGICBLOCK]  =
2395
            array(
2396
                "{" => PARSER_EVENT_LOGICBLOCK,
2397
                '"' => PARSER_EVENT_QUOTE,
2398
            );
2399
        $this->tokenpushEvent[PARSER_EVENT_LOGICBLOCK] =
2400
            array(
2401
                T_GLOBAL                   => PARSER_EVENT_FUNC_GLOBAL,
2402
                T_STATIC                   => PARSER_EVENT_STATIC_VAR,
2403
                T_START_HEREDOC            => PARSER_EVENT_EOFQUOTE,
2404
                T_CURLY_OPEN               => PARSER_EVENT_LOGICBLOCK,
2405
                T_DOLLAR_OPEN_CURLY_BRACES => PARSER_EVENT_LOGICBLOCK,
2406
            );
2407
        $this->wordpopEvent[PARSER_EVENT_LOGICBLOCK]   = array("}");
2408
        $this->tokenpopEvent[PARSER_EVENT_LOGICBLOCK]  = array(T_CURLY_OPEN);
2409
 
2410
        /**************************************************************/
2411
 
2412
        $this->tokenpushEvent[PARSER_EVENT_ARRAY] =
2413
            array(
2414
                T_COMMENT     => PARSER_EVENT_COMMENT,
2415
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2416
            );
2417
        $this->wordpopEvent[PARSER_EVENT_ARRAY]   = array(")");
2418
        /**************************************************************/
2419
 
2420
        $this->tokenpushEvent[PARSER_EVENT_FUNC_GLOBAL] =
2421
            array(
2422
                T_COMMENT     => PARSER_EVENT_COMMENT,
2423
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2424
            );
2425
        $this->wordpopEvent[PARSER_EVENT_FUNC_GLOBAL]   = array(";");
2426
        /**************************************************************/
2427
 
2428
        $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR] =
2429
            array(
2430
                T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
2431
                T_COMMENT                  => PARSER_EVENT_COMMENT,
2432
                T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
2433
            );
2434
        $this->wordpushEvent[PARSER_EVENT_STATIC_VAR]  =
2435
            array(
2436
                "=" => PARSER_EVENT_STATIC_VAR_VALUE,
2437
            );
2438
        $this->wordpopEvent[PARSER_EVENT_STATIC_VAR]   = array(";");
2439
        /**************************************************************/
2440
 
2441
        $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR_VALUE] =
2442
            array(
2443
                T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
2444
                T_COMMENT                  => PARSER_EVENT_COMMENT,
2445
                T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
2446
                T_ARRAY                    => PARSER_EVENT_ARRAY,
2447
            );
2448
        $this->wordpushEvent[PARSER_EVENT_STATIC_VAR_VALUE]  =
2449
            array(
2450
                '"' => PARSER_EVENT_QUOTE,
2451
                "'" => PARSER_EVENT_QUOTE,
2452
            );
2453
        $this->wordpopEvent[PARSER_EVENT_STATIC_VAR_VALUE]   = array(";", ",");
2454
        /**************************************************************/
2455
        $this->tokenpushEvent[PARSER_EVENT_QUOTE] =
2456
            array(
2457
                T_OBJECT_OPERATOR => PARSER_EVENT_CLASS_MEMBER,
2458
                T_CURLY_OPEN      => PARSER_EVENT_QUOTE_VAR,
2459
            );
2460
        $this->wordpopEvent[PARSER_EVENT_QUOTE]   = array('"');
2461
        /**************************************************************/
2462
        $this->tokenpushEvent[PARSER_EVENT_QUOTE_VAR] =
2463
            array(
2464
                T_OBJECT_OPERATOR => PARSER_EVENT_CLASS_MEMBER,
2465
                T_CURLY_OPEN      => PARSER_EVENT_QUOTE_VAR,
2466
            );
2467
        $this->wordpushEvent[PARSER_EVENT_QUOTE_VAR]  =
2468
            array(
2469
                "{" => PARSER_EVENT_QUOTE_VAR,
2470
                '"' => PARSER_EVENT_QUOTE_VAR,
2471
                "'" => PARSER_EVENT_QUOTE_VAR,
2472
            );
2473
        $this->wordpopEvent[PARSER_EVENT_QUOTE_VAR]   = array('}');
2474
        /**************************************************************/
2475
 
2476
        $this->tokenpushEvent[PARSER_EVENT_DEFINE] =
2477
            array(
2478
                T_COMMENT                  => PARSER_EVENT_COMMENT,
2479
                T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
2480
                T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
2481
            );
2482
        $this->wordpushEvent[PARSER_EVENT_DEFINE]  =
2483
            array(
2484
                "(" => PARSER_EVENT_DEFINE_PARAMS,
2485
            );
2486
        $this->wordpopEvent[PARSER_EVENT_DEFINE]   = array(";");
2487
        /**************************************************************/
2488
 
2489
        $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS] =
2490
            array(
2491
                T_COMMENT     => PARSER_EVENT_COMMENT,
2492
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2493
            );
2494
        $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS]  =
2495
            array(
2496
                "(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
2497
                '"' => PARSER_EVENT_QUOTE,
2498
                "'" => PARSER_EVENT_QUOTE,
2499
            );
2500
        $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS]   = array(")");
2501
        /**************************************************************/
2502
 
2503
        $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] =
2504
            array(
2505
                T_COMMENT     => PARSER_EVENT_COMMENT,
2506
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2507
            );
2508
        $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS]  =
2509
            array(
2510
                "(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
2511
                '"' => PARSER_EVENT_QUOTE,
2512
                "'" => PARSER_EVENT_QUOTE,
2513
            );
2514
        $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS]   = array(")");
2515
        /**************************************************************/
2516
 
2517
        $this->tokenpushEvent[PARSER_EVENT_VAR] =
2518
            array(
2519
                T_COMMENT     => PARSER_EVENT_COMMENT,
2520
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2521
                T_ARRAY       => PARSER_EVENT_ARRAY,
2522
            );
2523
        $this->wordpopEvent[PARSER_EVENT_VAR]   = array(";");
2524
        /**************************************************************/
2525
 
2526
        $this->tokenpushEvent[PARSER_EVENT_CLASS] =
2527
            array(
2528
                T_FUNCTION    => PARSER_EVENT_METHOD,
2529
                T_VAR         => PARSER_EVENT_VAR,
2530
                T_COMMENT     => PARSER_EVENT_DOCBLOCK,
2531
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2532
                T_CLOSE_TAG   => PARSER_EVENT_OUTPHP,
2533
            );
2534
        $this->wordpopEvent[PARSER_EVENT_CLASS]   = array("}");
2535
        /**************************************************************/
2536
 
2537
        $this->wordpushEvent[PARSER_EVENT_METHOD]  =
2538
            array(
2539
                '{' => PARSER_EVENT_METHOD_LOGICBLOCK,
2540
                '(' => PARSER_EVENT_FUNCTION_PARAMS,
2541
            );
2542
        $this->tokenpushEvent[PARSER_EVENT_METHOD] =
2543
            array(
2544
                T_COMMENT     => PARSER_EVENT_COMMENT,
2545
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2546
            );
2547
        $this->wordpopEvent[PARSER_EVENT_METHOD]   = array("}", ";");
2548
        /**************************************************************/
2549
 
2550
        $this->wordpushEvent[PARSER_EVENT_METHOD_LOGICBLOCK]  =
2551
            array(
2552
                "{" => PARSER_EVENT_METHOD_LOGICBLOCK,
2553
                '"' => PARSER_EVENT_QUOTE,
2554
            );
2555
        $this->tokenpushEvent[PARSER_EVENT_METHOD_LOGICBLOCK] =
2556
            array(
2557
                T_OBJECT_OPERATOR          => PARSER_EVENT_CLASS_MEMBER,
2558
                T_GLOBAL                   => PARSER_EVENT_FUNC_GLOBAL,
2559
                T_STATIC                   => PARSER_EVENT_STATIC_VAR,
2560
                T_CURLY_OPEN               => PARSER_EVENT_LOGICBLOCK,
2561
                T_DOLLAR_OPEN_CURLY_BRACES => PARSER_EVENT_LOGICBLOCK,
2562
            );
2563
        $this->wordpopEvent[PARSER_EVENT_METHOD_LOGICBLOCK]   = array("}");
2564
        $this->tokenpopEvent[PARSER_EVENT_METHOD_LOGICBLOCK]  = array(T_CURLY_OPEN);
2565
        /**************************************************************/
2566
 
2567
        $this->tokenpushEvent[PARSER_EVENT_INCLUDE] =
2568
            array(
2569
                T_COMMENT     => PARSER_EVENT_COMMENT,
2570
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2571
            );
2572
        $this->wordpushEvent[PARSER_EVENT_INCLUDE]  =
2573
            array(
2574
                "(" => PARSER_EVENT_INCLUDE_PARAMS,
2575
            );
2576
        $this->wordpopEvent[PARSER_EVENT_INCLUDE]   = array(";");
2577
        /**************************************************************/
2578
 
2579
        $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS] =
2580
            array(
2581
                T_COMMENT     => PARSER_EVENT_COMMENT,
2582
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2583
            );
2584
        $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS]  =
2585
            array(
2586
                "(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
2587
            );
2588
        $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS]   = array(")");
2589
        /**************************************************************/
2590
 
2591
        $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] =
2592
            array(
2593
                T_COMMENT     => PARSER_EVENT_COMMENT,
2594
                T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
2595
            );
2596
        $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS]  =
2597
            array(
2598
                "(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
2599
            );
2600
        $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS]   = array(")");
2601
    }
2602
}
2603
?>