mirror of
https://github.com/he0119/typecho-highlightjs.git
synced 2026-08-19 09:43:28 +08:00
chore: 添加 .editorconfig
This commit is contained in:
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1 @@
|
||||
highlight.zip
|
||||
highlight.zip
|
||||
|
||||
380
Plugin.php
380
Plugin.php
@@ -1,188 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace TypechoPlugin\HighlightJs;
|
||||
|
||||
use Typecho\Plugin\PluginInterface;
|
||||
use Typecho\Widget\Helper\Form;
|
||||
use Utils\Helper;
|
||||
use Widget\Archive;
|
||||
use Widget\Base\Comments;
|
||||
use Widget\Base\Contents;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight.JS插件,智能实现代码高亮
|
||||
*
|
||||
* @package Highlight Js
|
||||
* @author joyqi
|
||||
* @version 1.1.0
|
||||
* @since 1.2.0
|
||||
* @link https://github.com/he0119/typecho-highlightjs
|
||||
*/
|
||||
class Plugin implements PluginInterface
|
||||
{
|
||||
/**
|
||||
* 激活插件方法,如果激活失败,直接抛出异常
|
||||
*/
|
||||
public static function activate()
|
||||
{
|
||||
Contents::pluginHandle()->contentEx = __CLASS__ . '::parse';
|
||||
Contents::pluginHandle()->excerptEx = __CLASS__ . '::parse';
|
||||
Comments::pluginHandle()->contentEx = __CLASS__ . '::parse';
|
||||
Archive::pluginHandle()->header = __CLASS__ . '::header';
|
||||
Archive::pluginHandle()->footer = __CLASS__ . '::footer';
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用插件方法,如果禁用失败,直接抛出异常
|
||||
*/
|
||||
public static function deactivate()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件配置面板
|
||||
*
|
||||
* @param Form $form 配置面板
|
||||
*/
|
||||
public static function config(Form $form)
|
||||
{
|
||||
$compatibilityMode = new Form\Element\Radio('compatibilityMode', [
|
||||
0 => _t('不启用'),
|
||||
1 => _t('启用')
|
||||
], 0, _t('兼容模式'), _t('兼容模式一般用于对以前没有使用Markdown语法解析的文章'));
|
||||
$form->addInput($compatibilityMode->addRule('enum', _t('必须选择一个模式'), [0, 1]));
|
||||
|
||||
$styles = array_map('basename', glob(dirname(__FILE__) . '/res/styles/*.css'));
|
||||
$styles = array_combine($styles, $styles);
|
||||
$style = new Form\Element\Select('style', $styles, 'default.css',
|
||||
_t('代码配色样式'));
|
||||
$form->addInput($style->addRule('enum', _t('必须选择配色样式'), $styles));
|
||||
}
|
||||
|
||||
/**
|
||||
* 个人用户的配置面板
|
||||
*
|
||||
* @param Form $form
|
||||
*/
|
||||
public static function personalConfig(Form $form)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出头部css
|
||||
*/
|
||||
public static function header($header, Archive $archive)
|
||||
{
|
||||
if ($archive->is('single')) {
|
||||
$cssUrl = Helper::options()->pluginUrl . '/HighlightJs/res/styles/'
|
||||
. Helper::options()->plugin('HighlightJs')->style;
|
||||
echo '<link rel="stylesheet" type="text/css" href="' . $cssUrl . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出尾部js
|
||||
*/
|
||||
public static function footer(Archive $archive)
|
||||
{
|
||||
if ($archive->is('single')) {
|
||||
$jsUrl = Helper::options()->pluginUrl . '/HighlightJs/res/highlight.min.js';
|
||||
echo '<script type="text/javascript" src="' . $jsUrl . '"></script>';
|
||||
echo '<script type="text/javascript">window.onload = function () {
|
||||
var codes = document.getElementsByTagName("pre"),
|
||||
hlNames = {
|
||||
actionscript : /^as[1-3]$/i,
|
||||
cmake : /^(make|makefile)$/i,
|
||||
cs : /^csharp$/i,
|
||||
css : /^css[1-3]$/i,
|
||||
delphi : /^pascal$/i,
|
||||
javascript : /^js$/i,
|
||||
markdown : /^md$/i,
|
||||
objectivec : /^objective\-c$/i,
|
||||
php : /^php[1-6]$/i,
|
||||
sql : /^mysql$/i,
|
||||
xml : /^(html|html5|xhtml)$/i
|
||||
}, hlLangs = hljs.LANGUAGES;
|
||||
|
||||
for (var i = 0; i < codes.length; i ++) {
|
||||
var children = codes[i].getElementsByTagName("code"), highlighted = false;
|
||||
|
||||
if (children.length > 0) {
|
||||
var code = children[0], className = code.className;
|
||||
|
||||
if (!!className) {
|
||||
if (0 == className.indexOf("language-")) {
|
||||
var lang = className.substring(5).toLowerCase(), finalLang;
|
||||
|
||||
if (hlLangs[lang]) {
|
||||
finalLang = lang;
|
||||
} else {
|
||||
for (var l in hlNames) {
|
||||
if (lang.match(hlNames[l])) {
|
||||
finalLang = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!!finalLang) {
|
||||
var result = hljs.highlight(finalLang, code.textContent, true);
|
||||
code.innerHTML = result.value;
|
||||
highlighted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!highlighted) {
|
||||
var html = code.innerHTML;
|
||||
code.innerHTML = html.replace(/<\/?[a-z]+[^>]*>/ig, "");
|
||||
hljs.highlightElement(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}</script>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件实现方法
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public static function parse($text, $widget, $lastResult): string
|
||||
{
|
||||
$text = empty($lastResult) ? $text : $lastResult;
|
||||
|
||||
if (!Helper::options()->plugin('HighlightJs')->compatibilityMode) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
if ($widget instanceof Archive || $widget instanceof Comments) {
|
||||
$isMarkdown = $widget instanceof Comments ? Helper::options()->commentsMarkdown : $widget->isMarkdown;
|
||||
|
||||
return preg_replace_callback("/<(code|pre)(\s*[^>]*)>(.*?)<\/\\1>/is", function ($matches) use ($isMarkdown) {
|
||||
if ('code' == $matches[1] && !$isMarkdown) {
|
||||
$language = $matches[2];
|
||||
|
||||
if (!empty($language)) {
|
||||
if (preg_match("/^\s*(class|lang|language)=\"(?:lang-|language-)?([_a-z0-9-]+)\"$/i", $language, $out)) {
|
||||
$language = ' class="' . trim($out[2]) . '"';
|
||||
} elseif (preg_match("/\s*([_a-z0-9]+)/i", $language, $out)) {
|
||||
$language = ' class="language-' . trim($out[1]) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
return "<pre><code{$language}>" . htmlspecialchars(trim($matches[3])) . "</code></pre>";
|
||||
}
|
||||
|
||||
return $matches[0];
|
||||
}, $text);
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace TypechoPlugin\HighlightJs;
|
||||
|
||||
use Typecho\Plugin\PluginInterface;
|
||||
use Typecho\Widget\Helper\Form;
|
||||
use Utils\Helper;
|
||||
use Widget\Archive;
|
||||
use Widget\Base\Comments;
|
||||
use Widget\Base\Contents;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight.JS插件,智能实现代码高亮
|
||||
*
|
||||
* @package Highlight Js
|
||||
* @author joyqi
|
||||
* @version 1.1.0
|
||||
* @since 1.2.0
|
||||
* @link https://github.com/he0119/typecho-highlightjs
|
||||
*/
|
||||
class Plugin implements PluginInterface
|
||||
{
|
||||
/**
|
||||
* 激活插件方法,如果激活失败,直接抛出异常
|
||||
*/
|
||||
public static function activate()
|
||||
{
|
||||
Contents::pluginHandle()->contentEx = __CLASS__ . '::parse';
|
||||
Contents::pluginHandle()->excerptEx = __CLASS__ . '::parse';
|
||||
Comments::pluginHandle()->contentEx = __CLASS__ . '::parse';
|
||||
Archive::pluginHandle()->header = __CLASS__ . '::header';
|
||||
Archive::pluginHandle()->footer = __CLASS__ . '::footer';
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用插件方法,如果禁用失败,直接抛出异常
|
||||
*/
|
||||
public static function deactivate()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件配置面板
|
||||
*
|
||||
* @param Form $form 配置面板
|
||||
*/
|
||||
public static function config(Form $form)
|
||||
{
|
||||
$compatibilityMode = new Form\Element\Radio('compatibilityMode', [
|
||||
0 => _t('不启用'),
|
||||
1 => _t('启用')
|
||||
], 0, _t('兼容模式'), _t('兼容模式一般用于对以前没有使用Markdown语法解析的文章'));
|
||||
$form->addInput($compatibilityMode->addRule('enum', _t('必须选择一个模式'), [0, 1]));
|
||||
|
||||
$styles = array_map('basename', glob(dirname(__FILE__) . '/res/styles/*.css'));
|
||||
$styles = array_combine($styles, $styles);
|
||||
$style = new Form\Element\Select(
|
||||
'style',
|
||||
$styles,
|
||||
'default.css',
|
||||
_t('代码配色样式')
|
||||
);
|
||||
$form->addInput($style->addRule('enum', _t('必须选择配色样式'), $styles));
|
||||
}
|
||||
|
||||
/**
|
||||
* 个人用户的配置面板
|
||||
*
|
||||
* @param Form $form
|
||||
*/
|
||||
public static function personalConfig(Form $form)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出头部css
|
||||
*/
|
||||
public static function header($header, Archive $archive)
|
||||
{
|
||||
if ($archive->is('single')) {
|
||||
$cssUrl = Helper::options()->pluginUrl . '/HighlightJs/res/styles/'
|
||||
. Helper::options()->plugin('HighlightJs')->style;
|
||||
echo '<link rel="stylesheet" type="text/css" href="' . $cssUrl . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出尾部js
|
||||
*/
|
||||
public static function footer(Archive $archive)
|
||||
{
|
||||
if ($archive->is('single')) {
|
||||
$jsUrl = Helper::options()->pluginUrl . '/HighlightJs/res/highlight.min.js';
|
||||
echo '<script type="text/javascript" src="' . $jsUrl . '"></script>';
|
||||
echo '<script type="text/javascript">window.onload = function () {
|
||||
var codes = document.getElementsByTagName("pre"),
|
||||
hlNames = {
|
||||
actionscript : /^as[1-3]$/i,
|
||||
cmake : /^(make|makefile)$/i,
|
||||
cs : /^csharp$/i,
|
||||
css : /^css[1-3]$/i,
|
||||
delphi : /^pascal$/i,
|
||||
javascript : /^js$/i,
|
||||
markdown : /^md$/i,
|
||||
objectivec : /^objective\-c$/i,
|
||||
php : /^php[1-6]$/i,
|
||||
sql : /^mysql$/i,
|
||||
xml : /^(html|html5|xhtml)$/i
|
||||
}, hlLangs = hljs.LANGUAGES;
|
||||
|
||||
for (var i = 0; i < codes.length; i ++) {
|
||||
var children = codes[i].getElementsByTagName("code"), highlighted = false;
|
||||
|
||||
if (children.length > 0) {
|
||||
var code = children[0], className = code.className;
|
||||
|
||||
if (!!className) {
|
||||
if (0 == className.indexOf("language-")) {
|
||||
var lang = className.substring(5).toLowerCase(), finalLang;
|
||||
|
||||
if (hlLangs[lang]) {
|
||||
finalLang = lang;
|
||||
} else {
|
||||
for (var l in hlNames) {
|
||||
if (lang.match(hlNames[l])) {
|
||||
finalLang = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!!finalLang) {
|
||||
var result = hljs.highlight(finalLang, code.textContent, true);
|
||||
code.innerHTML = result.value;
|
||||
highlighted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!highlighted) {
|
||||
var html = code.innerHTML;
|
||||
code.innerHTML = html.replace(/<\/?[a-z]+[^>]*>/ig, "");
|
||||
hljs.highlightElement(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}</script>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件实现方法
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public static function parse($text, $widget, $lastResult): string
|
||||
{
|
||||
$text = empty($lastResult) ? $text : $lastResult;
|
||||
|
||||
if (!Helper::options()->plugin('HighlightJs')->compatibilityMode) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
if ($widget instanceof Archive || $widget instanceof Comments) {
|
||||
$isMarkdown = $widget instanceof Comments ? Helper::options()->commentsMarkdown : $widget->isMarkdown;
|
||||
|
||||
return preg_replace_callback("/<(code|pre)(\s*[^>]*)>(.*?)<\/\\1>/is", function ($matches) use ($isMarkdown) {
|
||||
if ('code' == $matches[1] && !$isMarkdown) {
|
||||
$language = $matches[2];
|
||||
|
||||
if (!empty($language)) {
|
||||
if (preg_match("/^\s*(class|lang|language)=\"(?:lang-|language-)?([_a-z0-9-]+)\"$/i", $language, $out)) {
|
||||
$language = ' class="' . trim($out[2]) . '"';
|
||||
} elseif (preg_match("/\s*([_a-z0-9]+)/i", $language, $out)) {
|
||||
$language = ' class="language-' . trim($out[1]) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
return "<pre><code{$language}>" . htmlspecialchars(trim($matches[3])) . "</code></pre>";
|
||||
}
|
||||
|
||||
return $matches[0];
|
||||
}, $text);
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
fetch.sh
2
fetch.sh
@@ -4,4 +4,4 @@ curl 'https://highlightjs.org/api/download' \
|
||||
-H 'referer: https://highlightjs.org/download' \
|
||||
--data-raw '{"api":2,"languages":["apache","xml","bash","coffeescript","cpp","csharp","css","markdown","diff","ruby","go","http","ini","java","javascript","json","kotlin","less","lua","makefile","perl","nginx","objectivec","php","php-template","properties","python","python-repl","r","rust","scss","shell","sql","swift","yaml","typescript","vbnet","apache","dockerfile","ini","nginx","properties","yaml","css","less","scss","sql","java","markdown","latex","arduino","http","json","fortran","mathematica","matlab","r","coffeescript","javascript","lua","typescript","cpp","go","rust","swift","django", "dart", "plaintext"]}' \
|
||||
--compressed \
|
||||
--output highlight.zip
|
||||
--output highlight.zip
|
||||
|
||||
Reference in New Issue
Block a user