import type { MaybeRefOrGetter } from '@vueuse/core' import { toValue } from '@vueuse/core' import { computed } from 'vue' import showdown from 'showdown' showdown.extension('openExternalInNewTab', { type: 'output', regex: //g, replace (text: string) { const matches = text.match(/href="(.+)">/) ?? [] const url = matches[1] ?? './' if ((!url.startsWith('http://') && !url.startsWith('https://')) || url.startsWith('mailto:')) { return text } const { hostname } = new URL(url) return hostname !== location.hostname && typeof matches[0] === 'string' ? text.replace(matches[0], `href="${url}" target="_blank" rel="noopener noreferrer">`) : text } }) showdown.extension('linkifyTags', { type: 'language', regex: /#[^\W]+/g, replace (text: string) { return `${text}` } }) const markdown = new showdown.Converter({ extensions: ['openExternalInNewTab', 'linkifyTags'], ghMentions: true, ghMentionsLink: '/@{u}', simplifiedAutoLink: true, openLinksInNewWindow: false, simpleLineBreaks: true, strikethrough: true, tables: true, tasklists: true, underline: true, noHeaderId: true, headerLevelStart: 3, literalMidWordUnderscores: true, excludeTrailingPunctuationFromURLs: true, encodeEmails: true, emoji: true }) export const useMarkdownRaw = (md: string) => markdown.makeHtml(md) export const useMarkdownComputed = (md: MaybeRefOrGetter) => computed(() => useMarkdownRaw(toValue(md))) export default useMarkdownComputed