92 lines
2.1 KiB
TypeScript
92 lines
2.1 KiB
TypeScript
import { fromAsyncCodeToHtml } from '@shikijs/markdown-it/async';
|
|
import { h } from 'hastscript';
|
|
import MarkdownItAsync from 'markdown-it-async';
|
|
import { codeToHtml } from 'shiki';
|
|
import DOMPurify from 'isomorphic-dompurify';
|
|
|
|
const md = MarkdownItAsync();
|
|
|
|
md.use(
|
|
fromAsyncCodeToHtml(
|
|
// Pass the codeToHtml function
|
|
codeToHtml,
|
|
{
|
|
themes: {
|
|
light: 'github-light-default',
|
|
dark: 'github-dark-default',
|
|
},
|
|
transformers: [
|
|
{
|
|
name: 'shiki-transformer-copy-button',
|
|
pre(node) {
|
|
const copyIcon = h(
|
|
'svg',
|
|
{
|
|
width: '24',
|
|
height: '24',
|
|
viewBox: '0 0 24 24',
|
|
fill: 'none',
|
|
stroke: 'currentColor',
|
|
'stroke-width': '2',
|
|
'stroke-linecap': 'round',
|
|
'stroke-linejoin': 'round',
|
|
},
|
|
[
|
|
h('rect', { width: '14', height: '14', x: '8', y: '8', rx: '2', ry: '2' }),
|
|
h('path', {
|
|
d: 'M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2',
|
|
}),
|
|
]
|
|
);
|
|
|
|
const checkIcon = h(
|
|
'svg',
|
|
{
|
|
width: '24',
|
|
height: '24',
|
|
viewBox: '0 0 24 24',
|
|
fill: 'none',
|
|
stroke: 'currentColor',
|
|
'stroke-width': '2',
|
|
'stroke-linecap': 'round',
|
|
'stroke-linejoin': 'round',
|
|
},
|
|
[h('path', { d: 'M20 6 9 17l-5-5' })]
|
|
);
|
|
|
|
const button = h(
|
|
'button',
|
|
{
|
|
class: 'copy',
|
|
'data-code': this.source,
|
|
onclick: `
|
|
navigator.clipboard.writeText(this.dataset.code);
|
|
this.classList.add('copied');
|
|
setTimeout(() => this.classList.remove('copied'), ${3000})
|
|
`,
|
|
},
|
|
[
|
|
h('span', { class: 'ready', style: 'background-color: transparent !important;' }, [
|
|
copyIcon,
|
|
]),
|
|
h(
|
|
'span',
|
|
{ class: 'success', style: 'background-color: transparent !important;' },
|
|
[checkIcon]
|
|
),
|
|
]
|
|
);
|
|
|
|
node.children.push(button);
|
|
},
|
|
},
|
|
],
|
|
}
|
|
)
|
|
);
|
|
|
|
function sanitizeHtml(html: string) {
|
|
return DOMPurify.sanitize(html);
|
|
}
|
|
|
|
export { md, sanitizeHtml };
|