mirror of
https://github.com/typecho/typecho.git
synced 2025-01-17 04:28:17 +01:00
fix autop
add ParsedownExtra parser
This commit is contained in:
parent
25c768a630
commit
bc12f48ac7
1822
var/ParsedownExtra.php
Normal file
1822
var/ParsedownExtra.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,31 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* 段落处理类
|
||||
*
|
||||
* @category typecho
|
||||
* @package Common
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* 用于对自动分段做处理
|
||||
*
|
||||
* @category typecho
|
||||
* @package Common
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* AutoP
|
||||
*
|
||||
* @copyright Copyright (c) 2012 Typecho Team. (http://typecho.org)
|
||||
* @author Joyqi <magike.net@gmail.com>
|
||||
* @license GNU General Public License 2.0
|
||||
*/
|
||||
class Typecho_Common_Paragraph
|
||||
class AutoP
|
||||
{
|
||||
// 作为段落的标签
|
||||
const BLOCK = 'p|pre|div|blockquote|form|ul|ol|dd|table|ins|h1|h2|h3|h4|h5|h6';
|
||||
|
||||
/**
|
||||
* 唯一id
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private static $_uniqueId = 0;
|
||||
private $_uniqueId = 0;
|
||||
|
||||
/**
|
||||
* 存储的段落
|
||||
@ -33,18 +26,7 @@ class Typecho_Common_Paragraph
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private static $_blocks = array();
|
||||
|
||||
/**
|
||||
* 作为段落看待的标签
|
||||
*
|
||||
* (default value: 'p|code|pre|div|blockquote|form|ul|ol|dd|table|h1|h2|h3|h4|h5|h6')
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
private static $_blockTag = 'p|code|pre|div|blockquote|form|ul|ol|dd|table|h1|h2|h3|h4|h5|h6';
|
||||
private $_blocks = array();
|
||||
|
||||
/**
|
||||
* 生成唯一的id, 为了速度考虑最多支持1万个tag的处理
|
||||
@ -52,11 +34,11 @@ class Typecho_Common_Paragraph
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private static function makeUniqueId()
|
||||
private function makeUniqueId()
|
||||
{
|
||||
return ':' . str_pad(self::$_uniqueId ++, 4, '0', STR_PAD_LEFT);
|
||||
return ':' . str_pad($this->_uniqueId ++, 4, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用段落方法处理换行
|
||||
*
|
||||
@ -64,18 +46,20 @@ class Typecho_Common_Paragraph
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
private static function cutByBlock($text)
|
||||
private function cutByBlock($text)
|
||||
{
|
||||
$space = "( | )";
|
||||
$text = str_replace("\r\n", "\n", trim($text));
|
||||
$text = preg_replace("/{$space}*\n{$space}*/is", "\n", $text);
|
||||
$text = preg_replace("/\s*<p:([0-9]{4})\/>\s*/is", "</p><p:\\1/><p>", $text);
|
||||
$text = preg_replace("/\n{2,}/", "</p><p>", $text);
|
||||
$text = nl2br($text);
|
||||
$text = preg_replace("/(<p>)?\s*<p:([0-9]{4})\/>\s*(<\/p>)?/s", "<p:\\2/>", $text);
|
||||
$text = preg_replace("/(<p>)?\s*<p:([0-9]{4})\/>\s*(<\/p>)?/is", "<p:\\2/>", $text);
|
||||
$text = preg_replace("/<p>{$space}*<\/p>/is", '', $text);
|
||||
$text = preg_replace("/\s*<p>\s*$/is", '', $text);
|
||||
$text = preg_replace("/^\s*<\/p>\s*/is", '', $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修复段落开头和结尾
|
||||
*
|
||||
@ -83,20 +67,20 @@ class Typecho_Common_Paragraph
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
private static function fixPragraph($text)
|
||||
private function fixPragraph($text)
|
||||
{
|
||||
$text = trim($text);
|
||||
if (!preg_match("/^<(" . self::$_blockTag . ")(\s|>)/i", $text)) {
|
||||
if (!preg_match("/^<(" . self::BLOCK . ")(\s|>)/i", $text)) {
|
||||
$text = '<p>' . $text;
|
||||
}
|
||||
|
||||
if (!preg_match("/<\/(" . self::$_blockTag . ")>$/i", $text)) {
|
||||
if (!preg_match("/<\/(" . self::BLOCK . ")>$/i", $text)) {
|
||||
$text = $text . '</p>';
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 替换段落的回调函数
|
||||
*
|
||||
@ -104,21 +88,21 @@ class Typecho_Common_Paragraph
|
||||
* @param array $matches 匹配值
|
||||
* @return string
|
||||
*/
|
||||
public static function replaceBlockCallback($matches)
|
||||
public function replaceBlockCallback($matches)
|
||||
{
|
||||
$tagMatch = '|' . $matches[1] . '|';
|
||||
$text = $matches[4];
|
||||
|
||||
switch (true) {
|
||||
/** 用br处理换行 */
|
||||
case false !== strpos('|li|dd|dt|td|p|a|span|cite|strong|sup|sub|small|del|u|i|b|h1|h2|h3|h4|h5|h6|', $tagMatch):
|
||||
case false !== strpos('|li|dd|dt|td|p|a|span|code|cite|strong|sup|sub|small|del|u|i|b|ins|h1|h2|h3|h4|h5|h6|', $tagMatch):
|
||||
$text = nl2br(trim($text));
|
||||
break;
|
||||
/** 用段落处理换行 */
|
||||
case false !== strpos('|div|blockquote|form|', $tagMatch):
|
||||
$text = self::cutByBlock($text);
|
||||
$text = $this->cutByBlock($text);
|
||||
if (false !== strpos($text, '</p><p>')) {
|
||||
$text = self::fixPragraph($text);
|
||||
$text = $this->fixPragraph($text);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -126,32 +110,30 @@ class Typecho_Common_Paragraph
|
||||
}
|
||||
|
||||
/** 没有段落能力的标签 */
|
||||
if (false !== strpos('|a|span|cite|strong|sup|sub|small|del|u|i|b|', $tagMatch)) {
|
||||
if (false !== strpos('|a|span|code|cite|strong|sup|sub|small|del|u|i|b|', $tagMatch)) {
|
||||
$key = '<b' . $matches[2] . '/>';
|
||||
} else {
|
||||
$key = '<p' . $matches[2] . '/>';
|
||||
}
|
||||
|
||||
self::$_blocks[$key] = "<{$matches[1]}{$matches[3]}>{$text}</{$matches[1]}>";
|
||||
$this->_blocks[$key] = "<{$matches[1]}{$matches[3]}>{$text}</{$matches[1]}>";
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理文本
|
||||
* 自动分段
|
||||
*
|
||||
* @access public
|
||||
* @param string $text 文本
|
||||
* @param string $text
|
||||
* @static
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
public static function process($text)
|
||||
public function parse($text)
|
||||
{
|
||||
/** 锁定标签 */
|
||||
$text = Typecho_Common::lockHTML($text);
|
||||
|
||||
/** 重置计数器 */
|
||||
self::$_uniqueId = 0;
|
||||
self::$_blocks = array();
|
||||
|
||||
$this->_uniqueId = 0;
|
||||
$this->_blocks = array();
|
||||
|
||||
/** 将已有的段落后面的换行处理掉 */
|
||||
$text = preg_replace(array("/<\/p>\s+<p(\s*)/is", "/\s*<br\s*\/?>\s*/is"), array("</p><p\\1", "<br />"), trim($text));
|
||||
|
||||
@ -159,7 +141,7 @@ class Typecho_Common_Paragraph
|
||||
$foundTagCount = 0;
|
||||
$textLength = strlen($text);
|
||||
$uniqueIdList = array();
|
||||
|
||||
|
||||
if (preg_match_all("/<\/\s*([a-z0-9]+)>/is", $text, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
foreach ($matches[0] as $key => $match) {
|
||||
$tag = $matches[1][$key][0];
|
||||
@ -184,7 +166,7 @@ class Typecho_Common_Paragraph
|
||||
}
|
||||
|
||||
if (false !== $pos) {
|
||||
$uniqueId = self::makeUniqueId();
|
||||
$uniqueId = $this->makeUniqueId();
|
||||
$uniqueIdList[$uniqueId] = $tag;
|
||||
$tagLength = strlen($tag);
|
||||
|
||||
@ -197,19 +179,17 @@ class Typecho_Common_Paragraph
|
||||
|
||||
foreach ($uniqueIdList as $uniqueId => $tag) {
|
||||
$text = preg_replace_callback("/<({$tag})({$uniqueId})([^>]*)>(.*)<\/\\1\\2>/is",
|
||||
array('Typecho_Common_Paragraph', 'replaceBlockCallback'), $text, 1);
|
||||
array($this, 'replaceBlockCallback'), $text, 1);
|
||||
}
|
||||
|
||||
$text = self::cutByBlock($text);
|
||||
$blocks = array_reverse(self::$_blocks);
|
||||
$text = $this->cutByBlock($text);
|
||||
$blocks = array_reverse($this->_blocks);
|
||||
|
||||
foreach ($blocks as $blockKey => $blockValue) {
|
||||
$text = str_replace($blockKey, $blockValue, $text);
|
||||
}
|
||||
|
||||
$text = self::fixPragraph($text);
|
||||
|
||||
/** 释放标签 */
|
||||
return Typecho_Common::releaseHTML($text);
|
||||
return $this->fixPragraph($text);
|
||||
}
|
||||
}
|
||||
|
@ -24,14 +24,6 @@ class Typecho_Common
|
||||
/** 程序版本 */
|
||||
const VERSION = '1.0/14.9.2';
|
||||
|
||||
/**
|
||||
* 锁定的代码块
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private static $_lockedBlocks = array('<p></p>' => '');
|
||||
|
||||
/**
|
||||
* 允许的属性
|
||||
*
|
||||
@ -56,19 +48,6 @@ class Typecho_Common
|
||||
*/
|
||||
public static $exceptionHandle;
|
||||
|
||||
/**
|
||||
* 锁定标签回调函数
|
||||
*
|
||||
* @access private
|
||||
* @param array $matches 匹配的值
|
||||
* @return string
|
||||
*/
|
||||
public static function __lockHTML(array $matches)
|
||||
{
|
||||
$guid = '<code>' . uniqid(time()) . '</code>';
|
||||
self::$_lockedBlocks[$guid] = $matches[0];
|
||||
return $guid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将url中的非法xss去掉时的数组回调过滤函数
|
||||
@ -828,71 +807,6 @@ EOF;
|
||||
return substr($str, 0, $maxLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉html中的分段
|
||||
*
|
||||
* @access public
|
||||
* @param string $html 输入串
|
||||
* @return string
|
||||
*/
|
||||
public static function removeParagraph($html)
|
||||
{
|
||||
/** 锁定标签 */
|
||||
$html = self::lockHTML($html);
|
||||
$html = str_replace(array("\r", "\n"), '', $html);
|
||||
|
||||
$html = trim(preg_replace(
|
||||
array("/\s*<p>(.*?)<\/p>\s*/is", "/\s*<br\s*\/>\s*/is",
|
||||
"/\s*<(div|blockquote|pre|code|script|table|fieldset|ol|ul|dl|h[1-6])([^>]*)>/is",
|
||||
"/<\/(div|blockquote|pre|code|script|table|fieldset|ol|ul|dl|h[1-6])>\s*/is", "/\s*<\!--more-->\s*/is"),
|
||||
array("\n\\1\n", "\n", "\n\n<\\1\\2>", "</\\1>\n\n", "\n\n<!--more-->\n\n"),
|
||||
$html));
|
||||
|
||||
return trim(self::releaseHTML($html));
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁定标签
|
||||
*
|
||||
* @access public
|
||||
* @param string $html 输入串
|
||||
* @return string
|
||||
*/
|
||||
public static function lockHTML($html)
|
||||
{
|
||||
return preg_replace_callback("/<(code|pre|script)[^>]*>.*?<\/\\1>/is", array('Typecho_Common', '__lockHTML'), $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放标签
|
||||
*
|
||||
* @access public
|
||||
* @param string $html 输入串
|
||||
* @return string
|
||||
*/
|
||||
public static function releaseHTML($html)
|
||||
{
|
||||
$html = trim(str_replace(array_keys(self::$_lockedBlocks), array_values(self::$_lockedBlocks), $html));
|
||||
self::$_lockedBlocks = array('<p></p>' => '');
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本分段函数
|
||||
*
|
||||
* @param string $string 需要分段的字符串
|
||||
* @return string
|
||||
*/
|
||||
public static function cutParagraph($string)
|
||||
{
|
||||
static $loaded;
|
||||
if (!$loaded) {
|
||||
$loaded = true;
|
||||
}
|
||||
|
||||
return Typecho_Common_Paragraph::process($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机字符串
|
||||
*
|
||||
|
@ -113,7 +113,7 @@ class Widget_Abstract_Comments extends Widget_Abstract
|
||||
$text = $this->pluginHandle(__CLASS__)->trigger($plugged)->content($text, $this);
|
||||
if (!$plugged) {
|
||||
$text = $this->options->commentsMarkdown ? $this->markdown($text)
|
||||
: Typecho_Common::cutParagraph($text);
|
||||
: $this->autoP($text);
|
||||
}
|
||||
|
||||
$text = $this->pluginHandle(__CLASS__)->contentEx($text, $this);
|
||||
@ -439,6 +439,30 @@ class Widget_Abstract_Comments extends Widget_Abstract
|
||||
echo Typecho_Common::subStr(strip_tags($this->content), 0, $length, $trim);
|
||||
}
|
||||
|
||||
/**
|
||||
* autoP
|
||||
*
|
||||
* @param mixed $text
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function autoP($text)
|
||||
{
|
||||
$html = $this->pluginHandle(__CLASS__)->trigger($parsed)->autoP($text);
|
||||
|
||||
if (!$parsed) {
|
||||
static $parser;
|
||||
|
||||
if (empty($parser)) {
|
||||
$parser = new AutoP();
|
||||
}
|
||||
|
||||
$html = $parser->parse($text);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* markdown
|
||||
*
|
||||
@ -451,8 +475,13 @@ class Widget_Abstract_Comments extends Widget_Abstract
|
||||
$html = $this->pluginHandle(__CLASS__)->trigger($parsed)->markdown($text);
|
||||
|
||||
if (!$parsed) {
|
||||
$parser = new ParsedownExtra();
|
||||
$parser->setBreaksEnabled(true);
|
||||
static $parser;
|
||||
|
||||
if (empty($parser)) {
|
||||
$parser = new ParsedownExtra();
|
||||
$parser->setBreaksEnabled(true);
|
||||
}
|
||||
|
||||
$html = $parser->text($text);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ class Widget_Abstract_Contents extends Widget_Abstract
|
||||
$content = $this->pluginHandle(__CLASS__)->trigger($plugged)->excerpt($this->text, $this);
|
||||
if (!$plugged) {
|
||||
$content = $this->isMarkdown ? $this->markdown($content)
|
||||
: Typecho_Common::cutParagraph($content);
|
||||
: $this->autoP($content);
|
||||
}
|
||||
|
||||
$contents = explode('<!--more-->', $content);
|
||||
@ -135,7 +135,7 @@ class Widget_Abstract_Contents extends Widget_Abstract
|
||||
|
||||
if (!$plugged) {
|
||||
$content = $this->isMarkdown ? $this->markdown($content)
|
||||
: Typecho_Common::cutParagraph($content);
|
||||
: $this->autoP($content);
|
||||
}
|
||||
|
||||
return $this->pluginHandle(__CLASS__)->contentEx($content, $this);
|
||||
@ -923,6 +923,30 @@ class Widget_Abstract_Contents extends Widget_Abstract
|
||||
echo $this->author->{$item};
|
||||
}
|
||||
|
||||
/**
|
||||
* autoP
|
||||
*
|
||||
* @param mixed $text
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function autoP($text)
|
||||
{
|
||||
$html = $this->pluginHandle(__CLASS__)->trigger($parsed)->autoP($text);
|
||||
|
||||
if (!$parsed) {
|
||||
static $parser;
|
||||
|
||||
if (empty($parser)) {
|
||||
$parser = new AutoP();
|
||||
}
|
||||
|
||||
$html = $parser->parse($text);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* markdown
|
||||
*
|
||||
@ -935,8 +959,13 @@ class Widget_Abstract_Contents extends Widget_Abstract
|
||||
$html = $this->pluginHandle(__CLASS__)->trigger($parsed)->markdown($text);
|
||||
|
||||
if (!$parsed) {
|
||||
$parser = new ParsedownExtra();
|
||||
$parser->setBreaksEnabled(true);
|
||||
static $parser;
|
||||
|
||||
if (empty($parser)) {
|
||||
$parser = new ParsedownExtra();
|
||||
$parser->setBreaksEnabled(true);
|
||||
}
|
||||
|
||||
$html = $parser->text($text);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user