1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\apidoc\helpers;
use cebe\markdown\GithubMarkdown;
use yii\apidoc\models\TypeDoc;
use yii\apidoc\renderers\BaseRenderer;
use yii\helpers\Inflector;
use yii\helpers\Markdown;
/**
* A Markdown helper with support for class reference links.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class ApiMarkdown extends GithubMarkdown
{
use ApiMarkdownTrait;
/**
* @var BaseRenderer
*/
public static $renderer;
protected $renderingContext;
/**
* @inheritdoc
*/
protected function renderCode($block)
{
if (isset($block['language'])) {
$class = isset($block['language']) ? ' class="language-' . $block['language'] . '"' : '';
return "<pre><code$class>" . $this->highlight($block['content'] . "\n", $block['language']) . "</code></pre>\n";
} else {
return parent::renderCode($block);
}
}
/**
* Highlights code
*
* @param string $code code to highlight
* @param string $language language of the code to highlight
* @return string HTML of highlighted code
*/
public static function highlight($code, $language)
{
if ($language !== 'php') {
return htmlspecialchars($code, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
// TODO improve code highlighting
if (strncmp($code, '<?php', 5) === 0) {
$text = @highlight_string(trim($code), true);
} else {
$text = highlight_string("<?php ".trim($code), true);
$text = str_replace('<?php', '', $text);
if (($pos = strpos($text, ' ')) !== false) {
$text = substr($text, 0, $pos) . substr($text, $pos + 6);
}
}
// remove <code><span style="color: #000000">\n and </span>tags added by php
$text = substr(trim($text), 36, -16);
return $text;
}
/**
* @inheritDoc
*/
protected function renderHeadline($block)
{
$content = $this->renderAbsy($block['content']);
$hash = Inflector::slug(strip_tags($content));
$hashLink = "<a href=\"#$hash\" id=\"$hash\" class=\"hashlink\">¶</a>";
$tag = 'h' . $block['level'];
return "<$tag>$content $hashLink</$tag>";
}
/**
* @inheritdoc
*/
protected function renderLink($block)
{
$result = parent::renderLink($block);
// add special syntax for linking to the guide
$result = preg_replace_callback('/href="guide:([A-z0-9-.#]+)"/i', function($match) {
return 'href="' . static::$renderer->generateGuideUrl($match[1]) . '"';
}, $result, 1);
return $result;
}
/**
* Converts markdown into HTML
*
* @param string $content
* @param TypeDoc $context
* @param boolean $paragraph
* @return string
*/
public static function process($content, $context = null, $paragraph = false)
{
if (!isset(Markdown::$flavors['api'])) {
Markdown::$flavors['api'] = new static;
}
if (is_string($context)) {
$context = static::$renderer->apiContext->getType($context);
}
Markdown::$flavors['api']->renderingContext = $context;
if ($paragraph) {
return Markdown::processParagraph($content, 'api');
} else {
return Markdown::process($content, 'api');
}
}
}