diff --git a/README.md b/README.md index 77857fe..28fc820 100644 --- a/README.md +++ b/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
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 thetag, 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. diff --git a/README_zh-CN.md b/README_zh-CN.md index 8bd0842..ddd631b 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -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 thetag, i.e., the theme's `background-color`. + pre_style: true # 保留标签的样式,即主题的 `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 ``` diff --git a/src/main.ts b/src/main.ts index a048495..5efdf5a 100644 --- a/src/main.ts +++ b/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(/]*>/, (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) + "
"; }