Skip to content

Commit

Permalink
fix: respect global link replacement settings: if not removing the li…
Browse files Browse the repository at this point in the history
…nk, use proper transformations, preserve wiki links and apply space normalizations in every case.
  • Loading branch information
Mr. Robot committed May 12, 2024
1 parent 00c8761 commit 4d9fc9d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 68 deletions.
130 changes: 65 additions & 65 deletions src/export/replace-local-links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export function replaceLocalLinks(
) {
for (const index in links) {
const link = links[index]
const original = link.originalPath;
const title = link.text;

// See if this link exists in the vault!
const linkedDocument = plugin.app.metadataCache.getFirstLinkpathDest(
Expand All @@ -30,28 +28,14 @@ export function replaceLocalLinks(

if (!linkedDocument) {
if (!settings.keepLinksNotFound){
exportProperties.outputContent = replaceAll(
`[${title}](${original})`,
exportProperties.outputContent,
`${title}`
);
removeLinks(link, exportProperties)

warn('Internal link not found! Removed.', title, original)
warn('Internal link not found! Removed.', link.text, link.originalPath)
link.error = "Internal Link Not Found at all! Removed."
} else {
// Still need to replace the link with the original normalized link, because
// it might be a wiki link.
let newLink = link.normalizedOriginalPath
if (newLink.indexOf(' ') > -1 && settings.normalizeSpacesInLinks) {
newLink = newLink.split('/').map((urlPart) => encodeURIComponent(urlPart)).join('/')
}

replaceAll(
`[${title}](${original})`,
exportProperties.outputContent,
`[${title}](${newLink})`)

warn('Internal link not found! Keeping due to settings keep not found. ', title, original)
replaceLinks(link.normalizedOriginalPath, link, settings, exportProperties)

warn('Internal link not found! Keeping due to settings keep not found. ', link.text, link.originalPath)
link.error = "Internal Link Not Found, NOT replacing due to Keep Links Not Found setting keep not found!"
}
continue
Expand All @@ -64,62 +48,78 @@ export function replaceLocalLinks(
if (allFileListMap[path]) {
const newFilePath = allFileListMap[path].toRelative;

// Remove the extension!
let newLink = newFilePath.substring(
// Remove the extension from actual links.
const newLink = newFilePath.substring(
0,
newFilePath.lastIndexOf(".")
);
replaceLinks(newLink, link, settings, exportProperties)

// There are spaces in the URL, normalize it!
if (newLink.indexOf(' ') > -1 && settings.normalizeSpacesInLinks) {
newLink = newLink.split('/').map((urlPart) => encodeURIComponent(urlPart)).join('/')
}
link.newPath = newLink
let newLinkWithTitle = `[${title}](${newLink})`;

// If a user wants spaces in their filenames in their output, normal [link](url)
// styled links do not cut it, as the matcher will have problems in other MD parsers
// than Obsidian. To eliminate this, we do two things:
// 1.- remember if it was a wiki link, and if it was, just render it as a wiki link.
// 2.- if it's not, but has a space, encode it with HTML encoding.
// only if it was not a wiki-link and it did not have a space preserve the original.
// @see discussion: https://forum.obsidian.md/t/how-to-link-a-file-with-filename-with-spaces/22592
// @see issue: https://github.com/symunona/obsidian-bulk-exporter/issues/3
if (link?.isWikiLink && settings.preserveWikiLinks) {
if (title === newLink) {
newLinkWithTitle = `[[${title}]]`
} else {
newLinkWithTitle = `[[${newLink}|${title}]]`
}
}

exportProperties.outputContent = replaceAll(
`[${title}](${original})`,
exportProperties.outputContent,
newLinkWithTitle);
} else {
// Removed as it's pointing to a file that's not being exported.
if (!settings.keepLinksPrivate){
warn("Internal link not found in output, removing!", original, title, path);
warn("Internal link not found in output, removing!", link.originalPath, link.text, path);
link.error = "Internal Link FOUND but not public, removed!"

exportProperties.outputContent = replaceAll(
`[${title}](${original})`,
exportProperties.outputContent,
`${title}`
);
removeLinks(link, exportProperties)
} else {
let newLink = link.normalizedOriginalPath
if (newLink.indexOf(' ') > -1 && settings.normalizeSpacesInLinks) {
newLink = newLink.split('/').map((urlPart) => encodeURIComponent(urlPart)).join('/')
}
exportProperties.outputContent = replaceAll(
`[${title}](${original})`,
exportProperties.outputContent,
`[${title}](${newLink})`)
warn("Internal link not found in output, kept due to settings keep private!", original, title, path);
replaceLinks(link.normalizedOriginalPath, link, settings, exportProperties)

warn("Internal link not found in output, kept due to settings keep private!", link.originalPath, link.text, path);
link.error = "Internal Link FOUND but not public, kept due to settings keep private!"
}
}
}
}

/**
* Remove the links and leave the title of the link.
* @param link
* @param exportProperties
*/
function removeLinks(link:AttachmentLink, exportProperties: ExportProperties){
exportProperties.outputContent = replaceAll(
`[${link.text}](${link.originalPath})`,
exportProperties.outputContent,
`${link.text}`
);
}

/**
* It handles wiki links, and spaces depending on settings
* @param newLink
* @param link
* @param settings
* @param exportProperties
*/
function replaceLinks(newLink: string, link: AttachmentLink, settings:BulkExportSettings, exportProperties: ExportProperties){
const title = link.text
const original = link.originalPath
// There are spaces in the URL, normalize it!
if (newLink.indexOf(' ') > -1 && settings.normalizeSpacesInLinks) {
newLink = newLink.split('/').map((urlPart) => encodeURIComponent(urlPart)).join('/')
}

let newLinkWithTitle = `[${title}](${newLink})`;

// If a user wants spaces in their filenames in their output, normal [link](url)
// styled links do not cut it, as the matcher will have problems in other MD parsers
// than Obsidian. To eliminate this, we do two things:
// 1.- remember if it was a wiki link, and if it was, just render it as a wiki link.
// 2.- if it's not, but has a space, encode it with HTML encoding.
// only if it was not a wiki-link and it did not have a space preserve the original.
// @see discussion: https://forum.obsidian.md/t/how-to-link-a-file-with-filename-with-spaces/22592
// @see issue: https://github.com/symunona/obsidian-bulk-exporter/issues/3
if (link?.isWikiLink && settings.preserveWikiLinks) {
if (title === newLink) {
newLinkWithTitle = `[[${title}]]`
} else {
newLinkWithTitle = `[[${newLink}|${title}]]`
}
}

exportProperties.outputContent = replaceAll(
`[${title}](${original})`,
exportProperties.outputContent,
newLinkWithTitle);
}
9 changes: 6 additions & 3 deletions test-vault/bulk-export-test/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ Obsidian URL:
[simple absolute subfolder](posts1/subfolder/sub-note1x) <<--- This should be NOT A LINK in the export, only if toggle is
[find it by name](header-image-test) <- exported


Wiki link: [[bla bla blah]]
Normal link: [bla](posts1/bla%20bla%20blah)
This link does not exist, should be removed, unless "preserve non-existent": [[asdf asdf asdf]]
Wiki link to be preserved if "preserve not public" toggle is on: [[bla bla blah]]
Wiki link same as the above with title: [[bla bla blah|i am a title]]
Normal link with %20 spaces: [bla](posts1/bla%20bla%20blah)
Normal link with NORMAL spaces: [bla](posts1/bla bla blah)
Obsidian Link: [bla](obsidian://open?vault=bulk-export-test&file=posts1%2Fbla%20bla%20blah)


0 comments on commit 4d9fc9d

Please sign in to comment.