mirror of
https://github.com/barryvdh/ReflectionDocBlock.git
synced 2026-08-18 10:07:12 +00:00
Write tests for DescriptionFactory and adjust components for minor bugs that were found
This commit is contained in:
@@ -14,6 +14,23 @@ namespace phpDocumentor\Reflection\DocBlock;
|
||||
|
||||
use phpDocumentor\Reflection\Types\Context;
|
||||
|
||||
/**
|
||||
* Creates a new Description object given a body of text.
|
||||
*
|
||||
* Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their
|
||||
* body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the
|
||||
* Description object's `render` method.
|
||||
*
|
||||
* In addition to the above does a Description support two types of escape sequences:
|
||||
*
|
||||
* 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}`
|
||||
* 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description
|
||||
* of an inline tag.
|
||||
*
|
||||
* If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning
|
||||
* of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping
|
||||
* over unexpected spaces as can be observed with tag descriptions.
|
||||
*/
|
||||
class DescriptionFactory
|
||||
{
|
||||
/** @var TagFactory */
|
||||
@@ -45,11 +62,16 @@ class DescriptionFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contents
|
||||
* @return array
|
||||
* Strips the contents from superfluous whitespace and splits the description into a series of tokens.
|
||||
*
|
||||
* @param string $contents
|
||||
*
|
||||
* @return string[] A series of tokens of which the description text is composed.
|
||||
*/
|
||||
private function lex($contents)
|
||||
{
|
||||
$contents = $this->removeSuperfluousStartingWhitespace($contents);
|
||||
|
||||
// performance optimalization; if there is no inline tag, don't bother splitting it up.
|
||||
if (strpos($contents, '{@') === false) {
|
||||
return [$contents];
|
||||
@@ -98,7 +120,8 @@ class DescriptionFactory
|
||||
{
|
||||
$count = count($tokens);
|
||||
$tagCount = 0;
|
||||
$tags = [];
|
||||
$tags = [];
|
||||
|
||||
for ($i = 1; $i < $count; $i += 2) {
|
||||
$tags[] = $this->tagFactory->create($tokens[$i], $context);
|
||||
$tokens[$i] = '%' . ++$tagCount . '$s';
|
||||
@@ -114,4 +137,55 @@ class DescriptionFactory
|
||||
return [implode('', $tokens), $tags];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the superfluous from a multi-line description.
|
||||
*
|
||||
* When a description has more than one line then it can happen that the second and subsequent lines have an
|
||||
* additional indentation. This is commonly in use with tags like this:
|
||||
*
|
||||
* {@}since 1.1.0 This is an example
|
||||
* description where we have an
|
||||
* indentation in the second and
|
||||
* subsequent lines.
|
||||
*
|
||||
* If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent
|
||||
* lines and this may cause rendering issues when, for example, using a Markdown converter.
|
||||
*
|
||||
* @param string $contents
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function removeSuperfluousStartingWhitespace($contents)
|
||||
{
|
||||
$lines = explode("\n", $contents);
|
||||
|
||||
// if there is only one line then we don't have lines with superfluous whitespace and
|
||||
// can use the contents as-is
|
||||
if (count($lines) <= 1) {
|
||||
return $contents;
|
||||
}
|
||||
|
||||
// determine how many whitespace characters need to be stripped
|
||||
$startingSpaceCount = 9999999;
|
||||
for ($i = 1; $i < count($lines); $i++) {
|
||||
// lines with a no length do not count as they are not indented at all
|
||||
if (strlen(trim($lines[$i])) === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// determine the number of prefixing spaces by checking the difference in line length before and after
|
||||
// an ltrim
|
||||
$startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i])));
|
||||
}
|
||||
|
||||
// strip the number of spaces from each line
|
||||
if ($startingSpaceCount > 0) {
|
||||
for ($i = 1; $i < count($lines); $i++) {
|
||||
$lines[$i] = substr($lines[$i], $startingSpaceCount);
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user