pierre highlights 渲染指南:用 codeToHtml / codeToTokens 生成高亮 HTML 与 Shiki 兼容 Token
【免费下载链接】pierrepierre’s open source code项目地址https://gitcode.com/gh_mirrors/pi/pierre点击查看免费下载本篇技术指南以pierre/highlightspierre 仓库中的 WebAssembly 代码高亮包的渲染能力为核心系统讲解两个顶级 API——codeToHtml()与codeToTokens()的用法、返回结构与选项语义并结合仓库源码说明其底层实现原理。读完本文你将掌握如何把任意代码片段渲染为自包含的pre classhighlightsHTML 片段、如何获取逐行 Shiki 兼容 Token 并自行实现渲染器以及如何正确管理语言参数、多主题输出与 WebAssembly 运行时初始化。pierre/highlights是一个用 WebAssembly TextWAT编写的代码高亮器见 packages/highlights/package.json 的描述词法器内置于 Wasm 模块中导入后即可同步使用无需语言注册。本文对应的技能文档位于 skills/highlights/references/rendering.md其余主题主题加载与多主题渲染、流式输入、增量编辑分别见 Themes 与 Incremental editing。安装与入口按 skills/highlights/SKILL.md 的说明安装pnpm add pierre/highlights从pierre/highlights导入即可。包的条件导出exports字段见 packages/highlights/package.json会在 Node.js、浏览器browser.ts和 Cloudflare Workersworkerd.ts下自动完成 WebAssembly 初始化例如 packages/highlights/lib/browser.ts 在导入时直接执行init(new WebAssembly.Module(wasmBytes));因此普通使用场景不需要手动调用init()或注册语言导入后即可同步调用高亮函数。HTML 输出codeToHtmlcodeToHtml()将源代码渲染为一个完整的代码块片段import { codeToHtml } from pierre/highlights; import { pierreDark } from pierre/highlights/themes; const html new TextDecoder().decode( codeToHtml(const answer 42;, { lang: ts, theme: pierreDark }) );返回值的语义与内存借用codeToHtml()返回的是UTF-8 字节Uint8Array内容是一个pre classhighlightscode…/code/pre片段源码文本会被 HTML 转义主题样式以内联方式应用到每个span必须立即解码字节返回值可能直接引用 Wasm 线性内存的subarray。如果要在另一次高亮或 tokenization 调用之后继续持有该数据必须先调用.slice()拷贝。这条约束来自底层实现packages/highlights/lib/highlighter.ts 中的codeToHtml()以this.buffer.subarray(outStart, outStart outLength)的形式返回字节而buffer是 Wasmmemory.buffer的视图下一次调用或内存增长后的bindMemory()会复用同一块内存因此旧返回值可能被覆盖。TextDecoder在解码时本身会复制内容所以示例中decode()完成后再持有字符串是安全的。顶层 API 共享同一个高亮器实例文档明确顶层codeToHtml()与codeToTokens()共享同一个实例。对应源码 packages/highlights/lib/highlighter.ts 中的assertShared()模块持有唯一的shared高亮器HighlightsHighlighter由init()创建Wasm 线性内存无法收缩因此当共享实例超过 128 页128 × 64 KiB 8 MiB而后续输入又回到单个 page 以内时会基于同一个wasmModule重新创建实例以回收容量连续的大输入则会继续复用现有容量避免无谓重建代码注释同样提醒在完成高亮或 tokenization 之后应立即解码返回值或调用.slice()再长期持有。Token 输出codeToTokens当你需要自定义渲染器例如自己做 HTML、控制 span 属性、接入 transformer时使用codeToTokens()获取结构化 Tokenimport { codeToTokens } from pierre/highlights; import { pierreDark } from pierre/highlights/themes; const result codeToTokens(const answer 42;\n, { lang: ts, theme: pierreDark, }); console.log(result.tokens[0]); // ThemedToken[] for the first line console.log(result.fg, result.bg); // Root foreground and background colors返回结构与行切分规则TokensResult.tokens是ThemedToken[][]每个元素对应一行ThemedToken[]类型定义见 packages/highlights/lib/index.ts。行切分遵循以下规则行终止符不包含在 token 的content中末尾的换行符会额外产生一个空行最后一行元素为空数组offset以 UTF-16 代码单元计数从完整输入的开头算起因此多行输入中后一行 token 的偏移是全局递增的。底层实现位于 packages/highlights/lib/tokens.ts 的lineRecordsToTokens()Wasm 词法器产出的 UTF-16 记录用0xffffffff作为行标记JavaScript 侧据此切分每行、把样式记录映射成ThemedToken对象。Token 字段表Token 字段含义content,offset文本及其绝对 UTF-16 起始索引color,fontStyle单主题颜色与 Shiki 风格字体标志htmlStyle多主题样式包括自定义属性应整体应用该 maptype1注释comment2字符串string3正则regex否则为0或被省略bgColor,htmlAttrs可选的背景色与 span 属性供渲染器 / transformer 集成使用各字段的类型定义见 packages/highlights/lib/index.ts 的ThemedToken接口其注释补充了更多细节fontStyle位标志Highlights 自身只输出斜体1与粗体2下划线4与删除线8由 transformer 提供。单主题模式下rangeToToken()/lineRecordsToTokens()把主题样式的italic与weight 600编码进该位掩码type标准类型映射standardTypes数组把词法类型见 packages/highlights/lib/token-types.ts 的 75 个 slot映射为 TextMate 标准类型——string.regex→3comment及comment.*→1string及string.*→2其余为0仅当类型非 0 时才会写出type字段。文档强调该语义与 Shiki 兼容但词法器边界与语法分类可能与 Shiki 不同htmlStyle共享对象在多主题模式下相同 token id 的运行会共享同一个htmlStyle对象themeHtmlStyle()按“主题集合 前缀 token id”构建一次并缓存。因此自定义单个 token 的样式时应替换replace该对象而不是原地修改否则会影响同一行乃至整个文档中所有同 id 的 token。使用自定义 HTML 渲染器的注意事项文档给出三点实操建议渲染 token 时使用文本节点或对content做转义防止注入同时应用根颜色fg/bg与 token 样式多主题模式下fg与bg可能是CSS 声明列表见下文不要把它们当作单个颜色值。选项与语言codeToHtml()与codeToTokens()接受相同的输入类型与主题选项输入可以是string、Uint8Array或ArrayBuffer字节按 UTF-8 解码必须提供lang并且theme与themes二选一类型ThemeOptions强制执行这一约束。选项表选项含义lang内置语言名或别名类型为Langtheme一个 ZedTheme或ThemeFamily对象themes非空的命名主题对象映射表参见 ThemescssVariablePrefixCSS 变量颜色与主题属性的前缀默认--hls-defaultColor与themes联用内联主题键默认light或false或light-dark()tokenizeMaxLineLength仅 tokenization行长度达到该 UTF-16 长度时整行变成一个无语法样式的 token0或省略表示禁用其中defaultCssVariablePrefix --hls-定义在 packages/highlights/lib/theme.ts主题表打包、颜色校验支持 3/4/6/8 位十六进制与color(display-p3 …)数值与 HTML 属性转义也在该文件中实现。tokenizeMaxLineLength 的底层行为tokenizeMaxLineLength是一个 DOM 安全限制语义对齐 Shiki 的同名选项文档补充了两个关键行为它减少的是 token 对象数量超长行只产出一个不带语法样式的 token对应lineRecordsToTokens()中end - start max的分支从而避免渲染器处理海量 span词法器仍会完整处理该行以保留后续行的词法状态例如多行注释、字符串上下文该选项同样作用于流式streaming与 live tokenization但不是 HTML 选项——codeToHtml()不接受它CodeToHtmlBaseOptions与CodeToTokensBaseOptions的类型分层印证了这一点。语言名与回退策略语言名与别名不区分大小写langIdOf()内部String(lang).toLowerCase()未知语言名会抛出RangeErrorunknown lang: ${lang}见 packages/highlights/lib/highlighter.tsHighlights不做任何自动语言检测或文件名解析因此对来自外部的语言标签要做校验并显式选择回退import { isSupportedLanguage } from pierre/highlights; const requestedLanguage: string typescript; const lang isSupportedLanguage(requestedLanguage) ? requestedLanguage : plain;isSupportedLanguage()把字符串收窄为Lang类型其判断依据是内置语言映射表packages/highlights/lib/languages.ts 中的LANGS纯文本别名包括plain、text、plaintext、txt都映射到语言 id 0词法器全部内置WAT 实现位于 packages/highlights/src自定义 TextMate 语法注册属于pierre/diffs中的 Shiki API不在 Highlights 的职责范围内。运行时与类型对于需要自行管理已编译WebAssembly.Module的嵌入方模块提供两个同步入口API行为init(module)替换共享高亮器实例返回新的HighlightercreateHighlighter(module)创建隔离的Highlighter不替换共享实例两者都是同步操作且都要求传入模块在 packages/highlights/lib/highlighter.ts 中分别对应init与createHighlighter。Highlighter接口暴露codeToHtml()与codeToTokens()签名与上述顶级函数一致见 packages/highlights/lib/index.ts。普通使用直接导入包入口即可获得自动初始化无需手动管理模块。核心公共类型包括HighlighterLangCodeToHtmlBaseOptions/CodeToHtmlOptionsCodeToTokensBaseOptions/CodeToTokensOptionsThemeOptionsThemedTokenTokensResult主题类型Theme、ThemeFamily、ThemeStyle、ThemeSyntaxSettings、ThemePlayer的细节见 Themeslive 类型与tokenNames见 Incremental editing。多主题输出与根样式虽然多主题渲染的完整主题加载方式在 Themesrendering.md中对渲染侧做了三点补充值得在此一并说明传入themes时token 的htmlStylemap 中默认主题defaultColor指定的键默认light以普通color/font-style/font-weight内联应用其余主题以${cssVariablePrefix}${key}命名的自定义属性输出实现见 packages/highlights/lib/tokens.ts 的themeHtmlStyle()当defaultColor: false所有主题都输出为自定义属性时TokensResult会提供rootStyle应将其作为容器pre的内联样式而当存在内联默认主题时根样式是background-color:${bg};color:${fg}形式——注意fg/bg可能包含额外的 CSS 声明分号分隔的声明列表不要把整个字符串当成单个颜色值见themeMeta()的拼接逻辑相等运行的 token 会共享同一htmlStyle对象以节省内存自定义单个 token 时请替换对象。小结pierre/highlights的渲染 API 设计围绕两条主线codeToHtml()提供开箱即用的完整 HTML 代码块codeToTokens()提供 Shiki 兼容、逐行、可自定义的 Token 结构。两者共享同一个 Wasm 高亮器实例输入统一支持字符串与 UTF-8 字节主题选项支持单主题theme与多主题themes含defaultColor三种模式。使用时的三个关键纪律是及时解码或复制codeToHtml()返回的字节、把多主题下的htmlStyle整体应用并替换而非修改共享对象、对外部语言标签用isSupportedLanguage()做校验并回退到plain。更深入的主题切换与多主题渲染细节可继续阅读 Themes。赞分享【免费下载链接】pierrepierre’s open source code项目地址https://gitcode.com/gh_mirrors/pi/pierre点击查看免费下载相关推荐Highlights 主题系统指南pierre/highlights 的 65 套 Shiki 目录主题与 10 套 Pierre 主题使用与原理Highlights 主题系统指南pierre/highlights 的 65 套 Shiki 目录主题与 10 套 Pierre 主题使用与原理 pieHighlights 性能基准全解析Pierre 高亮引擎的 HTML、Token、流式与内存实测数据Highlights 性能基准全解析Pierre 高亮引擎的 HTML、Token、流式与内存实测数据 本指南以 packages/highlights/bePierre Highlights用 WebAssembly Text 构建的高性能语法高亮引擎实战指南Pierre Highlights用 WebAssembly Text 构建的高性能语法高亮引擎实战指南 pierre/highlights 是 Pierr上一篇JUnit4测试代码质量工具AWS CloudFormation下一篇TensorFlow Hub 模型兼容性指南TF1 Hub 格式与 TF2 SavedModel 在 TF1/TF2 环境下的加载、微调与创建支持矩阵创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

AnyPS5项目解析:跨平台PS5兼容层技术原理与应用

AnyPS5项目解析:跨平台PS5兼容层技术原理与应用

我无法基于当前输入生成符合要求的博文。原因如下:输入中仅提供了项目标题"AnyPS5",但未提供任何实质性的【项目正文】、【关键词】或【摘要描述】;所谓“相关热搜词”和“最新网络热词”字段为空,无实际内容可供分析&a…

2026/10/10 5:19:31 阅读更多 →
机器学习预测股票:目标设计、特征工程与时间序列验证指南

机器学习预测股票:目标设计、特征工程与时间序列验证指南

简介:这份论文以股票预测为研究对象,系统梳理了仅使用历史数据与结合金融新闻文本的两类预测方法,涵盖分段线性表示、高斯过程分类、随机森林、深度递归神经网络、CNN、LSTM以及双重注意力机制等核心技术,并进一步介绍新闻事件结构…

2026/10/10 5:19:31 阅读更多 →
Python+Netmiko网络设备自动化配置实战:从批量备份到VLAN下发

Python+Netmiko网络设备自动化配置实战:从批量备份到VLAN下发

一直手动敲命令做网络配置的朋友,应该都体会过那种感觉:几十台交换机,一台台登录、一条条敲VLAN、改接口、配路由,碰上割接窗口更是连水都顾不上喝。我真正下决心用Python做网络设备自动配置,是在一次凌晨两点的批量变…

2026/10/10 5:19:31 阅读更多 →

最新新闻

Cursor配置本质是工作流重构:让AI成为可复用的编码协作者

Cursor配置本质是工作流重构:让AI成为可复用的编码协作者

1. 为什么“Cursor配置”不是设置问题,而是工作流重构命题“Cursor怎么配置才好用?”——这句提问背后藏着一个被普遍低估的事实:绝大多数人把Cursor当成“带AI的VS Code”,却没意识到它本质是一个可编程的智能协作终端。我最初也…

2026/10/10 6:02:47 阅读更多 →
workbuddy-to-dsh 实用教程:从 JSON 到 dsh 的数据迁移指南

workbuddy-to-dsh 实用教程:从 JSON 到 dsh 的数据迁移指南

先说一个很多人都遇得到的问题:你手里的任务和日程记录全躺在 workbuddy 里,某天想把它导出来接进自己的报表系统、自动化脚本或者新换的效率工具,结果发现导出的 JSON 字段跟目标格式完全对不上。自己写脚本去适配,看起来不难&am…

2026/10/10 6:02:47 阅读更多 →
SpringBoot咖啡厅座位预约系统:从并发控制到状态流转的设计实践

SpringBoot咖啡厅座位预约系统:从并发控制到状态流转的设计实践

1. 咖啡厅为什么要一个座位预约系统:从等位痛点聊到课题价值先说个很现实的场景。你去一家热门咖啡厅,下午两三点正是人多的时候,进门一看,靠窗的位子满了、插座旁边的位子满了、沙发区也满了。你端着咖啡站在过道里,等…

2026/10/10 6:02:46 阅读更多 →
PCA9422搭配PIC18F86J16的便携设备电源管理实战解析

PCA9422搭配PIC18F86J16的便携设备电源管理实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 6:02:46 阅读更多 →
Django认证与权限体系深度解析:从内置机制到实战踩坑

Django认证与权限体系深度解析:从内置机制到实战踩坑

接手一个新项目或者复盘别人代码的时候,我最先翻的往往不是业务逻辑,而是settings.py里的认证与权限配置。一个系统的认证权限设计,直接决定了它的安全边界,也决定了后续功能扩展时是顺滑还是处处踩坑。今天这篇就围绕Django的认证…

2026/10/10 6:02:46 阅读更多 →
Python BoundedSemaphore 有界信号量详解

Python BoundedSemaphore 有界信号量详解

Python BoundedSemaphore 有界信号量详解一、Python BoundedSemaphore 有界信号量详解1、 引言2、信号量基础回顾2.1、 什么是信号量2.2、 普通 Semaphore 的问题3、 BoundedSemaphore 的原理3.1、 有界约束3.2、 源码实现4、基本用法4.1、 标准「获取-释放」模式4.2、 使用上下…

2026/10/10 6:01:46 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →