Browse Source

markdown support and links

tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
55f9111f47
  1. 76
      extensions/yii/apidoc/helpers/Markdown.php
  2. 9
      extensions/yii/apidoc/models/BaseDoc.php
  3. 18
      extensions/yii/apidoc/models/ClassDoc.php
  4. 2
      extensions/yii/apidoc/models/FunctionDoc.php
  5. 24
      extensions/yii/apidoc/models/TypeDoc.php
  6. 33
      extensions/yii/apidoc/templates/BaseRenderer.php
  7. 15
      extensions/yii/apidoc/templates/html/Renderer.php
  8. 3
      extensions/yii/apidoc/templates/html/views/constSummary.php
  9. 3
      extensions/yii/apidoc/templates/html/views/eventDetails.php
  10. 3
      extensions/yii/apidoc/templates/html/views/eventSummary.php
  11. 9
      extensions/yii/apidoc/templates/html/views/methodDetails.php
  12. 5
      extensions/yii/apidoc/templates/html/views/methodSummary.php
  13. 3
      extensions/yii/apidoc/templates/html/views/propertyDetails.php
  14. 9
      extensions/yii/apidoc/templates/html/views/propertySummary.php
  15. 9
      extensions/yii/apidoc/templates/html/views/seeAlso.php
  16. 7
      extensions/yii/apidoc/templates/html/views/type.php
  17. 6
      extensions/yii/apidoc/templates/offline/assets/css/api.css

76
extensions/yii/apidoc/helpers/Markdown.php

@ -0,0 +1,76 @@
<?php
/**
*
*
* @author Carsten Brandt <mail@cebe.cc>
*/
namespace yii\apidoc\helpers;
use phpDocumentor\Reflection\DocBlock\Type\Collection;
use yii\apidoc\models\MethodDoc;
use yii\apidoc\models\TypeDoc;
use yii\apidoc\templates\BaseRenderer;
use yii\helpers\Html;
class Markdown extends \yii\helpers\Markdown
{
/**
* @var BaseRenderer
*/
public static $renderer;
/**
* Converts markdown into HTML
*
* @param string $content
* @param TypeDoc $context
* @return string
*/
public static function process($content, $context)
{
$content = trim(parent::process($content, []));
if (!strncmp($content, '<p>', 3) && substr($content, -4, 4) == '</p>') {
$content = substr($content, 3, -4);
}
$content = preg_replace_callback('/\[\[([\w\d\\\\\(\):]+)(\|[\w\d ]*)?\]\]/xm', function($matches) use ($context) {
$object = $matches[1];
$title = (empty($matches[2]) || $matches[2] == '|') ? null : substr($matches[2], 1);
if (($pos = strpos($object, '::')) !== false) {
$typeName = substr($object, 0, $pos);
$subjectName = substr($object, $pos + 2);
// Collection resolves relative types
$typeName = (new Collection([$typeName], $context->phpDocContext))->__toString();
$type = static::$renderer->context->getType($typeName);
if ($type === null) {
return '<span style="background: #f00;">' . $typeName . '::' . $subjectName . '</span>';
} else {
if (($subject = $type->findSubject($subjectName)) !== null) {
if ($title === null) {
$title = $type->name . '::' . $subject->name;
if ($subject instanceof MethodDoc) {
$title .= '()';
}
}
return static::$renderer->subjectLink($subject, $title);
} else {
return '<span style="background: #ff0;">' . $type->name . '</span><span style="background: #f00;">::' . $subjectName . '</span>';
}
}
} elseif (($subject = $context->findSubject($object)) !== null) {
return static::$renderer->subjectLink($subject, $title);
}
// Collection resolves relative types
$object = (new Collection([$object], $context->phpDocContext))->__toString();
if (($type = static::$renderer->context->getType($object)) !== null) {
return static::$renderer->typeLink($type, $title);
}
return '<span style="background: #f00;">' . $object . '</span>';
}, $content);
return $content;
}
}

9
extensions/yii/apidoc/models/BaseDoc.php

@ -18,6 +18,11 @@ use yii\base\Object;
*/ */
class BaseDoc extends Object class BaseDoc extends Object
{ {
/**
* @var \phpDocumentor\Reflection\DocBlock\Context
*/
public $phpDocContext;
public $name; public $name;
public $sourceFile; public $sourceFile;
@ -55,9 +60,11 @@ class BaseDoc extends Object
$docblock = $reflector->getDocBlock(); $docblock = $reflector->getDocBlock();
if ($docblock !== null) { if ($docblock !== null) {
$this->shortDescription = $docblock->getShortDescription(); $this->shortDescription = ucfirst($docblock->getShortDescription());
$this->description = $docblock->getLongDescription(); $this->description = $docblock->getLongDescription();
$this->phpDocContext = $docblock->getContext();
$this->tags = $docblock->getTags(); $this->tags = $docblock->getTags();
foreach($this->tags as $i => $tag) { foreach($this->tags as $i => $tag) {
if ($tag instanceof SinceTag) { if ($tag instanceof SinceTag) {

18
extensions/yii/apidoc/models/ClassDoc.php

@ -34,6 +34,24 @@ class ClassDoc extends TypeDoc
public $constants = []; public $constants = [];
public function findSubject($subjectName)
{
if (($subject = parent::findSubject($subjectName)) !== null) {
return $subject;
}
foreach($this->events as $name => $event) {
if ($subjectName == $name) {
return $event;
}
}
foreach($this->constants as $name => $constant) {
if ($subjectName == $name) {
return $constant;
}
}
return null;
}
/** /**
* @return EventDoc[] * @return EventDoc[]
*/ */

2
extensions/yii/apidoc/models/FunctionDoc.php

@ -60,7 +60,7 @@ class FunctionDoc extends BaseDoc
if (!isset($this->params[$paramName])) { if (!isset($this->params[$paramName])) {
echo 'undefined parameter documented: ' . $paramName . ' in ' . $this->name . "\n"; // todo add this to a log file echo 'undefined parameter documented: ' . $paramName . ' in ' . $this->name . "\n"; // todo add this to a log file
} }
$this->params[$paramName]->description = $tag->getDescription(); $this->params[$paramName]->description = ucfirst($tag->getDescription());
$this->params[$paramName]->type = $tag->getType(); $this->params[$paramName]->type = $tag->getType();
$this->params[$paramName]->types = $tag->getTypes(); $this->params[$paramName]->types = $tag->getTypes();
unset($this->tags[$i]); unset($this->tags[$i]);

24
extensions/yii/apidoc/models/TypeDoc.php

@ -30,6 +30,30 @@ class TypeDoc extends BaseDoc
public $namespace; public $namespace;
public function findSubject($subjectName)
{
if ($subjectName[0] != '$') {
foreach($this->methods as $name => $method) {
if (rtrim($subjectName, '()') == $name) {
return $method;
}
}
}
if (substr($subjectName, -2, 2) == '()') {
return null;
}
if ($this->properties === null) {
return null;
}
foreach($this->properties as $name => $property) {
if (ltrim($subjectName, '$') == ltrim($name, '$')) {
return $property;
}
}
return null;
}
/** /**
* @return MethodDoc[] * @return MethodDoc[]
*/ */

33
extensions/yii/apidoc/templates/BaseRenderer.php vendored

@ -8,11 +8,16 @@
namespace yii\apidoc\templates; namespace yii\apidoc\templates;
use Yii; use Yii;
use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\ConstDoc;
use yii\apidoc\models\Context;
use yii\apidoc\models\EventDoc;
use yii\apidoc\models\InterfaceDoc;
use yii\apidoc\models\MethodDoc;
use yii\apidoc\models\PropertyDoc;
use yii\apidoc\models\TraitDoc;
use yii\base\Component; use yii\base\Component;
use yii\console\Controller; use yii\console\Controller;
use yii\apidoc\models\Context;
use yii\web\AssetManager;
use yii\web\View;
/** /**
* Base class for all API documentation renderers * Base class for all API documentation renderers
@ -23,10 +28,32 @@ use yii\web\View;
abstract class BaseRenderer extends Component abstract class BaseRenderer extends Component
{ {
/** /**
* @var Context the [[Context]] currently being rendered.
*/
public $context;
/**
* Renders a given [[Context]]. * Renders a given [[Context]].
* *
* @param Context $context the api documentation context to render. * @param Context $context the api documentation context to render.
* @param Controller $controller the apidoc controller instance. Can be used to control output. * @param Controller $controller the apidoc controller instance. Can be used to control output.
*/ */
public abstract function render($context, $controller); public abstract function render($context, $controller);
/**
* creates a link to a type (class, interface or trait)
* @param ClassDoc|InterfaceDoc|TraitDoc $types
* @param string $title
* @return string
*/
public abstract function typeLink($types, $title = null);
/**
* creates a link to a subject
* @param PropertyDoc|MethodDoc|ConstDoc|EventDoc $subject
* @param string $title
* @return string
*/
public abstract function subjectLink($subject, $title = null);
} }

15
extensions/yii/apidoc/templates/html/Renderer.php vendored

@ -7,6 +7,7 @@
namespace yii\apidoc\templates\html; namespace yii\apidoc\templates\html;
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\BaseDoc; use yii\apidoc\models\BaseDoc;
use yii\apidoc\models\ConstDoc; use yii\apidoc\models\ConstDoc;
use yii\apidoc\models\EventDoc; use yii\apidoc\models\EventDoc;
@ -55,14 +56,16 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface
*/ */
public $indexView = '@yii/apidoc/templates/html/views/index.php'; public $indexView = '@yii/apidoc/templates/html/views/index.php';
/** /**
* @var Context the [[Context]] currently being rendered.
*/
protected $context;
/**
* @var View * @var View
*/ */
private $_view; private $_view;
public function init()
{
Markdown::$renderer = $this;
}
/** /**
* @return View the view instance * @return View the view instance
*/ */
@ -179,8 +182,12 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface
public function subjectLink($subject, $title = null) public function subjectLink($subject, $title = null)
{ {
if ($title === null) { if ($title === null) {
if ($subject instanceof MethodDoc) {
$title = $subject->name . '()';
} else {
$title = $subject->name; $title = $subject->name;
} }
}
if (($type = $this->context->getType($subject->definedBy)) === null) { if (($type = $this->context->getType($subject->definedBy)) === null) {
return $subject->name; return $subject->name;
} else { } else {

3
extensions/yii/apidoc/templates/html/views/constSummary.php vendored

@ -1,5 +1,6 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
/** /**
* @var ClassDoc $type * @var ClassDoc $type
@ -27,7 +28,7 @@ if (empty($type->constants)) {
<tr<?= $constant->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $constant->name ?>"> <tr<?= $constant->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $constant->name ?>">
<td><?= $constant->name ?></td> <td><?= $constant->name ?></td>
<td><?= $constant->value ?></td> <td><?= $constant->value ?></td>
<td><?= nl2br($constant->shortDescription . "\n" . $constant->description) ?></td> <td><?= Markdown::process($constant->shortDescription . "\n" . $constant->description, $type) ?></td>
<td><?= $this->context->typeLink($constant->definedBy) ?></td> <td><?= $this->context->typeLink($constant->definedBy) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>

3
extensions/yii/apidoc/templates/html/views/eventDetails.php vendored

@ -1,5 +1,6 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
/** /**
* @var ClassDoc $type * @var ClassDoc $type
@ -27,7 +28,7 @@ if (empty($events)) {
<?php echo $event->trigger->signature; ?> <?php echo $event->trigger->signature; ?>
</div>*/ ?> </div>*/ ?>
<p><?php echo $event->description; ?></p> <p><?= Markdown::process($event->description, $type); ?></p>
<?= $this->render('seeAlso', ['object' => $event]); ?> <?= $this->render('seeAlso', ['object' => $event]); ?>

3
extensions/yii/apidoc/templates/html/views/eventSummary.php vendored

@ -1,5 +1,6 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
/** /**
* @var ClassDoc $type * @var ClassDoc $type
@ -28,7 +29,7 @@ if (empty($type->events)) {
<td><?= $this->context->subjectLink($event) ?></td> <td><?= $this->context->subjectLink($event) ?></td>
<td><?= $this->context->typeLink($event->types) ?></td> <td><?= $this->context->typeLink($event->types) ?></td>
<td> <td>
<?= $event->shortDescription ?> <?= Markdown::process($event->shortDescription, $type) ?>
<?php if(!empty($event->since)): ?> <?php if(!empty($event->since)): ?>
(available since version <?php echo $event->since; ?>) (available since version <?php echo $event->since; ?>)
<?php endif; ?> <?php endif; ?>

9
extensions/yii/apidoc/templates/html/views/methodDetails.php vendored

@ -1,5 +1,6 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
/** /**
@ -36,14 +37,14 @@ if (empty($methods)) {
<tr> <tr>
<td class="paramNameCol"><?= $param->name ?></td> <td class="paramNameCol"><?= $param->name ?></td>
<td class="paramTypeCol"><?= $this->context->typeLink($param->types) ?></td> <td class="paramTypeCol"><?= $this->context->typeLink($param->types) ?></td>
<td class="paramDescCol"><?= $param->description ?></td> <td class="paramDescCol"><?= Markdown::process($param->description, $type) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php if(!empty($method->return)): ?> <?php if(!empty($method->return)): ?>
<tr> <tr>
<td class="paramNameCol"><?= '{return}'; ?></td> <td class="paramNameCol"><?= '{return}'; ?></td>
<td class="paramTypeCol"><?= $this->context->typeLink($method->returnTypes); ?></td> <td class="paramTypeCol"><?= $this->context->typeLink($method->returnTypes); ?></td>
<td class="paramDescCol"><?= $method->return; ?></td> <td class="paramDescCol"><?= Markdown::process($method->return, $type); ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
<?php endif; ?> <?php endif; ?>
@ -51,8 +52,8 @@ if (empty($methods)) {
<!-- --><?php //$this->renderPartial('sourceCode',array('object'=>$method)); ?> <!-- --><?php //$this->renderPartial('sourceCode',array('object'=>$method)); ?>
<p><strong><?= $method->shortDescription ?></strong></p> <p><?= Markdown::process($method->shortDescription, $type) ?></strong></p>
<p><?= nl2br($method->description) ?></p> <p><?= Markdown::process($method->description, $type) ?></p>
<?= $this->render('seeAlso', ['object' => $method]); ?> <?= $this->render('seeAlso', ['object' => $method]); ?>

5
extensions/yii/apidoc/templates/html/views/methodSummary.php vendored

@ -1,5 +1,6 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\InterfaceDoc; use yii\apidoc\models\InterfaceDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
@ -31,8 +32,8 @@ if ($protected && count($type->getProtectedMethods()) == 0 || !$protected && cou
<?php if($protected && $method->visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> <?php if($protected && $method->visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?>
<tr<?= $method->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $method->name ?>()"> <tr<?= $method->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $method->name ?>()">
<td><?= $this->context->subjectLink($method, $method->name.'()') ?></td> <td><?= $this->context->subjectLink($method, $method->name.'()') ?></td>
<td><?= $method->shortDescription ?></td> <td><?= Markdown::process($method->shortDescription, $type) ?></td>
<td><?= $this->context->typeLink($method->definedBy) ?></td> <td><?= $this->context->typeLink($method->definedBy, $type) ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>

3
extensions/yii/apidoc/templates/html/views/propertyDetails.php vendored

@ -1,5 +1,6 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
/** /**
@ -31,7 +32,7 @@ if (empty($properties)) {
<?php echo $this->context->renderPropertySignature($property); ?> <?php echo $this->context->renderPropertySignature($property); ?>
</div> </div>
<p><?= nl2br($property->description) ?></p> <p><?= Markdown::process($property->description, $type) ?></p>
<?= $this->render('seeAlso', ['object' => $property]); ?> <?= $this->render('seeAlso', ['object' => $property]); ?>

9
extensions/yii/apidoc/templates/html/views/propertySummary.php vendored

@ -1,5 +1,6 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
/** /**
@ -30,10 +31,10 @@ if ($protected && count($type->getProtectedProperties()) == 0 || !$protected &&
<?php foreach($type->properties as $property): ?> <?php foreach($type->properties as $property): ?>
<?php if($protected && $property->visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?> <?php if($protected && $property->visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?>
<tr<?= $property->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $property->name ?>"> <tr<?= $property->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $property->name ?>">
<td><?php echo $this->context->subjectLink($property); ?></td> <td><?= $this->context->subjectLink($property) ?></td>
<td><?php echo $this->context->typeLink($property->types); ?></td> <td><?= $this->context->typeLink($property->types) ?></td>
<td><?php echo $property->shortDescription; ?></td> <td><?= Markdown::process($property->shortDescription, $type) ?></td>
<td><?php echo $this->context->typeLink($property->definedBy); ?></td> <td><?= $this->context->typeLink($property->definedBy) ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>

9
extensions/yii/apidoc/templates/html/views/seeAlso.php vendored

@ -9,7 +9,12 @@ $see = [];
foreach($object->tags as $tag) { foreach($object->tags as $tag) {
/** @var $tag phpDocumentor\Reflection\DocBlock\Tag\SeeTag */ /** @var $tag phpDocumentor\Reflection\DocBlock\Tag\SeeTag */
if (get_class($tag) == 'phpDocumentor\Reflection\DocBlock\Tag\SeeTag') { if (get_class($tag) == 'phpDocumentor\Reflection\DocBlock\Tag\SeeTag') {
$see[] = $tag->getReference(); $ref = $tag->getReference();
if (strpos($ref, '://') === false) {
$see[] = '[[' . $ref . ']]';
} else {
$see[] = $ref;
}
} }
} }
if (empty($see)) { if (empty($see)) {
@ -20,7 +25,7 @@ if (empty($see)) {
<h4>See Also</h4> <h4>See Also</h4>
<ul> <ul>
<?php foreach($see as $ref): ?> <?php foreach($see as $ref): ?>
<li><?= $ref ?></li> <li><?= \yii\apidoc\helpers\Markdown::process($ref, $this->context->context->getType($object->definedBy)) ?></li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
</div> </div>

7
extensions/yii/apidoc/templates/html/views/type.php vendored

@ -1,12 +1,13 @@
<?php <?php
use yii\apidoc\helpers\Markdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\InterfaceDoc; use yii\apidoc\models\InterfaceDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
/** /**
* @var ClassDoc|InterfaceDoc|TraitDoc $type * @var ClassDoc|InterfaceDoc|TraitDoc $type
* @var yii\web\View $this * @var yii\web\View $this
* @var \yii\apidoc\components\OfflineRenderer $renderer * @var \yii\apidoc\templates\html\Renderer $renderer
*/ */
$renderer = $this->context; $renderer = $this->context;
@ -76,8 +77,8 @@ $renderer = $this->context;
</table> </table>
<div id="classDescription"> <div id="classDescription">
<strong><?= $type->shortDescription ?></strong> <strong><?= Markdown::process($type->shortDescription, $type) ?></strong>
<p><?= nl2br($type->description) ?></p> <p><?= Markdown::process($type->description, $type) ?></p>
</div> </div>
<a name="properties"></a> <a name="properties"></a>

6
extensions/yii/apidoc/templates/offline/assets/css/api.css vendored

@ -17,6 +17,12 @@ pre {
border-left: 6px solid #FFE6BF; border-left: 6px solid #FFE6BF;
} }
code {
color: #000000;
background-color: #FFF5E6;
padding: 1px;
}
div.code { div.code {
display: none; display: none;
color: #000000; color: #000000;

Loading…
Cancel
Save