ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

highlight.js 主题开发指南:从作用域到自动校验的完整实战

highlight.js 主题开发指南:从作用域到自动校验的完整实战 highlight.js 主题开发指南从作用域到自动校验的完整实战【免费下载链接】highlight.jsJavaScript syntax highlighter with language auto-detection and zero dependencies.项目地址: https://gitcode.com/gh_mirrors/hi/highlight.jshighlight.js 是一个零依赖、自带语言自动检测能力的 JavaScript 语法高亮库而主题Theme是它呈现效果的全部——一个主题就是一个独立的 CSS 文件用统一的hljs-*类名体系为不同语言的代码上色。本指南将带你掌握 highlight.js 主题的底层设计哲学语言无关的最小作用域集合、主题文件的书写规范与禁止项/允许项边界、根容器必备规则、subst作用域的坑以及如何用官方自动校验工具一键检查主题的作用域覆盖度与对比度可访问性。核心原则主题与语言无关highlight.js 主题设计的首要原则是语言无关language agnostic。项目官方文档明确指出Highlight.js themes are language agnostic.这句话的含义是highlight.js 并没有为一门语言单独设计一套花哨的类名而是维护了一套有限的、跨语言通用的类名集合即 scopes让同一套主题能够在几乎所有语言上表现良好。官方文档给出了两个重要推论主题往往趋于极简文档也承认这一点随项目演进已逐步改善不可能在所有场景下精确模仿其他高亮引擎的主题效果。这一设计与 highlight.js 的渲染模型直接对应语法解析器产出带scope的语法树节点HTML 渲染器 html_renderer.js 把每个 scope 转成 CSS 类名——顶层 scope 加配置的类前缀默认hljs-再包成span。因此主题作者只需要面对一套稳定的类名契约无需关心具体语言内部实现。主题是什么一份针对 scopes 的 CSS 文件一个主题就是单个 CSS 文件它为 scopes 参考文档 css-classes-reference.rst 中列出的作用域定义样式。这条约定意味着你必须为通用/核心类名集合提供样式你可以有意跳过某些类例如.attr通常会被刻意留空不设样式跳过是否合理可以借助官方提供的自动校验工具获得额外指导见下文。允许合并同类样式你不需要为每一组类名发明一套独立的样式完全可以按语义/颜色将它们归组。官方文档给出的示例.hljs-string, .hljs-section, .hljs-selector-class, .hljs-template-variable, .hljs-deletion { color: #800; }想用几种独特的样式组合都行——as few or as many as you want。这一理念在官方默认主题 default.css 中体现得淋漓尽致它把type/string/number/selector-id/selector-class/quote/template-tag/deletion合并为#880000把regexp/symbol/variable/template-variable/link/selector-attr/operator/selector-pseudo合并为#ab5656并在文件顶部明确注释purposely ignored来声明.hljs-formula、.hljs-attr、.hljs-property、.hljs-params这四个空规则是刻意为之。了解可样式化的作用域全集为了让主题与语法职责对齐理解 scopes 参考是必要的。以下分类摘录自 css-classes-reference.rst是主题文件实际可命中的完整作用域清单类别作用域含义通用keywordAlgol 风格语言中的关键字通用built_in内建或库对象常量、类、函数通用type数据类型如string、int、array通用literal内建值的特殊标识符true、false、null通用number数字含单位和修饰符通用operator运算符、-、、\|、通用punctuation需要弱化高亮的辅助标点括号、方括号等通用property对象属性obj.prop1.prop2.value通用regexp正则字面量通用string字符串、字符字面量通用char.escape转义字符如\n通用subst字符串字面量内部的已解析片段通用symbol符号常量、内部字符串、goto 标签通用class/function已废弃请用title.class/title.function通用variable变量通用variable.language语言中具特殊含义的变量this、window、super、self通用variable.constant常量变量如MAX_FILES通用title类或函数的名字通用title.class/title.class.inherited类名 / 被继承的类名通用title.function/title.function.invoke函数名 / 被调用时的函数名通用params声明处的函数参数块通用comment/doctag注释 / 注释内的文档标记如params元信息meta标志、修饰符、注解、预处理指令等元信息meta.promptREPL 或 shell 提示符元信息meta keyword/meta stringmeta 块内的关键字 / 字符串嵌套而非子作用域标签属性section配置文件的小节标题、文本标记中的标题标签属性tag/nameXML/HTML 标签 / 标签名或 s 表达式的首个词标签属性attr无语义定义的属性名JSON 键、ini 设置名等标签属性attribute带结构化值部分的属性名如 CSS 属性文本标记bullet、code、emphasis、strong、formula、link、quote列表项、代码块、强调、加粗、数学公式、超链接、引用CSSselector-tag、selector-id、selector-class、selector-attr、selector-pseudo各类 CSS 选择器模板template-tag、template-variable模板语言的标签 / 变量diffaddition、deletion新增/变更行、删除行关于作用域的通用性问题文档特别指出通用作用域general purpose scopes意在用于任何语言其他作用域在语义正确时也可使用。例如一个通用语言若允许内联 URL使用link类是合理的但考虑到很多主题未必为此设计过为了获得更好的主题兼容性改用string可能是更稳妥的选择。子作用域sub-scope的类名生成规则部分作用域名中含有.这是子作用域记号。生成 HTML 时它会展开为多个计算后的类名嵌套深度决定子作用域名追加的下划线数量。以title.class.other为例顶层作用域永远是应用了配置前缀默认hljs-的那个hljs-title第一层子作用域追加一个下划线class_第二层子作用域追加两个下划线other__生成的 HTML 为span classhljs-title class_ other__Render/span主题可以直接用如下选择器精确命中.hljs-title.class_.other__ { color: blue; }这一规则的实现位于 html_renderer.jsscopeToCSSClass把含.的作用域拆分为${prefix}${顶层名}与逐层追加_的子级名并以空格拼接为多个类名。新作用域与保留作用域较新的作用域operator、punctuation、property尚未获得所有主题的普遍支持。主题未支持时这些 token 不会被高亮——这不是说不要用它们而是随着支持度提升它们会高亮得越来越好。保留作用域ReasonML 语法使用的pattern-match、typing、constructor、module-access、module留在文档中仅为存档用途不应在其他语法中使用因为它们在所有主题中支持度都非常差。主题检查工具自动校验作用域覆盖与可访问性官方提供了主题自动检查工具checkTheme.js用来判断你的主题是否提供了足够的作用域覆盖。用法如下./tools/checkTheme.js src/styles/your_theme.css按照工具给出的提示修复问题即可。从源码 checkTheme.js 看该工具会做两件核心事情按分组逐类检查作用域覆盖工具内部定义了 CODEprogram code含comment、keyword、built_in、type、literal、number、property、regexp、string、subst、symbol、variable、title、params、doctag、meta、attr、attribute、OTHERmeta keyword、meta string可选、HIGH_FIDELITYtitle.class、title.class.inherited、punctuation、operator、title.function、char.escape、variable.language可选、CONFIG、MARKUP、CSS、TEMPLATES、DIFF 共 8 组。对每个作用域它通过scopeToSelector把它转换为形如.hljs-xxx的选择器子作用域同样按下划线规则展开例如title.class变为.hljs-title.class_再检测 CSS 规则中是否存在对应的声明如果某个作用域完全没有命中就会以黄色高亮提示 scope xxx is not highlighted如果是空声明skips_rule则会提示该作用域被故意留空。输出可访问性对比度报告Accessibility Report工具以.hljs规则作为基准背景/前景色支持light-dark()双模式颜色解析遍历所有带颜色的规则使用wcag-contrast计算每个规则的前景/背景 WCAG 对比度并以表格形式输出 ratio、选择器、前景色/背景色色块没有显式前景/背景的规则会从根容器继承基准色后参与计算。主题设计的 Dos and Donts官方对主题容器的排版行为有明确边界这些约束看似随意却是长期实践中make sense的结论。禁止使用影响字符布局的属性根容器.hljs上的非标准边框、margin、padding特定字体族specific font faces字号、行高以及其他任何影响容器内字符位置与大小的属性。原因是高亮主题应当只负责上色字符的排布由宿主页面统一控制主题擅自修改布局会导致不同主题切换时页面尺寸跳动也破坏与代码编辑页面的协调。允许使用颜色显然italic斜体、bold加粗、underline下划线等字体效果图片背景。根容器.hljs的必备规则有一组公共规则**必须逐字verbatim**定义在根容器上.hljs { display: block; overflow-x: auto; padding: 0.5em; }注意两点如果你的主题属于核心项目内部不需要手工添加这些规则——它们会在构建阶段由 makestuff.js 自动注入。源码中DEFAULT_CSS常量定义的基线样式是pre code.hljs { display: block; overflow-x: auto; padding: 1em; } code.hljs { padding: 3px 5px; }在installCleanCSS中这份基线 CSS 会被拼接到主题内容之前再经clean-css压缩后写入构建产物。正因如此default.css 顶部注释说明它特意把基线 CSS 原样内置使其成为唯一一份无需构建即可直接从仓库取用的 CSS 文件。如果你在自己项目中维护外部主题不随核心仓库发布则需要自行包含上述根容器规则.hljs上display: block; overflow-x: auto; padding: 0.5em;。别忘了.subst字符串内已解析片段的默认色.subst用于字符串内部被解析的片段如${variable}中的变量部分几乎总是应该重置回默认文字颜色否则它会意外继承字符串的高亮色视觉上显得突兀。官方推荐写法.hljs, .hljs-subst { color: black; }从模式定义侧看subst在 modes.js 等语法库中作为字符串模式的组成部分被产出因此几乎每种语言的字符串内部都会命中它——这也解释了为什么主题必须显式处理它。对照 default.css.hljs-subst { /* default */ }正是继承根容器默认色这一约定的体现而 monokai.css 则把.hljs-subst与字符串一起染成了#a6e22e这是刻意让字符串内插内容与整体字符串同色的风格选择。贡献你自己的主题如果你要为 highlight.js 仓库贡献主题需在 CSS 文件顶部加入带署名与元信息的注释块格式自由/* Fancy style (c) John Smith emaildomain.com */然后用./tools/checkTheme.js自检主题通过后以 pull request 方式提交。仓库内 src/styles 目录已包含 100 个主题如default.css、monokai.css、github.css、vs2015.css、a11y-dark.css等可作为风格、命名与注释规范的直接参照。从零编写一个主题的推荐流程综合官方文档与源码约定编写主题的完整流程可以归纳为确定基线参照default.css的结构先写根容器.hljs的背景色与默认前景色若主题独立于核心仓库分发则补上display: block; overflow-x: auto; padding: 0.5em;基线规则。覆盖核心作用域确保keyword、built_in、type、literal、number、string、comment、title、variable、meta、attr、attribute等 CODE/CONFIG 组作用域都有命中。补充标记类作用域视主题定位决定是否覆盖 MARKUPsection、bullet、strong、emphasis等、CSS各类selector-*、TEMPLATEStag、name、attr、template-*与 DIFFaddition、deletion。处理.subst将其颜色重置为根容器默认前景色。风格化新作用域按需为operator、punctuation、property等较新作用域上色注意它们尚未被所有主题支持。运行自动校验执行./tools/checkTheme.js src/styles/your_theme.css根据分组缺失提示补齐作用域并查看 Accessibility Report 的对比度数值必要时调整配色。检查布局约束确认没有为.hljs设置字体、字号、行高、边框或非常规 padding/margin。总结highlight.js 的主题体系建立在语言无关的有限作用域集合之上一份主题 一个针对hljs-*类名契约的 CSS 文件。理解 scopes 参考 的分类与子作用域下划线规则、遵守根容器布局边界与.subst约定、善用 checkTheme.js 的作用域覆盖检查与对比度报告你就能写出既跨语言通用、又可访问、风格统一的高质量主题并顺利通过仓库的贡献流程。【免费下载链接】highlight.jsJavaScript syntax highlighter with language auto-detection and zero dependencies.项目地址: https://gitcode.com/gh_mirrors/hi/highlight.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表