今回はピュアなPHPで実装する必要があったので 「php-markdown」を使ったMarkDown 処理を試してみました。
Composer で michelf/php-markdown をインストールします。
% composer require michelf/php-markdown
単純にマークダウンを使うときは、Markdown で大丈夫ですが、コードブロックの pre, code タグに対応していません。
use Michelf\Markdown;
コードブロックに対応するには、MarkdownExtra を利用します。
use Michelf\MarkdownExtra;
MarkDown を HTML に変換するのはこれだけです。
$markdown = new MarkdownExtra();
$content = $markdown->transform($content);
ただ、 prism.js にも対応させたいので code_class_prefix に language- をつけておきます。関数とかにまとめるとこんな感じです。
function markdownToHtml($content){
$markdown = new MarkdownExtra();
$markdown->code_class_prefix = 'language-';
return $markdown->transform($content);
}
//マークダウン文章
$markdown = "
``` php
function hoge($value)
{
return $value;
}
```
";
//HTMLに変換
$html = markdownToHtml($markdown);
これはマニュアルに載ってないので MarkdownExtra のソースコードを調べてみました。 $matches は文章に正規表現をかけた配列で、クラス名は index=2 にマッチします。あとは、 $code_class_prefix をくっつけてますね。
protected function _doFencedCodeBlocks_callback($matches) {
$classname =& $matches[2];
$attrs =& $matches[3];
$codeblock = $matches[4];
if ($this->code_block_content_func) {
$codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname);
} else {
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
}
$codeblock = preg_replace_callback('/^\n+/',
array($this, '_doFencedCodeBlocks_newlines'), $codeblock);
$classes = array();
if ($classname !== "") {
if ($classname[0] === '.') {
$classname = substr($classname, 1);
}
$classes[] = $this->code_class_prefix . $classname;
}
$attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes);
$pre_attr_str = $this->code_attr_on_pre ? $attr_str : '';
$code_attr_str = $this->code_attr_on_pre ? '' : $attr_str;
$codeblock = "<pre$pre_attr_str><code$code_attr_str>$codeblock</code></pre>";
return "\n\n".$this->hashBlock($codeblock)."\n\n";
}