January 8, 2020

LaravelでMarkdownをhtmlに変換・改

Laravel v6.10.0でparsedownからleague/commonmarkに変わったので再度。
https://github.com/thephpleague/commonmark

Illuminate\Mail\Markdown::parse()はLaravel内でのMail用なのでそのまま使うとhtmlがエスケープされずに危険。これを元に自分のプロジェクト用に作ればいい。

まずオートリンク用にleague/commonmark-ext-autolinkをインストール。その他の必要なパッケージは6.10以降ならLaravel側でインストールされている。

composer require league/commonmark-ext-autolink

app/Support/Markdown.phpを作る。

<?php

namespace App\Support;

use Illuminate\Support\HtmlString;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment;
use League\CommonMark\Ext\Table\TableExtension;
use League\CommonMark\Ext\Autolink\AutolinkExtension;

class Markdown
{
    /**
     * Parse the given Markdown text into HTML.
     *
     * @param  string  $text
     *
     * @return HtmlString
     */
    public static function parse($text)
    {
        $environment = Environment::createCommonMarkEnvironment();

        $environment->addExtension(new TableExtension());
        $environment->addExtension(new AutolinkExtension());

        $converter = new CommonMarkConverter([
            'html_input'         => 'escape',
            'allow_unsafe_links' => false,
        ], $environment);

        return new HtmlString($converter->convertToHtml($text ?? ''));
    }
}

htmlを完全に消すなら'html_input' => 'strip',でもいい。

使う時は

use App\Support\Markdown;

$html = Markdown::parse($markdown);

HtmlStringなのでviewでは{{ $html }}でもそのまま表示される。入力されたhtmlはエスケープ済なので変換後のhtmlは安全な前提。

© kawax