Typst代码块添加语言标识后自定义加粗格式失效问题求助
Typst代码块指定语言后自定义加粗失效的解决方法
问题背景
我用Typst展示代码块时,想通过自定义方式高亮重要内容,实现了两个核心逻辑:
- 自定义
text_bold函数实现文本加粗(未用Markdown原生加粗语法) - 通过正则匹配
#text_bold[xxx]标记,给对应内容应用加粗格式
未指定代码块语言时,自定义加粗正常生效:
dfir@dfir-mbp ~ % #text_bold[hello]
(效果:hello会被加粗)
但给代码块加上bash语言标识后,语言语法高亮会覆盖自定义加粗效果:
dfir@dfir-mbp ~ % #text_bold[hello]
(效果:#text_bold[hello]按bash语法高亮,hello未被加粗)
我的实现代码如下:
//------------------------------------------------------------ // Bold Function //------------------------------------------------------------ #let text_bold(body) = {text( weight: "bold", [#body])} //------------------------------------------------------------ // Raw converter Function //------------------------------------------------------------ #let raw_converter(body) = { //---------------------------------------------------------- // Find all matches with function #text_bold //---------------------------------------------------------- let matches_text_bold = body.text.matches(regex("#text_bold\[[^]]+\]{1,10}")) //---------------------------------------------------------- // Adding the rules //---------------------------------------------------------- show raw.where(): show_rule => { //-------------------------------------------------------- // Set the #text_bold rule //-------------------------------------------------------- for it in range(matches_text_bold.len()) { // Creating the value inside the #text_bold function let text_value = matches_text_bold.at(it).text.replace("#text_bold[","").replace("]","") show_rule = { // Remove the function to only keep the text inside show matches_text_bold.at(it).text: text_bold(text_value) show_rule } } show_rule } body } #let terminalbox( title: "", body_box, ) = { [... Creating the header of the Box ...] //------------------------------------------------------ // Body of the Box //------------------------------------------------------ rect( width: 100%, radius: (bottom-right: 6pt, bottom-left: 6pt), fill: body_color, inset: (y: 8pt, x: 5pt), stroke: (top: 0.8pt + line_color), text( box_text_size, raw_converter(body_box), fill: box_text_color, font: box_text_type, ), ), ) } #terminalbox(title: "Terminal", ```bash dfir@dfir-mbp ~ % #text_bold[hello] ```)
问题原因
当代码块指定语言后,Typst会启用对应语言的语法高亮器,此时代码内容会被转换成语法高亮后的结构化元素,不再是原始的raw文本。而你的raw_converter函数仅通过show raw.where()规则处理原始文本,对语法高亮后的内容无效,导致自定义加粗被覆盖。
解决方案
方案1:预处理文本后再应用语法高亮
先把代码中的#text_bold[xxx]标记替换成加粗文本,再传递给语法高亮器,确保加粗效果优先生效:
#let text_bold(body) = text(weight: "bold", body) #let terminalbox( title: "", body_box, ) = { // 预处理代码内容,替换#text_bold标记为加粗文本 let processed_body = body_box.text.replace( regex(r"#text_bold\[([^\]]+)\]"), content(match) => text_bold(match[1]) ) // 保留原有的头部创建逻辑 [... Creating the header of the Box ...] // 主体部分:传入预处理后的内容并指定bash语法 rect( width: 100%, radius: (bottom-right: 6pt, bottom-left: 6pt), fill: body_color, inset: (y: 8pt, x: 5pt), stroke: (top: 0.8pt + line_color), text( box_text_size, code(lang: "bash", processed_body), fill: box_text_color, font: box_text_type, ), ) } // 使用示例 #terminalbox(title: "Terminal", body_box: "dfir@dfir-mbp ~ % #text_bold[hello]")
方案2:拦截语法高亮后的代码块
通过全局show规则拦截指定语言的代码块,对其中的自定义标记进行替换,确保加粗在语法高亮后生效:
#let text_bold(body) = text(weight: "bold", body) // 全局规则:处理bash代码块中的#text_bold标记 show code.where(lang: "bash"): code_block => { let processed_content = code_block.body.replace( regex(r"#text_bold\[([^\]]+)\]"), content(match) => text_bold(match[1]) ) // 返回处理后的代码块 code(lang: "bash", processed_content) } #let terminalbox( title: "", body_box, ) = { [... Creating the header of the Box ...] // 主体部分直接传入代码块 rect( width: 100%, radius: (bottom-right: 6pt, bottom-left: 6pt), fill: body_color, inset: (y: 8pt, x: 5pt), stroke: (top: 0.8pt + line_color), text( box_text_size, body_box, fill: box_text_color, font: box_text_type, ), ), ) } // 使用示例 #terminalbox(title: "Terminal", body_box: code(lang: "bash", "dfir@dfir-mbp ~ % #text_bold[hello]"))
说明
- 方案1适合需要快速替换标记的场景,预处理后再高亮不会冲突
- 方案2更灵活,能保留语法高亮的同时,对指定内容单独加粗
内容的提问来源于stack exchange,提问作者greco
相关产品推荐
相关产品推荐

