diff --git a/src/embeds.ts b/src/embeds.ts index 2fcb287..f36cbc7 100644 --- a/src/embeds.ts +++ b/src/embeds.ts @@ -8,63 +8,58 @@ export async function replaceEmbed(app: App, embed: Node, settings: LinkRangeSet const res = checkLink(app, embedHtml, settings, true, "src"); const isLinkRange = res !== null && res.h2 !== undefined; - if (isLinkRange) { + const file = res?.file + if (isLinkRange && file !== undefined) { const { vault } = app; - const foundNote : TFile | undefined = app.vault.getMarkdownFiles().filter( - x => x.basename == res.note - ).first() + embedHtml.childNodes.forEach(x => { + x.remove() + }) - if (foundNote) { - embedHtml.childNodes.forEach(x => { - x.remove() + const linkRange = embedHtml.querySelectorAll("div.link-range-embed") + + linkRange.forEach(x => { + x.remove() + }) + + if (isMarkdownPost) { + // prevent default embed functionality for markdown post processor + embedHtml.removeClasses(["internal-embed"]) + // create a child div under embedHtml to place content inside + embedHtml = embedHtml.createDiv({ + cls: ["internal-embed", "markdown-embed", "inline-embed", "is-loaded", "link-range-embed"] }) - - const linkRange = embedHtml.querySelectorAll("div.link-range-embed") - - linkRange.forEach(x => { - x.remove() - }) - - if (isMarkdownPost) { - // prevent default embed functionality for markdown post processor - embedHtml.removeClasses(["internal-embed"]) - // create a child div under embedHtml to place content inside - embedHtml = embedHtml.createDiv({ - cls: ["internal-embed", "markdown-embed", "inline-embed", "is-loaded", "link-range-embed"] - }) - } - - embedHtml.setText("") - - embedHtml.createEl("h2", { - text: res.altText - }) - - const linkDiv = embedHtml.createDiv({ - cls: ["markdown-embed-link"], - }); - - setIcon(linkDiv, 'link') - - linkDiv.onClickEvent((ev: MouseEvent) => { - const leaf = app.workspace.getMostRecentLeaf(); - leaf?.openFile(foundNote, { - state: { - scroll: res.h1Line - } - }); - }) - - const fileContent = await vault.cachedRead(foundNote); - - let lines = fileContent.split("\n"); - lines = lines.slice(res.h1Line, res.h2Line); - - const contentDiv = embedHtml.createDiv({ - cls: ["markdown-embed-content"] - }) - - MarkdownRenderer.renderMarkdown(lines.join("\n"), contentDiv, "", null!) } + + embedHtml.setText("") + + embedHtml.createEl("h2", { + text: res.altText + }) + + const linkDiv = embedHtml.createDiv({ + cls: ["markdown-embed-link"], + }); + + setIcon(linkDiv, 'link') + + linkDiv.onClickEvent((ev: MouseEvent) => { + const leaf = app.workspace.getMostRecentLeaf(); + leaf?.openFile(file, { + state: { + scroll: res.h1Line + } + }); + }) + + const fileContent = await vault.cachedRead(file); + + let lines = fileContent.split("\n"); + lines = lines.slice(res.h1Line, res.h2Line); + + const contentDiv = embedHtml.createDiv({ + cls: ["markdown-embed-content"] + }) + + MarkdownRenderer.renderMarkdown(lines.join("\n"), contentDiv, "", null!) } } diff --git a/src/utils.ts b/src/utils.ts index d72ce8a..9c404c0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,19 +1,17 @@ import { App, TFile } from "obsidian"; import { LinkRangeSettings, Pattern } from "./settings"; +import * as path from 'path'; export interface ParsedLink { note: string; h1: string; h2?: string; altText?: string; + file?: TFile; h1Line?: number; h2Line?: number; } -const NOTE_PLACEHOLDER = "$note" -const H1_PLACEHOLDER = "$h1" -const H2_PLACEHOLDER = "$h2" - export function checkLinkText(href: string, settings: LinkRangeSettings): ParsedLink | null { const linkRegex = /([^#|]*)#?([^#|]*)?\|?(.*)?/; @@ -36,19 +34,18 @@ export function checkLinkText(href: string, settings: LinkRangeSettings): Parsed altText = matches[3] } else { - let pattern = findPatternForFile(note, settings); - - let headingVisual = pattern.headingVisual === '' ? '#' : pattern.headingVisual; - let headingSeparatorVisual = pattern.headingSeparatorVisual === '' ? settings.headingSeparator : pattern.headingSeparatorVisual; + const pattern = findPatternForFile(note, settings); + const baseNote = path.basename(note) + const headingVisual = pattern.headingVisual === '' ? '#' : pattern.headingVisual; + const headingSeparatorVisual = pattern.headingSeparatorVisual === '' ? settings.headingSeparator : pattern.headingSeparatorVisual; if (h2 !== undefined) { - altText = `${note}${headingVisual}${h1}${headingSeparatorVisual}${h2}` + altText = `${baseNote}${headingVisual}${h1}${headingSeparatorVisual}${h2}` } else { - altText = `${note}${headingVisual}${h1}` + altText = `${baseNote}${headingVisual}${h1}` } } - return { note, h1, h2, altText } } @@ -63,63 +60,69 @@ export function checkLink(app :App, linkHTML: HTMLElement, settings: LinkRangeSe const alt = linkHTML.getAttribute("alt") - if (res && app.metadataCache != null) { - // non-standard alt text, must be user provided via "|" - if (alt != null && !alt.contains(res.note)) { - res.altText = alt - } - - if (!isEmbed && !linkHTML.innerText.contains(res.note)) { - res.altText = linkHTML.innerText - } - - const foundNote : TFile | undefined = app.vault.getMarkdownFiles().filter( - x => x.basename == res.note - ).first() - - if (foundNote) { - const meta = app.metadataCache.getFileCache(foundNote); - - if (meta == undefined || meta?.headings == undefined) { - return null; - } - - const h1Line = meta?.headings?.filter( - h => h.heading == res.h1 - ).first()?.position.start.line; - - let h2Line = null; - - if (settings.endInclusive) { - let h2LineIndex = meta?.headings?.findIndex( - h => h.heading == res.h2 - ) - - if (meta?.headings?.length > h2LineIndex) { - h2LineIndex += 1 - } - - h2Line = meta?.headings?.at(h2LineIndex)?.position.end.line - - } - else { - h2Line = meta?.headings?.filter( - h => h.heading == res.h2 - ).first()?.position.end.line; - } - - if (h1Line == undefined) { - return null; - } - - res.h1Line = h1Line - res.h2Line = h2Line - - return res; - } + if (!res || app.metadataCache == null) { + return null; } - return null; + // non-standard alt text, must be user provided via "|" + if (alt != null && !alt.contains(res.note)) { + res.altText = alt + } + + if (!isEmbed && !linkHTML.innerText.contains(res.note)) { + res.altText = linkHTML.innerText + } + + // Locate the referenced file, including partial paths + const partialPath = res.note + ".md" + const basePart = path.basename(res.note) + const file : TFile | undefined = app.vault.getMarkdownFiles().filter( + x => x.basename == basePart && x.path.endsWith(partialPath) + ).first() + + if (!file) { + return null + } + + res.file = file + + const meta = app.metadataCache.getFileCache(file); + + if (meta == undefined || meta?.headings == undefined) { + return null; + } + + const h1Line = meta?.headings?.filter( + h => h.heading == res.h1 + ).first()?.position.start.line; + + let h2Line = null; + + if (settings.endInclusive) { + let h2LineIndex = meta?.headings?.findIndex( + h => h.heading == res.h2 + ) + + if (meta?.headings?.length > h2LineIndex) { + h2LineIndex += 1 + } + + h2Line = meta?.headings?.at(h2LineIndex)?.position.end.line + } + else { + h2Line = meta?.headings?.filter( + h => h.heading == res.h2 + ).first()?.position.end.line; + } + + if (h1Line == undefined) { + return null; + } + + res.h1Line = h1Line + res.h2Line = h2Line + + return res; } export function postProcessorUpdate(app: App) {