Hi Michelle. I did this a few years ago and modified it a few times too. You will find an array of words that you want to keep lowercase in the script— first you see the array capitalized, then you see it lowercase (the way you want it).
I found, after using my original script, that there were exceptions: words like “MacBook” and “iPhone” and “iTunes” needed to stay capitalized as they are. I made a list of words like those and put them in a text file. You would do this too. The name of the file doesn’t matter as it will be stored as a property. Next time you run the script, it will not ask you to locate the file as it will already know where it is. You can edit that file as time goes by— easier than editing the script since it’s just a list of words. You could delete this section of the script of course.
I also found that even though you don’t want to capitalize words like “a” and “an” you might need to anyway. For example, if you have a sentence like “A horse is not a good house pet” you want the first “a” to be capitalized and the second “a” not to be. So I added code to test whether I was leading a sentence with one of those words. You could throw this part of the script out too.
I also found that I was messing up URLs. Some are case-sensitive. So, if it’s a URL, I save it and put it back. In my case I knew that the URL would be on a line by itself, so I test for that. This should be generalized but I didn’t do it.
I also set this script up to allow you to display a dialog box asking whether you want to use the regular Change Case box or this new one. But it is commented out here.
Hoping this helps and makes sense. Here’s the script.
property the_file : ""
--If there is no value for "the_file" there will be the next time you run the script.
-- Using "grep" throughout.
-- February 18th, 2011. Corrected Step 2 for single-quotes.
-- Revised June 4th, 2011. Changed initial case change step to better method.
-- Revised again June 22nd, 2011. Was making errors by mistakenly affecting URLs.
-- Revised/corrected June 24th, 2011 to catch case where there aren't any links.
-- Created new method in which lines that begin with "http" are stored, and later put back into the changed text. Much more efficient than working line by line. Other speed improvements also.
--
--This script, with the "on run {} and "end run" wrapper, works when it is
--in the Menu Scripts folder, inside the BBEdit folder, inside the Application Support folder,
--in your user Library ("~/Library/Application Support/BBEdit/Menu Scripts/").
--
--The script gives the option of using the original Change Case command.
(*
-- we would use this On Run handler if we put the script into the Menu Scripts folder.
--
on run
-- The run handler is called when the script is invoked normally,
-- such as from BBEdit's Scripts menu.
changecaseformichelle()
end run
*)
--
(*
--commented out because we are not going to attach to a menu item after all
on menuselect()
-- The menuselect() handler gets called when the script is invoked
-- by BBEdit as a menu script.
-- true means we do the changecaseformichelle script instead of the normal command
-- false means we do the normal command
--
set the_status to changecaseformichelle()
return the_status
end menuselect
*)
--
-- this would be called "on changecaseformichelle() if we wanted to put this in the Menu Scripts folder.
on run {}
(*
-- User gets to choose whether to use standard Change Case or this modified version. Added 2-14-2011. Happy Valentine's Day.
set the_button to display dialog "Would you like to use the standard Change Case, or Michelle's version?" buttons {"Standard", "Michelle's"} default button "Michelle's"
*)
--set the_button to button returned of the_button-- as if it had been clicked.
set the_button to "Michelle's"
if the_button is "Michelle's" then
set the_exceptions_upper to {"A", "An", "And", "As", "At", "But", "By", "For", "From", "In", "Into", "It", "Nor", "Of", "On", "Onto", "Or", "so", "The", "To", "with"}
set the_exceptions_lower to {"a", "an", "and", "as", "at", "but", "by", "for", "from", "in", "into", "it", "nor", "of", "on", "onto", "or", "so", "the", "to", "with"}
-- Reading exceptions from a file
if the_file = "" then
set the_file to choose file with prompt "Choose the file where you store the exceptions."
end if
set the_text to read the_file
set replace_with to paragraphs of the_text
-- we will use "replace_with" in Part 4 below--
tell application "BBEdit"
replace ".http" using
"\\rhttp" searching in selection
of project window 1 options {search mode
:grep, starting at top
:false, wrap around
:false, backwards
:false, case sensitive
:false, match words
:false, extend selection
:false} --
set the_text to the selection
set theCountOfLines to count of lines of the_text
set numberOfCharacters to number of characters of the_text
set startingPoint to characterOffset of the_text
set endingPoint to (startingPoint + (length of the_text))
-- Storing line number and content of every link from the original text. Then we make changes, then we restore with original link text. Brilliant move.
try
set we_have_links to "false"
set link_line_text to contents of every line of the_text whose contents starts with "http"
set link_line_numbers to startLine of every line of the_text whose contents starts with "http"
set we_have_links to "true"
end try
--PART ONE: Capitalize The Words.
change case the_text making capitalize words
--Fixing numbers
set the_numbers to {"1St", "2Nd", "3Rd", "4Th", "5Th", "6Th", "7Th", "8Th", "9Th", "0Th", "11Th", "12Th", "13Th"}
set the_fixed_numbers to {"1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "0th", "11th", "12th", "13th"}
tell the_text
repeat with k from 1 to count of the_numbers
replace item k of the_numbers using item k of the_fixed_numbers
end repeat
end tell
--/ixing numbers
--PART TWO: Look for the exceptions and fix them.
--loop through the_exceptions_upper
repeat with j from 1 to count of the_exceptions_upper
-- Added the "hyphenated word" case here.
set the_search_string to "(([>]+)|(
\\s+)|(
\\r+)|(-+))" &
item j of the_exceptions_upper set the_replace_string
to "\\1" & item j
of the_exceptions_lower
-- All parts of hyphenated words get capitalized
set the_hyphenation_search_string to item j of the_exceptions_lower & "-"
set the_hyphenation_replace_string to item j of the_exceptions_upper & "-"
-- Also handle the case where the hyphen is leading.
set the_hyphenation_search_string2 to "-" & item j of the_exceptions_lower
set the_hyphenation_replace_string2 to "-" & item j of the_exceptions_upper
tell the_text
replace the_search_string using the_replace_string options {match words:true, search mode:grep}
-- All parts of hyphenated words get capitalized
replace the_hyphenation_search_string using the_hyphenation_replace_string options {match words:true}
replace the_hyphenation_search_string2 using the_hyphenation_replace_string2 options {match words:true}
end tell
end repeat
--PART THREE: look for words that start sentences etc and Capitalize them.
--Fast Method: canned GREPS.
--Note: this could be written as one grep statement, in this form:
--(a|b|c|d) with a, b, c, and d being the first argument from each
--replace below. But that's messy to read.
tell the_text
-- one or more returns, one or more returns and any number of spaces
-- first word after period, exclamation point, question mark, with at least one space following the punctuation
-- colon, colon and any number of spaces
-- two dashes, two dashes and any number of spaces
replace "(--\\s*)(
\\w)"
using "
\\1\\u\\2"
options {
search mode:
grep}
-- open parenthesis, open parenthesis and any number of spaces
-- one or more open double quote (curly)
replace "(
\\s+)([“]+)(
\\w+)"
using "
\\1\\2\\u\\3"
options {
search mode:
grep}
--searching in theCharacters
-- open double quote (straight), open double quote (straight) space
replace "(
\\s+)([\"]+)(
\\w+)"
using "
\\1\\2\\u\\3"
options {
search mode:
grep}
--searching in theCharacters
--PART FOUR: do the special case capitalizations, using "find_what" and "replace_with" lists at top of script. If you add something to "find_what" you have to add something to "replace_with" too. Example: change "pdf" to "PDF."
-- GREP
-- Reading from a file
repeat with i from 1 to count of replace_with
set the_search_string to "(([>]*)|(
\\s+)|(
\\r+)|(\\()|([\"]+))" & "(?i)" &
item i of replace_with set the_replace_string
to "\\1" & item i
of replace_with
replace the_search_string using the_replace_string options {match words:true, search mode:grep}
end repeat
end tell
--PART FIVE: now put the links back in
if we_have_links is "true" then
repeat with i from 1 to count of link_line_text
set contents of line (item i of link_line_numbers) of front text window to item i of link_line_text
end repeat
end if
--PART SIX: set the selection to be what it was when the script started
tell front text window
if endingPoint is greater than numberOfCharacters then
select (characters startingPoint through (endingPoint - 1))
else
select (characters startingPoint through endingPoint)