diff --git a/admin/js/hyperdown.js b/admin/js/hyperdown.js index 46430d4e..0eb394e6 100644 --- a/admin/js/hyperdown.js +++ b/admin/js/hyperdown.js @@ -230,6 +230,13 @@ return matches[1] + _this.makeHolder('<code>' + (htmlspecialchars(matches[3])) + '</code>'); }; })(this)); + text = text.replace(/(^|[^\\])(\$+)(.+?)\2/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return matches[1] + _this.makeHolder(matches[2] + (htmlspecialchars(matches[3])) + matches[2]); + }; + })(this)); text = text.replace(/\\(.)/g, (function(_this) { return function() { var escaped, matches; @@ -421,7 +428,7 @@ continue; } if (this.html) { - if (!!(matches = line.match(/^(\s*)!!!(\s*)$/i))) { + if (!!(matches = line.match(/^(\s*)!!!(\s*)$/))) { if (this.isBlock('shtml')) { this.setBlock(key).endBlock(); } else { @@ -433,6 +440,19 @@ continue; } } + if (this.html) { + if (!!(matches = line.match(/^(\s*)\$\$(\s*)$/))) { + if (this.isBlock('math')) { + this.setBlock(key).endBlock(); + } else { + this.startBlock('math', key); + } + continue; + } else if (this.isBlock('math')) { + this.setBlock(key); + continue; + } + } if (!!(matches = line.match(new RegExp("^\\s*<(" + special + ")(\\s+[^>]*)?>", 'i')))) { tag = matches[1].toLowerCase(); if (!(this.isBlock('html', tag)) && !(this.isBlock('pre'))) { @@ -678,6 +698,10 @@ return trim((lines.slice(1, -1)).join("\n")); }; + Parser.prototype.parseMath = function(lines) { + return '<p>' + (htmlspecialchars(lines.join("\n"))) + '</p>'; + }; + Parser.prototype.parseSh = function(lines, num) { var line; line = this.parseInline(trim(lines[0], '# ')); diff --git a/var/HyperDown.php b/var/HyperDown.php index ea84a7a4..85ea2529 100644 --- a/var/HyperDown.php +++ b/var/HyperDown.php @@ -275,6 +275,17 @@ class HyperDown $text ); + // mathjax + $text = preg_replace_callback( + "/(^|[^\\\])(\\$+)(.+?)\\2/", + function ($matches) use ($self) { + return $matches[1] . $self->makeHolder( + $matches[2] . htmlspecialchars($matches[3]) . $matches[2] + ); + }, + $text + ); + // escape $text = preg_replace_callback( "/\\\(.)/u", @@ -556,7 +567,7 @@ class HyperDown // super html mode if ($this->_html) { - if (preg_match("/^(\s*)!!!(\s*)$/i", $line, $matches)) { + if (preg_match("/^(\s*)!!!(\s*)$/", $line, $matches)) { if ($this->isBlock('shtml')) { $this->setBlock($key)->endBlock(); } else { @@ -570,6 +581,20 @@ class HyperDown } } + // mathjax mode + if (preg_match("/^(\s*)\\$\\$(\s*)$/", $line, $matches)) { + if ($this->isBlock('math')) { + $this->setBlock($key)->endBlock(); + } else { + $this->startBlock('math', $key); + } + + continue; + } else if ($this->isBlock('math')) { + $this->setBlock($key); + continue; + } + // html block is special too if (preg_match("/^\s*<({$special})(\s+[^>]*)?>/i", $line, $matches)) { $tag = strtolower($matches[1]); @@ -902,6 +927,17 @@ class HyperDown return trim(implode("\n", array_slice($lines, 1, -1))); } + /** + * parseMath + * + * @param array $lines + * @return string + */ + private function parseMath(array $lines) + { + return '<p>' . htmlspecialchars(implode("\n", $lines)) . '</p>'; + } + /** * parseSh * diff --git a/var/Markdown.php b/var/Markdown.php index ec87c0ed..94202797 100644 --- a/var/Markdown.php +++ b/var/Markdown.php @@ -10,11 +10,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Markdown { - /** - * @var HyperDown - */ - public static $parser; - /** * convert * @@ -23,14 +18,24 @@ class Markdown */ public static function convert($text) { - if (empty(self::$parser)) { - self::$parser = new HyperDown(); - self::$parser->hook('afterParseCode', array('Markdown', 'transerCodeClass')); - self::$parser->hook('beforeParseInline', array('Markdown', 'transerComment')); + static $parser; - self::$parser->enableHtml(true); - self::$parser->_commonWhiteList .= '|img|cite|embed|iframe'; - self::$parser->_specialWhiteList = array_merge(self::$parser->_specialWhiteList, array( + if (empty($parser)) { + $parser = new HyperDown(); + + $parser->hook('afterParseCode', function ($html) { + return preg_replace("/<code class=\"([_a-z0-9-]+)\">/i", "<code class=\"lang-\\1\">", $html); + }); + + $parser->hook('beforeParseInline', function ($html) use ($parser) { + return preg_replace_callback("/<!\-\-(.+?)\-\->/s", function ($matches) use ($parser) { + return $parser->makeHolder($matches[0]); + }, $html); + }); + + $parser->enableHtml(true); + $parser->_commonWhiteList .= '|img|cite|embed|iframe'; + $parser->_specialWhiteList = array_merge($parser->_specialWhiteList, array( 'ol' => 'ol|li', 'ul' => 'ul|li', 'blockquote' => 'blockquote', @@ -38,7 +43,7 @@ class Markdown )); } - return self::$parser->makeHtml($text); + return $parser->makeHtml($text); } /** diff --git a/var/Typecho/Common.php b/var/Typecho/Common.php index 1e472f9d..c7cf3a0c 100644 --- a/var/Typecho/Common.php +++ b/var/Typecho/Common.php @@ -22,7 +22,7 @@ define('__TYPECHO_MB_SUPPORTED__', function_exists('mb_get_info') && function_ex class Typecho_Common { /** 程序版本 */ - const VERSION = '1.1/17.4.24'; + const VERSION = '1.1/17.8.17'; /** * 允许的属性