【Laravel實戰】10分鐘學會如何在Laravel呈現Markdown內容

【Laravel實戰】10分鐘學會如何在Laravel呈現Markdown內容

思路

透過ParseDown套件來轉換Markdown語法變成HTML標籤

快速開始

Step 1.下載Parsedown套件

composer require erusev/parsedown

Step 2.執行內容轉換


use Parsedown;

$parser = new Parsedown();

echo $parser->text('Hello _Parsedown_!'); 
# prints: <p>Hello <em>Parsedown</em>!</p>

進階技巧

為生成的標籤加入樣式或屬性

作法是自建一個新的類別,並繼承 Parsedown,接著複寫相關的方法。以下舉幾個例子

這裡我宣告了一個名為 MyParsedown的類別,命名空間為 App\Http\Customs,其中命名空間可以自己規劃

<?php
namespace App\Http\Customs;

use Parsedown;

class MyParsedown extends Parsedown
{

    //在ul標籤裡頭加入list-group這個樣式類別
    protected function blockList($Line)
    {
        list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');

        if (preg_match('/^(' . $pattern . '[ ]+)(.*)/', $Line['text'], $matches)) {
            $Block = array(
                'indent' => $Line['indent'],
                'pattern' => $pattern,
                'element' => array(
                    'name' => $name,
                    'handler' => 'elements',
                    'attributes' => [
                        "class" => "list-group"
                    ]
                ),
            );

            if ($name === 'ol') {
                $listStart = stristr($matches[0], '.', true);

                if ($listStart !== '1') {
                    $Block['element']['attributes'] = array('start' => $listStart);
                }
            }

            $Block['li'] = array(
                'name' => 'li',
                'handler' => 'li',
                'text' => array(
                    $matches[2],
                ),
                'attributes' => [
                    "class" => "list-group-item"
                ]
            );

            $Block['element']['text'][] = &$Block['li'];

            return $Block;
        }
    }

    //在li標籤裡頭加入list-group-item這個樣式類別
    protected function blockListContinue($Line, array $Block)
    {
        if ($Block['indent'] === $Line['indent'] and preg_match('/^' . $Block['pattern'] . '(?:[ ]+(.*)|$)/', $Line['text'], $matches)) {
            if (isset($Block['interrupted'])) {
                $Block['li']['text'][] = '';

                $Block['loose'] = true;

                unset($Block['interrupted']);
            }

            unset($Block['li']);

            $text = isset($matches[1]) ? $matches[1] : '';

            $Block['li'] = array(
                'name' => 'li',
                'handler' => 'li',
                'text' => array(
                    $text,
                ),
                'attributes' => [
                    "class" => "list-group-item"
                ]
            );

            $Block['element']['text'][] = &$Block['li'];

            return $Block;
        }

        if ($Line['text'][0] === '[' and $this->blockReference($Line)) {
            return $Block;
        }

        if (!isset($Block['interrupted'])) {
            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);

            $Block['li']['text'][] = $text;

            return $Block;
        }

        if ($Line['indent'] > 0) {
            $Block['li']['text'][] = '';

            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);

            $Block['li']['text'][] = $text;

            unset($Block['interrupted']);

            return $Block;
        }
    }

    //在table標籤裡頭加入table table-striped樣式類別
    protected function blockTable($Line, array $Block = null)
    {
        if (!isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) {
            return;
        }

        if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '') {
            $alignments = array();

            $divider = $Line['text'];

            $divider = trim($divider);
            $divider = trim($divider, '|');

            $dividerCells = explode('|', $divider);

            foreach ($dividerCells as $dividerCell) {
                $dividerCell = trim($dividerCell);

                if ($dividerCell === '') {
                    continue;
                }

                $alignment = null;

                if ($dividerCell[0] === ':') {
                    $alignment = 'left';
                }

                if (substr($dividerCell, -1) === ':') {
                    $alignment = $alignment === 'left' ? 'center' : 'right';
                }

                $alignments[] = $alignment;
            }

            # ~

            $HeaderElements = array();

            $header = $Block['element']['text'];

            $header = trim($header);
            $header = trim($header, '|');

            $headerCells = explode('|', $header);

            foreach ($headerCells as $index => $headerCell) {
                $headerCell = trim($headerCell);

                $HeaderElement = array(
                    'name' => 'th',
                    'text' => $headerCell,
                    'handler' => 'line',
                );

                if (isset($alignments[$index])) {
                    $alignment = $alignments[$index];

                    $HeaderElement['attributes'] = array(
                        'style' => 'text-align: ' . $alignment . ';',
                    );
                }

                $HeaderElements[] = $HeaderElement;
            }

            # ~

            $Block = array(
                'alignments' => $alignments,
                'identified' => true,
                'element' => array(
                    'name' => 'table',
                    'handler' => 'elements',
                    'attributes' => [
                        "class" => "table table-striped"
                    ]
                ),
            );

            $Block['element']['text'][] = array(
                'name' => 'thead',
                'handler' => 'elements',
            );

            $Block['element']['text'][] = array(
                'name' => 'tbody',
                'handler' => 'elements',
                'text' => array(),
            );

            $Block['element']['text'][0]['text'][] = array(
                'name' => 'tr',
                'handler' => 'elements',
                'text' => $HeaderElements,
            );

            return $Block;
        }
    }

}

以高亮來顯示程式碼

如果希望能夠以顯明的方式來呈現變數或標籤等,則需要做高亮顯示

我們可以透過 highlight.js 來達到這個目的

Step 1.透過CDN等多種方式來載入JS和CSS

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/highlight.min.js"></script>

Step 2.啟動 highlight

<script>
    hljs.highlightAll();
</script>

參考資料

Parsedown官方網站 Markdown CheatCode highlightjs用法說明


分享這篇文章:

關聯文章:

訂閱電子報,索取 Laravel 學習手冊

價值超過 3000 元,包含常用 Laravel 語法與指令!

Laravel 百萬年薪特訓營

從最基礎的 PHP 語法開始,包含所有你該知道的網頁基礎知識,連同 Laravel 從零開始一直到實戰,最後還將告訴你如何找好工作,讓你及早擁有百萬年薪