【PHP】Parsedownを拡張するParsedownPlusを公開しました

PHP

PHP用の高速MarkdownパーサであるParsedown/ParsedownExtra用の拡張ライブラリ、ParsedownPlusをGitHubで公開しました。
合わせてPackagistに登録したのでcomposerで使用することができます。

この記事ではParsedownPlusの紹介をしたいと思います。

ParsedownPlusとは?

PHP用の高速Markdownパーサ、Parsedown/ParsedownExtra用の拡張ライブラリです。
以下の機能を提供します。

  1. 目次の自動作成
    1. 本文中に目次タグを指定することで自動作成した目次を挿入します。
  2. LaTeX形式の数式に対応
    1. $ ... $, $$ ... $$で囲まれた部分をLaTeX形式の数式と認識し、Markdownのパースを行いません。
    2. $ ... $はインライン形式、$$ ... $$はブロック形式として認識します。
  3. コードブロックのファイル名を認識
    1. コードフェンス後の```lang:file ... ```を認識し、<code>data-filename属性にファイル名を展開します。

公式


使用方法

Packagistに登録しているので、composerで使用することができます。

composer require izadori/parsedown-plus

Parsedownがインストールされていない場合は一緒にインストールされます。ParsedownExtraには依存していないので、必要な場合は手動でインストールしてください。

ParsedownPlusを使用するために、PHPのソース内でautoload.phpをrequireしてください。
Markdown形式のテキスト全体をパースするには、ParsedownPlus::text()を呼び出します。

require_once __DIR__ . "/vender/autoload.php";

use \Izadori\ParsedownPlus\ParsedownPlus;

$parser = new ParsedownPlus();

$text = <<<EOF
# Equation of _Circle_
$ x_{1}^{2} + x_{2}^{2} = 1 $
EOF;

$line = "It's **inline** text!";

// Markdown形式のテキスト全体をパースします
echo $parser->text($text); // prints: <h1>Equation of <em>Circle</em></h1> <p>$  x_{1}^{2} + x_{2}^{2} = 1  $</p>
// 行内の一部のMarkdownテキストをパースします
echo $parser->line($line); // prints: It's <strong>inline</strong> text!

オプション設定

ParsedownPlusはオプション設定用にいくつかのpublicメンバ変数を持ちます。

メンバ変数説明
$langPrefixコードフェンスで指定される言語名を表すクラスに付加する先頭文字列です。
デフォルトはprism.js用のlanguage-です。
$tocTag'begin''end'の2つのメンバを持つ連想配列です。
目次として認識する見出しタグの開始レベルと終了レベルを数値で指定します。
$tocIdentTagMarkdown本文中で目次を挿入する疑似タグを文字列の配列で指定します。
$tocFormat生成された目次(^1)を含む書式を指定します。
sprintf()を使っているので、目次に置き換える部分を%sで指定してください。

目次の生成について

ParsedownPlusが生成する目次は次のようなordered-listです。

<ol>
  <li>見出し1</li>
  <li>見出し2</li>
    <ol>
      <li>見出し2.1</li>
      <li>見出し2.2</li>
    </ol>
  <li>見出し3</li>
</ol>

LaTeX形式の数式について

LaTeX形式の数式を使うには、MathJaxやKaTeXが必要です。<head></head>に次の内容を貼り付けることで、インライン形式の数式は$~$で、ブロック形式の数式は$$~$$で認識されるようになります。
数式中ではMarkdownとしての解析をスキップするので、添字を表す_を強調のマークダウンとして認識されるのを回避することができます。

MathJax

<script>
  MathJax = {
    tex: {
      inlineMath: [['$', '$']]
    }
  };
</script>
<script type="text/javascript" id="MathJax-script"
  async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

KaTeX

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.css" integrity="sha384-zTROYFVGOfTw7JV7KUu8udsvW2fx4lWOsCEDqhBreBwlHI4ioVRtmIvEThzJHGET" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.js" integrity="sha384-GxNFqL3r9uRJQhR+47eDxuPoNE7yLftQM8LcxzgS4HT73tp970WS/wV5p8UzCOmb" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.18/dist/contrib/auto-render.min.js" integrity="sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl" crossorigin="anonymous"></script>
<script>
  document.addEventListener("DOMContentLoaded", function() {
    renderMathInElement(document.body, {
      delimiters: [
        {left: '$$', right: '$$', display: true},
        {left: '$', right: '$', display: false},
      ],
      throwOnError : false
    });
  });
</script>

まとめ

自作のPHP用ライブラリParsedownPlusについて紹介させていただきました。
小さな機能しかありませんが、ご興味がありましたら試しに使って見ていただければと思います。