generated from obsidianmd/obsidian-sample-plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.ts
131 lines (101 loc) · 3.96 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { App, MarkdownView, Plugin, PluginSettingTab, Setting } from 'obsidian';
interface PluginSettings {
autoConvert: boolean;
}
const DEFAULT_SETTINGS: PluginSettings = {
autoConvert: true
}
const isValidURL = (url: string) => {
if (url.endsWith(')') || url.startsWith('[') || url.includes('](')) return false;
let urlObj: URL;
try {
urlObj = new URL(url);
} catch (_) {
return false;
}
return urlObj.protocol === 'http:' || urlObj.protocol === 'https:';
}
const urlToHyperlink = (url: string) => {
if (!isValidURL(url)) return url;
url = url.trim().toLocaleLowerCase().replace('www.', '');
const elements = url.split('/')
let name = elements[elements.length - 1] !== '' ? elements[elements.length - 1] : elements[elements.length - 2];
name = name.split('.')[0].split('?')[0].replace(/-|_/gm, ' ')
.split(' ')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
return `[${name}](${url})`;
}
const convertUrlsFromString = (text: string) => {
text = text.replace(/(https?|ftp):\/\/[^\s/$.?#].[^\s,]*/ig, urlToHyperlink);
return text;
}
export default class LinkNameFromUrlPlugin extends Plugin {
settings: PluginSettings;
async onload() {
await this.loadSettings();
this.addCommand({
id: 'get-link-name-from-url',
name: 'Get link name from URL',
checkCallback: (checking: boolean) => {
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (!view) return false;
const view_mode = view.getMode();
switch (view_mode) {
case 'source':
if (!checking && 'editor' in view) {
const selection = view.editor.getSelection(); // TODO try to get the nearest URL
if (!selection.includes('http')) {
return false;
}
view.editor.replaceSelection(convertUrlsFromString(selection));
}
return true;
default:
return false;
}
}
});
this.addSettingTab(new SettingTab(this.app, this));
if (this.settings.autoConvert) {
this.registerEvent(this.app.workspace.on('editor-paste', (clipboard: ClipboardEvent) => {
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (!view || !this.settings.autoConvert) return false;
const clipboardText = clipboard.clipboardData!.getData("text/plain").trim();
if (clipboardText == null || clipboardText == "") return;
if (!clipboardText.includes('http')) return;
clipboard.stopPropagation();
clipboard.preventDefault();
view.editor.replaceSelection(convertUrlsFromString(clipboardText));
}))
}
}
onunload() {
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
}
class SettingTab extends PluginSettingTab {
plugin: LinkNameFromUrlPlugin;
constructor(app: App, plugin: LinkNameFromUrlPlugin) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const { containerEl } = this;
containerEl.empty();
new Setting(containerEl)
.setName('Auto convert')
.setDesc('Automatically convert links to hyperlinks with name.')
.addToggle(text => text
.setValue(this.plugin.settings.autoConvert)
.onChange(async (value) => {
this.plugin.settings.autoConvert = value;
await this.plugin.saveSettings();
}));
}
}