Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added features to ignore and replace urls #16

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This plugin archives links in your note so they're available to you even if the
Upon pressing the "Archive Links" button in the ribbon/left sidebar, the plugin:

1. looks up every external link in the current note,
2. sumbits each of them to https://archive.org,
2. submits each of them to https://archive.org,
3. as soon as they are saved, it embeds an `(Archived)` link after the regular link in your note.

The plugin will attempt not to recreate archive links for already-archived links (and the archive links themselves) - but this relies on not modifying the formatting of the archive links.
Expand Down Expand Up @@ -39,4 +39,4 @@ Initial release.

## Future plans

- Support for other archive providers
- Support for other archive providers
44 changes: 29 additions & 15 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { MarkdownView, Notice, Plugin, request } from "obsidian";
import { waybackSaveUrl, waybackUrl } from "./constants";
import { defaultSettings as DEFAULT_SETTINGS, LinkArchivePluginSettings as LinkArchivePluginSettings, LinkArchiveSettingTab } from "./settings";
import { defaultSettings as DEFAULT_SETTINGS, LinkArchivePluginSettings as LinkArchivePluginSettings, LinkArchiveSettingTab, LinkReplaceRule } from "./settings";

const urlRegex =/(\b(https?|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;

function replaceLinks(link: string, replaceRules: LinkReplaceRule[]): string {
let modifiedLink = link;

for (const rule of replaceRules) {
const regex = new RegExp(rule.originalPattern, "g");
modifiedLink = modifiedLink.replace(regex, rule.replacementPattern);
}

return modifiedLink;
}

export default class ObsidianLinkArchivePlugin extends Plugin {
settings: LinkArchivePluginSettings;

Expand Down Expand Up @@ -31,22 +42,24 @@ export default class ObsidianLinkArchivePlugin extends Plugin {
while ((linkArray = urlRegex.exec(viewData)) !== null) {
console.log(`Found ${linkArray[0]}. Next starts at ${urlRegex.lastIndex}.`);

//if(linkArray[0].startsWith(waybackUrl)) continue;

//if(viewData.substring(urlRegex.lastIndex, urlRegex.lastIndex + 14).contains(archiveText)) continue;

// replace clean logic with
// IF next link is the same except with archiveorg in front of it, skip it

reverseArray.unshift([linkArray[0], urlRegex.lastIndex]);
}

console.log(reverseArray);
console.log(reverseArray);

// ReSharper marks the "some" call as an error, but it's actually correct...
const cleanedList = reverseArray.filter(x =>
!x[0].startsWith(waybackUrl)
&& !reverseArray.some(y => y[0].startsWith(waybackUrl) && y[0].endsWith(x[0])));
const cleanedList = reverseArray.filter(x =>
// Filtering out links that start with the archive URL
!x[0].startsWith(waybackUrl)
// Testing if a link does not have an archived version in the reverseArray
&& !reverseArray.some(y =>
y[0].startsWith(waybackUrl) && y[0].endsWith(x[0]) // Already archived links
|| y[0].startsWith(waybackUrl) && y[0].endsWith(replaceLinks(x[0], this.settings.linkReplaceRules)) // Already replaced and archived links
)
// Testing if the link is not already associated with the archive text in viewData
&& !viewData.substring(x[1]+2, x[1]+2 + archiveText.length).includes(archiveText)
// Testing if the link is not in the ignore list
&& !this.settings.ignoreUrlPatterns.some(pattern => new RegExp(pattern).test(x[0])));

console.log(cleanedList);

Expand All @@ -62,12 +75,13 @@ export default class ObsidianLinkArchivePlugin extends Plugin {

for (const tuple of cleanedList) {
const currentLink = tuple[0];
const replacedLink = replaceLinks(currentLink, this.settings.linkReplaceRules);
const saveLink = `${waybackSaveUrl}${currentLink}`;
const archiveLink = ` ${archiveText}(${waybackUrl}${dateLinkPart}/${currentLink})`;
const archiveLink = ` ${archiveText}(${waybackUrl}${dateLinkPart}/${replacedLink})`;
const extraOffset = viewData.charAt(tuple[1]) === ")" ? 1 : 0;
const offset = view.editor.offsetToPos(tuple[1] + extraOffset);
const message = `(${i}/${totalLinks}) Successfully archived ${currentLink}!`;
const failMessage = `(${i}/${totalLinks}) Failed to archive ${currentLink}!`;
const message = `(${i}/${totalLinks}) Successfully archived ${replacedLink}!`;
const failMessage = `(${i}/${totalLinks}) Failed to archive ${replacedLink}!`;
i += 1;

await this.delay(400);
Expand Down
163 changes: 118 additions & 45 deletions settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { App, PluginSettingTab, Setting } from "obsidian";
import ObsidianLinkArchivePlugin from "./main";
import { defaultArchiveText } from "./constants";

export interface LinkReplaceRule {
originalPattern: string;
replacementPattern: string;
}

export const enum ArchiveOptions {
Wayback,
Archiveis,
Expand All @@ -12,11 +17,15 @@ export const enum ArchiveOptions {
export interface LinkArchivePluginSettings {
archiveOption: ArchiveOptions;
archiveText: string;
linkReplaceRules: LinkReplaceRule[];
ignoreUrlPatterns: string[];
}

export const defaultSettings: LinkArchivePluginSettings = {
archiveOption: ArchiveOptions.Archiveis,
archiveText: defaultArchiveText
archiveText: defaultArchiveText,
linkReplaceRules: [],
ignoreUrlPatterns: []
}


Expand All @@ -30,54 +39,118 @@ export class LinkArchiveSettingTab extends PluginSettingTab {

display(): void {
const plugin: ObsidianLinkArchivePlugin = (this as any).plugin;

const { containerEl } = this;
const { containerEl } = this;

containerEl.empty();

// add archive link text customization option
const archiveSettingsSection = containerEl.createDiv();
archiveSettingsSection.createEl("h2", { text: "Archive Settings" });

new Setting(archiveSettingsSection)
.setName("Link text")
.setDesc("The text of the archive links")
.addText(text =>
text
.setValue(plugin.settings.archiveText)
.onChange(async value => {
console.log(`Link text: ${value}`);
plugin.settings.archiveText = value;
await plugin.saveSettings();
}));

// link ignore rules
const linkIgnoreSection = containerEl.createDiv();
linkIgnoreSection.createEl("h2", { text: "Link Ignore Rules" });

new Setting(linkIgnoreSection)
.setName("Ignore URL Patterns")
.setDesc("Enter regular expressions to match URLs that should be ignored by the plugin")
.addButton(button => {
button.setButtonText("Add Pattern").onClick(() => {
plugin.settings.ignoreUrlPatterns.push("");
this.display();
});
});

// add ignore url patterns
for (let i = 0; i < plugin.settings.ignoreUrlPatterns.length; i++) {
const pattern = plugin.settings.ignoreUrlPatterns[i];

const setting = new Setting(containerEl)
.setName(`Pattern ${i + 1}`)
.addText(text => text
.setPlaceholder("URL Pattern")
.setValue(pattern)
.onChange(async value => {
plugin.settings.ignoreUrlPatterns[i] = value;
await plugin.saveSettings();
}));

setting.addButton(button => {
button.setIcon("cross")
.onClick(async () => {
plugin.settings.ignoreUrlPatterns.splice(i, 1);
await plugin.saveSettings();
this.display();
});
});
}

// add link replacement rules
const linkReplacementSection = containerEl.createDiv();
linkReplacementSection.createEl("h2", { text: "Link Replacement Rules" });

new Setting(linkReplacementSection)
.setDesc("Configure rules to replace specific links before archiving.")
.addButton(button => {
button.setButtonText("Add Rule").onClick(() => {
plugin.settings.linkReplaceRules.push({
originalPattern: "",
replacementPattern: ""
});
this.display();
});
});

// add link replacement rules
for (let i = 0; i < plugin.settings.linkReplaceRules.length; i++) {
const rule = plugin.settings.linkReplaceRules[i];

const setting = new Setting(containerEl)
.setName(`Rule ${i + 1}`)
.addText(text => text
.setPlaceholder("Original Pattern")
.setValue(rule.originalPattern)
.onChange(async value => {
rule.originalPattern = value;
await plugin.saveSettings();
}))
.addText(text => text
.setPlaceholder("Replacement Pattern")
.setValue(rule.replacementPattern)
.onChange(async value => {
rule.replacementPattern = value;
await plugin.saveSettings();
}));

setting.addButton(button => {
button.setIcon("cross")
.onClick(async () => {
plugin.settings.linkReplaceRules.splice(i, 1);
await plugin.saveSettings();
this.display();
});
});
}

// add about section
const aboutSection = containerEl.createDiv();
aboutSection.createEl("h2", { text: "About Link Archive" });

aboutSection.createEl("p", {text: "This plugin archives links in your note so they're available to you even if the original site goes down or gets removed."});

aboutSection.createEl("a", {text: "Open GitHub repository", href: "https://github.com/tomzorz/obsidian-link-archive"});

containerEl.createEl("h2", {text: "Archive Settings"});

new Setting(containerEl)
.setName("Link text")
.setDesc("The text of the archive links")
.addText(text =>
text
.setValue(plugin.settings.archiveText)
.onChange(async value => {
console.log(`Link text: ${value}`);
plugin.settings.archiveText = value;
await plugin.saveSettings();
}));

// new Setting(containerEl)
// .setName('Archive Provider')
// .setDesc('Choose a provider for the link archive')
// .addDropdown((dropdown) => {
// const options: Record<ArchiveOptions, string> = {
// 0: "Internet Archive",
// 1: "archive.is",
// 2: "Both"
// };

// dropdown
// .addOptions(options)
// .setValue(plugin.settings.archiveOption.toString())
// .onChange(async (value) => {
// console.log('Archive option: ' + value);
// plugin.settings.archiveOption = +value;
// await plugin.saveSettings();
// this.display();
// })
// });

containerEl.createEl("h2", {text: "About Link Archive"});

containerEl.createEl("p", {text: "This plugin archives links in your note so they're available to you even if the original site goes down or gets removed."});

containerEl.createEl("a", {text: "Open GitHub repository", href: "https://github.com/tomzorz/obsidian-link-archive"});

// TODO github support and ko-fi
}
}