import $ from 'jquery'; import React from 'react'; import ReactDOM from 'react-dom/client'; import { renderLanguageSelect } from 'vj/components/languageselect'; import Dom from 'vj/components/react/DomComponent'; import { NamedPage } from 'vj/misc/Page'; import { delay, getAvailableLangs, i18n, tpl, } from 'vj/utils'; async function initCodeLangHelper() { const $el = $(tpl`
`); $('[name="codeLang"]') .parent().parent().parent() .parent() .hide() .after($el); const main = {}; for (const key in window.LANGS) { if (!key.includes('.') && !window.LANGS[key].hidden) main[key] = window.LANGS[key].display; } await delay(50); renderLanguageSelect( document.getElementById('codelang-select'), $('[name="codeLang"]'), getAvailableLangs(), main, [$('[name="codeLang"]').val()], ); } function supportFontFamily(f) { const h = 'Arial'; if (f.toLowerCase() === h.toLowerCase()) return true; const canvas = document.createElement('canvas'); canvas.width = 100; canvas.height = 100; const ctx = canvas.getContext('2d'); ctx.textAlign = 'center'; ctx.fillStyle = 'black'; ctx.textBaseline = 'middle'; const g = (j) => { ctx.clearRect(0, 0, 100, 100); ctx.font = `100px ${j}, ${h}`; ctx.fillText('a', 50, 50); const k = ctx.getImageData(0, 0, 100, 100).data; return [].slice.call(k).filter((l) => l !== 0); }; return g(h).join('') !== g(f).join(''); } interface HighlightProps { theme: string; setAvailableThemes: (themes: string[]) => void; } function HighlightPreview(props: HighlightProps) { const [ready, setReady] = React.useState(false); const [html, setHtml] = React.useState(tpl``);
const [code, setCode] = React.useState('');
const [module, setShikiModule] = React.useState(null);
const [rerender, setRerender] = React.useState(0);
React.useEffect(() => {
$('[name="showInvisibleChar"]').on('change', (ev) => {
UserContext.showInvisibleChar = ev.target.checked;
setRerender((i) => i + 1);
});
Promise.all([
import('vj/components/highlighter/shiki'),
import('vj/components/highlighter/code-example'),
]).then(([m, { default: c }]) => {
setShikiModule(m);
setCode(c);
props.setAvailableThemes(Object.keys(m.bundledThemes));
});
}, []);
React.useEffect(() => {
setReady(false);
let theme = props.theme;
if (!module?.bundledThemes?.[theme]) theme = 'light-plus';
module?.createHighlighter({ langs: ['cpp'], themes: [theme] }).then((shiki) => {
setHtml(shiki.codeToHtml(code, { lang: 'cpp', theme, transformers: module.getTransformers() }));
setReady(true);
});
}, [props.theme, module, code, rerender]);
return