やりたいこと
PHPでMarkdownの文書をきれいなHTMLで表示させたかったので、自分なりにしっくりくるパターンを探してみた。
最終的にはBootstrapを使っているHTMLに組み込むので、多少の影響も受けると思いますが、ひとまず備忘録的に残しておきます。
使うもの
パーサ
何種類か試した結果Parsedownが一番しっくり来る感じ。
CSS
基本的には以下の2つをピックアップして使用します。
- https://raw.githubusercontent.com/mixu/markdown-styles/master/layouts/github/assets/css/github-markdown.css
- https://raw.githubusercontent.com/mixu/markdown-styles/master/layouts/github/assets/css/hljs-github.min.css
これに加えてhighlight.jsのCSSを使います。
Syntax Highlight
ダウンロードしたパッケージ含まれるhighlight.pack.js
とstyles/default.css
を使います。
最終的なフォーマット
上記をダウンロードするなどして最終的にまとめた感じが以下になります。
<?php
require_once(__DIR__ . '/parsedown/Parsedown.php');
$parser = new Parsedown();
$content = $parser->text(file_get_contents(__DIR__ . '/README.md'));
?>
<html lang="ja-jp">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="generator" content="Joomla! - Open Source Content Management" />
<title>tom-gs.com - HOME</title>
<link href="assets/css/github-markdown.css" rel="stylesheet" />
<link href="assets/css/hljs-github.min.css" rel="stylesheet" />
<link href="assets/scripts/highlight.js/styles/default.css" rel="stylesheet" />
<script src="assets/scripts/highlight.js/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body>
<div class="markdown-body markdown"><?php echo $content; ?></div>
</body>
</html>
2016.12.02追記
見出しのアンカーリンクが作られていないので、作ってみました。
CSS自体は対応しているので、あとはPHPとスタイルをちょっと調整するだけ。
Parsedownを書き換える
と言っても継承して、見出しを作っているメソッドをオーバーライドするだけです。
ParsedownExtraでも実装されていないみたいなので、独自でやっちゃいました。
<?php
class MyParsedown extends Parsedown
{
protected function createAnchorFragment($str)
{
$signs = array(
'.', ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '%', '#', '\\', '\'',
'|', '`', '^', '"', '<', '>', ')', '(', '}', '{', ']', '[',
);
$str = str_replace(' ', '-', $str);
$str = str_replace($signs, '', $str);
return $str;
}
protected function blockHeader($Line)
{
$Block = parent::blockHeader($Line);
$text = $Block['element']['text'];
// Github
$html = '<a id="%s" class="anchor" href="#%s" aria-hidden="true">';
$html .= '<span class="octicon octicon-link"></span></a>%s';
$fragment = 'user-content-' . $this->createAnchorFragment($text);
$Block['element']['text'] = sprintf($html, $fragment, $fragment, $text);
return $Block;
}
}
あとはサンプルコードでnew Parsedown()
となっているところをnew MyParsedown()
に変えればOK。
スタイルの調整
アンカーリンクのアイコンが見事に消えているので以下のCSSを追加して見える化。
.markdown-body {
padding-left: 30px;
padding-right: 30px;
}