Capitalize first letter of sentences in pasted document, even when the sentence starts with a single quotation mark

What I’m trying to do

A key workflow is making voice notes in Otter and then editing the transcript. On many lines, I add a single quotation mark to the beginning. I don’t bother to fix all the initial caps, as it would increase the time to edit the transcript. Instead, I copy the transcript into OneNote, where I have a macro to change the case of the first letter of sentences to uppercase. Then I cut it from OneNote and paste it into Obsidian.

Things I have tried

I tried the Text Format community plugin, with the command “Capitalize only first word of sentence”. This works to correctly capitalize the first words of sentences that don’t start with the single quotation mark. But it skips the sentences that have the single quotation mark.

So I’m forced to keep my old app in my workflow that I only use for this one thing. I would like to be able to paste directly into Obsidian and have a macro or something to capitalize the first letter of all sentences, including sentences that start with quotation marks or a single quotation.

can you share some of your lines?
you can make up anything e.g. chicken crossed the road, etc.

just to see how you would add the quotes and whether you have line breaks, etc.

because you see, for parsing sentences the script (maker) needs to know by what they can ascertain what the first word in a sentence would be…

this would be easier with language modules in Python programming language, but i’m guessing you’d just like to work this out with javascript within obsidian…

edit:
in fact, show how the lines are organized before you run the macro on them

  • it’d be a total waste of time to run a macro here, a script there… you need one solution

p.s.: i’m no coder but i can help you how to proceed

1 Like

The below is a snippet of my text before fixing the initial caps. As you can see, it’s laid out in paragraphs. I’m not very savvy about programming. The macro I’ve been using in OneNote was created by someone else.

"
Does it seem to work that what starts with life ends up as form?

'yes, yes. we are here. We are in love and not in fear.

So is there any validity to that observation?

'Yes.

Why does that occur?

'we would even ask, where would mind get its inspiration for “good ideas”, if not from us. We are where the life is and the mind imagines that it can contain this, bottle up this flow, this life to make sure that it always has it. But in doing so, what remains is this bottle and not the life, only the external form of it.

Why don’t you stay in the form?

'We are not controllable.

Why else though? seriously, why don’t you stay?

'there is no space. This rigidity is not allowing. This is not how we play. It is based on misunderstanding. this is all that mind can do.

Like what’s flashing into my mind is like how humans are trying to make artificial babies, so that they can maybe, like, prove that they can do it, like that there’s nothing magical.

'even if this were done, the life of any form is us.

"

i see

well, just to take the guess-work out of it, can you show me the output of text in the app Otter?

because as i told you, your workflow needs changing…
just use one app for voice notes* and one script that does the clean up job
no need to use an intermediate step as you’ve done thus far with Onenote

although i do understand you’d want to convert text you’d already processed in Onenote before you’d say goodbye to that intermediate step

of course, the difference between the two types of output (with or without the single quote in front) is trivial

the key is to have line breaks – do you have line breaks (carriage returns) in the output in Otter as well?

* there are even workflows in the share and showcase section where people hooked up the voice app of their choice (i forget the name(s)) and obsidian so no need to to copy and pasting – i am not conversant with otter and don’t use the methods mentioned tho…

okay

so familiarize yourself with the third party plugin Templater
you may need to install it from the plugin store first and then after enabling it, create a folder, e.g. meta/templater/ for your future template files

save this script

<%*
// Get the current file
const currentFile = app.workspace.getActiveFile();
if (!currentFile) return;

// Read the file content
let fileContent = await app.vault.read(currentFile);

// Separate YAML front matter from the rest of the content
const yamlRegex = /^---\n[\s\S]*?\n---\n/gm;
const yamlMatch = fileContent.match(yamlRegex);
const yamlBlock = yamlMatch ? yamlMatch[0] : '';
let content = fileContent.replace(yamlRegex, '');

// Check if there was an empty line between the YAML block and the content
const hasEmptyLineAfterYaml = fileContent.startsWith('\n', yamlBlock.length);

// Remove all single quotes that appear at the start of any line
content = content.replace(/^'/gm, '');

// Use regex to capitalize the first letter of each line, handling optional leading double quotes or punctuation
content = content.replace(/^\s*["]?\s*([a-z])/gm, (match, p1) => p1.toUpperCase());

// Remove orphaned double quotes
content = content.replace(/(^|\s)"(\s|$)/g, '');

// Ensure there is only one empty line between paragraphs
content = content.replace(/\n{2,}/g, '\n\n');

// Recombine the YAML block with the updated content, preserving the empty line if it was present
const updatedContent = yamlBlock + (hasEmptyLineAfterYaml ? '\n' : '') + content;

// Write back the changes
await app.vault.modify(currentFile, updatedContent);
_%>

to your folder with a name you’ll remember, e.g. Capitalize first letter script

then in Templater settings again in Template Hotkeys, press Add New Hotkey and add the file you’ve just created – you can bind a hotkey to this script
then try it on your lines

get back to me if you have problems

alternatively, you can sign up to a chatgpt account and ask a bot to tailor the script more to your liking

the script will work as it is, provided your lines (in Otter) are not a free-flowing mass, because then this simple javascript will not be enough

best of luck


edit: added check for yaml and empty line underneath

@Yurcee Thank you so much for your help! I took your code to Chat GPT and modified it slightly to not change the initial punctuation (because I actually need the single quotation marks to be in it). After a few edit rounds, I got something to work perfectly! I’m going to include it here in case anyone else has the same question. I was new to Templater, but it looks like you have to use the command “Open insert template modal” to actually get the script to run.

Here’s the script:

<%*
// Get the current file
const currentFile = app.workspace.getActiveFile();
if (!currentFile) return;

// Read the file content
let fileContent = await app.vault.read(currentFile);

// Separate YAML front matter from the rest of the content
const yamlRegex = /^---\n[\s\S]*?\n---\n/gm;
const yamlMatch = fileContent.match(yamlRegex);
const yamlBlock = yamlMatch ? yamlMatch[0] : '';
let content = fileContent.replace(yamlRegex, '');

// Capitalize the first letter of each sentence, including those starting with a single quotation mark
// This includes handling sentences after newlines and those after sentence-ending punctuation
content = content.replace(/(^|\n|\.\s+|\?\s+|\!\s+|\n['"]\s*)\s*([a-z])/gm, (match, p1, p2) => p1 + p2.toUpperCase());

// Recombine the YAML block with the updated content
const updatedContent = yamlBlock + content;

// Write back the changes
await app.vault.modify(currentFile, updatedContent);
%>

glad you have worked something out to your liking

from now on, you can use the base structure of the script and make others like it, bind them to hotkeys and toolbar icons, etc

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.