Skip to content

Commit

Permalink
Merge pull request #20 from decaf-dev/dev
Browse files Browse the repository at this point in the history
1.2.1
  • Loading branch information
decaf-dev authored Sep 14, 2024
2 parents b5106e0 + 26c6f18 commit ce6c902
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 56 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,28 @@ If disabled, a timestamp will be used as the title e.g. `note-splitter-170259191
> [!NOTE]
> Disabled by default.
#### Removed characters

Depending on your operating system, Obsidian will not allow certain characters in a file name.

When `Use first line as title` is enabled, invalid characters in the first line will be removed.

| Character | Removed On |
| --------- | --------------------- |
| `*` | Windows |
| `"` | Windows |
| `` ` `` | Windows |
| `?` | Windows |
| `<` | Windows |
| `>` | Windows |
| `:` | Windows, macOS, Linux |
| `\` | Windows, macOS, Linux |
| `/` | Windows, macOS, Linux |
| `^` | Windows, macOS, Linux |
| `[` | Windows, macOS, Linux |
| `]` | Windows, macOS, Linux |
| `#` | Windows, macOS, Linux |

### Append to split content

This text will be appended to each section of split content.
Expand Down
Binary file modified bun.lockb
Binary file not shown.
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.2.0",
"version": "1.2.1",
"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.2.0",
"version": "1.2.1",
"description": "Split notes based on a delimiter",
"main": "main.js",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MarkdownView, Notice, Plugin } from "obsidian";
import { MarkdownView, Notice, Platform, Plugin } from "obsidian";
import NoteSplitterSettingsTab from "./obsidian/note-splitter-settings-tab";
import { splitByDelimiter } from "./splitter/split-by-delimiter";
import { NodeFileSystem, NoteSplitterSettings, Notifier } from "./types";
Expand Down Expand Up @@ -47,7 +47,7 @@ export default class NoteSplitterPlugin extends Plugin {
read: (file) => this.app.vault.read(file),
};
const notifier: Notifier = (message: string) => new Notice(message);
await splitByDelimiter(fileSystem, notifier, file, this.settings);
await splitByDelimiter(fileSystem, notifier, file, Platform.isWin, this.settings);
},
});
}
Expand Down
37 changes: 19 additions & 18 deletions src/splitter/sanitize-file-name.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
/**
* Sanitizes a file name for use in a file system
*/
export const sanitizeFileName = (name: string) => {
// Replace colon with hyphen
name = name.replace(/:/g, "-");
// Replace back slash with space
name = name.replace(/\\/g, " ");
// Replace forward slash with space
name = name.replace(/\//g, " ");
// Replace carrot with nothing
name = name.replace(/\^/g, "");
// Replace left bracket with nothing
name = name.replace(/\[/g, "");
// Replace right bracket with nothing
name = name.replace(/\]/g, "");
// Replace hash tag with nothing
name = name.replace(/#/g, "");
// Replace pipe with nothing
name = name.replace(/\|/g, "");
return name.trim();
export const sanitizeFileName = (name: string, isWindows: boolean) => {
if (isWindows) {
name = name.replace(/\?/g, ""); // Remove question mark (Windows)
name = name.replace(/</g, ""); // Remove less than (Windows)
name = name.replace(/>/g, ""); // Remove greater than (Windows)
name = name.replace(/"/g, ""); // Remove double quote (Windows)
name = name.replace(/\*/g, ""); // Remove asterisk (Windows)
name = name.replace(/`/g, ""); // Remove backtick (Windows)
}

name = name.replace(/:/g, ""); // Remove colon (Windows, macOS)
name = name.replace(/\|/g, ""); // Remove pipe (Windows)
name = name.replace(/\\/g, ""); // Remove backslash (Windows, general cross-platform safety)
name = name.replace(/\//g, ""); // Remove forward slash (Windows, Linux, macOS)
name = name.replace(/\[/g, ""); // Remove left bracket (General safety, no specific OS restriction)
name = name.replace(/\]/g, ""); // Remove right bracket (General safety, no specific OS restriction)
name = name.replace(/#/g, ""); // Remove hashtag (General safety, no specific OS restriction)
name = name.replace(/\^/g, ""); // Remove caret (General safety, no specific OS restriction)
return name.trim(); // Trim whitespace from start and end (General cleanup)
};
7 changes: 4 additions & 3 deletions src/splitter/split-by-delimiter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { normalizePath, TFile } from "obsidian";
import { normalizePath, Platform, TFile } from "obsidian";
import { removeFrontmatterBlock } from "./remove-frontmatter-block";
import { sanitizeFileName } from "./sanitize-file-name";
import { truncateFileName } from "./truncate-file-name";
Expand All @@ -8,6 +8,7 @@ export const splitByDelimiter = async (
fileSystem: NodeFileSystem,
notify: Notifier,
file: TFile,
isWindows: boolean,
{
delimiter,
saveFolderPath,
Expand Down Expand Up @@ -69,8 +70,8 @@ export const splitByDelimiter = async (
fileName = `split-note-${Date.now() + i}.md`;
}

fileName = sanitizeFileName(fileName);
fileName = truncateFileName(fileName);
fileName = sanitizeFileName(fileName, isWindows);
fileName = truncateFileName(fileName, ".md");

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

Expand Down
13 changes: 6 additions & 7 deletions src/splitter/truncate-file-name.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/**
* Truncates the string to the maximum length allowed for a file name
*/
export const truncateFileName = (name: string) => {
export const truncateFileName = (name: string, extension: string) => {
const MAX_LENGTH = 255;

const splitArr = name.split(".");
if (splitArr.length < 2) {
throw new Error("Invalid file name");
//Add support for links
let length = name.length;
if (length > MAX_LENGTH) {
length = MAX_LENGTH;
}

const baseName = splitArr[0];
const extension = splitArr[1];
return baseName.substring(0, MAX_LENGTH - extension.length - 1) + "." + splitArr[1];
return name.substring(0, length - extension.length) + extension;
};
14 changes: 7 additions & 7 deletions test/integration/split-by-delimiter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe("splitByDelimiter", () => {
path: "file1.md",
} as TFile;

await splitByDelimiter(mockFileSystem, mockNotifier, file, {
await splitByDelimiter(mockFileSystem, mockNotifier, file, false, {
delimiter: "",
saveFolderPath: "",
useContentAsTitle: false,
Expand All @@ -47,7 +47,7 @@ describe("splitByDelimiter", () => {
path: "file1.md",
} as TFile;

await splitByDelimiter(mockFileSystem, mockNotifier, file, {
await splitByDelimiter(mockFileSystem, mockNotifier, file, false, {
delimiter: "\n",
saveFolderPath: "",
useContentAsTitle: false,
Expand All @@ -64,7 +64,7 @@ describe("splitByDelimiter", () => {
path: "file2.md",
} as TFile;

await splitByDelimiter(mockFileSystem, mockNotifier, file, {
await splitByDelimiter(mockFileSystem, mockNotifier, file, false, {
delimiter: "\n",
saveFolderPath: "",
useContentAsTitle: false,
Expand All @@ -81,7 +81,7 @@ describe("splitByDelimiter", () => {
path: "file3.md",
} as TFile;

await splitByDelimiter(mockFileSystem, mockNotifier, file, {
await splitByDelimiter(mockFileSystem, mockNotifier, file, false, {
delimiter: "\n",
saveFolderPath: "",
useContentAsTitle: false,
Expand Down Expand Up @@ -109,7 +109,7 @@ describe("splitByDelimiter", () => {
path: "file3.md",
} as TFile;

await splitByDelimiter(mockFileSystem, mockNotifier, file, {
await splitByDelimiter(mockFileSystem, mockNotifier, file, false, {
delimiter: "\n",
saveFolderPath: "",
useContentAsTitle: false,
Expand All @@ -126,7 +126,7 @@ describe("splitByDelimiter", () => {
path: "file3.md",
} as TFile;

await splitByDelimiter(mockFileSystem, mockNotifier, file, {
await splitByDelimiter(mockFileSystem, mockNotifier, file, false, {
delimiter: "\n",
saveFolderPath: "",
useContentAsTitle: false,
Expand All @@ -150,7 +150,7 @@ describe("splitByDelimiter", () => {
path: "file3.md",
} as TFile;

await splitByDelimiter(mockFileSystem, mockNotifier, file, {
await splitByDelimiter(mockFileSystem, mockNotifier, file, false, {
delimiter: "\n",
saveFolderPath: "",
useContentAsTitle: true,
Expand Down
14 changes: 7 additions & 7 deletions test/unit/sanitize-file-name.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,40 @@ describe("sanitizeFileName", () => {
const content = "file:name";

// Act
const result = sanitizeFileName(content);
const result = sanitizeFileName(content, false);

// Assert
expect(result).toEqual("file-name");
expect(result).toEqual("filename");
});

it("should replace backslash with space", () => {
// Arrange
const content = "file\\name";

// Act
const result = sanitizeFileName(content);
const result = sanitizeFileName(content, false);

// Assert
expect(result).toEqual("file name");
expect(result).toEqual("filename");
});

it("should replace forward slash with space", () => {
// Arrange
const content = "file//name";

// Act
const result = sanitizeFileName(content);
const result = sanitizeFileName(content, false);

// Assert
expect(result).toEqual("file name");
expect(result).toEqual("filename");
});

it("should remove invalid characters", () => {
// Arrange
const content = "file name #|^[]";

// Act
const result = sanitizeFileName(content);
const result = sanitizeFileName(content, false);

// Assert
expect(result).toEqual("file name");
Expand Down
18 changes: 9 additions & 9 deletions test/unit/truncate-file-name.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { truncateFileName } from "src/splitter/truncate-file-name";

describe("truncateFileName", () => {
it("should throw an error if the file name is invalid", () => {
it("should truncate the string to 255 characters", () => {
// Arrange
const fileName = "file";
const fileName = "a".repeat(260) + ".md";

// Act
const action = () => truncateFileName(fileName);
const result = truncateFileName(fileName, ".md");

// Assert
expect(action).toThrow();
expect(result.length).toEqual(255);
expect(result.endsWith(".md")).toEqual(true);
});

it("should truncate the string to 255 characters", () => {
it("should not modify a link shorter than 255 characters", () => {
// Arrange
const fileName = "a".repeat(260) + ".md";
const fileName = "https://example.com.md";

// Act
const result = truncateFileName(fileName);
const result = truncateFileName(fileName, ".md");

// Assert
expect(result.length).toEqual(255);
expect(result.endsWith(".md")).toEqual(true);
expect(result).toEqual(fileName);
});
});
3 changes: 2 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
"1.0.0": "0.15.0",
"1.1.0": "0.15.0",
"1.1.1": "0.15.0",
"1.2.0": "0.15.0"
"1.2.0": "0.15.0",
"1.2.1": "0.15.0"
}

0 comments on commit ce6c902

Please sign in to comment.