Skip to content

Commit

Permalink
Merge pull request #7 from decaf-dev/dev
Browse files Browse the repository at this point in the history
1.1.0
  • Loading branch information
decaf-dev authored Jun 28, 2024
2 parents fea3f02 + de84c5d commit 4d027c1
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 100 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ Note splitter is an [Obsidian.md](https://obsidian.md) plugin for desktop only.
## Usage

1. Open a note that you want to split
2. Open the Obsidian command palette
3. Type **Split by delimiter**
4. Press enter
5. Your note is now split
2. Switch to editing mode
3. Open the Obsidian command palette
4. Type **Split by delimiter**
5. Press enter
6. Your note is now split

>[!NOTE]
> 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.
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "note-splitter",
"name": "Note Splitter",
"version": "1.0.0",
"version": "1.1.0",
"minAppVersion": "0.15.0",
"description": "Split a note into individual notes based on a delimiter.",
"author": "DecafDev",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "obsidian-note-splitter",
"version": "1.0.0",
"version": "1.1.0",
"description": "Split notes based on a delimiter",
"main": "main.js",
"scripts": {
Expand Down
173 changes: 93 additions & 80 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Editor, MarkdownView, Notice, Plugin, normalizePath } from "obsidian";
import { escapeInvalidFileNameChars, findFrontmatterEndIndex, trimForFileName } from "./utils";
import { MarkdownView, Notice, Plugin, TFile, normalizePath } from "obsidian";
import { escapeInvalidFileNameChars, removeFrontmatterBlock, trimForFileName } from "./utils";
import NoteSplitterSettingsTab from "./obsidian/note-splitter-settings-tab";

interface NoteSplitterSettings {
Expand Down Expand Up @@ -27,102 +27,115 @@ export default class NoteSplitterPlugin extends Plugin {
this.addCommand({
id: "split-by-delimiter",
name: "Split by delimiter",
editorCallback: async (_editor: Editor, view: MarkdownView) => {
const file = view.file;
if (file === null) return;

//Obsidian will store `\n`` as `\\n` in the settings
const delimiter = this.settings.delimiter.replace(/\\n/g, "\n");

if (delimiter === "") {
new Notice("No delimiter set. Please set a delimiter in the settings.");
return;
}

const fileData = await this.app.vault.cachedRead(file);
const frontmatterEndIndex = findFrontmatterEndIndex(fileData);

let dataWithoutFrontmatter = fileData;
//Ignore frontmatter
if (frontmatterEndIndex !== -1) {
dataWithoutFrontmatter = dataWithoutFrontmatter.slice(frontmatterEndIndex + 1);
}
if (dataWithoutFrontmatter === "") {
new Notice("No content to split.");
callback: async () => {
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (view === null) {
new Notice("Please open a markdown note.");
return;
}

const splitLines = dataWithoutFrontmatter
.split(delimiter)
.map((line) => line.trim())
.filter((line) => line !== "");

if (splitLines.length === 0) {
new Notice("No content to split.");
const file = view.file;
if (file === null) {
new Notice("No file found for this note.");
return;
}

if (splitLines.length === 1) {
new Notice("Only one line found. Nothing to split.");
if (view.getMode() !== 'source') {
new Notice("Please switch to editing mode to split the note.");
return;
}

const folderPath =
this.settings.saveFolderPath ||
file.parent?.path ||
this.settings.saveFolderPath;

try {
await this.app.vault.createFolder(folderPath);
} catch (err) {
//Folder already exists
}

let filesCreated = 0;
for (const [i, line] of splitLines.entries()) {
let fileName = line;
if (this.settings.useContentAsTitle) {
fileName = escapeInvalidFileNameChars(fileName);
fileName = trimForFileName(fileName, ".md");
} else {
fileName = `split-note-${Date.now() + i}`;
}

const filePath = normalizePath(`${folderPath}/${fileName}.md`);
this.splitNoteByDelimiter(file);
},
});
}

onunload() { }

private async splitNoteByDelimiter(file: TFile) {
//Obsidian will store `\n`` as `\\n` in the settings
const delimiter = this.settings.delimiter.replace(/\\n/g, "\n");

if (delimiter === "") {
new Notice("No delimiter set. Please set a delimiter in the settings.");
return;
}

const data = await this.app.vault.cachedRead(file);

const dataWithoutFrontmatter = removeFrontmatterBlock(data);
if (dataWithoutFrontmatter === "") {
new Notice("No content to split.");
return;
}

const splitLines = dataWithoutFrontmatter
.split(delimiter)
.map((line) => line.trim())
.filter((line) => line !== "");

if (splitLines.length === 0) {
new Notice("No content to split.");
return;
}

if (splitLines.length === 1) {
new Notice("Only one line found. Nothing to split.");
return;
}

const folderPath =
this.settings.saveFolderPath ||
file.parent?.path ||
this.settings.saveFolderPath;

try {
await this.app.vault.createFolder(folderPath);
} catch (err) {
//Folder already exists
}

let filesCreated = 0;
for (const [i, line] of splitLines.entries()) {
let fileName = line;
if (this.settings.useContentAsTitle) {
fileName = escapeInvalidFileNameChars(fileName);
fileName = trimForFileName(fileName, ".md");
} else {
fileName = `split-note-${Date.now() + i}`;
}

const filePath = normalizePath(`${folderPath}/${fileName}.md`);

try {
await this.app.vault.create(filePath, line);
filesCreated++;
} catch (err) {
if (err.message.includes("already exists")) {
const newFilePath = `${folderPath}/Split conflict ${crypto.randomUUID()}.md`;
try {
await this.app.vault.create(filePath, line);
await this.app.vault.create(newFilePath, line);
filesCreated++;
} catch (err) {
if (err.message.includes("already exists")) {
const newFilePath = `${folderPath}/Split conflict ${crypto.randomUUID()}.md`;
try {
await this.app.vault.create(newFilePath, line);
filesCreated++;
} catch (err) {
console.error(err);
new Notice(`Error creating file: ${err.message}`);
}
continue;
}
console.error(err);
new Notice(`Error creating file: ${err.message}`);
console.log(err);
}
continue;
}

if (filesCreated === splitLines.length && this.settings.deleteOriginalNote) {
await this.app.vault.delete(file);
}

new Notice(
"Split into " + filesCreated + " note" + (filesCreated > 1 ? "s" : "") + ".",
);
},
});
new Notice(`Error creating file: ${err.message}`);
console.log(err);
}
}

if (filesCreated === splitLines.length && this.settings.deleteOriginalNote) {
await this.app.vault.delete(file);
}

new Notice(
"Split into " + filesCreated + " note" + (filesCreated > 1 ? "s" : "") + ".",
);
}

onunload() {}

async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
Expand Down
16 changes: 3 additions & 13 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
export const findFrontmatterEndIndex = (value: string) => {
export const removeFrontmatterBlock = (data: string) => {
// Define the regular expression for the frontmatter block
const regex = /^---\n([\s\S]*?)\n---/;

// Execute the regex on the string
const match = regex.exec(value);

// If a match is found, return the index where the block ends
if (match) {
// The ending index is the starting index of the match plus its length
return match[0].length;
}
// If no match is found, return -1
return -1;
const FRONTMATTER_REGEX = /^---\n([\s\S]*?)\n---/;
return data.replace(FRONTMATTER_REGEX, "").trim();
};

/**
Expand Down
3 changes: 2 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"0.5.0": "0.15.0",
"0.5.1": "0.15.0",
"0.6.0": "0.15.0",
"1.0.0": "0.15.0"
"1.0.0": "0.15.0",
"1.1.0": "0.15.0"
}

0 comments on commit 4d027c1

Please sign in to comment.