38 lines
1.0 KiB
Vue
38 lines
1.0 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* Renders markdown (with LaTeX) into styled prose HTML.
|
|
* Used on article pages and in the editor's live preview pane.
|
|
*/
|
|
const props = defineProps<{
|
|
content: string
|
|
/** Intercept clicks on internal links and use client-side routing. */
|
|
interceptLinks?: boolean
|
|
/**
|
|
* Prefix for the heading ids this article is given. Several articles are
|
|
* open at once in the reader, so their sections are namespaced by slug to
|
|
* keep two articles' "Proof" headings from sharing one id.
|
|
*/
|
|
namespace?: string
|
|
}>()
|
|
|
|
const rendered = computed(() => renderMarkdown(props.content, props.namespace))
|
|
|
|
const router = useRouter()
|
|
|
|
function onClick(e: MouseEvent) {
|
|
if (!props.interceptLinks) return
|
|
const target = e.target as HTMLElement
|
|
const anchor = target.closest?.('a')
|
|
if (!anchor) return
|
|
const href = anchor.getAttribute('href') || ''
|
|
if (href.startsWith('/')) {
|
|
e.preventDefault()
|
|
router.push(href)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="prose" v-html="rendered.html" @click="onClick" />
|
|
</template>
|