1<?php
2/**
3 * All abstract representations of inline tags are in this file
4 *
5 * phpDocumentor :: automatic documentation generator
6 *
7 * PHP versions 4 and 5
8 *
9 * Copyright (c) 2002-2008 Gregory Beaver
10 *
11 * LICENSE:
12 *
13 * This library is free software; you can redistribute it
14 * and/or modify it under the terms of the GNU Lesser General
15 * Public License as published by the Free Software Foundation;
16 * either version 2.1 of the License, or (at your option) any
17 * later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 * @category   ToolsAndUtilities
29 * @package    phpDocumentor
30 * @subpackage InlineTags
31 * @author     Gregory Beaver <cellog@php.net>
32 * @copyright  2002-2008 Gregory Beaver
33 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
34 * @version    CVS: $Id: InlineTags.inc 286921 2009-08-08 05:01:24Z ashnazg $
35 * @filesource
36 * @link       http://www.phpdoc.org
37 * @link       http://pear.php.net/PhpDocumentor
38 * @since      separate file since 1.2
39 * @todo       CS cleanup - change package to PhpDocumentor
40 */
41
42/**
43 * Use this element to represent an {@}inline tag} like {@}link}
44 *
45 * @category   ToolsAndUtilities
46 * @package    phpDocumentor
47 * @subpackage InlineTags
48 * @author     Gregory Beaver <cellog@php.net>
49 * @copyright  2002-2008 Gregory Beaver
50 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
51 * @version    Release: 1.4.4
52 * @filesource
53 * @link       http://www.phpdoc.org
54 * @link       http://pear.php.net/PhpDocumentor
55 * @see        parserStringWithInlineTags
56 * @since      1.0rc1
57 * @tutorial   inlinetags.pkg
58 * @todo       CS cleanup - change package to PhpDocumentor
59 * @todo       CS cleanup - change classname to PhpDocumentor_*
60 */
61class parserInlineTag extends parserBase
62{
63    /**
64     * Element type
65     *
66     * Type is used by many functions to skip the hassle of
67     *
68     * <code>
69     * if phpDocumentor_get_class($blah) == 'parserBlah'
70     * </code>
71     * always "inlinetag"
72     * @var string
73     */
74    var $type = 'inlinetag';
75    /**
76     * the name of the inline tag (like link)
77     * @var string
78     */
79    var $inlinetype = '';
80
81    /**
82     * sets up the tag
83     *
84     * @param string $type  tag type (example: link)
85     * @param string $value tag value (example: what to link to)
86     */
87    function parserInlineTag($type, $value)
88    {
89        $this->inlinetype = $type;
90        $this->value      = trim($value);
91    }
92
93    /**
94     * get length of the tag
95     *
96     * @return integer length of the tag
97     * @todo CS cleanup - rename to strLen for camelCase rule
98     */
99    function Strlen()
100    {
101        // fix 1203451
102        if (is_array($this->value)) {
103            return array_reduce(create_function('$a, $b', 'return $a + strlen($b);'))
104                + count($this->value);
105        }
106        return strlen($this->value);
107    }
108
109    /**
110     * always gets an empty string
111     *
112     * @return string always '', used by {@link Parser::handleDocBlock()} to
113     *                calculate the short description of a DocBlock
114     * @see parserStringWithInlineTags::getString()
115     * @see parserStringWithInlineTags::trimmedStrlen()
116     */
117    function getString()
118    {
119        return '';
120    }
121}
122
123/**
124 * represents inline links
125 *
126 * @category   ToolsAndUtilities
127 * @package    phpDocumentor
128 * @subpackage InlineTags
129 * @author     Gregory Beaver <cellog@php.net>
130 * @copyright  2002-2008 Gregory Beaver
131 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
132 * @version    Release: 1.4.4
133 * @filesource
134 * @link       http://www.phpdoc.org
135 * @link       http://pear.php.net/PhpDocumentor
136 * @see        parserStringWithInlineTags
137 * @since      1.0rc1
138 * @tutorial   tags.inlinelink.pkg
139 * @todo       CS cleanup - change package to PhpDocumentor
140 * @todo       CS cleanup - change classname to PhpDocumentor_*
141 */
142class parserLinkInlineTag extends parserInlineTag
143{
144    /**
145     * text to display in the link, can be different from the link for standard
146     * links like websites
147     * @var string
148     */
149    var $linktext = '';
150
151    /**
152     * sets up the tag
153     *
154     * @param string $link stored in $value, see {@link parserBase::$value}
155     * @param string $text see {@link $linktext}
156     */
157    function parserLinkInlineTag($link, $text)
158    {
159        if (strpos($link, ',')) {
160            $link = explode(',', $link);
161            parserInlineTag::parserInlineTag('link', '');
162            $this->value = $link;
163        } else {
164            parserInlineTag::parserInlineTag('link', $link);
165        }
166        $this->linktext = trim($text);
167    }
168
169    /**
170     * calls the output conversion
171     *
172     * @param Converter &$c converter used to change the abstract link
173     *                      into text for display
174     *
175     * @return false|string returns the converted link or false
176     *                      if not converted successfully
177     * @todo CS cleanup - rename to convert for camelCase rule
178     */
179    function Convert(&$c)
180    {
181        if (is_array($this->value)) {
182            $ret = '';
183            foreach ($this->value as $text) {
184                if (!empty($ret)) {
185                    $ret .= ', ';
186                }
187                $ret .= $this->ConvertPart($c, trim($text));
188            }
189            return $ret;
190        } else {
191            return $this->ConvertPart($c, $this->value);
192        }
193    }
194
195    /**
196     * convert part of the tag
197     *
198     * @param Converter &$c    the output converter
199     * @param string    $value the tag value
200     *
201     * @return string
202     * @todo CS cleanup - rename to convertPart for camelCase rule
203     */
204    function ConvertPart(&$c, $value)
205    {
206        if (strpos($value, '://') || (strpos($value, 'mailto:') === 0)) {
207            if (strpos($value, ' ')) {
208                $value = explode(' ', $value);
209                $link  = array_shift($value);
210                $text  = join(' ', $value);
211            } else {
212                $link = $value;
213                $text = $this->linktext;
214            }
215            return $c->returnLink($link, htmlspecialchars($text));
216        } else {
217            $savevalue = $value;
218            $descrip   = false;
219            if (strpos(trim($value), ' ')) {
220                $v = preg_split('/\s/', trim($value));
221                if (in_array(strtolower($v[0]), array('object', 'function'))) {
222                    if (!isset($v[1])
223                        || (isset($v[1]) && strlen($v[1])
224                            && !in_array($v[1]{0}, array('$','&'))
225                            && $v[1] != '###commanana####'
226                        )
227                    ) {
228                        $vsave = $v[0];
229                        array_shift($v);
230                        $v[0] = $vsave . ' ' . $v[0];
231                    }
232                }
233                $value = $c->getLink($v[0]);
234                array_shift($v);
235                $descrip = join($v, ' ');
236                $descrip = str_replace('###commanana####', ',', $descrip);
237            } else {
238                $value = $c->getLink($value);
239            }
240            if (is_string($value)) {
241                // feature 564991
242                if (strpos($value, '://')) {
243                    // php function
244                    return $c->returnLink($value, $descrip ? $descrip :
245                        str_replace('PHP_MANUAL#', '', $value));
246                }
247                return $value;
248            }
249            if (!$descrip) {
250                $descrip = $c->type_adjust($savevalue);
251            }
252            if (is_object($value)) {
253                return $c->returnSee($value, $descrip);
254            }
255            return $savevalue;
256        }
257    }
258}
259
260/**
261 * Represents inline links to external tutorial documentation
262 *
263 * @category   ToolsAndUtilities
264 * @package    phpDocumentor
265 * @subpackage InlineTags
266 * @author     Gregory Beaver <cellog@php.net>
267 * @copyright  2002-2008 Gregory Beaver
268 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
269 * @version    Release: 1.4.4
270 * @filesource
271 * @link       http://www.phpdoc.org
272 * @link       http://pear.php.net/PhpDocumentor
273 * @see        parserStringWithInlineTags
274 * @tutorial   tags.inlinetutorial.pkg
275 * @todo       CS cleanup - change package to PhpDocumentor
276 * @todo       CS cleanup - change classname to PhpDocumentor_*
277 */
278class parserTutorialInlineTag extends parserLinkInlineTag
279{
280    /**
281     * constructor
282     *
283     * @param string $link stored in $value, see {@link parserBase::$value}
284     * @param string $text see {@link $linktext}
285     */
286    function parserTutorialInlineTag($link,$text)
287    {
288        parserInlineTag::parserInlineTag('tutorial', $link);
289        $this->linktext = trim($text);
290    }
291
292    /**
293     * convert part of the tag
294     *
295     * @param Converter &$c converter used to change the abstract link
296     *                      into text for display
297     *
298     * @return mixed returns the converted link
299     *               or false if not converted successfully
300     * @todo CS cleanup - rename to convert for camelCase rule
301     */
302    function Convert(&$c)
303    {
304        $descrip = false;
305        if (strpos($this->value, ',') === false) {
306            if (strpos(trim($this->value), ' ')) {
307                $v     = explode(' ', trim($this->value));
308                $value = $c->getTutorialLink($v[0]);
309                array_shift($v);
310                $descrip = join($v, ' ');
311            } else {
312                $value = $c->getTutorialLink($this->value);
313            }
314        } else {
315            $vals    = explode(',', $this->value);
316            $descrip = array();
317            foreach ($vals as $val) {
318                $val = trim($val);
319                if (strpos($val, ' ')) {
320                    $v       = explode(' ', $val);
321                    $value[] = $c->getTutorialLink($v[0]);
322                    array_shift($v);
323                    $descrip[] = join($v, ' ');
324                } else {
325                    $value[]   = $c->getTutorialLink($val);
326                    $descrip[] = false;
327                }
328            }
329        }
330        if (is_string($value)) {
331            return $value;
332        }
333        if (is_object($value)) {
334            return $c->returnSee($value, $descrip);
335        }
336        /*
337         * getLink parsed a comma-delimited list of linked thingies,
338         * add the commas back in
339         */
340        if (is_array($value)) {
341            $a = '';
342            foreach ($value as $i => $bub) {
343                if (!empty($a)) {
344                    $a .= ', ';
345                }
346                if (is_string($value[$i])) {
347                    $a .= $value[$i];
348                }
349                if (is_object($value[$i])) {
350                    $a .= $c->returnSee($value[$i], $descrip[$i]);
351                }
352            }
353            return $a;
354        }
355        return false;
356    }
357}
358
359/**
360 * represents inline source tag, used for function/method source
361 *
362 * @category   ToolsAndUtilities
363 * @package    phpDocumentor
364 * @subpackage InlineTags
365 * @author     Gregory Beaver <cellog@php.net>
366 * @copyright  2002-2008 Gregory Beaver
367 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
368 * @version    Release: 1.4.4
369 * @filesource
370 * @link       http://www.phpdoc.org
371 * @link       http://pear.php.net/PhpDocumentor
372 * @see        parserStringWithInlineTags
373 * @tutorial   tags.inlinesource.pkg
374 * @todo       CS cleanup - change package to PhpDocumentor
375 * @todo       CS cleanup - change classname to PhpDocumentor_*
376 */
377class parserSourceInlineTag extends parserInlineTag
378{
379    /**
380     * always 'source'
381     * @var string
382     */
383    var $inlinetype = 'source';
384    /**
385     * First line of source code to display
386     * @var integer
387     * @see $end
388     */
389    var $start = 1;
390    /**
391     * Last line to display
392     * @var '*'|integer If '*' then the whole source will be used, otherwise
393     *                  the {@link $start} to $end line numbers will be displayed
394     */
395    var $end = '*';
396    /**
397     * tokenized source organized by line numbers for php 4.3.0+, the old
398     * {@}source} tag used a string
399     * @var string|array
400     */
401    var $source = false;
402    /**#@+ @access private */
403    /** @var string|false */
404    var $_class;
405    /**#@-*/
406
407    /**
408     * constructor
409     *
410     * @param string $value format "start [end]",
411     *                      where start and end are line numbers
412     *                      with the end line number optional
413     */
414    function parserSourceInlineTag($value)
415    {
416        parserInlineTag::parserInlineTag('source', '');
417        preg_match('/^([0-9]+)\W([0-9]*)$/', trim($value), $match);
418        if (!count($match)) {
419            preg_match('/^([0-9]+)$/', trim($value), $match);
420            if (count($match)) {
421                $this->start = (int) $match[1];
422            }
423        } else {
424            $this->start = (int) $match[1];
425            $this->end   = (int) $match[2];
426        }
427    }
428
429    /**
430     * only used to determine blank lines.  {@}source} will not be blank, probably
431     *
432     * @return int
433     */
434    function Strlen()
435    {
436        return 1;
437    }
438
439    /**
440     * gets the source string
441     *
442     * @return string
443     */
444    function getString()
445    {
446        return '{@source}';
447    }
448
449    /**
450     * sets the source tag's value
451     *
452     * @param string|array $source source code
453     * @param string|bool  $class  class name if this is a method,
454     *                             boolean in php 4.3.0,
455     *                             if this is a method this will be true
456     *
457     * @return void
458     */
459    function setSource($source, $class = false)
460    {
461        if (is_array($source)) {
462            $this->_class = $class;
463            $this->source = $source;
464        } else {
465            $source       = strstr($source, 'function');
466            $pos          = strrpos($source, '}');
467            $this->source = substr($source, 0, $pos + 1);
468        }
469    }
470
471    /**
472     * convert the tag
473     *
474     * @param Converter &$c the output converter object
475     *
476     * @return string
477     * @uses stringConvert() in PHP 4.2.3-, this method is used to convert
478     * @uses arrayConvert() in PHP 4.3.0+, this method is used to convert
479     * @todo CS cleanup - rename to convert for camelCase rule
480     */
481    function Convert(&$c)
482    {
483        if (is_string($this->source)) {
484            return $this->stringConvert($c);
485        }
486        return $this->arrayConvert($c);
487    }
488
489    /**
490     * converter helper used in PHP 4.3.0+
491     *
492     * @param Converter &$c the output converter object
493     *
494     * @return string
495     * @uses phpDocumentor_HighlightParser Parses the tokenized source
496     */
497    function arrayConvert(&$c)
498    {
499        $source = $this->source;
500        if ($this->end != '*') {
501            $source = array_slice($this->source, 0, $this->end + $this->start - 1);
502        }
503        $start = $this->start - 1;
504        if ($start < 0) {
505            $start = 0;
506        }
507        return $c->ProgramExample($source, true, true, $this->_class, $start);
508    }
509
510    /**
511     * converter helper used in PHP 4.2.3-
512     *
513     * @param Converter &$c the output converter object
514     *
515     * @return string
516     * @uses Converter::unmangle() remove the extraneous stuff from
517     *                             {@link highlight_string()}
518     * @deprecated in favor of PHP 4.3.0+ {@link arrayConvert()}
519     */
520    function stringConvert(&$c)
521    {
522        $source = highlight_string('<?php ' . $this->source . ' ?>', true);
523        $source = '<code>' . substr($source, strlen('<code><font color="#000000">
524<font color="#0000CC">&lt;?php&nbsp;</font>') - 1);
525        $source = str_replace('}&nbsp;</font><font color="#0000CC">?&gt;</font>',
526            '}</font></code>', $source);
527        if ($this->start || ($this->end != '*')) {
528            $source = explode('<br />', $source);
529            $start  = $this->start;
530            if ($this->end != '*') {
531                $source = array_slice($source, $start - 1, $this->end - $start + 1);
532            } else {
533                $source = array_slice($source, $start - 1);
534            }
535            $source = implode($source, '<br />');
536            if ($start > 0) {
537                $source = "<code>$source";
538            }
539            if ($this->end != '*') {
540                $source = "$source</code>";
541            }
542        }
543        $source = $c->unmangle($source, $this->source);
544        return $source;
545    }
546}
547
548/**
549 * Represents the example inline tag, used to display an example file
550 * inside a docblock or tutorial
551 *
552 * @category   ToolsAndUtilities
553 * @package    phpDocumentor
554 * @subpackage InlineTags
555 * @author     Gregory Beaver <cellog@php.net>
556 * @copyright  2002-2008 Gregory Beaver
557 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
558 * @version    Release: 1.4.4
559 * @filesource
560 * @link       http://www.phpdoc.org
561 * @link       http://pear.php.net/PhpDocumentor
562 * @see        parserStringWithInlineTags
563 * @tutorial   tags.inlineexample.pkg
564 * @todo       CS cleanup - change package to PhpDocumentor
565 * @todo       CS cleanup - change classname to PhpDocumentor_*
566 */
567class parserExampleInlineTag extends parserSourceInlineTag
568{
569    /**
570     * constructor
571     *
572     * @param string $value        format "filepath[ start [end]]"
573     *                             where start and end are line numbers
574     *                             with the end line number optional
575     * @param string $current_path full path to the current file,
576     *                             used to check relative directory locations
577     * @param bool   $isTutorial   if true, then this is in a tutorial
578     *
579     * @return mixed
580     * @todo replace tokenizer_ext constant with TOKENIZER_EXT for CS rule
581     */
582    function parserExampleInlineTag($value, $current_path, $isTutorial = false)
583    {
584        global $_phpDocumentor_setting;
585        parserInlineTag::parserInlineTag('example', '');
586        $path     = false;
587        $tagValue = trim($value);
588        $path     = $isAbsPath = $pathOnly = $fileName = $fileExt
589            = $original_path  = $title = false;
590        do {
591            // make sure the format is stuff.ext startline[ endline]
592            if (!preg_match('`(.*)\.(\w*)\s(.*)`', $tagValue, $match)) {
593                // or format is stuff.ext
594                if (!preg_match('`(.*)\.(\w*)\s*$`', $tagValue, $match)) {
595                    // Murphy: Some funny path was given
596                    $original_path = $tagValue; // used for error output
597                    break; // try-block
598                }
599            }
600            if (strlen($match[1]) === 0) {
601                // Murphy: Some funny path was given
602                $original_path = $tagValue; // used for error output
603                break; // try-block
604            }
605            $fileExt = $match[2];
606            if (isset($match[3])) {
607                $lines       = explode(' ', trim($match[3]));
608                $this->start = (int) $lines[0];
609                if (isset($lines[1])) {
610                    $this->end = (int) $lines[1];
611                }
612            }
613            // Replace windows '\' the path.
614            $pathTmp = str_replace('\\', '/', $match[1]);
615
616            // Is there a path and a file or is it just a file?
617            if (strpos($pathTmp, '/') === false) {
618                // No path part
619                $pathOnly = '';
620                $fileName = $pathTmp .'.'. $fileExt;
621            } else {
622                // split the path on the last directory, find the filename
623                $splitPos = strrpos($pathTmp, '/');
624                $pathOnly = substr($match[1], 0, $splitPos+1);
625                $fileName = substr($match[1], $splitPos+1) .'.'. $fileExt;
626                // Is the path absolute? (i.e. does it start like an absolute path?)
627                if (('/' === $pathTmp[0]) || preg_match('`^\w*:`i', $pathTmp)) {
628                    // works for both windows 'C:' and URLs like 'http://'
629                    $isAbsPath = true; // Yes
630                }
631            }
632
633            $original_path = $pathOnly . $fileName;
634
635            // Now look for the file starting with abs. path.
636            if ($isAbsPath) {
637                // remove any weirdities like /../file.ext
638                $tmp = realpath($original_path);
639                if ($tmp && is_file($tmp)) {
640                    $path = $tmp;
641                }
642                /*
643                 * Alway break if abs. path was detected,
644                 * even if file was not found.
645                 */
646                break; // try-block
647            }
648
649            // Search for the example file some standard places
650            // 1) Look if the ini-var examplesdir is set and look there ...
651            if (isset($_phpDocumentor_setting['examplesdir'])) {
652                $tmp = realpath($_phpDocumentor_setting['examplesdir']
653                    . PATH_DELIMITER  . $original_path);
654                if ($tmp && is_file($tmp)) {
655                    $path = $tmp; // Yo! found it :)
656                    break; // try-block
657                }
658            }
659
660            // 2) Then try to look for an 'example/'-dir
661            //    below the *currently* parsed file ...
662            if (!empty($current_path)) {
663                $tmp = realpath(dirname($current_path) . PATH_DELIMITER . 'examples'
664                    . PATH_DELIMITER . $fileName);
665                if ($tmp && is_file($tmp)) {
666                    $path = $tmp; // Yo! found it :)
667                    break; // try-block
668                }
669            }
670
671            // 3) Then try to look for the example file
672            //    below the subdir PHPDOCUMENTOR_BASE/examples/ ...
673            if (is_dir(PHPDOCUMENTOR_BASE . PATH_DELIMITER . 'examples')) {
674                $tmp = realpath(PHPDOCUMENTOR_BASE . PATH_DELIMITER . 'examples'
675                    . PATH_DELIMITER . $original_path);
676                if ($tmp && is_file($tmp)) {
677                    $path = $tmp; // Yo! found it :)
678                    break; // try-block
679                }
680            }
681
682            $tmp = realpath(PHPDOCUMENTOR_BASE . PATH_DELIMITER . $original_path);
683            if ($tmp && is_file($tmp)) {
684                $path = $tmp; // Yo! found it :)
685                break; // try-block
686            }
687            // If we reach this point, nothing was found and $path is false.
688        } while (false);
689
690        if (!$path) {
691            addWarning(PDERROR_EXAMPLE_NOT_FOUND, $original_path);
692            $this->path = false;
693        } else {
694            $f = @fopen($path, 'r');
695            if ($f) {
696                $example = fread($f, filesize($path));
697                if (tokenizer_ext && !$isTutorial) {
698                    $obj = new phpDocumentorTWordParser;
699                    $obj->setup($example);
700                    $this->setSource($obj->getFileSource());
701                    unset($obj);
702                } else {
703                    $this->setSource($example);
704                }
705            }
706        }
707    }
708
709    /**
710     * sets the source
711     *
712     * @param string|array $source source code
713     * @param string|bool  $class  class name if this is a method,
714     *                             boolean in php 4.3.0,
715     *                             if this is a method this will be true
716     *
717     * @return void
718     */
719    function setSource($source, $class = false)
720    {
721        $this->_class = $class;
722        $this->source = $source;
723    }
724
725    /**
726     * converter helper for PHP 4.3.0+
727     *
728     * @param Converter &$c output converter
729     *
730     * @return string
731     * @uses phpDocumentor_HighlightParser Parses the tokenized source
732     */
733    function arrayConvert(&$c)
734    {
735        $source = $this->source;
736        if ($this->end != '*') {
737            $source = array_slice($this->source, 0, $this->end + $this->start - 1);
738        }
739        $start = $this->start - 1;
740        if ($start < 0) {
741            $start = 0;
742        }
743        return $c->exampleProgramExample($source, true, true, $this->_class, $start);
744    }
745
746    /**
747     * Return the source for the example file, enclosed in
748     * a <programlisting> tag to use in a tutorial
749     *
750     * @return string
751     */
752    function getProgramListing()
753    {
754        $source = explode("\n", $this->source);
755        $start  = $this->start;
756        if ($this->end != '*') {
757            $source = array_slice($source, $start - 1, $this->end - $start + 1);
758        } else {
759            $source = array_slice($source, $start - 1);
760        }
761        $source = join("\n", $source);
762        return
763        "<programlisting role=\"php\">
764         <![CDATA[\n" .
765          $source .
766        "\n]]>\n</programlisting>";
767    }
768}
769
770/**
771 * Represents the inheritdoc inline tag, used by classes/methods/vars to inherit
772 * documentation from the parent class if possible
773 *
774 * @category   ToolsAndUtilities
775 * @package    phpDocumentor
776 * @subpackage InlineTags
777 * @author     Gregory Beaver <cellog@php.net>
778 * @copyright  2002-2008 Gregory Beaver
779 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
780 * @version    Release: 1.4.4
781 * @filesource
782 * @link       http://www.phpdoc.org
783 * @link       http://pear.php.net/PhpDocumentor
784 * @see        parserStringWithInlineTags
785 * @tutorial   tags.inlineinheritdoc.pkg
786 * @todo       CS cleanup - change package to PhpDocumentor
787 * @todo       CS cleanup - change classname to PhpDocumentor_*
788 */
789class parserInheritdocInlineTag extends parserInlineTag
790{
791    /**
792     * always 'inheritdoc'
793     * @var string
794     */
795    var $inlinetype = 'inheritdoc';
796
797    /**
798     * Does nothing, overrides parent constructor
799     */
800    function parserInheritdocInlineTag()
801    {
802    }
803
804    /**
805     * only sets a warning and returns empty
806     *
807     * @return string
808     * @todo CS cleanup - rename to convert for camelCase rule
809     */
810    function Convert()
811    {
812        addWarning(PDERROR_INHERITDOC_DONT_WORK_HERE);
813        return '';
814    }
815}
816
817/**
818 * Represents the inline {@}id} tag for tutorials
819 *
820 * @category   ToolsAndUtilities
821 * @package    phpDocumentor
822 * @subpackage InlineTags
823 * @author     Gregory Beaver <cellog@php.net>
824 * @copyright  2002-2008 Gregory Beaver
825 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
826 * @version    Release: 1.4.4
827 * @filesource
828 * @link       http://www.phpdoc.org
829 * @link       http://pear.php.net/PhpDocumentor
830 * @see        parserStringWithInlineTags
831 * @tutorial   tags.inlineid.pkg
832 * @todo       CS cleanup - change package to PhpDocumentor
833 * @todo       CS cleanup - change classname to PhpDocumentor_*
834 */
835class parserIdInlineTag extends parserInlineTag
836{
837    /**
838     * always 'id'
839     * @var string
840     */
841    var $inlinetype = 'id';
842    /**
843     * package of the {@}id}
844     * @var string
845     */
846    var $package = 'default';
847    /**
848     * category of the {@}id}
849     * @var string
850     */
851    var $category = 'default';
852    /**
853     * subpackage of the {@}id}
854     * @var string
855     */
856    var $subpackage = '';
857    /**
858     * full name of the tutorial
859     * @var string
860     */
861    var $tutorial;
862    /**
863     * section/subsection name
864     * @var string
865     */
866    var $id;
867
868    /**
869     * constructor
870     *
871     * @param string $category   category name
872     * @param string $package    package name
873     * @param string $subpackage subpackage name
874     * @param string $tutorial   tutorial name
875     * @param string $id         section/subsection name
876     */
877    function parserIdInlineTag($category,$package,$subpackage,$tutorial,$id = false)
878    {
879        $this->package    = $package;
880        $this->subpackage = $subpackage;
881        $this->tutorial   = $tutorial;
882        $this->id         = $id;
883        $this->category   = $category;
884    }
885
886    /**
887     * converter
888     *
889     * @param Converter &$c output converter
890     *
891     * @return string
892     * @uses Converter::getTutorialId() retrieve converter-specific ID
893     * @todo CS cleanup - rename to convert for camelCase rule
894     */
895    function Convert(&$c)
896    {
897        if (!$this->id) {
898            return '';
899        }
900        return $c->getTutorialId($this->package, $this->subpackage,
901            $this->tutorial, $this->id, $this->category);
902    }
903}
904
905/**
906 * Represents {@}toc} for table of contents generation in tutorials
907 *
908 * @category   ToolsAndUtilities
909 * @package    phpDocumentor
910 * @subpackage InlineTags
911 * @author     Gregory Beaver <cellog@php.net>
912 * @copyright  2002-2008 Gregory Beaver
913 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
914 * @version    Release: 1.4.4
915 * @filesource
916 * @link       http://www.phpdoc.org
917 * @link       http://pear.php.net/PhpDocumentor
918 * @see        parserStringWithInlineTags
919 * @tutorial   tags.inlinetoc.pkg
920 * @todo       CS cleanup - change package to PhpDocumentor
921 * @todo       CS cleanup - change classname to PhpDocumentor_*
922 */
923class parserTocInlineTag extends parserInlineTag
924{
925    /**
926     * always 'toc'
927     * @var string
928     */
929    var $inlinetype = 'toc';
930    /**
931     * @var array format:
932     * <pre>
933     * array(
934     *     array(
935     *         'tagname' => section,
936     *         'link'    => returnsee link,
937     *         'id'      => anchor name,
938     *         'title'   => from title tag
939     *     ),
940     *     ...
941     * )
942     * </pre>
943     * @access private
944     */
945    var $_toc = false;
946    /**
947     * full path to tutorial, used in conversion
948     * @var string
949     * @access private
950     */
951    var $_path = false;
952
953    /**
954     * constructor
955     */
956    function parserTocInlineTag()
957    {
958        parent::parserInlineTag('toc', '');
959    }
960
961    /**
962     * set the TOC
963     *
964     * @param array $toc format:
965     * <pre>
966     * array(
967     *     array(
968     *         'tag'   => {@link parserXMLDocBookTag},
969     *         'id'    => {@link parserIdInlineTag},
970     *         'title' => {@link parserXMLDocBookTag title}
971     *     ),
972     *     ...
973     * )
974     * </pre>
975     *
976     * @return void
977     */
978    function setTOC($toc)
979    {
980        $this->toc = $toc;
981    }
982
983    /**
984     * set the path
985     *
986     * @param string $path the path
987     *
988     * @return void
989     */
990    function setPath($path)
991    {
992        $this->_path = $path;
993    }
994
995    /**
996     * converter method
997     *
998     * <pre>
999     * array(
1000     *    'tagname' => string name of tag,
1001     *    'link'    => {@link tutorialLink} to the tutorial,
1002     *    'id'      => converter specific tutorial ID from
1003     *                     {@link Converter::getTutorialId()}
1004     *    'title'   => title of the tutorial)
1005     * </pre>
1006     * and returns the results as the table of contents
1007     *
1008     * @param Converter &$c converter object
1009     *
1010     * @return mixed
1011     * @uses Converter::getTutorialId() retrieve the tutorial ID for
1012     * @uses Converter::formatTutorialTOC() passes an array of format:
1013     * @todo CS cleanup - rename to convert for camelCase rule
1014     */
1015    function Convert(&$c)
1016    {
1017        $newtoc = array();
1018        if (isset($this->toc) && is_array($this->toc)) {
1019            foreach ($this->toc as $i => $toc) {
1020                if (isset($toc['title'])) {
1021                    $toc['tag']->setTitle($toc['title']);
1022                } else {
1023                    $toc['tag']->setTitle(new parserStringWithInlineTags);
1024                }
1025                $newtoc[$i]['tagname'] = $toc['tag']->name;
1026                $l                     = new tutorialLink;
1027                if (!isset($toc['title'])) {
1028                    $title = 'section '.$toc['id']->id;
1029                } else {
1030                    $title = $toc['title']->Convert($c);
1031                }
1032                $l->addLink($toc['id']->id, $this->_path, basename($this->_path),
1033                    $toc['id']->package, $toc['id']->subpackage, strip_tags($title));
1034                $newtoc[$i]['link']  = $c->returnSee($l);
1035                $newtoc[$i]['id']    = $c->getTutorialId($toc['id']->package,
1036                    $toc['id']->subpackage, basename($this->_path),
1037                    $toc['id']->id, $toc['id']->category);
1038                $newtoc[$i]['title'] = $title;
1039            }
1040        }
1041        return $c->formatTutorialTOC($newtoc);
1042    }
1043}
1044?>
1045