Use markdown block renderer for post content

This commit is contained in:
silverpill 2022-10-08 18:52:18 +00:00
parent 2177fb4948
commit f975167ea7
4 changed files with 41 additions and 8 deletions

View file

@ -91,13 +91,20 @@ function getContent(): string {
white-space: pre-wrap; white-space: pre-wrap;
} }
:deep(p),
:deep(pre) {
&:not(:last-child) {
margin-bottom: 1em;
}
}
:deep(a) { :deep(a) {
@include block-link; @include block-link;
} }
:deep(pre), :deep(pre),
:deep(code) { :deep(code) {
overflow-x: scroll; overflow-x: auto;
} }
:deep(ul), :deep(ul),

View file

@ -10,7 +10,15 @@ const markdown = new MarkdownIt({ linkify: true, breaks: true })
// Minimal renderer // Minimal renderer
const markdownLite = new MarkdownIt({ linkify: true, breaks: true }) const markdownLite = new MarkdownIt({ linkify: true, breaks: true })
.disable(["strikethrough", "image"]) .disable([
"blockquote",
"list",
"heading",
"lheading",
"hr",
"strikethrough",
"image",
])
.use( .use(
MarkdownItLinkAttrs, MarkdownItLinkAttrs,
{ attrs: { target: "_blank", rel: "noopener" } }, { attrs: { target: "_blank", rel: "noopener" } },
@ -19,11 +27,20 @@ const markdownLite = new MarkdownIt({ linkify: true, breaks: true })
// Remove \n from output // Remove \n from output
markdownLite.renderer.rules.hardbreak = () => "<br>" markdownLite.renderer.rules.hardbreak = () => "<br>"
markdownLite.renderer.rules.softbreak = () => "<br>" markdownLite.renderer.rules.softbreak = () => "<br>"
markdownLite.renderer.rules.paragraph_close = () => "</p>"
const default_fence_rule = markdownLite.renderer.rules.fence
markdownLite.renderer.rules.fence = (...args: any[]) => {
return default_fence_rule(...args).trim()
}
export function renderMarkdown(text: string): string { export function renderMarkdown(text: string): string {
return markdown.render(text) return markdown.render(text)
} }
export function renderMarkdownLite(text: string): string { export function renderMarkdownLite(text: string): string {
return markdownLite.render(text)
}
export function renderMarkdownLiteInline(text: string): string {
return markdownLite.renderInline(text) return markdownLite.renderInline(text)
} }

View file

@ -97,7 +97,7 @@ import ProfileCard from "@/components/ProfileCard.vue"
import SidebarLayout from "@/components/SidebarLayout.vue" import SidebarLayout from "@/components/SidebarLayout.vue"
import { useCurrentUser } from "@/store/user" import { useCurrentUser } from "@/store/user"
import { setupAutoResize } from "@/utils/autoresize" import { setupAutoResize } from "@/utils/autoresize"
import { renderMarkdownLite } from "@/utils/markdown" import { renderMarkdownLiteInline } from "@/utils/markdown"
import { fileToDataUrl, dataUrlToBase64 } from "@/utils/upload" import { fileToDataUrl, dataUrlToBase64 } from "@/utils/upload"
const router = useRouter() const router = useRouter()
@ -152,7 +152,7 @@ const profilePreview = $computed<Profile>(() => {
function onBioUpdate(event: Event) { function onBioUpdate(event: Event) {
form.note_source = (event.target as HTMLTextAreaElement).value form.note_source = (event.target as HTMLTextAreaElement).value
form.note = renderMarkdownLite(form.note_source) form.note = renderMarkdownLiteInline(form.note_source)
} }
async function onFilePicked(fieldName: "avatar" | "header", event: Event) { async function onFilePicked(fieldName: "avatar" | "header", event: Event) {
@ -167,7 +167,7 @@ async function onFilePicked(fieldName: "avatar" | "header", event: Event) {
function onExtraFieldUpdate(field: ProfileFieldAttrs, event: Event) { function onExtraFieldUpdate(field: ProfileFieldAttrs, event: Event) {
field.value_source = (event.target as HTMLInputElement).value field.value_source = (event.target as HTMLInputElement).value
field.value = renderMarkdownLite(field.value_source) field.value = renderMarkdownLiteInline(field.value_source)
} }
function isValidExtraField(index: number): boolean { function isValidExtraField(index: number): boolean {

View file

@ -1,10 +1,19 @@
import { expect } from "chai" import { expect } from "chai"
import { renderMarkdownLite } from "@/utils/markdown" import {
renderMarkdownLite,
renderMarkdownLiteInline,
} from "@/utils/markdown"
describe("Render markdown", () => { describe("Render markdown", () => {
const text = "# heading\n\ntest **bold** test *italic* test ~~strike~~ with `code`, <span>html</span> and https://example.com\nnew line\n\ntwo new lines and a list:\n- item 1\n- item 2\n\ncode block:\n```\nlet test\ntest = 1\n```"
it("Render markdown lite", () => { it("Render markdown lite", () => {
const text = "test **bold** test *italic* test ~~strike~~ with `code`, <span>html</span> and https://example.com\nnew line\n\ntwo new lines and a list:\n- item 1\n- item 2\n\ncode block:\n```\nlet test\ntest = 1\n```"
const html = renderMarkdownLite(text) const html = renderMarkdownLite(text)
expect(html).to.equal('test <strong>bold</strong> test <em>italic</em> test ~~strike~~ with <code>code</code>, &lt;span&gt;html&lt;/span&gt; and <a href="https://example.com" target="_blank" rel="noopener">https://example.com</a><br>new line<br><br>two new lines and a list:<br>- item 1<br>- item 2<br><br>code block:<br><code>let test test = 1</code>') expect(html).to.equal('<p># heading</p><p>test <strong>bold</strong> test <em>italic</em> test ~~strike~~ with <code>code</code>, &lt;span&gt;html&lt;/span&gt; and <a href="https://example.com" target="_blank" rel="noopener">https://example.com</a><br>new line</p><p>two new lines and a list:<br>- item 1<br>- item 2</p><p>code block:</p><pre><code>let test\ntest = 1\n</code></pre>')
})
it("Render markdown lite inline", () => {
const html = renderMarkdownLiteInline(text)
expect(html).to.equal('# heading<br><br>test <strong>bold</strong> test <em>italic</em> test ~~strike~~ with <code>code</code>, &lt;span&gt;html&lt;/span&gt; and <a href="https://example.com" target="_blank" rel="noopener">https://example.com</a><br>new line<br><br>two new lines and a list:<br>- item 1<br>- item 2<br><br>code block:<br><code>let test test = 1</code>')
}) })
}) })