# Class yii\apidoc\helpers\ApiMarkdown

Inheritance | yii\apidoc\helpers\ApiMarkdown » cebe\markdown\GithubMarkdown
Uses Traits | yii\apidoc\helpers\ApiMarkdownTrait, yii\apidoc\helpers\MarkdownHighlightTrait
Available since version | 2.0
Source Code | https://github.com/yiisoft/yii2-apidoc/blob/master/helpers/ApiMarkdown.php

A Markdown helper with support for class reference links.

## Public Properties

Hide inherited properties

Property | Type | Description | Defined By
--- | --- | --- | ---
$blockTranslations | array | Translation for guide block types | yii\apidoc\helpers\ApiMarkdown
$headings |  |  | yii\apidoc\helpers\ApiMarkdown
$renderer | yii\apidoc\renderers\BaseRenderer |  | yii\apidoc\helpers\ApiMarkdown
$renderingContext |  |  | yii\apidoc\helpers\ApiMarkdown

## Protected Properties

Hide inherited properties

Property | Type | Description | Defined By
--- | --- | --- | ---

## Public Methods

Hide inherited methods

Method | Description | Defined By
--- | --- | ---
getHeadings() |  | yii\apidoc\helpers\ApiMarkdown
highlight() | Highlights code | yii\apidoc\helpers\MarkdownHighlightTrait
parse() |  | yii\apidoc\helpers\ApiMarkdown
process() | Converts markdown into HTML | yii\apidoc\helpers\ApiMarkdown
renderTable() | Add bootstrap classes to tables. | yii\apidoc\helpers\ApiMarkdown

## Protected Methods

Hide inherited methods

Method | Description | Defined By
--- | --- | ---
applyToc() |  | yii\apidoc\helpers\ApiMarkdown
consumeQuote() | Consume lines for a blockquote element | yii\apidoc\helpers\ApiMarkdownTrait
parseApiLinkForContext() | Attempts to parse an API link for the given context. | yii\apidoc\helpers\ApiMarkdownTrait
parseApiLinks() |  | yii\apidoc\helpers\ApiMarkdownTrait
prepare() |  | yii\apidoc\helpers\ApiMarkdown
renderApiLink() | Renders API link | yii\apidoc\helpers\ApiMarkdownTrait
renderApiLinkText() |  | yii\apidoc\helpers\ApiMarkdownTrait
renderBrokenApiLink() | Renders API link that is broken i.e. points nowhere | yii\apidoc\helpers\ApiMarkdownTrait
renderCode() |  | yii\apidoc\helpers\MarkdownHighlightTrait
renderHeadline() |  | yii\apidoc\helpers\ApiMarkdown
renderLink() |  | yii\apidoc\helpers\ApiMarkdown
renderQuote() | Renders a blockquote | yii\apidoc\helpers\ApiMarkdownTrait
translateBlockType() |  | yii\apidoc\helpers\ApiMarkdown

## Property Details

Hide inherited properties

$blockTranslations public static property (available since version 2.0.5)

Translation for guide block types

public static array $blockTranslations = []
$headings protected property
protected $headings = []
$renderer public static property
public static yii\apidoc\renderers\BaseRenderer $renderer = null
$renderingContext protected property
protected $renderingContext = null

## Method Details

Hide inherited methods

applyToc() protected method (available since version 2.0.5)

protected void applyToc ( $content )
$content |  |

Source code

consumeQuote() protected method

Defined in: yii\apidoc\helpers\ApiMarkdownTrait::consumeQuote()

Consume lines for a blockquote element

protected void consumeQuote ( $lines, $current )
$lines |  |
$current |  |

Source code

                    protected function consumeQuote($lines, $current)
    {
        $block = parent::consumeQuote($lines, $current);
        $blockTypes = [
            'warning',
            'note',
            'info',
            'tip',
        ];
        // check whether this is a special Info, Note, Warning, Tip block
        $content = $block[0]['content'];
        $first = reset($content);
        if (isset($first[0]) && $first[0] === 'paragraph') {
            $parfirst = reset($first['content']);
            if (isset($parfirst[0]) && $parfirst[0] === 'text') {
                foreach ($blockTypes as $type) {
                    if (strncasecmp("$type: ", $parfirst[1], $len = strlen($type) + 2) === 0) {
                        // remove block indicator
                        $block[0]['content'][0]['content'][0][1] = substr($parfirst[1], $len);
                        // add translated block indicator as bold text
                        array_unshift($block[0]['content'][0]['content'], [
                            'strong',
                            [
                                ['text', $this->translateBlockType($type)],
                            ],
                        ]);
                        $block[0]['blocktype'] = $type;
                        break;
                    }
                }
            }
        }
        return $block;
    }

getHeadings() public method (available since version 2.0.5)

public array getHeadings ( )
return | array | The headlines of this document

Source code

                    public function getHeadings()
    {
        return $this->headings;
    }

highlight() public static method

Defined in: yii\apidoc\helpers\MarkdownHighlightTrait::highlight()

Highlights code

public static string highlight ( $code, $language )
$code | string | Code to highlight
$language | string | Language of the code to highlight
return | string | HTML of highlighted code

Source code

                    public static function highlight($code, $language)
    {
        if ($language !== 'php') {
            return htmlspecialchars($code, ENT_NOQUOTES | ENT_SUBSTITUTE);
        }
        if (strncmp($code, '<?php', 5) === 0) {
            $text = @highlight_string(trim($code), true);
        } else {
            $text = highlight_string("<?php " . trim($code), true);
            $text = str_replace('&lt;?php', '', $text);
            if (($pos = strpos($text, '&nbsp;')) !== 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;
    }

parse() public method

public void parse ( $text )
$text |  |

Source code

                    public function parse($text)
    {
        $markup = parent::parse($text);
        $markup = $this->applyToc($markup);
        return $markup;
    }

parseApiLinkForContext() protected method (available since version 2.1.3)

Defined in: yii\apidoc\helpers\ApiMarkdownTrait::parseApiLinkForContext()

Attempts to parse an API link for the given context.

protected array parseApiLinkForContext ( $offset, $object, $title, $context )
$offset | integer |
$object | string |
$title | string|null |
$context | yii\apidoc\models\TypeDoc|null |
throws | yii\apidoc\helpers\BrokenLinkException | if the object can't be resolved

Source code

                    protected function parseApiLinkForContext($offset, $object, $title, $context)
    {
        if (($pos = strpos($object, '::')) !== false) {
            $typeName = substr($object, 0, $pos);
            $subjectName = substr($object, $pos + 2);
            if ($context !== null) {
                if (!$context->phpDocContext) {
                    throw new BrokenLinkException($object, $context);
                }
                if (isset($context->phpDocContext->getNamespaceAliases()[$typeName])) {
                    $typeName = $context->phpDocContext->getNamespaceAliases()[$typeName];
                } else {
                    $typeName = $context->phpDocContext->getNamespace() . '\\' . $typeName;
                }
            }
            /** @var $type TypeDoc */
            $type = static::$renderer->apiContext->getType($typeName);
            if ($type === null || $subjectName === '') {
                throw new BrokenLinkException($typeName . '::' . $subjectName, $context);
            }
            if (($subject = $type->findSubject($subjectName)) === null) {
                throw new BrokenLinkException($type->name . '::' . $subjectName, $context);
            }
            if ($title === null) {
                $title = $type->name . '::' . $subject->name;
                if ($subject instanceof MethodDoc) {
                    $title .= '()';
                }
            }
            return [
                ['apiLink', static::$renderer->createSubjectLink($subject, $title)],
                $offset
            ];
        }
        if ($context !== null) {
            if (($subject = $context->findSubject($object)) !== null) {
                return [
                    ['apiLink', static::$renderer->createSubjectLink($subject, $title)],
                    $offset
                ];
            }
            if (!$context->phpDocContext) {
                throw new BrokenLinkException($object, $context);
            }
            if (isset($context->phpDocContext->getNamespaceAliases()[$object])) {
                $object = $context->phpDocContext->getNamespaceAliases()[$object];
            } else {
                $object = $context->phpDocContext->getNamespace() . '\\' . $object;
            }
        }
        if (($type = static::$renderer->apiContext->getType($object)) !== null) {
            return [
                ['apiLink', static::$renderer->createTypeLink($type, null, $title)],
                $offset
            ];
        }
        if (strpos($typeLink = static::$renderer->createTypeLink($object, null, $title), '<a href') !== false) {
            return [
                ['apiLink', $typeLink],
                $offset
            ];
        }
        throw new BrokenLinkException($object, $context);
    }

parseApiLinks() protected method

Defined in: yii\apidoc\helpers\ApiMarkdownTrait::parseApiLinks()

protected void parseApiLinks ( $text )
$text |  |

Source code

                    protected function parseApiLinks($text)
    {
        if (!preg_match('/^\[\[([\w\d\\\\():$]+)(\|[^]]*)?]]/', $text, $matches)) {
            return [['text', '[['], 2];
        }
        $offset = strlen($matches[0]);
        $object = $matches[1];
        $title = (empty($matches[2]) || $matches[2] === '|') ? null : substr($matches[2], 1);
        $title = $this->renderApiLinkText($title);
        /** @var TypeDoc[] $contexts */
        $contexts = [];
        $this->_findContexts($this->renderingContext, $contexts);
        $contexts = array_unique($contexts, SORT_REGULAR);
        $contexts[] = null;
        $e = null;
        foreach ($contexts as $context) {
            /** @var TypeDoc|null $context */
            try {
                return $this->parseApiLinkForContext($offset, $object, $title, $context);
            } catch (BrokenLinkException $e) {
                // Keep going if there are more contexts to check
            }
        }
        // If we made it this far, there was a broken link
        /** @var BrokenLinkException $e */
        static::$renderer->apiContext->errors[] = [
            'file' => ($e->context !== null) ? $e->context->sourceFile : null,
            'message' => $e->getMessage(),
        ];
        return [
            ['brokenApiLink', '<span class="broken-link">' . $object . '</span>'],
            $offset
        ];
    }

prepare() protected method

protected void prepare ( )

Source code

                    protected function prepare()
    {
        parent::prepare();
        $this->headings = [];
    }

process() public static method

Converts markdown into HTML

public static string process ( $content, $context = null, $paragraph = false )
$content | string |
$context | yii\apidoc\models\TypeDoc |
$paragraph | boolean |

Source code

                    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');
        }
    }

renderApiLink() protected method

Defined in: yii\apidoc\helpers\ApiMarkdownTrait::renderApiLink()

Renders API link

protected string renderApiLink ( $block )
$block | array |

Source code

                    protected function renderApiLink($block)
    {
        return $block[1];
    }

renderApiLinkText() protected method

Defined in: yii\apidoc\helpers\ApiMarkdownTrait::renderApiLinkText()

protected null|string renderApiLinkText ( $title )
$title | null|string |

Source code

                    protected function renderApiLinkText($title)
    {
        if (!$title) {
            return $title;
        }
        $title = Markdown::process($title);
        $title = mb_convert_encoding($title, 'HTML-ENTITIES', 'UTF-8');
        $doc = new DOMDocument();
        $doc->loadHTML($title);
        return $doc->getElementsByTagName('p')[0]->childNodes[0]->c14n();
    }

renderBrokenApiLink() protected method

Defined in: yii\apidoc\helpers\ApiMarkdownTrait::renderBrokenApiLink()

Renders API link that is broken i.e. points nowhere

protected string renderBrokenApiLink ( $block )
$block | array |

Source code

                    protected function renderBrokenApiLink($block)
    {
        return $block[1];
    }

renderCode() protected method

Defined in: yii\apidoc\helpers\MarkdownHighlightTrait::renderCode()

protected void renderCode ( $block )
$block |  |

Source code

                    protected function renderCode($block)
    {
        if (self::$highlighter === null) {
            self::$highlighter = new Highlighter();
            self::$highlighter->setAutodetectLanguages([
                'apache', 'nginx',
                'bash', 'dockerfile', 'http',
                'css', 'less', 'scss',
                'javascript', 'json', 'markdown',
                'php', 'sql', 'twig', 'xml',
            ]);
        }
        try {
            if (isset($block['language'])) {
                if ($block['language'] === 'php' && strpos($block['content'], '<?=') !== false) {
                    $block['language'] = 'html';
                }
                $result = self::$highlighter->highlight($block['language'], $block['content'] . "\n");
                return "<pre><code class=\"hljs {$result->language} language-{$block['language']}\">{$result->value}</code></pre>\n";
            } else {
                $result = self::$highlighter->highlightAuto($block['content'] . "\n");
                return "<pre><code class=\"hljs {$result->language}\">{$result->value}</code></pre>\n";
            }
        } catch (DomainException $e) {
            return parent::renderCode($block);
        }
    }

renderHeadline() protected method

protected void renderHeadline ( $block )
$block |  |

Source code

                    protected function renderHeadline($block)
    {
        $content = $this->renderAbsy($block['content']);
        if (preg_match('~<span id="(.*?)"></span>~', $content, $matches)) {
            $hash = $matches[1];
            $content = preg_replace('~<span id=".*?"></span>~', '', $content);
        } else {
            $hash = Inflector::slug(strip_tags($content));
        }
        $hashLink = "<span id=\"$hash\"></span><a href=\"#$hash\" class=\"hashlink\">&para;</a>";
        if ($block['level'] == 2) {
            $this->headings[] = [
                'title' => trim($content),
                'id' => $hash,
            ];
        } elseif ($block['level'] > 2) {
            if (end($this->headings)) {
                $this->headings[key($this->headings)]['sub'][] = [
                    'title' => trim($content),
                    'id' => $hash,
                ];
            }
        }
        $tag = 'h' . $block['level'];
        return "<$tag>$content $hashLink</$tag>";
    }

renderLink() protected method

protected void renderLink ( $block )
$block |  |

Source code

                    protected function renderLink($block)
    {
        $url = $block['url'];
        if (!$url) {
            static::$renderer->apiContext->errors[] = [
                'line' => null,
                'file' => null,
                'message' => "Using empty link.",
            ];
            return parent::renderLink($block);
        }
        $linkHtml = parent::renderLink($block);
        // add special syntax for linking to the guide
        $guideLinkHtml = preg_replace_callback('/href="guide:([A-z0-9-.#]+)"/i', function ($matches) {
            return 'href="' . static::$renderer->generateGuideUrl($matches[1]) . '"';
        }, $linkHtml, 1);
        if ($guideLinkHtml !== $linkHtml) {
            return $guideLinkHtml;
        }
        if (!property_exists(static::$renderer, 'repoUrl')) {
            return $linkHtml;
        }
        $repoUrl = static::$renderer->repoUrl;
        if (!$repoUrl) {
            static::$renderer->apiContext->errors[] = [
                'line' => null,
                'file' => null,
                'message' => "Using relative link ($url) but repoUrl is not set.",
            ];
            return $linkHtml;
        }
        return preg_replace_callback('/href="(.+)"/i', function ($matches) use ($repoUrl) {
            return 'href="' . $repoUrl . '/' . $matches[1] . '"';
        }, $linkHtml, 1);
    }

renderQuote() protected method

Defined in: yii\apidoc\helpers\ApiMarkdownTrait::renderQuote()

Renders a blockquote

protected void renderQuote ( $block )
$block |  |

Source code

                    protected function renderQuote($block)
    {
        $class = '';
        if (isset($block['blocktype'])) {
            $class = ' class="' . $block['blocktype'] . '"';
        }
        return "<blockquote{$class}>" . $this->renderAbsy($block['content']) . "</blockquote>\n";
    }

renderTable() public method

Add bootstrap classes to tables.

public void renderTable ( $block )
$block |  |

Source code

                    public function renderTable($block)
    {
        return str_replace('<table>', '<table class="table table-bordered table-striped">', parent::renderTable($block));
    }

translateBlockType() protected method (available since version 2.0.5)

protected void translateBlockType ( $type )
$type |  |

Source code

                    protected function translateBlockType($type)
    {
        $key = ucfirst($type) . ':';
        if (isset(static::$blockTranslations[$key])) {
            $translation = static::$blockTranslations[$key];
        } else {
            $translation = $key;
        }
        return "$translation ";
    }