Commit 29753b3e by Carsten Brandt

apidocs: use erusev/parsedown for markdown parsing

added quick and dirty code highlighing and got much faster
parent 62290c13
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
"require": { "require": {
"yiisoft/yii2": "*", "yiisoft/yii2": "*",
"yiisoft/yii2-bootstrap": "*", "yiisoft/yii2-bootstrap": "*",
"phpdocumentor/reflection": "dev-master | >1.0.2" "phpdocumentor/reflection": "dev-master | >1.0.2",
"erusev/parsedown": "0.9.*"
}, },
"autoload": { "autoload": {
"psr-4": { "yii\\apidoc\\": "" } "psr-4": { "yii\\apidoc\\": "" }
......
...@@ -7,10 +7,8 @@ ...@@ -7,10 +7,8 @@
namespace yii\apidoc\helpers; namespace yii\apidoc\helpers;
use phpDocumentor\Reflection\DocBlock\Type\Collection; use Parsedown;
use yii\apidoc\models\MethodDoc; use yii\base\Component;
use yii\apidoc\models\TypeDoc;
use yii\apidoc\templates\BaseRenderer;
/** /**
* A Markdown helper with support for class reference links. * A Markdown helper with support for class reference links.
...@@ -18,83 +16,45 @@ use yii\apidoc\templates\BaseRenderer; ...@@ -18,83 +16,45 @@ use yii\apidoc\templates\BaseRenderer;
* @author Carsten Brandt <mail@cebe.cc> * @author Carsten Brandt <mail@cebe.cc>
* @since 2.0 * @since 2.0
*/ */
class Markdown extends \yii\helpers\Markdown class Markdown extends Component
{ {
/** private $_parseDown;
* @var BaseRenderer
*/
public static $renderer;
/** protected function getParseDown()
* Converts markdown into HTML
*
* @param string $content
* @param TypeDoc $context
* @return string
*/
public static function process($content, $context = null)
{ {
if (is_string($context)) { if ($this->_parseDown === null) {
$context = static::$renderer->context->getType($context); $this->_parseDown = new ParseDown();
} }
return $this->_parseDown;
$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\\\\\(\):$]+)(\|[^\]]*)?\]\]/xm', function($matches) use ($context) { public function parse($markdown)
$object = $matches[1]; {
$title = (empty($matches[2]) || $matches[2] == '|') ? null : substr($matches[2], 1); return $this->getParseDown()->parse($markdown);
if (($pos = strpos($object, '::')) !== false) {
$typeName = substr($object, 0, $pos);
$subjectName = substr($object, $pos + 2);
if ($context !== null) {
// Collection resolves relative types
$typeName = (new Collection([$typeName], $context->phpDocContext))->__toString();
}
$type = static::$renderer->context->getType($typeName);
if ($type === null) {
static::$renderer->context->errors[] = [
'file' => ($context !== null) ? $context->sourceFile : null,
'message' => 'broken link to ' . $typeName . '::' . $subjectName . (($context !== null) ? ' in ' . $context->name : ''),
];
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 {
static::$renderer->context->errors[] = [
'file' => ($context !== null) ? $context->sourceFile : null,
'message' => 'broken link to ' . $type->name . '::' . $subjectName . (($context !== null) ? ' in ' . $context->name : ''),
];
return '<span style="background: #ff0;">' . $type->name . '</span><span style="background: #f00;">::' . $subjectName . '</span>';
} }
public function parseLine($markdown)
{
return $this->getParseDown()->parseLine($markdown);
} }
} elseif ($context !== null && ($subject = $context->findSubject($object)) !== null) {
return static::$renderer->subjectLink($subject, $title); public function registerBlockHander($blockName, $callback)
{
$this->getParseDown()->register_block_handler($blockName, $callback);
} }
if ($context !== null) {
// Collection resolves relative types public function unregisterBlockHander($blockName)
$object = (new Collection([$object], $context->phpDocContext))->__toString(); {
$this->getParseDown()->remove_block_handler($blockName);
} }
if (($type = static::$renderer->context->getType($object)) !== null) {
return static::$renderer->typeLink($type, $title); public function registerInlineMarkerHandler($marker, $callback)
{
$this->getParseDown()->add_span_marker($marker, $callback);
} }
static::$renderer->context->errors[] = [
'file' => ($context !== null) ? $context->sourceFile : null,
'message' => 'broken link to ' . $object . (($context !== null) ? ' in ' . $context->name : ''),
];
return '<span style="background: #f00;">' . $object . '</span>';
}, $content);
return $content; public function unregisterInlineMarkerHandler($marker)
{
$this->getParseDown()->remove_span_marker($marker);
} }
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*/ */
namespace yii\apidoc\templates\bootstrap; namespace yii\apidoc\templates\bootstrap;
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\Context; use yii\apidoc\models\Context;
use yii\console\Controller; use yii\console\Controller;
use Yii; use Yii;
...@@ -145,7 +145,7 @@ class Renderer extends \yii\apidoc\templates\html\Renderer ...@@ -145,7 +145,7 @@ class Renderer extends \yii\apidoc\templates\html\Renderer
mkdir($dir, 0777, true); mkdir($dir, 0777, true);
} }
Markdown::$renderer = $this; ApiMarkdown::$renderer = $this;
$fileCount = count($files) + 1; $fileCount = count($files) + 1;
Console::startProgress(0, $fileCount, 'Rendering markdown files: ', false); Console::startProgress(0, $fileCount, 'Rendering markdown files: ', false);
...@@ -165,7 +165,7 @@ class Renderer extends \yii\apidoc\templates\html\Renderer ...@@ -165,7 +165,7 @@ class Renderer extends \yii\apidoc\templates\html\Renderer
} }
foreach($fileData as $file => $content) { foreach($fileData as $file => $content) {
$output = Markdown::process($content); // TODO generate links to yiiframework.com by default $output = ApiMarkdown::process($content); // TODO generate links to yiiframework.com by default
$output = $this->fixMarkdownLinks($output); $output = $this->fixMarkdownLinks($output);
if ($this->guideLayout !== false) { if ($this->guideLayout !== false) {
$params = [ $params = [
......
...@@ -9,7 +9,7 @@ use yii\apidoc\models\TraitDoc; ...@@ -9,7 +9,7 @@ use yii\apidoc\models\TraitDoc;
*/ */
if (isset($readme)) { if (isset($readme)) {
echo \yii\apidoc\helpers\Markdown::process($readme); echo \yii\apidoc\helpers\ApiMarkdown::process($readme);
} }
?><h1>Class Reference</h1> ?><h1>Class Reference</h1>
...@@ -30,7 +30,7 @@ foreach($types as $i=>$class): ...@@ -30,7 +30,7 @@ foreach($types as $i=>$class):
?> ?>
<tr> <tr>
<td><?= $this->context->typeLink($class, $class->name) ?></td> <td><?= $this->context->typeLink($class, $class->name) ?></td>
<td><?= \yii\apidoc\helpers\Markdown::process($class->shortDescription, $class) ?></td> <td><?= \yii\apidoc\helpers\ApiMarkdown::process($class->shortDescription, $class, true) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</table> </table>
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
namespace yii\apidoc\templates\html; namespace yii\apidoc\templates\html;
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
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;
...@@ -65,7 +65,7 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface ...@@ -65,7 +65,7 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface
public function init() public function init()
{ {
Markdown::$renderer = $this; ApiMarkdown::$renderer = $this;
} }
/** /**
......
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
...@@ -33,7 +33,7 @@ ArrayHelper::multisort($constants, 'name'); ...@@ -33,7 +33,7 @@ ArrayHelper::multisort($constants, 'name');
<tr<?= $constant->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $constant->name ?>"> <tr<?= $constant->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $constant->name ?>">
<td><?= $constant->name ?><a name="<?= $constant->name ?>-detail"></a></td> <td><?= $constant->name ?><a name="<?= $constant->name ?>-detail"></a></td>
<td><?= $constant->value ?></td> <td><?= $constant->value ?></td>
<td><?= Markdown::process($constant->shortDescription . "\n" . $constant->description, $constant->definedBy) ?></td> <td><?= APiMarkdown::process($constant->shortDescription . "\n" . $constant->description, $constant->definedBy, true) ?></td>
<td><?= $this->context->typeLink($constant->definedBy) ?></td> <td><?= $this->context->typeLink($constant->definedBy) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
......
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
...@@ -32,7 +32,7 @@ ArrayHelper::multisort($events, 'name'); ...@@ -32,7 +32,7 @@ ArrayHelper::multisort($events, 'name');
<?php echo $event->trigger->signature; ?> <?php echo $event->trigger->signature; ?>
</div>*/ ?> </div>*/ ?>
<p><?= Markdown::process($event->description, $type); ?></p> <p><?= ApiMarkdown::process($event->description, $type); ?></p>
<?= $this->render('seeAlso', ['object' => $event]); ?> <?= $this->render('seeAlso', ['object' => $event]); ?>
......
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
...@@ -34,7 +34,7 @@ ArrayHelper::multisort($events, 'name'); ...@@ -34,7 +34,7 @@ ArrayHelper::multisort($events, 'name');
<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>
<?= Markdown::process($event->shortDescription, $event->definedBy) ?> <?= ApiMarkdown::process($event->shortDescription, $event->definedBy, true) ?>
<?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; ?>
......
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
...@@ -39,21 +39,21 @@ ArrayHelper::multisort($methods, 'name'); ...@@ -39,21 +39,21 @@ ArrayHelper::multisort($methods, 'name');
<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"><?= Markdown::process($param->description, $type) ?></td> <td class="paramDescCol"><?= ApiMarkdown::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"><?= Markdown::process($method->return, $type); ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($method->return, $type); ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
<?php foreach($method->exceptions as $exception => $description): ?> <?php foreach($method->exceptions as $exception => $description): ?>
<tr> <tr>
<td class="paramNameCol"><?= 'throws' ?></td> <td class="paramNameCol"><?= 'throws' ?></td>
<td class="paramTypeCol"><?= $this->context->typeLink($exception) ?></td> <td class="paramTypeCol"><?= $this->context->typeLink($exception) ?></td>
<td class="paramDescCol"><?= Markdown::process($description, $type) ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($description, $type) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
...@@ -61,8 +61,8 @@ ArrayHelper::multisort($methods, 'name'); ...@@ -61,8 +61,8 @@ ArrayHelper::multisort($methods, 'name');
<!-- --><?php //$this->renderPartial('sourceCode',array('object'=>$method)); ?> <!-- --><?php //$this->renderPartial('sourceCode',array('object'=>$method)); ?>
<p><?= Markdown::process($method->shortDescription, $type) ?></strong></p> <p><?= ApiMarkdown::process($method->shortDescription, $type, true) ?></strong></p>
<p><?= Markdown::process($method->description, $type) ?></p> <p><?= ApiMarkdown::process($method->description, $type) ?></p>
<?= $this->render('seeAlso', ['object' => $method]); ?> <?= $this->render('seeAlso', ['object' => $method]); ?>
......
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
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;
...@@ -37,7 +37,7 @@ foreach($methods as $method): ?> ...@@ -37,7 +37,7 @@ foreach($methods as $method): ?>
<?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><?= Markdown::process($method->shortDescription, $method->definedBy) ?></td> <td><?= ApiMarkdown::process($method->shortDescription, $method->definedBy, true) ?></td>
<td><?= $this->context->typeLink($method->definedBy, $type) ?></td> <td><?= $this->context->typeLink($method->definedBy, $type) ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
......
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
...@@ -34,7 +34,7 @@ ArrayHelper::multisort($properties, 'name'); ...@@ -34,7 +34,7 @@ ArrayHelper::multisort($properties, 'name');
<div class="signature"><?php echo $this->context->renderPropertySignature($property); ?></div> <div class="signature"><?php echo $this->context->renderPropertySignature($property); ?></div>
<p><?= Markdown::process($property->description, $type) ?></p> <p><?= ApiMarkdown::process($property->description, $type) ?></p>
<?= $this->render('seeAlso', ['object' => $property]); ?> <?= $this->render('seeAlso', ['object' => $property]); ?>
......
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc; use yii\apidoc\models\TraitDoc;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
...@@ -38,7 +38,7 @@ foreach($properties as $property): ?> ...@@ -38,7 +38,7 @@ foreach($properties as $property): ?>
<tr<?= $property->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $property->name ?>"> <tr<?= $property->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $property->name ?>">
<td><?= $this->context->subjectLink($property) ?></td> <td><?= $this->context->subjectLink($property) ?></td>
<td><?= $this->context->typeLink($property->types) ?></td> <td><?= $this->context->typeLink($property->types) ?></td>
<td><?= Markdown::process($property->shortDescription, $property->definedBy) ?></td> <td><?= ApiMarkdown::process($property->shortDescription, $property->definedBy, true) ?></td>
<td><?= $this->context->typeLink($property->definedBy) ?></td> <td><?= $this->context->typeLink($property->definedBy) ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
......
...@@ -25,7 +25,7 @@ if (empty($see)) { ...@@ -25,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><?= \yii\apidoc\helpers\Markdown::process($ref, $object->definedBy) ?></li> <li><?= \yii\apidoc\helpers\ApiMarkdown::process($ref, $object->definedBy, true) ?></li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
</div> </div>
<?php <?php
use yii\apidoc\helpers\Markdown; use yii\apidoc\helpers\ApiMarkdown;
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;
...@@ -77,8 +77,8 @@ $renderer = $this->context; ...@@ -77,8 +77,8 @@ $renderer = $this->context;
</table> </table>
<div id="classDescription"> <div id="classDescription">
<strong><?= Markdown::process($type->shortDescription, $type) ?></strong> <strong><?= ApiMarkdown::process($type->shortDescription, $type, true) ?></strong>
<p><?= Markdown::process($type->description, $type) ?></p> <p><?= ApiMarkdown::process($type->description, $type) ?></p>
</div> </div>
<a name="properties"></a> <a name="properties"></a>
......
...@@ -26,7 +26,7 @@ foreach($types as $i=>$class): ...@@ -26,7 +26,7 @@ foreach($types as $i=>$class):
?> ?>
<tr> <tr>
<td><?= $this->context->typeLink($class, $class->name) ?></td> <td><?= $this->context->typeLink($class, $class->name) ?></td>
<td><?= \yii\apidoc\helpers\Markdown::process($class->shortDescription, $class) ?></td> <td><?= \yii\apidoc\helpers\ApiMarkdown::process($class->shortDescription, $class, true) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</table> </table>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment