generated from obsidianmd/obsidian-sample-plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.ts
140 lines (113 loc) · 4.79 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
132
133
134
135
136
137
138
139
140
import { Plugin } from 'obsidian';
export default class TodoPlugin extends Plugin {
async onload() {
console.log('Loading Todo Plugin');
await this.updateTodoFile();
// Function to check if a line contains a todo or a calendar emoji
function containsTodo(line: string): boolean {
return line.includes('#todo') || line.includes('📅');
}
// Register an event listener for when a file is saved
this.registerEvent(
this.app.vault.on('modify', async (file) => {
if (file.path === 'todo.txt') {
// Do not trigger if todo.txt is modified
return;
}
// Read the file
const fileContent = await this.app.vault.read(file);
// Check if the file content has #todo tag or 📅 symbol
if (containsTodo(fileContent)) {
await this.updateTodoFile();
}
})
);
// Register an event listener for when a file is deleted
this.registerEvent(
this.app.vault.on('delete', async (file) => {
// Check if deleted file has #todo tag
if (containsTodo(file.path)) {
await this.updateTodoFile();
}
})
);
// Register an event listener for when a new file is created
this.registerEvent(
this.app.vault.on('create', async (file) => {
// Check if created file has #todo tag
if (containsTodo(await this.app.vault.read(file))) {
await this.updateTodoFile();
}
})
);
}
async updateTodoFile() {
// Get all the Markdown notes in the vault
const markdownFiles = this.getMarkdownFiles();
// Filter out notes that do not have the #todo tag
const todoNotes = markdownFiles.filter(async (note) => {
const content = await this.app.vault.read(note);
return containsTodo(content);
});
const filteredTodoNotes = todoNotes.filter((note) => note !== undefined);
// Get the todo items from each note with #todo tag
const todoItems = filteredTodoNotes.map(async (note) => {
const items = (await this.app.vault.read(note))
?.split('\n')
.filter((line) => (line.includes('- [ ]') || line.includes('- [x]') || line.includes('- [/]')) && (line.includes('#todo') || line.includes('📅')))
.map((line) => {
// Replace Obsidian Tasks notations to todo.txt due date
line = line.replace('📅 ', 'due:');
line = line.replace('📅', 'due:');
// Replace Obsidian Tasks recurrence notation to todo.txt recurrence
line = line.replace('🔁 every day', 'rec:1d');
line = line.replace('🔁 every two days', 'rec:2d');
line = line.replace(/🔁 every (\d+) day(s)?/gi, 'rec:$1d'); // e.g. every n days
line = line.replace('🔁 every week', 'rec:1w');
line = line.replace(/🔁 every (\d+) week(s)?/gi, 'rec:$1w'); // e.g. every n weeks
line = line.replace('🔁 every month', 'rec:1m');
line = line.replace(/🔁 every (\d+) month(s)?/gi, 'rec:$1m'); // e.g. every n months
// Replace Obsidian Tasks notations to todo.txt priority notation
const priorityRegex = /[\u{1F53A}\u{23EB}\u{1F53C}\u{1F53D}]/gu; // use 'g' flag to match all occurrences
const matches = [...line.matchAll(priorityRegex)];
let priority = '';
matches.forEach((match) => {
const priorityChar = match[0];
if (priorityChar === '\u{1F53A}') {
priority = '(A)';
} else if (priorityChar === '\u{23EB}') {
priority = '(B)';
} else if (priorityChar === '\u{1F53C}') {
priority = '(C)';
} else if (priorityChar === '\u{1F53D}') {
priority = '(D)';
}
line = line.replace(priorityChar, '');
});
// Append the priority notation to the beginning of the line
if (priority) {
line = `${priority} ${line}`;
}
// Replace ticked off items with x and append to beginning of line
line = line.includes('- [x] ') ? `x ${line.replace('- [x] ', '')}` : line;
// line = line.includes('- [a] ') ? `a ${line.replace('- [a] ', '')}` : line;
// Remove the checkbox and any tags from the line
line = line.replace('- [ ]', '').replace('- [/]', '').replace('#todo', '');
return line.trim();
}) || [];
return items;
});
// Wait for all promises to resolve before continuing
const allItems = await Promise.all(todoItems);
// Update the todo.txt file with the latest todo items
await this.app.vault.adapter.write(
'todo.txt',
allItems.flat().join('\n') + '\n'
);
// console.log('Updated todo.txt file');
}
getMarkdownFiles() {
const { vault } = this.app;
return vault.getMarkdownFiles();
}
}