import { useEffect } from 'react' import Prism from 'prismjs' // 所有语言的prismjs 使用autoloader引入 // import 'prismjs/plugins/autoloader/prism-autoloader' import 'prismjs/plugins/toolbar/prism-toolbar' import 'prismjs/plugins/toolbar/prism-toolbar.min.css' import 'prismjs/plugins/show-language/prism-show-language' import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard' import 'prismjs/plugins/line-numbers/prism-line-numbers' import 'prismjs/plugins/line-numbers/prism-line-numbers.css' // mermaid图 import { loadExternalResource } from '@/lib/utils' import { useRouter } from 'next/navigation' import { useGlobal } from '@/lib/global' import { siteConfig } from '@/lib/config' /** * 代码美化相关 * @author https://github.com/txs/ * @returns */ const PrismMac = () => { const router = useRouter() const { isDarkMode } = useGlobal() const codeMacBar = siteConfig('CODE_MAC_BAR') const prismjsAutoLoader = siteConfig('PRISM_JS_AUTO_LOADER') const prismjsPath = siteConfig('PRISM_JS_PATH') const prismThemeSwitch = siteConfig('PRISM_THEME_SWITCH') const prismThemeDarkPath = siteConfig('PRISM_THEME_DARK_PATH') const prismThemeLightPath = siteConfig('PRISM_THEME_LIGHT_PATH') const prismThemePrefixPath = siteConfig('PRISM_THEME_PREFIX_PATH') const mermaidCDN = siteConfig('MERMAID_CDN') const codeLineNumbers = siteConfig('CODE_LINE_NUMBERS') const codeCollapse = siteConfig('CODE_COLLAPSE') const codeCollapseExpandDefault = siteConfig('CODE_COLLAPSE_EXPAND_DEFAULT') useEffect(() => { if (codeMacBar) { loadExternalResource('/css/prism-mac-style.css', 'css') } // 加载prism样式 loadPrismThemeCSS(isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath) // 折叠代码 loadExternalResource(prismjsAutoLoader, 'js').then((url) => { if (window?.Prism?.plugins?.autoloader) { window.Prism.plugins.autoloader.languages_path = prismjsPath } renderPrismMac(codeLineNumbers) renderMermaid(mermaidCDN) renderCollapseCode(codeCollapse, codeCollapseExpandDefault) }) }, [router, isDarkMode]) return <>> } /** * 加载Prism主题样式 */ const loadPrismThemeCSS = (isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath) => { let PRISM_THEME let PRISM_PREVIOUS if (prismThemeSwitch) { if (isDarkMode) { PRISM_THEME = prismThemeDarkPath PRISM_PREVIOUS = prismThemeLightPath } else { PRISM_THEME = prismThemeLightPath PRISM_PREVIOUS = prismThemeDarkPath } const previousTheme = document.querySelector(`link[href="${PRISM_PREVIOUS}"]`) if (previousTheme) { previousTheme.parentNode.removeChild(previousTheme) } loadExternalResource(PRISM_THEME, 'css') } else { loadExternalResource(prismThemePrefixPath, 'css') } } /* * 将代码块转为可折叠对象 */ const renderCollapseCode = (codeCollapse, codeCollapseExpandDefault) => { if (!codeCollapse) { return } const codeBlocks = document.querySelectorAll('.code-toolbar') for (const codeBlock of codeBlocks) { // 判断当前元素是否被包裹 if (codeBlock.closest('.collapse-wrapper')) { continue // 如果被包裹了,跳过当前循环 } const code = codeBlock.querySelector('code') const language = code.getAttribute('class').match(/language-(\w+)/)[1] const collapseWrapper = document.createElement('div') collapseWrapper.className = 'collapse-wrapper w-full py-2' const panelWrapper = document.createElement('div') panelWrapper.className = 'border dark:border-gray-600 rounded-md hover:border-indigo-500 duration-200 transition-colors' const header = document.createElement('div') header.className = 'flex justify-between items-center px-4 py-2 cursor-pointer select-none' header.innerHTML = `