How to parse Markdown in PHP?

后端 未结 5 902
误落风尘
误落风尘 2020-12-23 20:48

First, I know, there already is a Markdown parser for PHP. I also took a look to this question but it doesn\'t answer to my question.

Obviously, even if the title me

相关标签:
5条回答
  • 2020-12-23 21:26

    Ciconia - A New Markdown Parser for PHP is a good one I found.

    You just need 3 things to do :

    1.Install Ciconia and parse file according to the document.
    2. Add corresponding css theme to make it nice, like github markdown style or here.
    3. Add syntax highlighting javascript, like google Javascript code prettifier.

    Then everything will look pretty good.

    If you want a complete example, here is my working demo for github style markdown:

    <?php
    header("Content-Type: text/html;charset=utf-8");
    require 'vendor/autoload.php';
    use Ciconia\Ciconia;
    use Ciconia\Extension\Gfm;
    
    $ciconia = new Ciconia();
    $ciconia->addExtension(new Gfm\FencedCodeBlockExtension());
    $ciconia->addExtension(new Gfm\TaskListExtension());
    $ciconia->addExtension(new Gfm\InlineStyleExtension());
    $ciconia->addExtension(new Gfm\WhiteSpaceExtension());
    $ciconia->addExtension(new Gfm\TableExtension());
    $ciconia->addExtension(new Gfm\UrlAutoLinkExtension());
    $contents = file_get_contents('Readme.md');
    $html = $ciconia->render($contents);
    ?>
    <!DOCTYPE html>
    <html>
        <head>
            <title>Excel to Lua table - Readme</title>
            <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
            <link rel="stylesheet" href="./github-markdown.css">
            <style>
                .markdown-body {
                    box-sizing: border-box;
                    min-width: 200px;
                    max-width: 980px;
                    margin: 0 auto;
                    padding: 45px;
                }
            </style>
        </head>
        <body>
            <article class="markdown-body">
            <?php
                # Put HTML content in the document
                echo $html;
            ?>
            </article>
        </body>
    </html>
    
    0 讨论(0)
  • 2020-12-23 21:28

    Using regexes.

    <?php
    
    /**
     * Slimdown - A very basic regex-based Markdown parser. Supports the
     * following elements (and can be extended via Slimdown::add_rule()):
     *
     * - Headers
     * - Links
     * - Bold
     * - Emphasis
     * - Deletions
     * - Quotes
     * - Inline code
     * - Blockquotes
     * - Ordered/unordered lists
     * - Horizontal rules
     *
     * Author: Johnny Broadway <johnny@johnnybroadway.com>
     * Website: https://gist.github.com/jbroadway/2836900
     * License: MIT
     */
    class Slimdown {
        public static $rules = array (
            '/(#+)(.*)/' => 'self::header',                           // headers
            '/\[([^\[]+)\]\(([^\)]+)\)/' => '<a href=\'\2\'>\1</a>',  // links
            '/(\*\*|__)(.*?)\1/' => '<strong>\2</strong>',            // bold
            '/(\*|_)(.*?)\1/' => '<em>\2</em>',                       // emphasis
            '/\~\~(.*?)\~\~/' => '<del>\1</del>',                     // del
            '/\:\"(.*?)\"\:/' => '<q>\1</q>',                         // quote
            '/`(.*?)`/' => '<code>\1</code>',                         // inline code
            '/\n\*(.*)/' => 'self::ul_list',                          // ul lists
            '/\n[0-9]+\.(.*)/' => 'self::ol_list',                    // ol lists
            '/\n(&gt;|\>)(.*)/' => 'self::blockquote ',               // blockquotes
            '/\n-{5,}/' => "\n<hr />",                                // horizontal rule
            '/\n([^\n]+)\n/' => 'self::para',                         // add paragraphs
            '/<\/ul>\s?<ul>/' => '',                                  // fix extra ul
            '/<\/ol>\s?<ol>/' => '',                                  // fix extra ol
            '/<\/blockquote><blockquote>/' => "\n"                    // fix extra blockquote
        );
    
        private static function para ($regs) {
            $line = $regs[1];
            $trimmed = trim ($line);
            if (preg_match ('/^<\/?(ul|ol|li|h|p|bl)/', $trimmed)) {
                return "\n" . $line . "\n";
            }
            return sprintf ("\n<p>%s</p>\n", $trimmed);
        }
    
        private static function ul_list ($regs) {
            $item = $regs[1];
            return sprintf ("\n<ul>\n\t<li>%s</li>\n</ul>", trim ($item));
        }
    
        private static function ol_list ($regs) {
            $item = $regs[1];
            return sprintf ("\n<ol>\n\t<li>%s</li>\n</ol>", trim ($item));
        }
    
        private static function blockquote ($regs) {
            $item = $regs[2];
            return sprintf ("\n<blockquote>%s</blockquote>", trim ($item));
        }
    
        private static function header ($regs) {
            list ($tmp, $chars, $header) = $regs;
            $level = strlen ($chars);
            return sprintf ('<h%d>%s</h%d>', $level, trim ($header), $level);
        }
    
        /**
         * Add a rule.
         */
        public static function add_rule ($regex, $replacement) {
            self::$rules[$regex] = $replacement;
        }
    
        /**
         * Render some Markdown into HTML.
         */
        public static function render ($text) {
            $text = "\n" . $text . "\n";
            foreach (self::$rules as $regex => $replacement) {
                if (is_callable ( $replacement)) {
                    $text = preg_replace_callback ($regex, $replacement, $text);
                } else {
                    $text = preg_replace ($regex, $replacement, $text);
                }
            }
            return trim ($text);
        }
    }
    
    
    echo Slimdown::render ("# Title
    
    And *now* [a link](http://www.google.com) to **follow** and [another](http://yahoo.com/).
    
    * One
    * Two
    * Three
    
    ## Subhead
    
    One **two** three **four** five.
    
    One __two__ three _four_ five __six__ seven _eight_.
    
    1. One
    2. Two
    3. Three
    
    More text with `inline($code)` sample.
    
    > A block quote
    > across two lines.
    
    More text...");
    

    Origin https://gist.github.com/jbroadway/2836900

    0 讨论(0)
  • 2020-12-23 21:36

    Also, there is an object-oriented implementation of Markdown which is faster: markdown-oo-php

    0 讨论(0)
  • 2020-12-23 21:40

    There is PHP Markdown Extra that seems to be popular, you could start by looking at its source.

    0 讨论(0)
  • 2020-12-23 21:44

    You should have a look at Parsedown.

    It parses Markdown text the way people do. First, it divides texts into lines. Then it looks at how these lines start and relate to each other. Finally, it looks for special characters to identify inline elements.

    0 讨论(0)
提交回复
热议问题