A Description object can consist of plain text but can also include tags. A Description Formatter can then combine
a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete
description text using the format that you would prefer.
Because parsing a Description text can be a verbose process this is handled by the {@see \DescriptionFactory}. It is
thus recommended to use that to create a Description object, like this:
$description = $descriptionFactory->create('This is a {@see \Description}', $context);
The description factory will interpret the given body and create a body template and list of tags from them, and pass
that onto the constructor if this class.
> The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace
> and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial
> type names and FQSENs.
If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this:
$description = new Description(
'This is a %1$s',
[ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ]
);
It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object
is mainly responsible for rendering.
/** * @covers ::__construct * @covers ::render * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter */ public function testDescriptionCanRenderUsingABodyWithPlaceholdersAndTags() { $body = 'This is a %1$s body.'; $expected = 'This is a {@internal significant } body.'; $tags = [new Generic('internal', new Description('significant '))]; $fixture = new Description($body, $tags); // without formatter (thus the PassthroughFormatter by default) $this->assertSame($expected, $fixture->render()); // with a custom formatter $formatter = m::mock(PassthroughFormatter::class); $formatter->shouldReceive('format')->with($tags[0])->andReturn('@internal significant '); $this->assertSame($expected, $fixture->render($formatter)); }
private function buildDescription($docBlock, $content = null) { if ($content === null) { $content = $docBlock->getText(); } $desc = new Description($content, $docBlock); $parsedContents = $desc->getParsedContents(); if (count($parsedContents) > 1) { // convert inline {@see} tag to custom type link foreach ($parsedContents as &$part) { if ($part instanceof Seetag) { $reference = $part->getReference(); if (substr_compare($reference, 'Google\\Cloud', 0, 12) === 0) { $part = $this->buildLink($reference); } } } $content = implode('', $parsedContents); } $content = str_ireplace('[optional]', '', $content); return $this->markdown->parse($content); }
/** * Gets the parsed text of this description. * * @return array An array of strings and tag objects, in the order they * occur within the description. */ public function getParsedDescription() { if (null === $this->parsedDescription) { $description = new Description($this->description, $this->docblock); $this->parsedDescription = $description->getParsedContents(); } return $this->parsedDescription; }