Beispiel #1
0
 public function parse($markdown)
 {
     if (!is_string($markdown)) {
         throw new InvalidArgumentException('markdown', 'type_invalid');
     }
     if (!mb_check_encoding($markdown, 'UTF-8')) {
         throw new InvalidArgumentException('markdown', 'encoding_invalid');
     }
     // 目的:我们希望用户输入在 code block 以外的尖括号当成普通字符对待,而不是 HTML 标签被处理
     // 替换所有尖括号(成对出现时会被当成标签而忽略)
     $markdown = str_replace('<', '&lt;', $markdown);
     $markdown = str_replace('>', '&gt;', $markdown);
     $html = Marked::render($markdown, ['gfm' => true, 'tables' => true, 'breaks' => true, 'sanitize' => false, 'langPrefix' => 'prettyprint lang-']);
     // 恢复 <code> 中的特殊符号(它们被 escape 了两次,第二次是 markdown 引擎)
     $pBegin = 0;
     while (false !== ($pBegin = stripos($html, '<code>', $pBegin))) {
         $pEnd = strpos($html, '</code>', $pBegin + 6);
         if ($pEnd === false) {
             break;
         }
         $inner = substr($html, $pBegin + 6, $pEnd - $pBegin - 6);
         $inner = str_replace('&amp;lt;', '&lt;', $inner);
         $inner = str_replace('&amp;gt;', '&gt;', $inner);
         $html = substr_replace($html, $inner, $pBegin + 6, $pEnd - $pBegin - 6);
         $pBegin += strlen($inner) + 6;
     }
     // 由 HTML Purifier 进一步过滤内容确保输入安全
     $html = $this->purifier->purify($html);
     return $html;
 }
Beispiel #2
0
 public static function edit($title, $md, $url, $time = null, $category = null, $tags = [], $state = self::STATE_OPEN, $id = null)
 {
     if ($id !== null && mb_strlen((string) $id) !== 24) {
         throw new \Exception('Invalid argument: id');
     }
     if ($time == null) {
         $time = time();
     }
     $html = \Breezewish\Marked\Marked::render($md, ['langPrefix' => 'prettyprint lang-', 'breaks' => true]);
     if (P_HTML_FILTER) {
         $html = \BWBlog\Escaper::purify($html);
     }
     // page doesn't need short introductions
     if ($state != self::STATE_PAGE) {
         // process introduction
         foreach (['<!-- more -->', '<!--more -->', '<!-- more-->', '<!--more-->'] as $meta) {
             $pos = mb_stripos($html, $meta, 0, 'UTF-8');
             if ($pos !== false) {
                 break;
             }
         }
         if ($pos !== false) {
             $intro = \BWBlog\Utils::closeTags(mb_substr($html, 0, $pos));
             $more = true;
         } else {
             $intro = $html;
             $more = false;
         }
     } else {
         $more = false;
         $intro = '';
     }
     // page uses direct url
     if ($state != self::STATE_PAGE) {
         $rest_url = \BWBlog\Utils::trimRestURI(str_replace('\\', '/', date('Y/m/d/', $time) . $url));
     } else {
         $rest_url = \BWBlog\Utils::trimRestURI(str_replace('\\', '/', 'page/' . $url));
     }
     $doc = ['title' => $title, 'content' => ['markdown' => $md, 'html' => $html, 'introhtml' => $intro, 'more' => $more], 'time' => ['main' => $time], 'url' => $url, 'rest_url' => $rest_url, 'category' => $category, 'lcategory' => strtolower($category), 'tags' => $tags, 'ltags' => array_map('strtolower', array_map('trim', $tags)), 'state' => (int) $state];
     global $db;
     if ($id === null) {
         // create
         $doc['time']['create'] = time();
         $db->selectCollection(MONGO_PREFIX . 'posts')->insert($doc);
         return $doc['_id'];
     } else {
         // update
         $doc['time']['edit'] = time();
         $result = $db->selectCollection(MONGO_PREFIX . 'posts')->findAndModify(['_id' => new \MongoId((string) $id)], ['$set' => $doc], ['_id' => 1], ['upsert' => true, 'new' => true]);
         return $result['_id'];
     }
 }
Beispiel #3
0
Marked::$inline['link'] = Utils::replace(Marked::$inline['link'], array(array('inside', Marked::$inline['_inside']), array('href', Marked::$inline['_href'])));
Marked::$inline['reflink'] = Utils::replace(Marked::$inline['reflink'], array(array('inside', Marked::$inline['_inside'])));
/**
 * Normal Inline Grammar
 */
Marked::$inline['normal'] = Marked::$inline;
/**
 * Pedantic Inline Grammar
 */
Marked::$inline['pedantic'] = Marked::$inline['normal'];
Marked::$inline['pedantic']['strong'] = new RegExp('^__(?=\\S)([\\s\\S]*?\\S)__(?!_)|^\\*\\*(?=\\S)([\\s\\S]*?\\S)\\*\\*(?!\\*)');
Marked::$inline['pedantic']['em'] = new RegExp('^_(?=\\S)([\\s\\S]*?\\S)_(?!_)|^\\*(?=\\S)([\\s\\S]*?\\S)\\*(?!\\*)');
/**
 * GFM Inline Grammar
 */
Marked::$inline['gfm'] = Marked::$inline['normal'];
Marked::$inline['gfm']['escape'] = Utils::replace(Marked::$inline['escape'], array(array('])', '~|])')));
Marked::$inline['gfm']['url'] = new RegExp('^(https?:\\/\\/[^\\s<]+[^<.,:;"\')\\]\\s])');
Marked::$inline['gfm']['del'] = new RegExp('^~~(?=\\S)([\\s\\S]*?\\S)~~');
Marked::$inline['gfm']['text'] = Utils::replace(Marked::$inline['text'], array(array(']|', '~]|'), array('|', '|https?:\\/\\/|')));
/**
 * GFM + Line Breaks Inline Grammar
 */
Marked::$inline['breaks'] = Marked::$inline['gfm'];
Marked::$inline['breaks']['br'] = Utils::replace(Marked::$inline['br'], array(array('{2,}', '*')));
Marked::$inline['breaks']['text'] = Utils::replace(Marked::$inline['gfm']['text'], array(array('{2,}', '*')));
/**
 * Options
 */
Marked::$defaults = array('gfm' => true, 'tables' => true, 'breaks' => false, 'pedantic' => false, 'sanitize' => false, 'smartLists' => false, 'highlight' => null, 'langPrefix' => 'lang-', 'smartypants' => false, 'headerPrefix' => '', 'renderer' => new Renderer(), 'xhtml' => false);