fix: expand code syntax highlighting options (#307)

* added locale for context-menu

* fix: expand code syntax highlighting options

* fix: type for theme

---------

Co-authored-by: injurka <ikornilov.ext@prosebya.ru~>
This commit is contained in:
injurka
2024-11-08 07:59:05 +04:00
committed by GitHub
parent a81960bd7b
commit db45f12daf
13 changed files with 287 additions and 253 deletions
@@ -0,0 +1,87 @@
import { useTheme } from '@renderer/context/ThemeProvider'
import { useSettings } from '@renderer/hooks/useSettings'
import { CodeStyleVarious, ThemeMode } from '@renderer/types'
import { loadScript } from '@renderer/utils'
import React, { createContext, PropsWithChildren, useContext, useEffect, useMemo, useState } from 'react'
import {
BundledLanguage,
bundledLanguages,
BundledTheme,
bundledThemes,
createHighlighter,
HighlighterGeneric
} from 'shiki'
interface SyntaxHighlighterContextType {
codeToHtml: (code: string, language: string) => string
}
const SyntaxHighlighterContext = createContext<SyntaxHighlighterContextType | undefined>(undefined)
export const SyntaxHighlighterProvider: React.FC<PropsWithChildren> = ({ children }) => {
const { theme } = useTheme()
const [highlighter, setHighlighter] = useState<HighlighterGeneric<BundledLanguage, BundledTheme> | null>(null)
const { codeStyle } = useSettings()
const highlighterTheme = useMemo(() => {
if (codeStyle === 'auto') return theme === ThemeMode.light ? 'one-light' : 'material-theme-darker'
else return codeStyle
}, [theme, codeStyle])
useEffect(() => {
const initMermaid = async () => {
if (!window.mermaid) {
await loadScript('https://unpkg.com/mermaid@10.9.1/dist/mermaid.min.js')
window.mermaid.initialize({
startOnLoad: true,
theme: theme === ThemeMode.dark ? 'dark' : 'default',
securityLevel: 'loose'
})
window.mermaid.contentLoaded()
}
}
initMermaid()
}, [theme])
useEffect(() => {
const initHighlighter = async () => {
const hl = await createHighlighter({
themes: Object.keys(bundledThemes),
langs: Object.keys(bundledLanguages)
})
setHighlighter(hl)
}
initHighlighter()
}, [])
const codeToHtml = (code: string, language: string) => {
if (!highlighter) return ''
return highlighter.codeToHtml(code, {
lang: language,
theme: highlighterTheme,
transformers: [
{
preprocess(code) {
if (code.endsWith('\n')) code = code.slice(0, -1)
return code
}
}
]
})
}
return <SyntaxHighlighterContext.Provider value={{ codeToHtml }}>{children}</SyntaxHighlighterContext.Provider>
}
export const useSyntaxHighlighter = () => {
const context = useContext(SyntaxHighlighterContext)
if (!context) {
throw new Error('useSyntaxHighlighter must be used within a SyntaxHighlighterProvider')
}
return context
}
export const codeThemes = ['auto', ...Object.keys(bundledThemes)] as CodeStyleVarious[]