84 lines
1.6 KiB
JavaScript
84 lines
1.6 KiB
JavaScript
import { marked } from "marked";
|
|
|
|
marked.setOptions({
|
|
gfm: true,
|
|
breaks: true,
|
|
headerIds: false,
|
|
mangle: false,
|
|
sanitize: false,
|
|
smartLists: true,
|
|
smartypants: false,
|
|
});
|
|
|
|
|
|
function applyShortcodes(md, ctx = {}) {
|
|
md = md.replace(/{{\s*channels\s*}}/g, () => {
|
|
if (!ctx.kanaly) return "";
|
|
|
|
const html = ctx.kanaly
|
|
.map(
|
|
(k) => `
|
|
<div class="flex items-center justify-center p-1">
|
|
<img
|
|
src="${k.logo}"
|
|
alt="${k.name}"
|
|
title="${k.name}"
|
|
class="channel-logo w-20 h-auto object-contain rounded"
|
|
/>
|
|
</div>
|
|
`
|
|
)
|
|
.join("");
|
|
|
|
return `
|
|
<div class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-10 gap-2 my-4">
|
|
${html}
|
|
</div>
|
|
`;
|
|
});
|
|
|
|
return md;
|
|
}
|
|
|
|
export default function FuzMarkdown({ text, ctx = {} }) {
|
|
if (!text) return null;
|
|
|
|
|
|
let processed = applyShortcodes(text, ctx);
|
|
|
|
processed = processed.replace(
|
|
/\[([^\]]+)\]\(#([^) "]+)(?:\s+"([^"]+)")?\)/g,
|
|
(match, label, modalId, title) => {
|
|
return `<a href="#" class="modal-link" data-modal="${modalId}"${title ? ` title="${title}"` : ""
|
|
}>${label}</a>`;
|
|
}
|
|
);
|
|
|
|
processed = processed.replace(
|
|
/\[([^\]]+)\]\("([^"]+)"(?:\s+"([^"]+)")?\s+btn\)/g,
|
|
(match, label, href, title) => {
|
|
return `
|
|
<div class="">
|
|
<a
|
|
href="${href}"
|
|
class="btn btn-primary"
|
|
target="_blank"
|
|
rel="noopener noreferrer"${title ? ` title="${title}"` : ""}
|
|
>
|
|
${label}
|
|
</a>
|
|
</div>`;
|
|
}
|
|
);
|
|
|
|
|
|
const html = marked(processed);
|
|
|
|
return (
|
|
<div
|
|
class="fuz-markdown max-w-none"
|
|
dangerouslySetInnerHTML={{ __html: html }}
|
|
/>
|
|
);
|
|
}
|