侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

highlight.js 集成到 marked 并动态切换明暗两种主题

barwe
2023-03-10 / 0 评论 / 1 点赞 / 3,284 阅读 / 1,356 字
温馨提示:
本文最后更新于 2023-03-10,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

以 atom-one 主题为例,首先我们将两个样式表抄过来:

  • highlight.js/styles/atom-one-dark.css 抄到 assets/css/hljs/atom-one-dark.scss 里面,并在外面套个 .hljs-atom-one-dark{} 壳子
  • highlight.js/styles/atom-one-light.css 抄到 assets/css/hljs/atom-one-light.scss 里面,并在外面套个 .hljs-atom-one-light{} 壳子

加壳子是因为原来的两个样式文件没有命名空间的区分,同时导入会导致覆盖和冲突。

然后在 assets/css/global.scss 中导出它们:

// @import 'highlight.js/styles/atom-one-dark.css';
@import './hljs/atom-one-dark.scss';

// @import 'highlight.js/styles/atom-one-light.css';
@import './hljs/atom-one-light.scss';

然后在 main.ts 中导入这个全局样式文件:

import './assets/css/global.scss';

然后根据我们的主题动态计算主题样式类的名称:

const isLightTheme = ref(false)
const themeClass = computed(() => isLightTheme.value ? 'hljs-atom-one-light' : 'hljs-atom-one-dark')

将其添加到外层的某一个父元素上:

<template>
	<div v-html="html" :class=`markdown-body ${themeClass}`></div>
</template>

其中 html 是 marked 解析的 MarkDown 文档,markdown-body 是全局定义的 MarkDown 文档样式。

另外将 hljs 集成到 marked 中的方法:

import { marked } from 'marked'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js'
import he from 'he'

onMounted(() => marked.setOptions({
  highlight: (code, lang) => {
    let result = null
    if (lang && hljs.getLanguage(lang)) {
      try {
        result = hljs.highlight(lang, code, true).value
      } catch (__) { }
    }
    if (result === null) result = he.encode(code) as string
    return `<pre class="hljs " style="padding: 12px; border-radius: 4px;"><code>${result}</code></pre>`
  }
}))
1

评论区