From 33217ab15cbb543049eb63fd5fb7dc0baefe92ad Mon Sep 17 00:00:00 2001 From: ipshing Date: Wed, 4 Oct 2023 22:16:55 -0700 Subject: [PATCH] Improve title case --- src/main.ts | 10 ++++++-- src/text.ts | 74 +++++++++++++++++++++++------------------------------ 2 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/main.ts b/src/main.ts index e0188dd..d65d0f0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import { Editor, Plugin } from "obsidian"; -import { toTitleCase } from "./text"; +import { convertToTitleCase } from "./text"; import { TextTransformSettingsTab } from "./settings"; interface TextTransformSettings { @@ -46,7 +46,13 @@ export default class TextTransform extends Plugin { this.addCommand({ id: "title-case", name: "Transform to Title Case", - editorCallback: (editor) => toTitleCase(editor, this), + editorCallback: (editor) => { + if (editor.hasFocus()) { + let selection = editor.getSelection(); + selection = convertToTitleCase(selection, this.settings.wordBoundaryChars, this.settings.titleCaseIgnore); + this.replaceSelection(editor, selection); + } + }, }); console.log("Text Transform plugin loaded"); diff --git a/src/text.ts b/src/text.ts index ab5b2b6..0eac47c 100644 --- a/src/text.ts +++ b/src/text.ts @@ -1,47 +1,37 @@ -import { Editor } from "obsidian"; -import TextTransform from "./main"; +export function convertToTitleCase(text: string, wordBoundaryChars: string[], ignore: string[]): string { + // Add space and tab to wordBoundaryChars + wordBoundaryChars.push(" ", "\t"); -export function toTitleCase(editor: Editor, plugin: TextTransform) { - // Get the selected text - const from = editor.getCursor("from"); - const to = editor.getCursor("to"); - const selection = editor.getSelection(); - - // First put the string into lower case - let transformed = selection.toLowerCase(); - // Replace all chars in wordBoundaryChars with spaces - for (const char of plugin.settings.wordBoundaryChars) { - transformed = transformed.replace(char, " "); - } - // Split using space as separator - const words = transformed.split(" "); - // Transform words - transformed = ""; - for (const word of words) { - // Check for ignored words - if (plugin.settings.titleCaseIgnore.includes(word)) { - transformed += word + " "; - continue; - } - // Transform first character - if (word.length > 0) { - transformed += word[0].toUpperCase(); - } - // Add in remaining characters - if (word.length > 1) { - transformed += word.slice(1); - } - // Add separator (space) - transformed += " "; - } - // Replace spaces with original characters - for (const [i, char] of [...selection].entries()) { - if (plugin.settings.wordBoundaryChars.includes(char)) { - transformed = transformed.slice(0, i) + char + transformed.slice(i + 1); + let transformed = ""; + let word = ""; + // Iterate the characters and build each word + for (const char of text) { + if (wordBoundaryChars.includes(char)) { + // push 'word' to 'transformed' + transformed += convertWord(word, ignore); + // push 'char' to 'transformed' + transformed += char; + // clear 'word' + word = ""; + } else { + // push 'char' to 'word' + word += char; } } + // Push 'word' one last time + transformed += convertWord(word, ignore); - // Replace the selection and re-highlight - editor.replaceSelection(transformed.trim()); - editor.setSelection(from, to); + return transformed; +} + +function convertWord(word: string, ignore: string[]): string { + if (word.length > 0) { + // convert to lowercase + word = word.toLocaleLowerCase(); + // only capitalize if not in 'ignore' list + if (!ignore.includes(word)) { + word = word[0].toLocaleUpperCase() + word.slice(1); + } + } + return word; }