|
1 | | -import { MarkdownView, Notice, Plugin, TFile, normalizePath } from "obsidian"; |
2 | | -import { escapeInvalidFileNameChars, removeFrontmatterBlock, trimForFileName } from "./utils"; |
| 1 | +import { MarkdownView, Notice, Plugin } from "obsidian"; |
3 | 2 | import NoteSplitterSettingsTab from "./obsidian/note-splitter-settings-tab"; |
4 | | - |
5 | | -interface NoteSplitterSettings { |
6 | | - saveFolderPath: string; |
7 | | - useContentAsTitle: boolean; |
8 | | - delimiter: string; |
9 | | - deleteOriginalNote: boolean; |
10 | | -} |
| 3 | +import { splitByDelimiter } from "./splitter/split-by-delimiter"; |
| 4 | +import { NodeFileSystem, NoteSplitterSettings, Notifier } from "./types"; |
11 | 5 |
|
12 | 6 | const DEFAULT_SETTINGS: NoteSplitterSettings = { |
13 | 7 | saveFolderPath: "note-splitter", |
14 | 8 | useContentAsTitle: false, |
15 | 9 | delimiter: "\\n", |
| 10 | + appendToSplitContent: "", |
16 | 11 | deleteOriginalNote: false, |
17 | 12 | }; |
18 | 13 |
|
@@ -40,101 +35,24 @@ export default class NoteSplitterPlugin extends Plugin { |
40 | 35 | return; |
41 | 36 | } |
42 | 37 |
|
43 | | - if (view.getMode() !== 'source') { |
44 | | - new Notice("Please switch to editing mode to split the note."); |
| 38 | + if (view.getMode() !== "source") { |
| 39 | + new Notice("Please switch to editing mode to split this note."); |
45 | 40 | return; |
46 | 41 | } |
47 | 42 |
|
48 | | - this.splitNoteByDelimiter(file); |
| 43 | + const fileSystem: NodeFileSystem = { |
| 44 | + create: (filePath, content) => this.app.vault.create(filePath, content), |
| 45 | + createFolder: (folderPath) => this.app.vault.createFolder(folderPath), |
| 46 | + delete: (file) => this.app.vault.delete(file), |
| 47 | + read: (file) => this.app.vault.read(file), |
| 48 | + }; |
| 49 | + const notifier: Notifier = (message: string) => new Notice(message); |
| 50 | + await splitByDelimiter(fileSystem, notifier, file, this.settings); |
49 | 51 | }, |
50 | 52 | }); |
51 | 53 | } |
52 | 54 |
|
53 | | - onunload() { } |
54 | | - |
55 | | - private async splitNoteByDelimiter(file: TFile) { |
56 | | - //Obsidian will store `\n`` as `\\n` in the settings |
57 | | - const delimiter = this.settings.delimiter.replace(/\\n/g, "\n"); |
58 | | - |
59 | | - if (delimiter === "") { |
60 | | - new Notice("No delimiter set. Please set a delimiter in the settings."); |
61 | | - return; |
62 | | - } |
63 | | - |
64 | | - const data = await this.app.vault.cachedRead(file); |
65 | | - |
66 | | - const dataWithoutFrontmatter = removeFrontmatterBlock(data); |
67 | | - if (dataWithoutFrontmatter === "") { |
68 | | - new Notice("No content to split."); |
69 | | - return; |
70 | | - } |
71 | | - |
72 | | - const splitContent = dataWithoutFrontmatter |
73 | | - .split(delimiter) |
74 | | - .map((content) => content.trim()) |
75 | | - .filter((content) => content !== ""); |
76 | | - |
77 | | - if (splitContent.length === 0) { |
78 | | - new Notice("No content to split."); |
79 | | - return; |
80 | | - } |
81 | | - |
82 | | - if (splitContent.length === 1) { |
83 | | - new Notice("Only one piece of content found. Nothing to split."); |
84 | | - return; |
85 | | - } |
86 | | - |
87 | | - const folderPath = |
88 | | - this.settings.saveFolderPath || |
89 | | - file.parent?.path || |
90 | | - this.settings.saveFolderPath; |
91 | | - |
92 | | - try { |
93 | | - await this.app.vault.createFolder(folderPath); |
94 | | - } catch (err) { |
95 | | - //Folder already exists |
96 | | - } |
97 | | - |
98 | | - let filesCreated = 0; |
99 | | - for (const [i, content] of splitContent.entries()) { |
100 | | - let fileName = content.split("\n")[0]; |
101 | | - if (this.settings.useContentAsTitle) { |
102 | | - fileName = escapeInvalidFileNameChars(fileName); |
103 | | - fileName = trimForFileName(fileName, ".md"); |
104 | | - } else { |
105 | | - fileName = `split-note-${Date.now() + i}`; |
106 | | - } |
107 | | - |
108 | | - const filePath = normalizePath(`${folderPath}/${fileName}.md`); |
109 | | - |
110 | | - try { |
111 | | - await this.app.vault.create(filePath, content); |
112 | | - filesCreated++; |
113 | | - } catch (err) { |
114 | | - if (err.message.includes("already exists")) { |
115 | | - const newFilePath = `${folderPath}/Split conflict ${crypto.randomUUID()}.md`; |
116 | | - try { |
117 | | - await this.app.vault.create(newFilePath, content); |
118 | | - filesCreated++; |
119 | | - } catch (err) { |
120 | | - console.error(err); |
121 | | - new Notice(`Error creating file: ${err.message}`); |
122 | | - } |
123 | | - continue; |
124 | | - } |
125 | | - new Notice(`Error creating file: ${err.message}`); |
126 | | - console.log(err); |
127 | | - } |
128 | | - } |
129 | | - |
130 | | - if (filesCreated === splitContent.length && this.settings.deleteOriginalNote) { |
131 | | - await this.app.vault.delete(file); |
132 | | - } |
133 | | - |
134 | | - new Notice( |
135 | | - "Split into " + filesCreated + " note" + (filesCreated > 1 ? "s" : "") + ".", |
136 | | - ); |
137 | | - } |
| 55 | + onunload() {} |
138 | 56 |
|
139 | 57 | async loadSettings() { |
140 | 58 | this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); |
|
0 commit comments