feat: support custom theme.
feat: support to set default theme color and css variable prefix options.
This commit is contained in:
parent
b3068350db
commit
c03510a8a7
14
README.md
14
README.md
@ -1,4 +1,6 @@
|
||||
# Hexo-Highlight-Shiki
|
||||
![NPM Version](https://img.shields.io/npm/v/hexo-highlighter-shiki?style=flat)
|
||||
|
||||
English丨[简体中文](README_zh-CN.md)
|
||||
|
||||
A hexo plugin to use [Shiki](https://github.com/shikijs/shiki) as code block highlighter.
|
||||
@ -33,11 +35,15 @@ The complete configuration is as follows:
|
||||
```yaml
|
||||
shiki:
|
||||
theme: one-dark-pro # see https://shiki.style/themes for supported themes.
|
||||
line_number: false
|
||||
strip_indent: true
|
||||
tab_replace: " "
|
||||
pre_style: true # Preserve the style of the <pre> tag, i.e., the theme's `background-color`.
|
||||
line_number: false # default: false
|
||||
strip_indent: true # default: true
|
||||
tab_replace: " " # default: " "
|
||||
pre_style: true # Preserve the style of the <pre> tag, i.e., the theme's `background-color`. default: true
|
||||
default_color: light # Only take effect when using multiple themes. default: light
|
||||
css_variable_prefix: --shiki- # Only take effect when using multiple themes. default: --shiki-
|
||||
additional:
|
||||
themes: # List of the TextMate theme json to be added.
|
||||
- path/to/theme.json
|
||||
langs: # List of the TextMate grammar json of languages to be added.
|
||||
- path/to/lang_grammar.json
|
||||
lang_alias: # List of the alias of languages.
|
||||
|
@ -1,4 +1,6 @@
|
||||
# Hexo-Highlight-Shiki
|
||||
![NPM Version](https://img.shields.io/npm/v/hexo-highlighter-shiki?style=flat)
|
||||
|
||||
[English](README.md)丨简体中文
|
||||
|
||||
一个使用 [Shiki](https://github.com/shikijs/shiki) 作为代码块高亮器的 Hexo 插件。
|
||||
@ -31,15 +33,18 @@ shiki:
|
||||
完整配置如下:
|
||||
```yaml
|
||||
shiki:
|
||||
theme: "one-dark-pro" # Theme, see https://shiki.style/themes for supported themes.
|
||||
theme: "one-dark-pro" # 主题,请参阅 https://shiki.style/themes 以获取支持的主题列表。
|
||||
line_number: false
|
||||
strip_indent: true
|
||||
tab_replace: " "
|
||||
pre_style: true # Preserve the style of the <pre> tag, i.e., the theme's `background-color`.
|
||||
pre_style: true # 保留 <pre> 标签的样式,即主题的 `background-color`。
|
||||
default_color: light # 仅在同时使用多个主题时生效。默认值:light
|
||||
css_variable_prefix: --shiki- # 仅在同时使用多个主题时生效。默认值:--shiki-
|
||||
additional:
|
||||
langs: # List of the TextMate grammar json of languages to be added.
|
||||
themes: # 要添加的主题的 TextMate 主题 json 列表。
|
||||
langs: # 要添加的语言的 TextMate 语法 json 列表。
|
||||
- path/to/lang_grammar.json
|
||||
lang_alias: # List of the alias of languages.
|
||||
lang_alias: # 语言的别名列表。
|
||||
your_alias1: lang_name1
|
||||
your_alias2: lang_name2
|
||||
```
|
||||
|
34
src/main.ts
34
src/main.ts
@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
import { bundledLanguages, createHighlighter, ShikiTransformer } from "shiki";
|
||||
import { bundledLanguages, bundledThemes, createHighlighter, ShikiTransformer } from "shiki";
|
||||
import type Hexo from "hexo";
|
||||
import { HighlightOptions } from "hexo/dist/extend/syntax_highlight";
|
||||
import { stripIndent, htmlTag } from "hexo-util";
|
||||
@ -13,22 +13,41 @@ export async function init(hexo: Hexo) {
|
||||
strip_indent: true,
|
||||
tab_replace: " ",
|
||||
pre_style: true,
|
||||
default_color: "light",
|
||||
css_variable_prefix: "--shiki-",
|
||||
additional: {
|
||||
themes: [],
|
||||
langs: [],
|
||||
lang_alias: {},
|
||||
},
|
||||
},
|
||||
hexo.config.shiki || {}
|
||||
);
|
||||
|
||||
// 处理自定义语言 json
|
||||
let additional_langs = [];
|
||||
if (config.additional.langs)
|
||||
for (const extra_lang of [].concat(config.additional.langs)) {
|
||||
additional_langs.push(JSON.parse(readFileSync(extra_lang, "utf8")));
|
||||
}
|
||||
const langs = [...Object.keys(bundledLanguages), ...additional_langs];
|
||||
|
||||
// 处理自定义主题 json
|
||||
let additional_themes = [];
|
||||
if (config.additional.themes)
|
||||
for (const extra_theme of [].concat(config.additional.themes)) {
|
||||
additional_themes.push(JSON.parse(readFileSync(extra_theme, "utf8")));
|
||||
}
|
||||
const themes = additional_themes.concat(
|
||||
(typeof config.theme === "string" ? [config.theme] : Object.values(config.theme)).filter(
|
||||
(theme) => theme in bundledThemes
|
||||
)
|
||||
);
|
||||
|
||||
// 创建 highlighter
|
||||
let highlighter_options = {
|
||||
langs: langs,
|
||||
themes: typeof config.theme === "string" ? [config.theme] : Object.values(config.theme),
|
||||
themes: themes,
|
||||
};
|
||||
if (config.additional.lang_alias && Object.keys(config.additional.lang_alias).length > 0) {
|
||||
highlighter_options["langAliases"] = config.additional.lang_alias;
|
||||
@ -45,6 +64,7 @@ export async function init(hexo: Hexo) {
|
||||
ansi: true,
|
||||
}
|
||||
);
|
||||
|
||||
const hexoHighlighter = (code: string, options: HighlightOptions) => {
|
||||
var code = config.strip_indent ? (stripIndent(code) as string) : code;
|
||||
code = config.tab_replace ? code.replace(/\t/g, config.tab_replace) : code;
|
||||
@ -57,7 +77,7 @@ export async function init(hexo: Hexo) {
|
||||
|
||||
// 处理代码块语法高亮
|
||||
let pre = "";
|
||||
const transformer = (): ShikiTransformer => {
|
||||
const transformerMarkedLine = (): ShikiTransformer => {
|
||||
return {
|
||||
line(node, line) {
|
||||
if (options.mark && options.mark.includes(line)) {
|
||||
@ -71,13 +91,15 @@ export async function init(hexo: Hexo) {
|
||||
pre = highlighter.codeToHtml(code, {
|
||||
lang,
|
||||
theme: config.theme,
|
||||
transformers: [transformer()],
|
||||
transformers: [transformerMarkedLine()],
|
||||
});
|
||||
else
|
||||
pre = highlighter.codeToHtml(code, {
|
||||
lang,
|
||||
themes: config.theme,
|
||||
transformers: [transformer()],
|
||||
transformers: [transformerMarkedLine()],
|
||||
defaultColor: config.default_color,
|
||||
cssVariablePrefix: config.css_variable_prefix,
|
||||
});
|
||||
// 删除多余内容
|
||||
pre = pre.replace(/<pre[^>]*>/, (match) => {
|
||||
@ -97,7 +119,7 @@ export async function init(hexo: Hexo) {
|
||||
(options.line_number || true) && // 代码块中未设置不显示行号
|
||||
(options.line_threshold || 0) < options.lines_length; // 代码行数超过阈值
|
||||
if (show_line_number) {
|
||||
const firstLine = options.firstLine || 1
|
||||
const firstLine = options.firstLine || 1;
|
||||
for (let i = firstLine, len = code.split("\n").length + firstLine; i < len; i++) {
|
||||
numbers += htmlTag("span", { class: "line" }, `${i}`, false) + "<br>";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user