4a688dffcbc55ac71593c7b141c3568ea0bae28d
[atutor.git] / mods / phpdoc2 / PhpDocumentor / phpDocumentor / DocBlockTags.inc
1 <?php\r
2 /**\r
3  * All abstract representations of DocBlock tags are defined\r
4  * by the classes in this file\r
5  *\r
6  * phpDocumentor :: automatic documentation generator\r
7  * \r
8  * PHP versions 4 and 5\r
9  *\r
10  * Copyright (c) 2002-2006 Gregory Beaver\r
11  * \r
12  * LICENSE:\r
13  * \r
14  * This library is free software; you can redistribute it\r
15  * and/or modify it under the terms of the GNU Lesser General\r
16  * Public License as published by the Free Software Foundation;\r
17  * either version 2.1 of the License, or (at your option) any\r
18  * later version.\r
19  * \r
20  * This library is distributed in the hope that it will be useful,\r
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
23  * Lesser General Public License for more details.\r
24  * \r
25  * You should have received a copy of the GNU Lesser General Public\r
26  * License along with this library; if not, write to the Free Software\r
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
28  *\r
29  * @package    phpDocumentor\r
30  * @subpackage DocBlockTags\r
31  * @author     Greg Beaver <cellog@php.net>\r
32  * @copyright  2002-2006 Gregory Beaver\r
33  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL\r
34  * @version    CVS: $Id: DocBlockTags.inc,v 1.10 2007/04/19 20:20:57 ashnazg Exp $\r
35  * @filesource\r
36  * @link       http://www.phpdoc.org\r
37  * @link       http://pear.php.net/PhpDocumentor\r
38  * @see        parserDocBlock, parserInclude, parserPage, parserClass\r
39  * @see        parserDefine, parserFunction, parserMethod, parserVar\r
40  * @since      separate file since version 1.2\r
41  */\r
42 /**\r
43  * used to represent standard tags like @access, etc.\r
44  * This class is aware of inline tags, and will automatically handle them\r
45  * using inherited functions\r
46  * @package phpDocumentor\r
47  * @subpackage DocBlockTags\r
48  * @author Greg Beaver <cellog@php.net>\r
49  * @since 1.0rc1\r
50  * @version $Id: DocBlockTags.inc,v 1.10 2007/04/19 20:20:57 ashnazg Exp $\r
51  */\r
52 class parserTag extends parserStringWithInlineTags\r
53 {\r
54     /**\r
55      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'\r
56      * always '_tag'\r
57      * @var string\r
58      */\r
59     var $type = '_tag';\r
60     /**\r
61      * tag name (see, access, etc.)\r
62      * @var string\r
63      */\r
64     var $keyword = '';\r
65     \r
66     /**\r
67      * Set up the tag\r
68      *\r
69      * {@source}\r
70      * @param string $keyword tag name\r
71      * @param parserStringWithInlineTags $value\r
72      * @param boolean whether to parse the $value for html tags\r
73      */\r
74     function parserTag($keyword, $value, $noparse = false)\r
75     {\r
76         $this->keyword = $keyword;\r
77         if (!$noparse)\r
78         {\r
79             $parser = new parserDescParser;\r
80             $parser->subscribe('*',$this);\r
81             $parser->parse($value->value,true,'parserstringwithinlinetags');\r
82         } else $this->value = $value;\r
83     }\r
84     \r
85     /**\r
86      * @param Converter\r
87      * @see Converter\r
88      */\r
89     function Convert(&$converter)\r
90     {\r
91         if (is_array($this->value))\r
92         {\r
93             if (count($this->value) == 1)\r
94             {\r
95                 reset($this->value);\r
96                 list(,$val) = each($this->value);\r
97                 $a = $val->Convert($converter);\r
98                 return $a;\r
99             }\r
100             $result = '';\r
101             foreach($this->value as $val)\r
102             {\r
103                 // this is only true if we processed the description in\r
104                 // the constructor\r
105                 if (phpDocumentor_get_class($val) == 'parserstringwithinlinetags')\r
106                 $result .= $converter->EncloseParagraph($val->Convert($converter));\r
107                 else\r
108                 $result .= $val->Convert($converter);\r
109             }\r
110             return $result;\r
111         } else\r
112         {\r
113             $a = $this->value->Convert($converter);\r
114             return $a;\r
115         }\r
116     }\r
117     \r
118     /**\r
119      * Gets a count of the number of paragraphs in this\r
120      * tag's description.\r
121      *\r
122      * Useful in determining whether to enclose the\r
123      * tag in a paragraph or not.\r
124      * @access private\r
125      * @return integer\r
126      */\r
127     function _valueParagraphCount()\r
128     {\r
129     }\r
130     \r
131     /**\r
132      * Called by the {@link parserDescParser} when processing a description.\r
133      * @param integer not used\r
134      * @param array array of {@link parserStringWithInlineTags} representing\r
135      *              paragraphs in the tag description\r
136      * @see parserTag::parserTag()\r
137      */\r
138     function HandleEvent($a,$desc)\r
139     {\r
140         $this->value = $desc;\r
141     }\r
142     \r
143     /**\r
144      * @return string returns the text minus any inline tags\r
145      * @see parserStringWithInlineTags::getString()\r
146      */\r
147     function getString()\r
148     {\r
149         if (is_array($this->value))\r
150         {\r
151             $result = '';\r
152             foreach($this->value as $val)\r
153             {\r
154                 $result .= $val->getString();\r
155             }\r
156             return $result;\r
157         } else return $this->value->getString();\r
158     }\r
159 }\r
160 \r
161 /**\r
162  * This class represents the @name tag\r
163  * @tutorial tags.name.pkg\r
164  * @package phpDocumentor\r
165  * @subpackage DocBlockTags\r
166  */\r
167 class parserNameTag extends parserTag\r
168 {\r
169     /**\r
170      * tag name\r
171      * @var string\r
172      */\r
173     var $keyword = 'name';\r
174     \r
175     /**\r
176      * @param string not used\r
177      * @param string name\r
178      */\r
179     function parserNameTag($name, $value)\r
180     {\r
181         $this->value = $value;\r
182     }\r
183     \r
184     /**\r
185      * @see parserStringWithInlineTags::Convert()\r
186      * @param Converter\r
187      * @return string converted value of the tag\r
188      */\r
189     function Convert(&$c)\r
190     {\r
191         return $this->value;\r
192     }\r
193 }\r
194 \r
195 /**\r
196  * This class represents the @access tag\r
197  * @tutorial tags.access.pkg\r
198  * @package phpDocumentor\r
199  * @subpackage DocBlockTags\r
200  */\r
201 class parserAccessTag extends parserTag\r
202 {\r
203     /**\r
204      * tag name\r
205      * @var string\r
206      */\r
207     var $keyword = 'access';\r
208     \r
209     /**\r
210      * set to true if the returned tag has a value type of private, protected\r
211      * or public, false otherwise\r
212      * @var boolean\r
213      */\r
214     var $isvalid = false;\r
215     \r
216     /**\r
217      * checks $value to make sure it is private, protected or public, otherwise\r
218      * it's not a valid @access tag\r
219      * @see $isvalid\r
220      * @param parserStringWithInlineTags $value\r
221      */\r
222     function parserAccessTag($value)\r
223     {\r
224         if (!is_string($value))\r
225         {\r
226             if (is_object($value))\r
227             {\r
228                 if (method_exists($value,'getstring'))\r
229                 {\r
230                     $value = $value->getString();\r
231                 }\r
232             }\r
233         }\r
234         switch(trim($value))\r
235         {\r
236             case 'private' :\r
237             case 'public' :\r
238             case 'protected' :\r
239                 $this->value = $value;\r
240                 $this->isvalid = true;\r
241             break;\r
242             default :\r
243             addError(PDERROR_ACCESS_WRONG_PARAM,$value);\r
244                 $this->value = 'public';\r
245             break;\r
246         }\r
247     }\r
248     \r
249     /**\r
250      * @see parserStringWithInlineTags::Convert()\r
251      * @param Converter\r
252      * @return string converted value of the tag\r
253      */\r
254     function Convert(&$converter)\r
255     {\r
256         return $this->value;\r
257     }\r
258     \r
259     /**\r
260      * No inline tags are possible, returns 'public', 'protected' or 'private'\r
261      * @return string returns the text minus any inline tags\r
262      */\r
263     function getString()\r
264     {\r
265         return $this->value;\r
266     }\r
267 }\r
268 \r
269 /**\r
270  * represents "@return"\r
271  * @tutorial tags.return.pkg\r
272  * @package phpDocumentor\r
273  * @subpackage DocBlockTags\r
274  * @author Greg Beaver <cellog@php.net>\r
275  * @since 1.0rc1\r
276  * @version $Id: DocBlockTags.inc,v 1.10 2007/04/19 20:20:57 ashnazg Exp $\r
277  */\r
278 class parserReturnTag extends parserTag\r
279 {\r
280     /**\r
281      * always 'return'\r
282      * @var string\r
283      */\r
284     var $keyword = 'return';\r
285     /**\r
286      * the type a function returns\r
287      */\r
288     var $returnType = 'void';\r
289     \r
290     /**\r
291      * contains a link to the documentation for a class passed as a type in @return, @var or @param\r
292      *\r
293      * Example:\r
294      *\r
295      * <code>\r
296      * class myclass\r
297      * {\r
298      * ...\r
299      * }\r
300      * /** @return myclass blahblahblah\r
301      * ...\r
302      * </code>\r
303      *\r
304      * In this case, $converted_returnType will contain a link to myclass instead of the string 'myclass'\r
305      * @var mixed either the same as $returnType or a link to the docs for a class\r
306      * @see $returnType\r
307      */\r
308     var $converted_returnType = false;\r
309     \r
310     /**\r
311      * @param string\r
312      * @param parserStringWithInlineTags\r
313      */\r
314     function parserReturnTag($returnType, $value)\r
315     {\r
316         $this->returnType = $returnType;\r
317         parent::parserTag('return',$value);\r
318     }\r
319     \r
320     /**\r
321      * sets up $converted_returnType\r
322      * @see parserStringWithInlineTags::Convert(), $converted_returnType\r
323      * @param Converter\r
324      * @return string converted value of the tag\r
325      */\r
326     function Convert(&$converter)\r
327     {\r
328         $my_types = '';\r
329         if (strpos($this->returnType,'|'))\r
330         {\r
331             $types = explode('|',$this->returnType);\r
332             foreach($types as $returntype)\r
333             {\r
334                 $a = $converter->getLink($returntype);\r
335                 if (is_object($a) && phpDocumentor_get_class($a) == 'classlink')\r
336                 {\r
337                     if (!empty($my_types)) $my_types .= '|';\r
338                     $my_types .= $converter->returnSee($a,$converter->type_adjust($returntype));\r
339                 } else\r
340                 {\r
341                     if (!empty($my_types)) $my_types .= '|';\r
342                     $my_types .= $converter->type_adjust($returntype);\r
343                 }\r
344             }\r
345             $this->converted_returnType = $my_types;\r
346         } else\r
347         {\r
348             $a = $converter->getLink($this->returnType);\r
349             if (is_object($a) && phpDocumentor_get_class($a) == 'classlink')\r
350             {\r
351                 $this->converted_returnType = $converter->returnSee($a,$converter->type_adjust($this->returnType));\r
352             } else\r
353             {\r
354                 $this->converted_returnType = $converter->type_adjust($this->returnType);\r
355             }\r
356         }\r
357         return parserTag::Convert($converter);\r
358     }\r
359 }\r
360 \r
361 /**\r
362  * represents "@property" tag\r
363  * @package phpDocumentor\r
364  * @subpackage DocBlockTags\r
365  */\r
366 class parserPropertyTag extends parserReturnTag\r
367 {\r
368     /**\r
369      * always 'property'\r
370      * @var string\r
371      */\r
372     var $keyword = 'property';\r
373     /**\r
374      * the type a property has\r
375      * @var string\r
376      */\r
377     var $returnType = 'mixed';\r
378 \r
379     /**\r
380      * @param string\r
381      * @param parserStringWithInlineTags\r
382      */\r
383     function parserPropertyTag( $returnType, $value )\r
384     {\r
385         $this->returnType = $returnType;\r
386         parent::parserTag( $this->keyword, $value );\r
387     }\r
388 }\r
389 \r
390 /**\r
391  * represents "@property-read" tag\r
392  * @package phpDocumentor\r
393  * @subpackage DocBlockTags\r
394  */\r
395 class parserPropertyReadTag extends parserPropertyTag\r
396 {\r
397     /**\r
398      * always 'property-read'\r
399      * @var string\r
400      */\r
401     var $keyword = 'property-read';\r
402 }\r
403 \r
404 /**\r
405  * represents "@property-write" tag\r
406  * @package phpDocumentor\r
407  * @subpackage DocBlockTags\r
408  */\r
409 class parserPropertyWriteTag extends parserPropertyTag\r
410 {\r
411     /**\r
412      * always 'property-write'\r
413      * @var string\r
414      */\r
415     var $keyword = 'property-write';\r
416 }\r
417 \r
418 /**\r
419  * represents "@method" tag\r
420  * @package phpDocumentor\r
421  * @subpackage DocBlockTags\r
422  */\r
423 class parserMethodTag extends parserPropertyTag\r
424 {\r
425     /**\r
426      * always 'method'\r
427      * @var string\r
428      */\r
429     var $keyword = 'method';\r
430     /**\r
431      * the return type a method has\r
432      * @var string\r
433      */\r
434     var $returnType = 'void';\r
435 }\r
436 \r
437 /**\r
438  * represents "@var"\r
439  * @tutorial tags.var.pkg\r
440  * @package phpDocumentor\r
441  * @subpackage DocBlockTags\r
442  * @author Greg Beaver <cellog@php.net>\r
443  * @since 1.0rc1\r
444  * @version $Id: DocBlockTags.inc,v 1.10 2007/04/19 20:20:57 ashnazg Exp $\r
445  */\r
446 class parserVarTag extends parserReturnTag\r
447 {\r
448     /**\r
449      * always 'var'\r
450      * @var string\r
451      */\r
452     var $keyword = 'var';\r
453     /**\r
454      * the type a var has\r
455      * @var string\r
456      */\r
457     var $returnType = 'mixed';\r
458 }\r
459 \r
460 /**\r
461  * Represents "@param"\r
462  * @tutorial tags.param.pkg\r
463  * @package phpDocumentor\r
464  * @subpackage DocBlockTags\r
465  */\r
466 class parserParamTag extends parserVarTag\r
467 {\r
468     /**\r
469      * always 'param'\r
470      * @var string\r
471      */\r
472     var $keyword = 'param';\r
473 }\r
474 \r
475 /**\r
476  * Represents "@staticvar"\r
477  * @tutorial tags.staticvar.pkg\r
478  * @package phpDocumentor\r
479  * @subpackage DocBlockTags\r
480  */\r
481 class parserStaticvarTag extends parserParamTag\r
482 {\r
483     /**\r
484      * always 'staticvar'\r
485      * @var string\r
486      */\r
487     var $keyword = 'staticvar';\r
488 }\r
489 \r
490 /**\r
491  * represents "@link"\r
492  * @tutorial tags.link.pkg\r
493  * @package phpDocumentor\r
494  * @subpackage DocBlockTags\r
495  * @author Greg Beaver <cellog@php.net>\r
496  * @since 1.0rc1\r
497  * @version $Id: DocBlockTags.inc,v 1.10 2007/04/19 20:20:57 ashnazg Exp $\r
498  */\r
499 class parserLinkTag extends parserTag\r
500 {\r
501     /**\r
502      * always 'link'\r
503      * @var string\r
504      */\r
505     var $keyword = 'link';\r
506     \r
507     /**\r
508      * URL to link to\r
509      * @param string $link\r
510      */\r
511     function parserLinkTag($link)\r
512     {\r
513         $start = $val = $link->getString();\r
514         if (strpos($val,' '))\r
515         {\r
516             $start = array_shift($val = explode(' ',$val));\r
517             $val = join($val, ' ');\r
518         }\r
519         $a = new parserLinkInlineTag($start,$val);\r
520         $b = new parserStringWithInlineTags;\r
521         $b->add($a);\r
522         $this->value = $b;\r
523     }\r
524 }\r
525 \r
526 /**\r
527  * represents "@see"\r
528  * @tutorial tags.see.pkg\r
529  * @package phpDocumentor\r
530  * @subpackage DocBlockTags\r
531  * @author Greg Beaver <cellog@php.net>\r
532  * @since 1.0rc1\r
533  * @version $Id: DocBlockTags.inc,v 1.10 2007/04/19 20:20:57 ashnazg Exp $\r
534  */\r
535 class parserSeeTag extends parserLinkTag\r
536 {\r
537     /**\r
538      * always 'see'\r
539      * @var string\r
540      */\r
541     var $keyword = 'see';\r
542     \r
543     /**\r
544      * @param string element to link to\r
545      */\r
546     function parserSeeTag($name)\r
547     {\r
548         parserTag::parserTag($this->keyword,$name,true);\r
549     }\r
550 \r
551     /**\r
552      * @param Converter\r
553      * @see parserStringWithInlineTags::Convert()\r
554      */\r
555     function Convert(&$converter)\r
556     {\r
557         if ($this->value->hasInlineTag())\r
558         {\r
559             addErrorDie(PDERROR_INLINETAG_IN_SEE);\r
560         }\r
561         $a = $converter->getLink(trim($this->value->Convert($converter)));\r
562         if (is_string($a))\r
563         {\r
564             // feature 564991\r
565             if (strpos($a,'://'))\r
566             {\r
567                 // php function\r
568                 return $converter->returnLink($a,str_replace('PHP_MANUAL#','',$this->value->Convert($converter)));\r
569             }\r
570             return $a;\r
571         }\r
572         if (is_object($a)) return $converter->returnSee($a);\r
573         // getLink parsed a comma-delimited list of linked thingies, add the commas back in\r
574         if (is_array($a))\r
575         {\r
576             $b = '';\r
577             foreach($a as $i => $bub)\r
578             {\r
579                 if (!empty($b)) $b .= ', ';\r
580                 if (is_string($a[$i])) $b .= $a[$i];\r
581                 if (is_object($a[$i])) $b .= $converter->returnSee($a[$i]);\r
582             }\r
583             return $b;\r
584         }\r
585         return false;\r
586     }\r
587 }\r
588 \r
589 /**\r
590  * represents "@license"\r
591  *\r
592  * Link to a license, instead of including lines and lines of license information\r
593  * in every file\r
594  * @tutorial tags.license.pkg\r
595  * @package phpDocumentor\r
596  * @subpackage DocBlockTags\r
597  */\r
598 class parserLicenseTag extends parserLinkTag\r
599 {\r
600     /**\r
601      * always 'license'\r
602      * @var string\r
603      */\r
604     var $keyword = 'license';\r
605     \r
606     /**\r
607      * URL to link to\r
608      * @param string $link\r
609      */\r
610     function parserLicenseTag($name, $link)\r
611     {\r
612         $a = explode(' ',$link->getString());\r
613         $url = array_shift($a);\r
614         $license = join($a,' ');\r
615         if (empty($license)) $license = $url;\r
616         $a = new parserLinkInlineTag($url, $license);\r
617         $b = new parserStringWithInlineTags;\r
618         $b->add($a);\r
619         $this->value = $b;\r
620     }\r
621 }\r
622 \r
623 /**\r
624  * represents "@uses"\r
625  *\r
626  * This is exactly like @see except that the element used has a @useby link to this element added to its docblock\r
627  * @package phpDocumentor\r
628  * @subpackage DocBlockTags\r
629  * @tutorial tags.uses.pkg\r
630  * @since 1.2\r
631  */\r
632 class parserUsesTag extends parserSeeTag\r
633 {\r
634     /**\r
635      * Always "uses"\r
636      * @var string\r
637      */\r
638     var $keyword = 'uses';\r
639     /** @access private */\r
640     var $_description;\r
641     \r
642     /**\r
643      * @param string element to link to\r
644      * @param parserStringWithInlineTags description of how the element is used\r
645      */\r
646     function parserUsesTag($seeel, $description)\r
647     {\r
648         if ($seeel->hasInlineTag()) {\r
649             addErrorDie(PDERROR_DUMB_USES);\r
650         }\r
651         parent::parserSeeTag($seeel);\r
652         $this->_description = $description;\r
653     }\r
654     \r
655     /**\r
656      * Return a link to documentation for other element, and description of how\r
657      * it is used\r
658      *\r
659      * Works exactly like {@link parent::Convert()} except that it also includes\r
660      * a description of how the element used is used.\r
661      * @return string\r
662      * @param Converter\r
663      */\r
664     function Convert(&$c)\r
665     {\r
666         $val = $this->value;\r
667         $see = parent::Convert($c);\r
668         $this->value = $this->_description;\r
669                   $desc_val = parserTag::Convert($c);\r
670         if (!empty($desc_val)) {\r
671            $see .= ' - '.$desc_val;\r
672         }\r
673         $this->value = $val;\r
674         return $see;\r
675     }\r
676     \r
677     /**\r
678      * Get the text of the link to the element that is being used\r
679      * @return string\r
680      * @access private\r
681      */\r
682     function getSeeElement()\r
683     {\r
684         return $this->value->getString();\r
685     }\r
686     \r
687     /**\r
688      * Get the description of how the element used is being used.\r
689      * @return parserStringWithInlineTags\r
690      */\r
691     function getDescription()\r
692     {\r
693         return $this->_description;\r
694     }\r
695 }\r
696 \r
697 /**\r
698  * This is a virtual tag, it is created by @uses to cross-reference the used element\r
699  *\r
700  * This is exactly like @uses.\r
701  * @package phpDocumentor\r
702  * @subpackage DocBlockTags\r
703  * @since 1.2\r
704  */\r
705 class parserUsedByTag extends parserUsesTag\r
706 {\r
707     /**\r
708      * Always "usedby"\r
709      * @var string\r
710      */\r
711     var $keyword = 'usedby';\r
712     /** @access private */\r
713     var $_link;\r
714     \r
715     /**\r
716      * @param abstractLink link of element that uses this element\r
717      * @param string description of how the element is used\r
718      */\r
719     function parserUsedByTag($link, $description)\r
720     {\r
721         $this->value = $description;\r
722         $this->_link = $link;\r
723     }\r
724     \r
725     /**\r
726      * @return string\r
727      * @param Converter\r
728      */\r
729     function Convert(&$c)\r
730     {\r
731         $see = $c->returnSee($this->_link);\r
732                   $desc_val = parserTag::Convert($c);\r
733         if (!empty($desc_val)) {\r
734            $see .= ' - '.$desc_val;\r
735         }\r
736         return $see;\r
737     }\r
738 }\r
739 \r
740 /**\r
741  * represents "@tutorial"\r
742  *\r
743  * This is exactly like @see except that it only links to tutorials\r
744  * @tutorial phpDocumentor/tutorials.pkg\r
745  * @tutorial tags.tutorial.pkg\r
746  * @package phpDocumentor\r
747  * @subpackage DocBlockTags\r
748  * @since 1.2\r
749  */\r
750 class parserTutorialTag extends parserSeeTag\r
751 {\r
752     /**\r
753      * Always "tutorial"\r
754      * @var string\r
755      */\r
756     var $keyword = 'tutorial';\r
757     /**\r
758      * @param Converter\r
759      * @see parserStringWithInlineTags::Convert()\r
760      */\r
761     function Convert(&$converter)\r
762     {\r
763         $a = $converter->getTutorialLink(trim($this->value->Convert($converter)));\r
764         if (is_string($a))\r
765         {\r
766             return $a;\r
767         }\r
768         if (is_object($a)) return $converter->returnSee($a);\r
769         // getLink parsed a comma-delimited list of linked thingies, add the commas back in\r
770         if (is_array($a))\r
771         {\r
772             $b = '';\r
773             foreach($a as $i => $bub)\r
774             {\r
775                 if (!empty($b)) $b .= ', ';\r
776                 if (is_string($a[$i])) $b .= $a[$i];\r
777                 if (is_object($a[$i])) $b .= $converter->returnSee($a[$i]);\r
778             }\r
779             return $b;\r
780         }\r
781         return false;\r
782     }\r
783 }\r
784 \r
785 /**\r
786  * represents "@filesource"\r
787  * \r
788  * Use this to create a link to a highlighted phpxref-style source file listing\r
789  * @package phpDocumentor\r
790  * @subpackage DocBlockTags\r
791  * @tutorial tags.filesource.pkg\r
792  */\r
793 class parserFileSourceTag extends parserTag\r
794 {\r
795     /**\r
796      * Always "filesource"\r
797      * @var string\r
798      */\r
799     var $keyword = 'filesource';\r
800     /** @var array */\r
801     var $source;\r
802     /** @var string */\r
803     var $path;\r
804     /**\r
805      * Flag variable, controls double writes of file for each converter\r
806      * @access private\r
807      * @var array\r
808      */\r
809     var $_converted = array();\r
810     /**\r
811      * Set {@link $source} to $value, and set up path\r
812      * @param string\r
813      * @param array output from {@link phpDocumentorTWordParser::getFileSource()}\r
814      */\r
815     function parserFileSourceTag($filepath, $value)\r
816     {\r
817         parent::parserTag($this->keyword, '');\r
818         $this->path = $filepath;\r
819         $this->source = $value;\r
820     }\r
821 \r
822     /**\r
823      * Return a link to the highlighted source and generate the source\r
824      * @uses ConvertSource() generate source code and write it out\r
825      * @return string output from {@link getSourceLink()}\r
826      * @param Converter\r
827      */\r
828     function Convert(&$c)\r
829     {\r
830         $this->ConvertSource($c);\r
831         return $this->getSourceLink($c);\r
832     }\r
833 \r
834     /**\r
835      * @param Converter\r
836      * @uses phpDocumentor_HighlightParser highlights source code\r
837      * @uses writeSource()\r
838      */\r
839     function ConvertSource(&$c)\r
840     {\r
841         $this->writeSource($c, $c->ProgramExample($this->source, true, false, false, false, $this->path));\r
842         return;\r
843         $parser = new phpDocumentor_HighlightParser;\r
844         $return = '';\r
845         $return = $parser->parse($this->source,$c, false, false, false, $this->path);\r
846         $this->writeSource($c, $return);\r
847     }\r
848 \r
849     /**\r
850      * @param Converter\r
851      * @param string highlighted source code\r
852      * @uses Converter::writeSource() export highlighted file source\r
853      */\r
854     function writeSource(&$c, $source)\r
855     {\r
856         $c->writeSource($this->path, $source);\r
857     }\r
858 \r
859     /**\r
860      * @uses Converter::getSourceLink()\r
861      * @param Converter\r
862      * @return output from getSourceLink()\r
863      */\r
864     function getSourceLink(&$c)\r
865     {\r
866         return $c->getSourceLink($this->path);\r
867     }\r
868 }\r
869 \r
870 /**\r
871  * represents "@example"\r
872  * \r
873  * The example tag \r
874  * @package phpDocumentor\r
875  * @subpackage DocBlockTags\r
876  * @tutorial tags.example.pkg\r
877  */\r
878 class parserExampleTag extends parserFileSourceTag\r
879 {\r
880     /**\r
881      * always "example"\r
882      * @var string\r
883      */\r
884     var $keyword = 'example';\r
885     /**\r
886      * Reads and parses the example file indicated\r
887      *\r
888      * The example tag takes one parameter: the full path to a php file that\r
889      * should be parsed and included as an example.\r
890      * @uses phpDocumentorTWordParser::getFileSource() uses to parse an example\r
891      *       and retrieve all tokens by line number\r
892      * @param parserStringWithInlineTags\r
893      * @param string path of file containing this @example tag\r
894      */\r
895     function parserExampleTag($value, $current_path)\r
896     {\r
897         global $_phpDocumentor_setting;\r
898         parent::parserTag('example', $value);\r
899         $path = false;\r
900         // code thanks to Sam Blum, modified by Greg Beaver\r
901         $tagValue = $value->getString();\r
902         $path = $isAbsPath = $pathOnly = $fileName = $fileExt = $original_path  = $title = FALSE;\r
903         do\r
904         {\r
905             // make sure the format is stuff.ext description\r
906             if (!preg_match('`(.*)\.(\w*)\s(.*)`', $tagValue, $match))\r
907             {\r
908                 // or format is stuff.ext\r
909                 if (!preg_match('`(.*)\.(\w*)\s*$`', $tagValue, $match))\r
910                 {\r
911                     // Murphy: Some funny path was given\r
912                     $original_path = $tagValue; // used for error output\r
913                     break; // try-block\r
914                 }\r
915             }\r
916             if (strlen($match[1]) === 0)\r
917             {\r
918                 // Murphy: Some funny path was given\r
919                 $original_path = $tagValue; // used for error output\r
920                 break; // try-block\r
921             }\r
922             $fileExt = $match[2];\r
923             $title = 'example';\r
924             if (isset($match[3]))\r
925             {\r
926                 $title = trim($match[3]);\r
927             }\r
928             $pathTmp = str_replace('\\', '/', $match[1]); // Replace windows '\' the path.\r
929 \r
930             // Is there a path and a file or is it just a file?\r
931             if (strpos($pathTmp,'/') === false)\r
932             {\r
933                 // No path part\r
934                 $pathOnly = '';\r
935                 $fileName = $pathTmp .'.'. $fileExt;\r
936             } else\r
937             {\r
938                 $splitPos = strrpos($pathTmp,'/'); // split the path on the last directory, find the filename\r
939                 $pathOnly = substr($match[1], 0, $splitPos+1);\r
940                 $fileName = substr($match[1], $splitPos+1) .'.'. $fileExt;\r
941                 // Is the path absolute? (i.e. does it start like an absolute path?)\r
942                 if (('/' === $pathTmp[0]) || preg_match('`^\w*:`i', $pathTmp))\r
943                 { // works for both windows 'C:' and URLs like 'http://'\r
944                     $isAbsPath = true; // Yes\r
945                 }\r
946             }\r
947 \r
948             $original_path = $pathOnly . $fileName;\r
949 \r
950             // Now look for the file starting with abs. path.\r
951             if ($isAbsPath)\r
952             {\r
953                 $tmp = realpath($original_path); // remove any weirdities like /../file.ext\r
954                 if ($tmp && is_file($tmp))\r
955                 {\r
956                     $path = $tmp;\r
957                 }\r
958                 // Alway break if abs. path was detected; even if file was not found.\r
959                 break; // try-block\r
960             }\r
961 \r
962             // Search for the example file some standard places \r
963             // 1) Look if the ini-var examplesdir is set and look there ...\r
964             if (isset($_phpDocumentor_setting['examplesdir']))\r
965             {\r
966                 $tmp = realpath($_phpDocumentor_setting['examplesdir'] . PATH_DELIMITER  . $original_path);\r
967                 if ($tmp && is_file($tmp))\r
968                 {\r
969                     $path = $tmp; // Yo! found it :)\r
970                     break; // try-block\r
971                 }\r
972             }\r
973 \r
974             // 2) Then try to look for an 'example/'-dir below the *currently* parsed file ...\r
975             if (!empty($current_path))\r
976             {\r
977                 $tmp = realpath(dirname($current_path) . PATH_DELIMITER . 'examples' . PATH_DELIMITER . $fileName);\r
978                 if ($tmp && is_file($tmp))\r
979                 {\r
980                     $path = $tmp; // Yo! found it :)\r
981                     break; // try-block\r
982                 }\r
983             }\r
984 \r
985             // 3) Then try to look for the example file below the subdir PHPDOCUMENTOR_BASE/examples/ ...\r
986             if (is_dir(PHPDOCUMENTOR_BASE . PATH_DELIMITER . 'examples'))\r
987             {\r
988                 $tmp = realpath(PHPDOCUMENTOR_BASE . PATH_DELIMITER . 'examples' . PATH_DELIMITER . $original_path);\r
989                 if ($tmp && is_file($tmp))\r
990                 {\r
991                     $path = $tmp; // Yo! found it :)\r
992                     break; // try-block\r
993                 }\r
994             }\r
995 \r
996             $tmp = realpath(PHPDOCUMENTOR_BASE . PATH_DELIMITER . $original_path);\r
997             if ($tmp && is_file($tmp))\r
998             {\r
999                 $path = $tmp; // Yo! found it :)\r
1000                 break; // try-block\r
1001             }\r
1002             // If we reach this point, nothing was found and $path is false.\r
1003         } while (false);\r
1004 \r
1005         if (!$path)\r
1006         {\r
1007             addWarning(PDERROR_EXAMPLE_NOT_FOUND, $original_path);\r
1008             $this->_title = 'example not found';\r
1009             $this->path = false;\r
1010         } else\r
1011         {\r
1012             $this->_title = ($title) ? $title : 'example';\r
1013             // make a unique html-filename but avoid it to get too long.\r
1014             $uniqueFileName = str_replace(array(':', DIRECTORY_SEPARATOR,'/'), array('_', '_', '_'), $path);\r
1015             $uniqueFileName = substr($uniqueFileName,-50) . '_' . md5($path);\r
1016             $this->path = $uniqueFileName;\r
1017             \r
1018             $f = @fopen($path,'r');\r
1019             if ($f)\r
1020             {\r
1021                 $example = fread($f,filesize($path));\r
1022                 if (tokenizer_ext)\r
1023                 {\r
1024                     $obj = new phpDocumentorTWordParser;\r
1025                     $obj->setup($example);\r
1026                     $this->source = $obj->getFileSource();\r
1027                     $this->origsource = $example;\r
1028                     unset($obj);\r
1029                 } else\r
1030                 {\r
1031                     $this->source = $example;\r
1032                 }\r
1033             }\r
1034         }\r
1035     }\r
1036     \r
1037     /**\r
1038      * @param Converter\r
1039      * @uses phpDocumentor_HighlightParser highlights source code\r
1040      * @uses writeSource()\r
1041      */\r
1042     function ConvertSource(&$c)\r
1043     {\r
1044         $this->writeSource($c, $c->ProgramExample($this->source, true, null,\r
1045                             null, null, null, $this->origsource));\r
1046         return;\r
1047         $parser = new phpDocumentor_HighlightParser;\r
1048         $return = '';\r
1049         $return = $parser->parse($this->source,$c);\r
1050         $this->writeSource($c, $return);\r
1051     }\r
1052 \r
1053     /**\r
1054      * @param Converter $c\r
1055      * @param string parsed example source\r
1056      * @uses Converter::writeExample() writes final example out\r
1057      * @access private\r
1058      */\r
1059     function writeSource(&$c, $source)\r
1060     {\r
1061         if ($this->path)\r
1062         $c->writeExample($this->_title, $this->path, $source);\r
1063     }\r
1064 \r
1065     /**\r
1066      * Retrieve a converter-specific link to the example\r
1067      *\r
1068      * @param Converter\r
1069      * @uses Converter::getExampleLink() retrieve the link to the example\r
1070      */\r
1071     function getSourceLink(&$c)\r
1072     {\r
1073         if (!$this->path) return $this->_title;\r
1074         return $c->getExampleLink($this->path, $this->_title);\r
1075     }\r
1076 }\r
1077 \r
1078 ?>\r