mirror of
https://github.com/rmellmer/obsidian-link-range.git
synced 2026-07-22 07:40:31 +00:00
commit
61754fff07
2 changed files with 118 additions and 120 deletions
103
src/embeds.ts
103
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 res = checkLink(app, embedHtml, settings, true, "src");
|
||||||
|
|
||||||
const isLinkRange = res !== null && res.h2 !== undefined;
|
const isLinkRange = res !== null && res.h2 !== undefined;
|
||||||
if (isLinkRange) {
|
const file = res?.file
|
||||||
|
if (isLinkRange && file !== undefined) {
|
||||||
const { vault } = app;
|
const { vault } = app;
|
||||||
const foundNote : TFile | undefined = app.vault.getMarkdownFiles().filter(
|
embedHtml.childNodes.forEach(x => {
|
||||||
x => x.basename == res.note
|
x.remove()
|
||||||
).first()
|
})
|
||||||
|
|
||||||
if (foundNote) {
|
const linkRange = embedHtml.querySelectorAll("div.link-range-embed")
|
||||||
embedHtml.childNodes.forEach(x => {
|
|
||||||
x.remove()
|
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!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
135
src/utils.ts
135
src/utils.ts
|
|
@ -1,19 +1,17 @@
|
||||||
import { App, TFile } from "obsidian";
|
import { App, TFile } from "obsidian";
|
||||||
import { LinkRangeSettings, Pattern } from "./settings";
|
import { LinkRangeSettings, Pattern } from "./settings";
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
export interface ParsedLink {
|
export interface ParsedLink {
|
||||||
note: string;
|
note: string;
|
||||||
h1: string;
|
h1: string;
|
||||||
h2?: string;
|
h2?: string;
|
||||||
altText?: string;
|
altText?: string;
|
||||||
|
file?: TFile;
|
||||||
h1Line?: number;
|
h1Line?: number;
|
||||||
h2Line?: number;
|
h2Line?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NOTE_PLACEHOLDER = "$note"
|
|
||||||
const H1_PLACEHOLDER = "$h1"
|
|
||||||
const H2_PLACEHOLDER = "$h2"
|
|
||||||
|
|
||||||
export function checkLinkText(href: string, settings: LinkRangeSettings): ParsedLink | null {
|
export function checkLinkText(href: string, settings: LinkRangeSettings): ParsedLink | null {
|
||||||
const linkRegex = /([^#|]*)#?([^#|]*)?\|?(.*)?/;
|
const linkRegex = /([^#|]*)#?([^#|]*)?\|?(.*)?/;
|
||||||
|
|
||||||
|
|
@ -36,19 +34,18 @@ export function checkLinkText(href: string, settings: LinkRangeSettings): Parsed
|
||||||
altText = matches[3]
|
altText = matches[3]
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let pattern = findPatternForFile(note, settings);
|
const pattern = findPatternForFile(note, settings);
|
||||||
|
const baseNote = path.basename(note)
|
||||||
let headingVisual = pattern.headingVisual === '' ? '#' : pattern.headingVisual;
|
const headingVisual = pattern.headingVisual === '' ? '#' : pattern.headingVisual;
|
||||||
let headingSeparatorVisual = pattern.headingSeparatorVisual === '' ? settings.headingSeparator : pattern.headingSeparatorVisual;
|
const headingSeparatorVisual = pattern.headingSeparatorVisual === '' ? settings.headingSeparator : pattern.headingSeparatorVisual;
|
||||||
|
|
||||||
if (h2 !== undefined) {
|
if (h2 !== undefined) {
|
||||||
altText = `${note}${headingVisual}${h1}${headingSeparatorVisual}${h2}`
|
altText = `${baseNote}${headingVisual}${h1}${headingSeparatorVisual}${h2}`
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
altText = `${note}${headingVisual}${h1}`
|
altText = `${baseNote}${headingVisual}${h1}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { note, h1, h2, altText }
|
return { note, h1, h2, altText }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,63 +60,69 @@ export function checkLink(app :App, linkHTML: HTMLElement, settings: LinkRangeSe
|
||||||
|
|
||||||
const alt = linkHTML.getAttribute("alt")
|
const alt = linkHTML.getAttribute("alt")
|
||||||
|
|
||||||
if (res && app.metadataCache != null) {
|
if (!res || app.metadataCache == null) {
|
||||||
// non-standard alt text, must be user provided via "|"
|
return null;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
export function postProcessorUpdate(app: App) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue