1 Commits

Author SHA1 Message Date
domrichardson
cf94697d07 feat: Added better md styling
All checks were successful
Build and Push App Image / build-and-push (push) Successful in 58s
2026-03-26 11:41:16 +00:00
7 changed files with 112 additions and 7 deletions

View File

@@ -13,7 +13,9 @@
"axios": "^1.4.0",
"bootstrap": "^5.3.0",
"dompurify": "^3.0.0",
"highlight.js": "^11.11.1",
"marked": "^9.0.0",
"marked-highlight": "^2.2.3",
"pinia": "^2.1.0",
"vue": "^3.3.0",
"vue-router": "^4.2.0"
@@ -1433,6 +1435,15 @@
"node": ">= 0.4"
}
},
"node_modules/highlight.js": {
"version": "11.11.1",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz",
"integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
@@ -1556,6 +1567,15 @@
"node": ">= 16"
}
},
"node_modules/marked-highlight": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.2.3.tgz",
"integrity": "sha512-FCfZRxW/msZAiasCML4isYpxyQWKEEx44vOgdn5Kloae+Qc3q4XR7WjpKKf8oMLk7JP9ZCRd2vhtclJFdwxlWQ==",
"license": "MIT",
"peerDependencies": {
"marked": ">=4 <18"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",

View File

@@ -15,7 +15,9 @@
"axios": "^1.4.0",
"bootstrap": "^5.3.0",
"dompurify": "^3.0.0",
"highlight.js": "^11.11.1",
"marked": "^9.0.0",
"marked-highlight": "^2.2.3",
"pinia": "^2.1.0",
"vue": "^3.3.0",
"vue-router": "^4.2.0"

View File

@@ -25,6 +25,70 @@ body,
width: 100%;
}
.markdown-body table {
width: 100%;
margin: 1rem 0;
border-collapse: collapse;
border-spacing: 0;
background: #fff;
}
.markdown-body th,
.markdown-body td {
padding: 0.7rem 0.9rem;
border: 1px solid var(--border-color);
text-align: left;
vertical-align: top;
}
.markdown-body th {
font-weight: 600;
background: #f3f6fb;
}
.markdown-body tr:nth-child(even) td {
background: #fbfcfe;
}
.markdown-body table code {
white-space: nowrap;
}
.markdown-body blockquote {
margin: 1rem 0;
padding: 0.75rem 1rem;
border-left: 4px solid #748ffc;
background: #f8f9ff;
color: #334155;
}
.markdown-body blockquote > :last-child {
margin-bottom: 0;
}
.markdown-body pre {
margin: 1rem 0;
padding: 1rem;
border-radius: 0.75rem;
background: #111827;
color: #f9fafb;
overflow-x: auto;
}
.markdown-body pre code {
background: transparent;
color: inherit;
padding: 0;
}
.markdown-body code {
font-family: "Courier New", monospace;
font-size: 0.95em;
padding: 0.1rem 0.3rem;
border-radius: 0.35rem;
background: #f1f3f5;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 8px;

View File

@@ -31,7 +31,7 @@
<div :class="showFileExplorer ? 'col-12 col-md-4 mt-3 mt-md-0' : 'col-12 col-md-6 mt-3 mt-md-0'">
<div class="preview-pane border rounded p-3">
<div v-html="renderedMarkdown"></div>
<div class="markdown-body" v-html="renderedMarkdown"></div>
</div>
</div>
@@ -96,10 +96,9 @@
<script setup>
import { ref, computed, watch, onBeforeUnmount, onMounted, nextTick } from "vue";
import { marked } from "marked";
import DOMPurify from "dompurify";
import { useSettingsStore } from "../stores/settingsStore";
import { preprocessMarkdown } from "../utils/markdown.js";
import { renderMarkdown } from "../utils/markdown.js";
import FileExplorer from "./FileExplorer.vue";
const props = defineProps({
@@ -138,7 +137,7 @@ const saveState = ref("saved");
const saveStateTimeout = ref(null);
const renderedMarkdown = computed(() => {
const html = marked.parse(preprocessMarkdown(editingNote.value.content || ""));
const html = renderMarkdown(editingNote.value.content || "");
return DOMPurify.sanitize(html);
});

View File

@@ -30,9 +30,8 @@
<script setup>
import { computed } from "vue";
import { marked } from "marked";
import DOMPurify from "dompurify";
import { preprocessMarkdown } from "../utils/markdown.js";
import { renderMarkdown } from "../utils/markdown.js";
const props = defineProps({
note: {
@@ -50,7 +49,7 @@ const props = defineProps({
});
const renderedMarkdown = computed(() => {
const html = marked.parse(preprocessMarkdown(props.note.content || ""));
const html = renderMarkdown(props.note.content || "");
return DOMPurify.sanitize(html);
});

View File

@@ -4,6 +4,7 @@ import router from "./router";
import App from "./App.vue";
import "bootstrap/dist/css/bootstrap.min.css";
import "@mdi/font/css/materialdesignicons.min.css";
import "highlight.js/styles/github-dark.min.css";
import "./assets/styles/main.css";
const app = createApp(App);

View File

@@ -1,3 +1,19 @@
import { marked } from "marked";
import { markedHighlight } from "marked-highlight";
import hljs from "highlight.js/lib/common";
marked.use(
markedHighlight({
langPrefix: "hljs language-",
highlight(code, lang) {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(code, { language: lang }).value;
}
return hljs.highlightAuto(code).value;
},
}),
);
/**
* Preprocesses markdown content to support extended image size syntax:
*
@@ -24,3 +40,7 @@ export function preprocessMarkdown(content) {
return `<img ${attrs}>`;
});
}
export function renderMarkdown(content) {
return marked.parse(preprocessMarkdown(content || ""), { gfm: true });
}