如果你使用 Typst 的话,你肯定想在自己的 Blog 中对 Typst 代码进行高亮。但由于目前为止 Typst 还处于发展阶段,比较小众, highlight.js 并没有对 Typst 进行支持。但感谢社区的贡献,一款 highlight.js 的 Typst 支持库诞生了:来自于 typst.ts 项目的 highlighter

本文主要针对于 Papermod 主题进行 highlighter 的配置。

首先我们需要进入到 Blog 目录下的 themes 目录,并找到 PaperMod 的位置。在此我用 %blog_dir%/themes/PaperMod 表示。可以发现其中的结构如下:

.
├── LICENSE
├── README.md
├── assets
├── go.mod
├── i18n
├── images
├── layouts
└── theme.toml

首先我们先要进入到 assets 目录更换 highlight.js 的版本,因为 highlighter 最低需要 11.9.0 的版本。我们前往官网下载最新版本,并将 highlight.min.js 丢入 ./assets/js 替换掉原本的(可以对原先的 highlight.js 进行备份操作)。

然后我们前往 ./layouts/partials/head.html 进行 HTML 头的修改以初始化 highlight.js。

通过搜索 highlight 关键字,我们可以找到如下代码:

{{- /* Highlight.js */}}
{{- $isHLJSdisabled := (site.Params.assets.disableHLJS | default .Params.disableHLJS ) }}
{{- if (and (eq .Kind "page") (ne .Layout "archives") (ne .Layout "search") (not $isHLJSdisabled)) }}
{{- if not site.Params.assets.disableFingerprinting }}
{{- $highlight := slice (resources.Get "js/highlight.min.js") | resources.Concat "assets/js/highlight.js" | fingerprint }}
<script defer crossorigin="anonymous" src="{{ $highlight.RelPermalink }}" integrity="{{ $highlight.Data.Integrity }}" onload="hljs.initHighlightingOnLoad();"></script>
{{- else }}
{{- $highlight := slice (resources.Get "js/highlight.min.js") | resources.Concat "assets/js/highlight.js" }}
<script defer crossorigin="anonymous" src="{{ $highlight.RelPermalink }}" onload="hljs.initHighlightingOnLoad();"></script>
{{- end }}
{{- end }}

我们将其修改为以下代码:

{{- /* Highlight.js */}}
{{- $isHLJSdisabled := (site.Params.assets.disableHLJS | default .Params.disableHLJS ) }}
{{- if (and (eq .Kind "page") (ne .Layout "archives") (ne .Layout "search") (not $isHLJSdisabled)) }}
{{- if not site.Params.assets.disableFingerprinting }}
{{- $highlight := slice (resources.Get "js/highlight.min.js") | resources.Concat "assets/js/highlight.js" | fingerprint }}
<!-- <script defer crossorigin="anonymous" src="{{ $highlight.RelPermalink }}" integrity="{{ $highlight.Data.Integrity }}"
    onload="hljs.initHighlightingOnLoad();"></script> -->
<script crossorigin="anonymous" src="{{ $highlight.RelPermalink }}" integrity="{{ $highlight.Data.Integrity }}"></script>
<script
  id="script-main"
  src="https://cdn.jsdelivr.net/npm/@myriaddreamin/highlighter-typst/dist/cjs/contrib/hljs/typst.bundle.js"
></script>
<script>
    const run = () => {
        $typst$parserModule.then(() => {
            hljs.registerLanguage(
                'typst',
                window.hljsTypst({ // TypstHljsOptions
                    codeBlockDefaultLanguage: 'typst',
                }),
            )
        }).then(() => {
            document.querySelectorAll('pre code').forEach(el => {
                if (!el.getAttribute('data-highlighted')) {
                    hljs.highlightElement(el);
                }
            });
        });
    }
    run();
</script>
{{- else }}
{{- $highlight := slice (resources.Get "js/highlight.min.js") | resources.Concat "assets/js/highlight.js" }}
<!-- // <script defer crossorigin="anonymous" src="{{ $highlight.RelPermalink }}" onload="hljs.initHighlightingOnLoad();"></script> -->
<script crossorigin="anonymous" src="{{ $highlight.RelPermalink }}"></script>
<script
  id="script-main"
  src="https://cdn.jsdelivr.net/npm/@myriaddreamin/highlighter-typst/dist/cjs/contrib/hljs/typst.bundle.js"
></script>
<script>
    const run = () => {
        $typst$parserModule.then(() => {
            hljs.registerLanguage(
                'typst',
                window.hljsTypst({ // TypstHljsOptions
                    codeBlockDefaultLanguage: 'typst',
                }),
            )
        }).then(() => {
            document.querySelectorAll('pre code').forEach(el => {
                if (!el.getAttribute('data-highlighted')) {
                    hljs.highlightElement(el);
                }
            });
        });
    }
    run();
</script>
{{- end }}
{{- end }}

这段代码在原有加载 highlight.js 的基础上注册了 typst.bundle.js 的语言支持。要注意的是,需要将原有的 defer 去除,不然会出现 highlight.js 与 typst.bundle.js 加载顺序的问题。

至此,Hugo PaperMod 应该已经可以高亮 Typst 代码了。

result