Skip to content

Commit 4d027c1

Browse files
authored
Merge pull request #7 from decaf-dev/dev
1.1.0
2 parents fea3f02 + de84c5d commit 4d027c1

File tree

6 files changed

+105
-100
lines changed

6 files changed

+105
-100
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ Note splitter is an [Obsidian.md](https://obsidian.md) plugin for desktop only.
2424
## Usage
2525

2626
1. Open a note that you want to split
27-
2. Open the Obsidian command palette
28-
3. Type **Split by delimiter**
29-
4. Press enter
30-
5. Your note is now split
27+
2. Switch to editing mode
28+
3. Open the Obsidian command palette
29+
4. Type **Split by delimiter**
30+
5. Press enter
31+
6. Your note is now split
3132

3233
>[!NOTE]
3334
> Splitting a note will not modify the original note, unless the [delete original](#delete-original) setting is enabled. It will create new notes in an output folder that you specify.

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "note-splitter",
33
"name": "Note Splitter",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"minAppVersion": "0.15.0",
66
"description": "Split a note into individual notes based on a delimiter.",
77
"author": "DecafDev",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "obsidian-note-splitter",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "Split notes based on a delimiter",
55
"main": "main.js",
66
"scripts": {

src/main.ts

Lines changed: 93 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Editor, MarkdownView, Notice, Plugin, normalizePath } from "obsidian";
2-
import { escapeInvalidFileNameChars, findFrontmatterEndIndex, trimForFileName } from "./utils";
1+
import { MarkdownView, Notice, Plugin, TFile, normalizePath } from "obsidian";
2+
import { escapeInvalidFileNameChars, removeFrontmatterBlock, trimForFileName } from "./utils";
33
import NoteSplitterSettingsTab from "./obsidian/note-splitter-settings-tab";
44

55
interface NoteSplitterSettings {
@@ -27,102 +27,115 @@ export default class NoteSplitterPlugin extends Plugin {
2727
this.addCommand({
2828
id: "split-by-delimiter",
2929
name: "Split by delimiter",
30-
editorCallback: async (_editor: Editor, view: MarkdownView) => {
31-
const file = view.file;
32-
if (file === null) return;
33-
34-
//Obsidian will store `\n`` as `\\n` in the settings
35-
const delimiter = this.settings.delimiter.replace(/\\n/g, "\n");
36-
37-
if (delimiter === "") {
38-
new Notice("No delimiter set. Please set a delimiter in the settings.");
39-
return;
40-
}
41-
42-
const fileData = await this.app.vault.cachedRead(file);
43-
const frontmatterEndIndex = findFrontmatterEndIndex(fileData);
44-
45-
let dataWithoutFrontmatter = fileData;
46-
//Ignore frontmatter
47-
if (frontmatterEndIndex !== -1) {
48-
dataWithoutFrontmatter = dataWithoutFrontmatter.slice(frontmatterEndIndex + 1);
49-
}
50-
if (dataWithoutFrontmatter === "") {
51-
new Notice("No content to split.");
30+
callback: async () => {
31+
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
32+
if (view === null) {
33+
new Notice("Please open a markdown note.");
5234
return;
5335
}
5436

55-
const splitLines = dataWithoutFrontmatter
56-
.split(delimiter)
57-
.map((line) => line.trim())
58-
.filter((line) => line !== "");
59-
60-
if (splitLines.length === 0) {
61-
new Notice("No content to split.");
37+
const file = view.file;
38+
if (file === null) {
39+
new Notice("No file found for this note.");
6240
return;
6341
}
6442

65-
if (splitLines.length === 1) {
66-
new Notice("Only one line found. Nothing to split.");
43+
if (view.getMode() !== 'source') {
44+
new Notice("Please switch to editing mode to split the note.");
6745
return;
6846
}
6947

70-
const folderPath =
71-
this.settings.saveFolderPath ||
72-
file.parent?.path ||
73-
this.settings.saveFolderPath;
74-
75-
try {
76-
await this.app.vault.createFolder(folderPath);
77-
} catch (err) {
78-
//Folder already exists
79-
}
80-
81-
let filesCreated = 0;
82-
for (const [i, line] of splitLines.entries()) {
83-
let fileName = line;
84-
if (this.settings.useContentAsTitle) {
85-
fileName = escapeInvalidFileNameChars(fileName);
86-
fileName = trimForFileName(fileName, ".md");
87-
} else {
88-
fileName = `split-note-${Date.now() + i}`;
89-
}
90-
91-
const filePath = normalizePath(`${folderPath}/${fileName}.md`);
48+
this.splitNoteByDelimiter(file);
49+
},
50+
});
51+
}
9252

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 splitLines = dataWithoutFrontmatter
73+
.split(delimiter)
74+
.map((line) => line.trim())
75+
.filter((line) => line !== "");
76+
77+
if (splitLines.length === 0) {
78+
new Notice("No content to split.");
79+
return;
80+
}
81+
82+
if (splitLines.length === 1) {
83+
new Notice("Only one line 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, line] of splitLines.entries()) {
100+
let fileName = line;
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, line);
112+
filesCreated++;
113+
} catch (err) {
114+
if (err.message.includes("already exists")) {
115+
const newFilePath = `${folderPath}/Split conflict ${crypto.randomUUID()}.md`;
93116
try {
94-
await this.app.vault.create(filePath, line);
117+
await this.app.vault.create(newFilePath, line);
95118
filesCreated++;
96119
} catch (err) {
97-
if (err.message.includes("already exists")) {
98-
const newFilePath = `${folderPath}/Split conflict ${crypto.randomUUID()}.md`;
99-
try {
100-
await this.app.vault.create(newFilePath, line);
101-
filesCreated++;
102-
} catch (err) {
103-
console.error(err);
104-
new Notice(`Error creating file: ${err.message}`);
105-
}
106-
continue;
107-
}
120+
console.error(err);
108121
new Notice(`Error creating file: ${err.message}`);
109-
console.log(err);
110122
}
123+
continue;
111124
}
112-
113-
if (filesCreated === splitLines.length && this.settings.deleteOriginalNote) {
114-
await this.app.vault.delete(file);
115-
}
116-
117-
new Notice(
118-
"Split into " + filesCreated + " note" + (filesCreated > 1 ? "s" : "") + ".",
119-
);
120-
},
121-
});
125+
new Notice(`Error creating file: ${err.message}`);
126+
console.log(err);
127+
}
128+
}
129+
130+
if (filesCreated === splitLines.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+
);
122137
}
123138

124-
onunload() {}
125-
126139
async loadSettings() {
127140
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
128141
}

src/utils.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
1-
export const findFrontmatterEndIndex = (value: string) => {
1+
export const removeFrontmatterBlock = (data: string) => {
22
// Define the regular expression for the frontmatter block
3-
const regex = /^---\n([\s\S]*?)\n---/;
4-
5-
// Execute the regex on the string
6-
const match = regex.exec(value);
7-
8-
// If a match is found, return the index where the block ends
9-
if (match) {
10-
// The ending index is the starting index of the match plus its length
11-
return match[0].length;
12-
}
13-
// If no match is found, return -1
14-
return -1;
3+
const FRONTMATTER_REGEX = /^---\n([\s\S]*?)\n---/;
4+
return data.replace(FRONTMATTER_REGEX, "").trim();
155
};
166

177
/**

versions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
"0.5.0": "0.15.0",
1010
"0.5.1": "0.15.0",
1111
"0.6.0": "0.15.0",
12-
"1.0.0": "0.15.0"
12+
"1.0.0": "0.15.0",
13+
"1.1.0": "0.15.0"
1314
}

0 commit comments

Comments
 (0)