Qiita / Kobito 風MarkdownをPHPでうまくHTMLに出力するTips
Qiita の Markdown では、
```php:inc/hoge.php function hoge(){ echo "hoge"; } ```
と書くと、
inc/hoge.php ←ここは強調される function hoge(){ echo "hoge"; }
のように表示されます。
しかしPHPのMarkdownパーサーでこれを上手く表現できるものが見当たりませんでした。そこで PHP Markdown Extra で上記を表現するクイックハックをやってみたら上手くいったので、ここに載せておきます。
いろんなライブラリの中からこれを選択した理由は、DokuwikiのMarkdown Extraプラグイン
plugin:markdownextra [DokuWiki]
の内部で使っているものがこれだったからです。つまり、Qiita用に書いたMarkdownをそのままDokuwikiに貼り付けてきちんと表示されるようにする、というのが今回のミッションです。が、Dokuwikiを使っていなくてもPHPで上記を実現したいという人は、参考になると思いますので試してみて下さい。あくまでクイックハックですので元々実装されているコードブロックのclassやattrへの実装関係は完全に無視し、Qiita方言にのみ対応しています。
PHP Markdown Extra の改造
- まずは、PHP Markdown Extra からClassic version の PHP Markdown Extra 1.2.8 をダウンロードします。Dokuwiki の Markdown Extraプラグイン内で使用しているのは Classic version なのでLib版でなくこちらをダウンロードします。
- markdown.php の 2921行目からのdoFencedCodeBlocksと_doFencedCodeBlocks_callbackを以下のように書き換えます。
function doFencedCodeBlocks($text) { # # Adding the fenced code block syntax to regular Markdown: # # ~~~ # Code block # ~~~ # $less_than_tab = $this->tab_width; $text = preg_replace_callback('{ (?:\n|\A) # 1: Opening marker ( (?:~{3,}|`{3,}) # 3 or more tildes/backticks. ) [ ]* (?: \.?([-_a-zA-Z0-9]+) # 2: lang )? (:.*|) #3: filename [ ]* \n # Whitespace and newline following marker. # 4: Content ( (?> (?!\1 [ ]* \n) # Not a closing marker. .*\n+ )+ ) # Closing marker. \1 [ ]* (?= \n ) }xm', array(&$this, '_doFencedCodeBlocks_callback'), $text); return $text; } function _doFencedCodeBlocks_callback($matches) { $lang =& $matches[2]; $filename = substr($matches[3],1); if (trim($filename)!="") { $filename = "<div class=\"code-lang\">$filename</div>"; } $codeblock = $matches[4]; $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); $codeblock = preg_replace_callback('/^\n+/', array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock); $codeblock = "<div class=\"code-frame\" data-lang=\"$lang\">$filename<div class=\"highlight\"><pre>$codeblock</pre></div></div>"; return "\n\n".$this->hashBlock($codeblock)."\n\n"; }
- 変更点はこれだけです。
テスト
<?php require_once 'markdown.php'; $text = file_get_contents ('sample.md'); echo markdown($text)
Dokuwikiへの組み込み
Dokuwikiへの組み込みは以下の手順です。
- plugin:markdownextra [DokuWiki] をDokuwikiにインストールします。このプラグインは
で囲まれた範囲のみをMarkdownとしてパースするので、Dokuwikiルールでの記述と混在できて便利です。 - サーバ上のdokuwikiインストールディレクトリ配下の lib/plugins/markdownextra/markdown.php を上記のものに差し替えます。
以上です。プラグインマネージャで「更新」を行うと元の実装に戻ってしまうので注意して下さい。
その他のTIPS
Dokuwikiでmarkdownextraプラグインを使った箇所にスタイルを適用したい場合は、lib/plugins/markdownextra/syntax.phpの38行目あたり
function handle($match, $state, $pos, Doku_Handler $handler) { switch ($state) { case DOKU_LEXER_ENTER : return array($state, ''); case DOKU_LEXER_UNMATCHED : return array($state, '<div class="markdown">'.Markdown($match).'</div>'); //ここ case DOKU_LEXER_EXIT : return array($state, ''); } return array($state,''); }
にdivをつけてクラスを指定して下さい。あとはテーマのcssにdiv.markdownのスタイルを記述すればOKです。
ご質問、ご意見などあればお気軽にコメントどうぞ。