diff --git a/src/components/PostContent.vue b/src/components/PostContent.vue index 0ac8f45..ea1e3a3 100644 --- a/src/components/PostContent.vue +++ b/src/components/PostContent.vue @@ -91,13 +91,20 @@ function getContent(): string { white-space: pre-wrap; } + :deep(p), + :deep(pre) { + &:not(:last-child) { + margin-bottom: 1em; + } + } + :deep(a) { @include block-link; } :deep(pre), :deep(code) { - overflow-x: scroll; + overflow-x: auto; } :deep(ul), diff --git a/src/utils/markdown.ts b/src/utils/markdown.ts index 37b6fc5..7fe837c 100644 --- a/src/utils/markdown.ts +++ b/src/utils/markdown.ts @@ -10,7 +10,15 @@ const markdown = new MarkdownIt({ linkify: true, breaks: true }) // Minimal renderer const markdownLite = new MarkdownIt({ linkify: true, breaks: true }) - .disable(["strikethrough", "image"]) + .disable([ + "blockquote", + "list", + "heading", + "lheading", + "hr", + "strikethrough", + "image", + ]) .use( MarkdownItLinkAttrs, { attrs: { target: "_blank", rel: "noopener" } }, @@ -19,11 +27,20 @@ const markdownLite = new MarkdownIt({ linkify: true, breaks: true }) // Remove \n from output markdownLite.renderer.rules.hardbreak = () => "
" markdownLite.renderer.rules.softbreak = () => "
" +markdownLite.renderer.rules.paragraph_close = () => "

" +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 { return markdown.render(text) } export function renderMarkdownLite(text: string): string { + return markdownLite.render(text) +} + +export function renderMarkdownLiteInline(text: string): string { return markdownLite.renderInline(text) } diff --git a/src/views/ProfileForm.vue b/src/views/ProfileForm.vue index be027fa..5906f8e 100644 --- a/src/views/ProfileForm.vue +++ b/src/views/ProfileForm.vue @@ -97,7 +97,7 @@ import ProfileCard from "@/components/ProfileCard.vue" import SidebarLayout from "@/components/SidebarLayout.vue" import { useCurrentUser } from "@/store/user" import { setupAutoResize } from "@/utils/autoresize" -import { renderMarkdownLite } from "@/utils/markdown" +import { renderMarkdownLiteInline } from "@/utils/markdown" import { fileToDataUrl, dataUrlToBase64 } from "@/utils/upload" const router = useRouter() @@ -152,7 +152,7 @@ const profilePreview = $computed(() => { function onBioUpdate(event: Event) { 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) { @@ -167,7 +167,7 @@ async function onFilePicked(fieldName: "avatar" | "header", event: Event) { function onExtraFieldUpdate(field: ProfileFieldAttrs, event: Event) { 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 { diff --git a/tests/unit/markdown.spec.ts b/tests/unit/markdown.spec.ts index 2379156..7e28e67 100644 --- a/tests/unit/markdown.spec.ts +++ b/tests/unit/markdown.spec.ts @@ -1,10 +1,19 @@ import { expect } from "chai" -import { renderMarkdownLite } from "@/utils/markdown" +import { + renderMarkdownLite, + renderMarkdownLiteInline, +} from "@/utils/markdown" describe("Render markdown", () => { + const text = "# heading\n\ntest **bold** test *italic* test ~~strike~~ with `code`, html 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", () => { - const text = "test **bold** test *italic* test ~~strike~~ with `code`, html 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) - expect(html).to.equal('test bold test italic test ~~strike~~ with code, <span>html</span> and https://example.com
new line

two new lines and a list:
- item 1
- item 2

code block:
let test test = 1') + expect(html).to.equal('

# heading

test bold test italic test ~~strike~~ with code, <span>html</span> and https://example.com
new line

two new lines and a list:
- item 1
- item 2

code block:

let test\ntest = 1\n
') + }) + + it("Render markdown lite inline", () => { + const html = renderMarkdownLiteInline(text) + expect(html).to.equal('# heading

test bold test italic test ~~strike~~ with code, <span>html</span> and https://example.com
new line

two new lines and a list:
- item 1
- item 2

code block:
let test test = 1') }) })