用途
本技能用于扩展 @tanstack/highlight 的语言支持,即在 configure-selective-highlighting 的基础上,为高亮库添加自定义或内置语言。它围绕 defineLanguage、LanguageDefinition、TokenRange、HighlightTokenClass 和 TokenizerContext 这几个核心概念展开,指导开发者编写隔离的分词器,将源码转换为语义化的 token 范围。
主要能力
- 使用 defineLanguage 定义语言,可指定 name、aliases 和 tokenize 函数。
- tokenize 返回 TokenRange 数组,每个范围包含 start、end 和 className,用于标记源码中的语义片段。
- 未覆盖的间隙自动保持为纯文本。
- 通过 TokenizerContext 实现可选的语言委托,让外层语言定义保持独立,由应用决定是否注册嵌入目标。
- 支持通过注册表委托嵌入内容,例如在 script-document 中委托给 js 语言。
- 强调源码重建不变式:分词后 token 的 value 拼接必须等于原始源码。
使用方式
基本流程是:先定义语言(defineLanguage),再通过 createHighlighter 注册语言并创建高亮器,最后调用 highlighter.tokenize(code, { lang: '...' }) 获取分词结果。
示例中定义了一个 task-list 语言,用正则匹配 TODO、DONE、BLOCKED 等关键词,并返回对应的 TokenRange。DONE 映射为 inserted 类,其余映射为 keyword 类。
对于嵌入内容,示例展示了 script-document 语言如何通过 context.hasLanguage('js') 和 context.tokenize(match[1], 'js') 委托给 js 语言,并将返回的范围偏移到正确位置。外层定义不直接导入 js 定义,从而避免将嵌入依赖打包进每个外层语言包。
适用场景
- 需要为 @tanstack/highlight 添加自定义语言或领域特定语法高亮。
- 需要在一种语言中嵌入另一种语言的高亮(如 HTML 中嵌入 JavaScript)。
- 需要控制语言注册与打包体积,避免不必要的依赖引入。
- 需要为已发布语言编写质量门禁测试。
限制与注意事项
- 范围必须是非重叠、从零开始、结束位置不包含的 UTF-16 偏移量。结束位置应与 String.prototype.slice() 一致,不包含结束偏移。
- 核心会按源码位置排序并丢弃后续重叠范围,因此较早的宽泛范围可能抑制更具体的范围。
- 不要在语言定义中直接导入嵌入定义,否则会使嵌入依赖成为每个外层语言包的一部分。
- 不要臆造语言专属的 token 类,应使用固定的语义联合类型,以保证主题完整且与语言无关。
- 已发布语言需要有效的代码夹具、源码重建测试、针对性回归测试和显式导入体积评估。
- 委托目标必须注册在同一个注册表中,否则委托内容会保持为纯文本。
- 语言隔离与嵌入深度之间存在张力,应使用 TokenizerContext 进行可选委托,由应用注册目标。
常见错误
- 返回包含式范围结尾(end 多减 1)。
- 返回重叠的 token 范围。
- 在语言中直接导入嵌入定义。
- 臆造语言专属 token 类。
- 未经过分词器质量门禁就发布。
- 遗漏嵌入分词器的注册。
以上内容均来自技能文档,未提供的功能、收费、价格、平台或效果信息暂未提供。