Yaffs site version 1.1
[yaffs-website] / vendor / phpdocumentor / reflection-docblock / src / phpDocumentor / Reflection / DocBlock / Description.php
1 <?php
2 /**
3  * phpDocumentor
4  *
5  * PHP Version 5.3
6  *
7  * @author    Mike van Riel <mike.vanriel@naenius.com>
8  * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
9  * @license   http://www.opensource.org/licenses/mit-license.php MIT
10  * @link      http://phpdoc.org
11  */
12
13 namespace phpDocumentor\Reflection\DocBlock;
14
15 use phpDocumentor\Reflection\DocBlock;
16
17 /**
18  * Parses a Description of a DocBlock or tag.
19  *
20  * @author  Mike van Riel <mike.vanriel@naenius.com>
21  * @license http://www.opensource.org/licenses/mit-license.php MIT
22  * @link    http://phpdoc.org
23  */
24 class Description implements \Reflector
25 {
26     /** @var string */
27     protected $contents = '';
28
29     /** @var array The contents, as an array of strings and Tag objects. */
30     protected $parsedContents = null;
31
32     /** @var DocBlock The DocBlock which this description belongs to. */
33     protected $docblock = null;
34
35     /**
36      * Populates the fields of a description.
37      *
38      * @param string   $content  The description's conetnts.
39      * @param DocBlock $docblock The DocBlock which this description belongs to.
40      */
41     public function __construct($content, DocBlock $docblock = null)
42     {
43         $this->setContent($content)->setDocBlock($docblock);
44     }
45
46     /**
47      * Gets the text of this description.
48      *
49      * @return string
50      */
51     public function getContents()
52     {
53         return $this->contents;
54     }
55
56     /**
57      * Sets the text of this description.
58      *
59      * @param string $content The new text of this description.
60      *
61      * @return $this
62      */
63     public function setContent($content)
64     {
65         $this->contents = trim($content);
66
67         $this->parsedContents = null;
68         return $this;
69     }
70
71     /**
72      * Returns the parsed text of this description.
73      *
74      * @return array An array of strings and tag objects, in the order they
75      *     occur within the description.
76      */
77     public function getParsedContents()
78     {
79         if (null === $this->parsedContents) {
80             $this->parsedContents = preg_split(
81                 '/\{
82                     # "{@}" is not a valid inline tag. This ensures that
83                     # we do not treat it as one, but treat it literally.
84                     (?!@\})
85                     # We want to capture the whole tag line, but without the
86                     # inline tag delimiters.
87                     (\@
88                         # Match everything up to the next delimiter.
89                         [^{}]*
90                         # Nested inline tag content should not be captured, or
91                         # it will appear in the result separately.
92                         (?:
93                             # Match nested inline tags.
94                             (?:
95                                 # Because we did not catch the tag delimiters
96                                 # earlier, we must be explicit with them here.
97                                 # Notice that this also matches "{}", as a way
98                                 # to later introduce it as an escape sequence.
99                                 \{(?1)?\}
100                                 |
101                                 # Make sure we match hanging "{".
102                                 \{
103                             )
104                             # Match content after the nested inline tag.
105                             [^{}]*
106                         )* # If there are more inline tags, match them as well.
107                            # We use "*" since there may not be any nested inline
108                            # tags.
109                     )
110                 \}/Sux',
111                 $this->contents,
112                 null,
113                 PREG_SPLIT_DELIM_CAPTURE
114             );
115
116             $count = count($this->parsedContents);
117             for ($i=1; $i<$count; $i += 2) {
118                 $this->parsedContents[$i] = Tag::createInstance(
119                     $this->parsedContents[$i],
120                     $this->docblock
121                 );
122             }
123
124             //In order to allow "literal" inline tags, the otherwise invalid
125             //sequence "{@}" is changed to "@", and "{}" is changed to "}".
126             //See unit tests for examples.
127             for ($i=0; $i<$count; $i += 2) {
128                 $this->parsedContents[$i] = str_replace(
129                     array('{@}', '{}'),
130                     array('@', '}'),
131                     $this->parsedContents[$i]
132                 );
133             }
134         }
135         return $this->parsedContents;
136     }
137
138     /**
139      * Return a formatted variant of the Long Description using MarkDown.
140      *
141      * @todo this should become a more intelligent piece of code where the
142      *     configuration contains a setting what format long descriptions are.
143      *
144      * @codeCoverageIgnore Will be removed soon, in favor of adapters at
145      *     PhpDocumentor itself that will process text in various formats.
146      *
147      * @return string
148      */
149     public function getFormattedContents()
150     {
151         $result = $this->contents;
152
153         // if the long description contains a plain HTML <code> element, surround
154         // it with a pre element. Please note that we explicitly used str_replace
155         // and not preg_replace to gain performance
156         if (strpos($result, '<code>') !== false) {
157             $result = str_replace(
158                 array('<code>', "<code>\r\n", "<code>\n", "<code>\r", '</code>'),
159                 array('<pre><code>', '<code>', '<code>', '<code>', '</code></pre>'),
160                 $result
161             );
162         }
163
164         if (class_exists('Parsedown')) {
165             $markdown = \Parsedown::instance();
166             $result = $markdown->parse($result);
167         } elseif (class_exists('dflydev\markdown\MarkdownExtraParser')) {
168             $markdown = new \dflydev\markdown\MarkdownExtraParser();
169             $result = $markdown->transformMarkdown($result);
170         }
171
172         return trim($result);
173     }
174
175     /**
176      * Gets the docblock this tag belongs to.
177      *
178      * @return DocBlock The docblock this description belongs to.
179      */
180     public function getDocBlock()
181     {
182         return $this->docblock;
183     }
184
185     /**
186      * Sets the docblock this tag belongs to.
187      *
188      * @param DocBlock $docblock The new docblock this description belongs to.
189      *     Setting NULL removes any association.
190      *
191      * @return $this
192      */
193     public function setDocBlock(DocBlock $docblock = null)
194     {
195         $this->docblock = $docblock;
196
197         return $this;
198     }
199
200     /**
201      * Builds a string representation of this object.
202      *
203      * @todo determine the exact format as used by PHP Reflection
204      *     and implement it.
205      *
206      * @return void
207      * @codeCoverageIgnore Not yet implemented
208      */
209     public static function export()
210     {
211         throw new \Exception('Not yet implemented');
212     }
213
214     /**
215      * Returns the long description as a string.
216      *
217      * @return string
218      */
219     public function __toString()
220     {
221         return $this->getContents();
222     }
223 }