为 Sway 构建 Prism 语法高亮:prism-sway 语言定义与构建流程解析
2026/9/12 6:23:24 网站建设 项目流程

为 Sway 构建 Prism 语法高亮:prism-sway 语言定义与构建流程解析

【免费下载链接】sway🌴 Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway

Sway 是 Fuel 生态中用于编写智能合约与脚本的领域专用语言。为了让开发者社区能够借助 PrismJS 在网页、文档与代码分享场景中高亮 Sway 代码,本仓库在 scripts/prism 目录下维护了一套独立的 Prism 语言定义与构建脚本。本文将基于 scripts/prism/README.md 的构建指引,逐层拆解prism-sway.js的 token 定义、components.json的组件清单、build.sh的完整构建流程,并给出可复现的更新、构建与本地调试操作步骤,帮助你在修改高亮规则后快速产出可发布的prism-sway.min.js

一、文件组成与各自职责

scripts/prism 目录只包含四个文件,职责非常清晰:

文件作用
README.md构建与测试操作指引(本文依据的主文档)
prism-sway.jsSway 语言的 Prism 语法定义(源文件,需人工维护)
prism-sway.min.js构建产物,供网页直接引用的压缩版本
components.jsonPrism 官方构建系统使用的组件清单,在其中注册了sway语言
build.sh自动克隆 Prism、注入 Sway 定义并执行官方构建的脚本

工作流的核心是:修改prism-sway.js→ 运行./build.sh→ 得到更新后的prism-sway.min.js。这与 README 第一句 "Updateprism-sway.jsfile" 完全对应。

二、prism-sway.js:Sway 语言定义逐项拆解

prism-sway.js 是整条链路的灵魂。它以 IIFE 的形式向全局Prism对象注册Prism.languages.sway,通过一系列正则模式将 Sway 源码切分为可着色的 token。以下按定义顺序说明各 token 的技术细节。

1. 注释:支持 4 层嵌套的多行注释

Sway 允许多行注释嵌套,这是很多语言的高亮器容易处理错的地方。prism-sway.js在 第 3–8 行 用递归替换<self>占位符的方式构造了一个可嵌套 4 层的多行注释正则:

var multilineComment = /\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source; for (var i = 0; i < 2; i++) { // support 4 levels of nested comments multilineComment = multilineComment.replace(/<self>/g, function () { return multilineComment; }); }

随后在 第 12–23 行 注册两类注释:嵌套多行注释/* ... */greedy: true,使用(^|[^\\])前置断言避免把转义场景误判)和单行注释// ...(前置断言(^|[^\\:])保证不会吞掉://之类的路径写法)。

2. 字符串、字符与字节前缀

  • 字符串模式(第 24–27 行)同时支持可选的b前缀(字节串)、r#...形式的原始字符串(可带多个#作为定界标记),并处理\\转义。
  • 字符模式(第 28–32 行)支持\xNN十六进制转义、\u{...}Unicode 码点转义,并alias: 'string'复用字符串着色。

3. 属性(attribute)

第 33–40 行 定义了#![...](内部属性)与#[...](外部属性)的匹配,alias: 'attr-name',内部字符串单独着色。Sway 中常见的#[storage(read)]#[test]等即由它高亮。

4. 闭包参数:避免与按位或|混淆

Sway 闭包用|x, y|声明参数,这与按位或运算符字形相同。定义在 第 42–54 行 的closure-params通过前置断言([=(,:]\s*|\bmove\s*)或前瞻(?=\s*(?:\{|->))严格限定上下文,只在确实可能是闭包形参的位置匹配,并把两端的|单独列为closure-punctuation。这是整个定义里最容易踩坑的部分,修改时务必保留这个上下文约束。

5. 格式化字符串片段与变量

第 56–61 行 定义了$name:形式的 fragment specifier 以及$\w+变量。Sway 的字符串插值语法会用到$var引用。

6. 定义类 token:fn / enum / struct / 模块声明

  • function-definition(第 63–67 行):fn关键字后紧跟的函数名,alias: 'function'
  • type-definition(第 68–72 行):enumstruct后紧跟的类型名,alias: 'class-name'
  • module-declaration(第 73–87 行):覆盖mod/script/contract/predicate/library声明的程序类型关键字,以及crate::self::super::这类路径前缀,alias: 'namespace'

7. 关键字与内置原语

第 88–92 行 定义了两组关键字:

  1. 语言关键字:asbreakconstcontinueelseenumfnforifimplinletmatchmodmutprivpubrefreturnstaticstructtraittypeunsizedusewhere等(覆盖 Sway 的程序类型关键字contractpredicatelibraryscriptself/Self)。
  2. 原语类型:u8u16u32u64u128usizef32f64boolcharstr

8. 函数调用、宏、常量与类名

  • function(第 96 行):以小写或下划线开头的标识符后紧跟((或::<),按 snake_case 约定避免大写开头误报。
  • macro(第 97–100 行):name!形式,如log()之类,alias: 'property'
  • constant(第 101 行):[A-Z_][A-Z_\d]+全大写常量。
  • class-name(第 102 行):[A-Z]\w*首字母大写类型名。
  • namespace(第 104–109 行):形如a::b::的路径命名空间。

9. 数字:进制前缀、下划线分隔与类型后缀

第 111–112 行 是 Sway 数字字面量的完整支持:

  • 十六进制0x...、八进制0o...、二进制0b...
  • 十进制(含小数与Ee科学计数法);
  • 全部支持_视觉分隔符(如1_000_000);
  • 可选类型后缀:u8/u16/u32/u64/usizef32/f64

10. 布尔、标点与运算符

  • boolean(第 113 行):true/false
  • punctuation(第 114 行):->..=.../../.::、大中小括号与逗号分号。
  • operator(第 115 行):覆盖赋值、算术、位运算、比较与逻辑运算符,包括==!=&&||<</>>@?等。

最后,第 118–119 行 做了两处引用补齐:把closure-params内部剩余的rest指向整个 sway 定义以便继续递归着色,同时把attribute内部的字符串恢复为字符串 token。

三、components.json:把 Sway 注册进 Prism 构建系统

Prism 的官方构建脚本依赖一个组件清单来决定打包哪些语言与插件。components.json 即承担此角色。其中与 Sway 直接相关的声明位于 第 42–47 行:

"languages": { "sway": { "title": "Sway", "owner": "Fuel" } }

其余部分是构建元信息:core指定必须引入components/prism-core.jsthemes列出可选的 CSS 主题(Default、Dark、Funky、Okaidia、Twilight、Coy、Solarized Light、Tomorrow Night),plugins列出可选的增强插件(行号、工具栏、复制到剪贴板等)。当build.sh把该文件复制进 Prism 仓库后,官方构建工具就能识别sway语言并生成对应的prism-sway.js/prism-sway.min.js

四、build.sh:完整的构建链路

build.sh 是整个流程的自动化实现,共分五步:

  1. 克隆 Prism 仓库(第 6–8 行):若当前目录下不存在prism/目录,则通过git clone拉取 PrismJS 官方仓库。
  2. 注入 Sway 定义(第 10–11 行):将维护中的 prism-sway.js 复制为prism/components/prism-sway.js,将 components.json 复制到 Prism 仓库根目录,覆盖其默认组件清单。
  3. 安装依赖(第 13 行):npm ci按锁文件安装 Prism 的构建依赖。
  4. 执行官方构建(第 15 行):npm run build调用 Prism 自身的构建脚本,基于组件清单产出压缩版语言文件。
  5. 回拷产物并清理(第 16–21 行):把生成的components/prism-sway.min.js复制回本仓库根目录覆盖 prism-sway.min.js;除非命令带keep参数,否则删除克隆的prism/目录。

注意:npm ci需要本机已安装 Node.js 与 npm,且克隆 Prism 需要网络与 git 访问权限;因此构建前置条件是具备 Node 环境并能访问远程 git 仓库。

五、更新与构建:标准操作步骤

按 README.md 的指引,更新高亮规则的完整流程为:

  1. 编辑 prism-sway.js,按需调整上述任一 token 的正则或别名。
  2. 执行构建:
./build.sh
  1. 构建成功后,根目录下的 prism-sway.min.js 即被更新为新的压缩版本。

六、本地调试:keep 模式与 test-suite.html

如果正在反复修改并希望即时验证高亮效果,README 建议保留 Prism 源码目录再构建:

./build.sh keep

加上keep参数后,build.sh 跳过最后的清理步骤,prism/目录会被保留。此时可以打开 Prism 官方自带的可交互测试页面(test-suite.html,位于克隆下来的prism/目录内),在其中直接输入 Sway 代码实时查看各 token 的着色结果。因为npm run build已经把新的prism-sway.js打进了测试页依赖,所以无需手动改配置即可迭代验证正则改动,确认无误后再跑一次不带keep./build.sh产出正式文件并自动清理临时目录。

七、与 highlight.js 集成的对照

值得一提的是,Prism 并不是本仓库唯一维护的第三方高亮集成。scripts/highlightjs/README.md 描述了一套完全平行的流程:修改sway.js→ 运行./build.sh(同样支持keep参数保留 highlight.js 仓库目录)。从仓库结构看,docs/book/theme/highlight.js 与 docs/reference/theme/highlight.js 是 mdBook 站点实际使用的 highlight.js 构建产物,说明 Sway 文档站走的是 highlight.js 路线,而 scripts/prism 则为需要 PrismJS 的场景(如第三方博客、文档生成器、代码分享工具)提供另一套官方维护的 Sway 高亮方案。两套定义的 token 设计理念一致,但正则实现相互独立,修改时需分别维护。

八、常见注意事项

  • 嵌套注释层数prism-sway.js只支持 4 层嵌套多行注释,更深层的嵌套将无法被完整匹配;如需提升,需调整 第 3–8 行 的递归展开次数。
  • 闭包参数与按位或:不要轻易放宽 closure-params 的上下文约束,否则|x| x | y这类表达式会整体被错误着色。
  • greedy 匹配顺序:注释、字符串均设为greedy: true,Prism 会优先尝试最长匹配,这能减少注释与字符串内部关键字被二次着色的概率;新增 token 时建议同样遵循 greedy 惯例。
  • 产物提交prism-sway.min.js是构建产物但被提交进仓库,改动源文件后应重新构建并同步更新它,避免源文件与压缩版本不一致。

通过上述机制,Sway 社区可以像使用任意主流语言一样,在基于 PrismJS 的页面中零成本获得准确、可扩展的语法着色体验。

【免费下载链接】sway🌴 Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询