(note, headingSlug = null)
| 176 | // --- Loading and rendering notes ------------------------------ |
| 177 | |
| 178 | async function loadNote(note, headingSlug = null) { |
| 179 | activeNoteId = note.id; |
| 180 | renderBreadcrumb(note); |
| 181 | setActiveLink(note.id); |
| 182 | pushNav(note.id); // navigation history |
| 183 | addToRecent(note.id); // recently viewed |
| 184 | |
| 185 | contentEl.textContent = "Loading…"; |
| 186 | |
| 187 | let md; |
| 188 | if (noteCache.has(note.path)) { |
| 189 | md = noteCache.get(note.path); |
| 190 | } else { |
| 191 | const res = await fetch(note.path); |
| 192 | if (!res.ok) { |
| 193 | contentEl.textContent = `Failed to load: ${note.path}`; |
| 194 | return; |
| 195 | } |
| 196 | md = await res.text(); |
| 197 | noteCache.set(note.path, md); |
| 198 | } |
| 199 | |
| 200 | // Process image embeds FIRST, then wiki links — order matters |
| 201 | const withImages = replaceImageEmbeds(md); |
| 202 | const withWiki = replaceWikiLinks(withImages); |
| 203 | const html = marked.parse(withWiki); |
| 204 | |
| 205 | // Wrap in .prose so the column centres without breaking pre overflow |
| 206 | const prose = document.createElement("div"); |
| 207 | prose.className = "prose"; |
| 208 | prose.innerHTML = html; |
| 209 | contentEl.innerHTML = ""; |
| 210 | contentEl.appendChild(prose); |
| 211 | |
| 212 | addHeadingIds(prose); |
| 213 | wireWikiLinks(prose); |
| 214 | |
| 215 | // Syntax highlighting |
| 216 | if (typeof hljs !== "undefined") { |
| 217 | prose.querySelectorAll("pre code").forEach((block) => { |
| 218 | hljs.highlightElement(block); |
| 219 | }); |
| 220 | } |
| 221 | |
| 222 | // Copy-to-clipboard buttons on every code block |
| 223 | addCopyButtons(prose); |
| 224 | |
| 225 | if (headingSlug) requestAnimationFrame(() => scrollToHeading(headingSlug)); |
| 226 | |
| 227 | // Sync URL hash without pushing a new history entry |
| 228 | history.replaceState(null, "", "#" + note.id); |
| 229 | } |
| 230 | |
| 231 | function wireWikiLinks(container) { |
| 232 | container = container || contentEl; |
no test coverage detected