Spell checking script not catching all misspelled words

I have a spell checking script for InDesign that isn’t catching all the misspelled words in the InDesign document. For instance, the designer had the word “defnece” instead of “defense”. I checked and the script is in fact running the word “defnece” through the part of the code that spell checks. It just doesn’t think the word “defnece” is misspelled apparently - unlike this forum which underlined every instance of the word. :stuck_out_tongue: Ironically, if I add an a and change it to “defnecea”, it catches that. Is there some code I need to change to get the spell checker part of the script to catch all misspelled words?

Here’s the function that checks the spelling:

--FUNCTION NEEDED TO CHECK SPELLING
on check_spelling(theString, current_dictionary)
	
	--Verifying that the script is actually checking the word -->Yes, it is
	display dialog "Checking spelling for word: " & theString as string
	
	set anNSString to (current application's NSMutableString's stringWithString:theString)
	set theChecker to current application's NSSpellChecker's sharedSpellChecker()
	(theChecker's setLanguage:"en_US") -- optional
	set theProblems to (theChecker's checkString:anNSString range:{0, anNSString's |length|()} types:(current application's NSTextCheckingTypeSpelling) options:(missing value) inSpellDocumentWithTag:0 orthography:(missing value) wordCount:(missing value))
	
	--Creating blank lists to add misspelled words not in dictionary
	set susWords to {}
	
	--Running each potentially misspelled word through the ok list
	repeat with aFind in theProblems
		set potential_prob to (anNSString's substringWithRange:(aFind's range())) as text
		
		--Checking if the spell checker is picking up the misspelled word --> No it is not
		display dialog "Potential misspelled word found: " & (potential_prob as string) as string
		
		--Adding problem words to the problem word list IF the problem word is not in the ok list
		if potential_prob as string is not in current_dictionary then -->excluding all words in the ok list (like brand names)
			if potential_prob & return as string is not in current_dictionary then -->excluding the word if it's in the ok list but has a return after it
				set susWords to susWords & (potential_prob as string) -->adding all potential misspellings to a list
			end if
		end if
	end repeat
	return susWords
end check_spelling

And the full code for reference:

--------------------------------------------------------------------------------------------------------------------------------
--ADDING WORDS TO THE SPELL CHECKING DICTIONARY
--------------------------------------------------------------------------------------------------------------------------------

--Creating a list of ok words to not spell check
--Vendor names would go here
set ok_words to {"Absorbine", "Adams", "Addie", "Advantix", "Agratronix", "Agrimaster", "Alfred", "Algoma", "Ameristep", "Andis", "Ardisam", "Armorall", "Armour", "Aruba", "Attwood", "Avalon", "Avantect", "Baraboo", "Barronett", "Benjamin", "Belcaro", "Behlen", "Berkley", "Blackstone", "Boehringer", "Boone", "Bostitch", "Bovikalc", "Buddeez", "California", "Camco", "Canidae", "Carhartt", "Carbor", "Carlisle", "Cathy", "Caviness", "cg/cg®", "Chippewa", "Citgo", "Columbia", "Contico", "Crayola", "Daiwa", "Danby", "Daniels", "Dasco", "Dayco", "Deere", "Delco", "Delonghi", "De’longhi", "Delvac", "Delmont", "Deroma", "Dewalt", "Dogzilla", "Doorbusters", "Doritos", "Doskocil", "Doug", "Delavan", "Dramm", "Drive-Maxx", "Drylok", "Dupont", "Durabilt", "Duracraft", "Durafork", "Durvet", "Eco-Flo", "Ecolution", "Edsal", "Enoz", "Eppinger", "Eprinex", "Erika", "Ertl", "Esoterra", "Estwing", "equaline", "Equimax", "Eukanuba", "Farnam", "Farberware", "Fats Tackle", "Fats Tackle ", "Fimco", "Fiora", "Firstect", "Fiskars", "Flexbrew", "Flotec", "Flueriares", "Folgers", "Flexzilla", "Freshtech", "Friskies", "Frogg", "Gabriel", "Generac", "Geneseo", "Genflex", "Geotek", "Giftables", "Gilmour", "Gojo", "Graco", "Greenleaf", "Grubex", "Gumout", "Hackzall", "Hamilton", "Harvestpro", "Havahart", "Heinz", "Herculiner", "Hershey's", "Hobart", "Holmes", "Homeright", "Homz", "Honda", "Hornady", "Husqvarna", "Hypro", "Iams", "Ingelheim", "Intex", "Invizx", "Irwin", "Jakks", "Jobes", "Kaboodle", "Kärcher", "Karcher", "Kawasaki", "Kaytee", "Kilz", "KitchenAid", "Klean-Strip", "Kote", "Krups", "Kurgo", "Larin", "Leviton", "Lews", "Lincoln", "Livingston", "Lucas", "Lund", "Lunex", "Marklyn", "Masterbuilt", "Maxx", "Mccloskey", "Mcsunley", "Meguiar’s", "Meguiar's", "Melissa", "Merial", "Merrick", "Michelin", "Milorganite", "Milwaukee", "Minnkota", "Minwax", "Miracle-Gro", "Monroe", "Moonrays", "Morton", "Motorcraft", "Muckster", "Multifloor", "Munsing", "Mystik", "Naptha", "Nesco", "Neverkink", "Nexave", "Norpro", "Nutrena", "Nutrish", "Nyjer", "Nylabone", "Odessa", "Oespectrum", "Oil", "Okeechobee", "O’keeffe’s", "O'keeffe's", "Okuma", "Oxy-Acetylene", "Peg-Pérego", "Petlodge", "Permatex", "Petsafe", "Pflueger", "Philips", "Piranhamax", "Pradco", "Proheat", "Progrip", "Proplan", "Prozap", "Purolator", "Rachael", "Rapala", "Rayovac", "Realtree", "Reebok", "Reese", "Remington", "Rinehart", "Roebic", "Rotella", "Sakrete", "Sandusky", "Sawzall", "Scalibor", "Scotts", "Seaguar", "Seaquest", "Seasense", "Sellars", "Seresto", "Seymour", "Shademaker", "Sheba", "Shelterlogic", "Shimano", "Shur", "Shur-tred", "Shur-Line", "Skechers", "Sonicare", "Sorel", "Speeco", "Spiderwire", "Standlee", "Stax", "Stearns", "Stihl", "Stik", "Stratton", "Sperry", "Sturtevant", "Suncast", "Sundolphin", "Sunfilm", "Sunjoy", "Sweepfire", "Swiffer", "Swiveleze", "Tannerite", "Teske", "T-Fal", "Thermacell", "Thompson", "Toggs", "Tonka", "Toughmax", "Tricam", "Trico", "Trilene", "Trimec", "Troy-Bilt", "Trufuel", "Truper", "Twizzlers", "Ultra-Maxx", "Uquality", "Valvoline", "Vanderbilt", "Varathane", "Ventamatic", "Vetality", "Wahl", "Weatherbeater", "Weatherguard", "Werner", "Wyoming", "Zareba", "Zecol", "ZeroXposur", "Zimecterin", "Zinsser", "Zuke's"}


--------------------------------------------------------------------------------------------------------------------------------
--ENABLING SCRIPTING ADDITIONS
--------------------------------------------------------------------------------------------------------------------------------

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"


--------------------------------------------------------------------------------------------------------------------------------
--CHECKING SPELLING
--------------------------------------------------------------------------------------------------------------------------------

tell application "Adobe InDesign CC 2018"
	activate
	
	--Setting user interaction settings to allow all prompts to come up --> necessary to make sure the misspelled word dialog comes up
	set user interaction level of script preferences to interact with all
	
	--Creating a blank list to add misspelled words to
	set potential_prob_words to {}
	
	--Looping through every word of every story in the InDesign document
	tell active document to set my_stories to every story
	set the_doc to active document
	repeat with my_story in my_stories
		tell the_doc to set parent_text_frame to (every text frame whose contents contains (contents of my_story))
		set my_words to every word of my_story
		set word_count to count my_words
		set current_count to 1
		repeat word_count times
			set my_word to word current_count of my_story
			
			--Running the check_spelling function towards the bottom of the script
			set misspelled_word to (my check_spelling(my_word, ok_words))
			
			--Selecting the potentially misspelled word
			if misspelled_word is not {} then
				select parent_text_frame
				select word current_count of my_story
				
				
				--------------------------------------------------------------------------------------------------------------------------------
				--DISPLAYING THE SPELL CHECK DIALOG
				--------------------------------------------------------------------------------------------------------------------------------
				
				--Creating the dialog
				set my_field_width to 200
				set dialog_name to "CHECK SPELLING FOR WORD " & misspelled_word as string
				set myDialog to make dialog with properties {name:dialog_name}
				tell myDialog
					set can cancel to false
					tell (make dialog column)
						
						--Creating the page size fields
						tell (make dialog row)
							make static text with properties {static label:"Enter the correct spelling (or hit enter, if word is ok):"}
						end tell
						tell (make dialog row)
							make static text with properties {static label:(misspelled_word as string)}
							set respell_field to make text editbox with properties {edit contents:(misspelled_word as string), min width:my_field_width}
						end tell
					end tell
				end tell
				
				--Getting the respelled word
				if (show myDialog) = true then
					set respelled_word to edit contents of respell_field
				end if
				
				--Making the dialog go away
				destroy myDialog
				
				--Replacing the problem word with the respelled word
				if misspelled_word as string is not respelled_word as string then
					my find_replace((misspelled_word as string), respelled_word)
				end if
				
			end if
			
			--Incrementing the current count by 1
			set current_count to current_count + 1
			
		end repeat
	end repeat
	
	
	--------------------------------------------------------------------------------------------------------------------------------
	--DISPLAYING THE FINISHED DIALOG
	--------------------------------------------------------------------------------------------------------------------------------
	
	if potential_prob_words is not {} then
		display dialog "SPELL CHECK COMPLETE" & return & "Spell check is done checking the page(s)" with icon 1 giving up after 5400
	else
		display dialog "HALLELUIAH!" & return & "No misspelled words found" with icon 1 giving up after 5400
	end if
	
end tell


--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
--FUNCTIONS
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------

--FUNCTION NEEDED TO CHECK SPELLING
on check_spelling(theString, current_dictionary)
	
	--Verifying that the script is actually checking the word -->Yes, it is
	display dialog "Checking spelling for word: " & theString as string
	
	set anNSString to (current application's NSMutableString's stringWithString:theString)
	set theChecker to current application's NSSpellChecker's sharedSpellChecker()
	(theChecker's setLanguage:"en_US") -- optional
	set theProblems to (theChecker's checkString:anNSString range:{0, anNSString's |length|()} types:(current application's NSTextCheckingTypeSpelling) options:(missing value) inSpellDocumentWithTag:0 orthography:(missing value) wordCount:(missing value))
	
	--Creating blank lists to add misspelled words not in dictionary
	set susWords to {}
	
	--Running each potentially misspelled word through the ok list
	repeat with aFind in theProblems
		set potential_prob to (anNSString's substringWithRange:(aFind's range())) as text
		
		--Checking if the spell checker is picking up any misspelled words --> No it is not
		display dialog "Potential misspelled word found: " & (potential_prob as string) as string
		
		--Adding problem words to the problem word list IF the problem word is not in the ok list
		if potential_prob as string is not in current_dictionary then -->excluding all words in the ok list (like brand names)
			if potential_prob & return as string is not in current_dictionary then -->excluding the word if it's in the ok list but has a return after it
				set susWords to susWords & (potential_prob as string) -->adding all potential misspellings to a list
			end if
		end if
	end repeat
	return susWords
end check_spelling


-------------------------------------------------------------
-------------------------------------------------------------


--FUNCTION TO REPLACE TEXT
on find_replace(search_term, replace_term)
	
	tell application "Adobe InDesign CC 2018"
		set find text preferences to nothing
		set change text preferences to nothing
		
		set find what of find text preferences to search_term
		set change to of change text preferences to replace_term
		
		change text document 1
		
		set find text preferences to nothing
		set change text preferences to nothing
	end tell
end find_replace

Hi.

Have you at some time accidentally added “defnece” to your user spelling dictionary? The relevant file’s probably /Users/yourname/Library/Spelling/en_US or /Users/yourname/Library/Spelling/LocalDictionary on your machine. It’s editable in either TextEdit or BBEdit. Or maybe better by script:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set theChecker to current application's NSSpellChecker's sharedSpellChecker()
tell theChecker to unlearnWord:("defnece")

I found the local dictionary file in /Users/yourname/Library/Spelling/LocalDictionary and opened it in TextEdit. It’s zero bytes and blank. Is this my problem? It was however still catching some words, like it caught the brand name. It also caught my attempts at changing “defnece” to “defnace” but it thought both “defnece” and “defenece” were spelled correctly even with the unlearnWord added.

I couldn’t find a file named “en_US”. Just for kicks, I tried changing the language to “fr” and “es” to see if it would catch the English words as misspelled and it didn’t. I don’t seem to have “en_US” as an available option when I tried logging the available languages?

Spell checking function:

--FUNCTION NEEDED TO CHECK SPELLING
on check_spelling(theString, current_dictionary)
	--display dialog "Checking spelling for word: " & theString as string
	--set number_list to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"} -->adding number list to check measurements against (will be excluding measurements from spell check)
	set anNSString to (current application's NSMutableString's stringWithString:theString)
	set theChecker to current application's NSSpellChecker's sharedSpellChecker()
	set myLang to (theChecker's setLanguage:"fr") -- optional
	tell theChecker to unlearnWord:("defnece")
	
	--Checking available languages
	set avail_lang to (current application's NSSpellChecker's sharedSpellChecker()'s availableLanguages)
	repeat with a_lang in avail_lang
		set a_lang to a_lang as text
		log a_lang
	end repeat
	--delay 10
	
	-->Displays defnece
	display dialog anNSString as string
	
	set theProblems to (theChecker's checkString:anNSString range:{0, anNSString's |length|()} types:(current application's NSTextCheckingTypeSpelling) options:(missing value) inSpellDocumentWithTag:0 orthography:(missing value) wordCount:(missing value))
	
	
	--Creating blank lists to add misspelled words not in dictionary
	set susWords to {}
	
	
	repeat with aFind in theProblems
		--display dialog "Potential misspelled word found: " & (aFind as string) as string
		set potential_prob to (anNSString's substringWithRange:(aFind's range())) as text
		
		-->Doesn't display defnece 
		display dialog "Maybe a problem" & return & potential_prob as string
		--display dialog "Potential misspelled word found: " & (potential_prob as string) as string
		
		--Adding problem words to the problem word list IF the problem word is not in the ok list
		--and the problem word doesn't contain Reg. etc.
		if potential_prob as string is not in current_dictionary then -->excluding all words in the ok list (like brand names)
			set temp_list to {} -->beginning of excluding measurements code (excluding things like 11x12x24 to keep measurements out of spell check)
			if potential_prob & return as string is not in current_dictionary then -->excluding the word if it's in the ok list but has a return after it
				set susWords to susWords & (potential_prob as string) -->adding all potential misspellings to a list
			end if
		end if
	end repeat
	return susWords
end check_spelling

Whole script:

--------------------------------------------------------------------------------------------------------------------------------
--ADDING WORDS TO THE SPELL CHECKING DICTIONARY
--------------------------------------------------------------------------------------------------------------------------------

--Creating a list of ok words to not spell check
--Vendor names would go here
set ok_words to {"Absorbine", "Adams", "Addie", "Advantix", "Agratronix", "Agrimaster", "Alfred", "Algoma", "Ameristep", "Andis", "Ardisam", "Armorall", "Armour", "Aruba", "Attwood", "Avalon", "Avantect", "Baraboo", "Barronett", "Benjamin", "Belcaro", "Behlen", "Berkley", "Blackstone", "Boehringer", "Boone", "Bostitch", "Bovikalc", "Buddeez", "California", "Camco", "Canidae", "Carhartt", "Carbor", "Carlisle", "Cathy", "Caviness", "cg/cg®", "Chippewa", "Citgo", "Columbia", "Contico", "Crayola", "Daiwa", "Danby", "Daniels", "Dasco", "Dayco", "Deere", "Delco", "Delonghi", "De’longhi", "Delvac", "Delmont", "Deroma", "Dewalt", "Dogzilla", "Doorbusters", "Doritos", "Doskocil", "Doug", "Delavan", "Dramm", "Drive-Maxx", "Drylok", "Dupont", "Durabilt", "Duracraft", "Durafork", "Durvet", "Eco-Flo", "Ecolution", "Edsal", "Enoz", "Eppinger", "Eprinex", "Erika", "Ertl", "Esoterra", "Estwing", "equaline", "Equimax", "Eukanuba", "Farnam", "Farberware", "Fats Tackle", "Fats Tackle ", "Fimco", "Fiora", "Firstect", "Fiskars", "Flexbrew", "Flotec", "Flueriares", "Folgers", "Flexzilla", "Freshtech", "Friskies", "Frogg", "Gabriel", "Generac", "Geneseo", "Genflex", "Geotek", "Giftables", "Gilmour", "Gojo", "Graco", "Greenleaf", "Grubex", "Gumout", "Hackzall", "Hamilton", "Harvestpro", "Havahart", "Heinz", "Herculiner", "Hershey's", "Hobart", "Holmes", "Homeright", "Homz", "Honda", "Hornady", "Husqvarna", "Hypro", "Iams", "Ingelheim", "Intex", "Invizx", "Irwin", "Jakks", "Jobes", "Kaboodle", "Kärcher", "Karcher", "Kawasaki", "Kaytee", "Kilz", "KitchenAid", "Klean-Strip", "Kote", "Krups", "Kurgo", "Larin", "Leviton", "Lews", "Lincoln", "Livingston", "Lucas", "Lund", "Lunex", "Marklyn", "Masterbuilt", "Maxx", "Mccloskey", "Mcsunley", "Meguiar’s", "Meguiar's", "Melissa", "Merial", "Merrick", "Michelin", "Milorganite", "Milwaukee", "Minnkota", "Minwax", "Miracle-Gro", "Monroe", "Moonrays", "Morton", "Motorcraft", "Muckster", "Multifloor", "Munsing", "Mystik", "Naptha", "Nesco", "Neverkink", "Nexave", "Norpro", "Nutrena", "Nutrish", "Nyjer", "Nylabone", "Odessa", "Oespectrum", "Oil", "Okeechobee", "O’keeffe’s", "O'keeffe's", "Okuma", "Oxy-Acetylene", "Peg-Pérego", "Petlodge", "Permatex", "Petsafe", "Pflueger", "Philips", "Piranhamax", "Pradco", "Proheat", "Progrip", "Proplan", "Prozap", "Purolator", "Rachael", "Rapala", "Rayovac", "Realtree", "Reebok", "Reese", "Remington", "Rinehart", "Roebic", "Rotella", "Sakrete", "Sandusky", "Sawzall", "Scalibor", "Scotts", "Seaguar", "Seaquest", "Seasense", "Sellars", "Seresto", "Seymour", "Shademaker", "Sheba", "Shelterlogic", "Shimano", "Shur", "Shur-tred", "Shur-Line", "Skechers", "Sonicare", "Sorel", "Speeco", "Spiderwire", "Standlee", "Stax", "Stearns", "Stihl", "Stik", "Stratton", "Sperry", "Sturtevant", "Suncast", "Sundolphin", "Sunfilm", "Sunjoy", "Sweepfire", "Swiffer", "Swiveleze", "Tannerite", "Teske", "T-Fal", "Thermacell", "Thompson", "Toggs", "Tonka", "Toughmax", "Tricam", "Trico", "Trilene", "Trimec", "Troy-Bilt", "Trufuel", "Truper", "Twizzlers", "Ultra-Maxx", "Uquality", "Valvoline", "Vanderbilt", "Varathane", "Ventamatic", "Vetality", "Wahl", "Weatherbeater", "Weatherguard", "Werner", "Wyoming", "Zareba", "Zecol", "ZeroXposur", "Zimecterin", "Zinsser", "Zuke's"}

--------------------------------------------------------------------------------------------------------------------------------
--ENABLING SCRIPTING ADDITIONS
--------------------------------------------------------------------------------------------------------------------------------

--Enabling scripting additions
--This is necessary because the spell check doesn't work without enabling additions
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"


--------------------------------------------------------------------------------------------------------------------------------
--CHECKING SPELLING
--------------------------------------------------------------------------------------------------------------------------------

tell application "Adobe InDesign CC 2018"
	activate
	set user interaction level of script preferences to interact with all
	
	set potential_prob_words to {}
	tell active document to set my_stories to every story
	set the_doc to active document
	repeat with my_story in my_stories
		tell the_doc to set parent_text_frame to (every text frame whose contents contains (contents of my_story))
		set my_words to every word of my_story
		set word_count to count my_words
		
		set current_count to 1
		repeat word_count times
			set my_word to word current_count of my_story
			
			--Running the check_spelling function towards the bottom of the script
			set misspelled_word to (my check_spelling(my_word, ok_words))
			
			--Selecting the potentially misspelled word
			if misspelled_word is not {} then
				select parent_text_frame
				select word current_count of my_story
				set potential_prob_words to potential_prob_words & misspelled_word
				
				
				--------------------------------------------------------------------------------------------------------------------------------
				--DISPLAYING THE SPELL CHECK DIALOG
				--------------------------------------------------------------------------------------------------------------------------------
				
				--Creating the dialog
				set my_field_width to 200
				set dialog_name to "CHECK SPELLING FOR WORD " & misspelled_word as string
				set myDialog to make dialog with properties {name:dialog_name}
				tell myDialog
					set can cancel to false
					--set «class uiCn» to false
					tell (make dialog column)
						
						--Creating the page size fields
						tell (make dialog row)
							make static text with properties {static label:"Enter the correct spelling (or hit enter, if word is ok):"}
						end tell
						tell (make dialog row)
							make static text with properties {static label:(misspelled_word as string)}
							set respell_field to make text editbox with properties {edit contents:(misspelled_word as string), min width:my_field_width}
						end tell
					end tell
				end tell
				
				--Getting the respelled word
				if (show myDialog) = true then
					set respelled_word to edit contents of respell_field
				end if
				
				--Making the dialog go away
				destroy myDialog
				
				--Replacing the problem word with the respelled word
				if misspelled_word as string is not respelled_word as string then
					my find_replace((misspelled_word as string), respelled_word)
				end if
				
			end if
			
			set current_count to current_count + 1
		end repeat
	end repeat
	
	
	--------------------------------------------------------------------------------------------------------------------------------
	--DISPLAYING THE FINISHED DIALOG
	--------------------------------------------------------------------------------------------------------------------------------
	
	if potential_prob_words is not {} then
		display dialog "SPELL CHECK COMPLETE" & return & "Spell check is done checking the page(s)" with icon 1 giving up after 5400
	else
		display dialog "HALLELUIAH!" & return & "No misspelled words found" with icon 1 giving up after 5400
	end if
	
end tell


--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
--FUNCTIONS
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------

--FUNCTION NEEDED TO CHECK SPELLING
on check_spelling(theString, current_dictionary)
	--display dialog "Checking spelling for word: " & theString as string
	--set number_list to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"} -->adding number list to check measurements against (will be excluding measurements from spell check)
	set anNSString to (current application's NSMutableString's stringWithString:theString)
	set theChecker to current application's NSSpellChecker's sharedSpellChecker()
	set myLang to (theChecker's setLanguage:"fr") -- optional
	tell theChecker to unlearnWord:("defnece")
	
	--Checking available languages
	set avail_lang to (current application's NSSpellChecker's sharedSpellChecker()'s availableLanguages)
	repeat with a_lang in avail_lang
		set a_lang to a_lang as text
		log a_lang
	end repeat
	--delay 10
	
	-->Displays defnece
	display dialog anNSString as string
	
	set theProblems to (theChecker's checkString:anNSString range:{0, anNSString's |length|()} types:(current application's NSTextCheckingTypeSpelling) options:(missing value) inSpellDocumentWithTag:0 orthography:(missing value) wordCount:(missing value))
	
	
	--Creating blank lists to add misspelled words not in dictionary
	set susWords to {}
	
	
	repeat with aFind in theProblems
		--display dialog "Potential misspelled word found: " & (aFind as string) as string
		set potential_prob to (anNSString's substringWithRange:(aFind's range())) as text
		
		-->Doesn't display defnece 
		display dialog "Maybe a problem" & return & potential_prob as string
		--display dialog "Potential misspelled word found: " & (potential_prob as string) as string
		
		--Adding problem words to the problem word list IF the problem word is not in the ok list
		--and the problem word doesn't contain Reg. etc.
		if potential_prob as string is not in current_dictionary then -->excluding all words in the ok list (like brand names)
			set temp_list to {} -->beginning of excluding measurements code (excluding things like 11x12x24 to keep measurements out of spell check)
			if potential_prob & return as string is not in current_dictionary then -->excluding the word if it's in the ok list but has a return after it
				set susWords to susWords & (potential_prob as string) -->adding all potential misspellings to a list
			end if
		end if
	end repeat
	return susWords
end check_spelling

-------------------------------------------------------------
-------------------------------------------------------------


--FUNCTION TO REPLACE TEXT
on find_replace(search_term, replace_term)
	
	tell application "Adobe InDesign CC 2018"
		set find text preferences to nothing
		set change text preferences to nothing
		
		set find what of find text preferences to search_term
		set change to of change text preferences to replace_term
		--set color swatch of change text preferences to "C=0 M=100 Y=0 K=0"
		--set applied character style of change text preferences to "Website Footer"
		tell selection to change text
		--change text document 1
		
		set find text preferences to nothing
		set change text preferences to nothing
	end tell
end find_replace

Browser: Safari 604.3.5
Operating System: Mac OS X (10.13 Developer Beta 3)

Interestingly enough, I tried the spell checker on another computer that is running Mac OS Sierra instead of Mac OS High Sierra. That computer caught defnece, but it didn’t get the memo that we’re working in English either. Neither computer flagged Spanish works like “gata” or “desayuno” or French words like “Je”, “suis” or “fille”

Browser: Safari 604.3.5
Operating System: Mac OS X (10.13 Developer Beta 3)

I think things have probably changed since my “en_GB” file was created. This file contains words I added to the spelling dictionary years ago, before I got bored with doing so. But the spelling system still accepts these words as OK — things like the name of my village or my friends’ surnames. When I added a word to the dictionary last week in High Sierra, using the facilities under Edit->Spelling and Grammar in one of the apps which offer them, it was added to “LocalDictionary”.

But I’m not sure how relevant these files are. This morning, I’ve deleted the contents of LocalLibrary and the system still accepts last week’s word as correctly spelt, even after a restart. And LocalLibrary’s still empty, so the spell check system didn’t save the word back to it during the restart. There must be a more permanent store somewhere else. :confused:

I went in to system preferences > keyboard > text and changed the drop down menu under spelling from “Automatic by Language” to “U.S. English”. The spell checker is now catching the word “defnece”. Apparently, that’s a real word in some language I don’t know…

Is there a way to override or change the system preference without doing it manually or using GUI scripting? Eventually, I’d be packaging this for my coworkers. If possible, I’m trying to avoid making them manually change the preference or get the assistive access error message (which GUI scripting can cause on High Sierra).

Thank you for all your help :slight_smile:


------------------------------------------------------------------------------------------------------
--ADDING WORDS TO THE SPELL CHECKING DICTIONARY
------------------------------------------------------------------------------------------------------

--Creating a list of ok words to not spell check
--Vendor names would go here
set ok_words to {"Absorbine", "Adams", "Addie", "Advantix", "Agratronix", "Agrimaster", "Alfred", "Algoma", "Ameristep", "Andis", "Ardisam", "Armorall", "Armour", "Aruba", "Attwood", "Avalon", "Avantect", "Baraboo", "Barronett", "Benjamin", "Belcaro", "Behlen", "Berkley", "Blackstone", "Boehringer", "Boone", "Bostitch", "Bovikalc", "Buddeez", "California", "Camco", "Canidae", "Carhartt", "Carbor", "Carlisle", "Cathy", "Caviness", "cg/cg®", "Chippewa", "Citgo", "Columbia", "Contico", "Crayola", "Daiwa", "Danby", "Daniels", "Dasco", "Dayco", "Deere", "Delco", "Delonghi", "De’longhi", "Delvac", "Delmont", "Deroma", "Dewalt", "Dogzilla", "Doorbusters", "Doritos", "Doskocil", "Doug", "Delavan", "Dramm", "Drive-Maxx", "Drylok", "Dupont", "Durabilt", "Duracraft", "Durafork", "Durvet", "Eco-Flo", "Ecolution", "Edsal", "Enoz", "Eppinger", "Eprinex", "Erika", "Ertl", "Esoterra", "Estwing", "equaline", "Equimax", "Eukanuba", "Farnam", "Farberware", "Fats Tackle", "Fats Tackle ", "Fimco", "Fiora", "Firstect", "Fiskars", "Flexbrew", "Flotec", "Flueriares", "Folgers", "Flexzilla", "Freshtech", "Friskies", "Frogg", "Gabriel", "Generac", "Geneseo", "Genflex", "Geotek", "Giftables", "Gilmour", "Gojo", "Graco", "Greenleaf", "Grubex", "Gumout", "Hackzall", "Hamilton", "Harvestpro", "Havahart", "Heinz", "Herculiner", "Hershey's", "Hobart", "Holmes", "Homeright", "Homz", "Honda", "Hornady", "Husqvarna", "Hypro", "Iams", "Ingelheim", "Intex", "Invizx", "Irwin", "iXtreme", "Jakks", "Jobes", "Kaboodle", "Kärcher", "Karcher", "Kawasaki", "Kaytee", "Kilz", "KitchenAid", "Klean-Strip", "Kote", "Krups", "Kurgo", "Larin", "Leviton", "Lews", "Lincoln", "Livingston", "Lucas", "Lund", "Lunex", "Marklyn", "Masterbuilt", "Maxx", "Mccloskey", "Mcsunley", "Meguiar’s", "Meguiar's", "Melissa", "Merial", "Merrick", "Michelin", "Milorganite", "Milwaukee", "Minnkota", "Minwax", "Miracle-Gro", "Monroe", "Moonrays", "Morton", "Motorcraft", "Muckster", "Multifloor", "Munsing", "Mystik", "Naptha", "Nesco", "Neverkink", "Nexave", "Norpro", "Nutrena", "Nutrish", "Nyjer", "Nylabone", "Odessa", "Oespectrum", "Oil", "Okeechobee", "O’keeffe’s", "O'keeffe's", "Okuma", "Oxy-Acetylene", "Peg-Pérego", "Petlodge", "Permatex", "Petsafe", "Pflueger", "Philips", "Piranhamax", "Pradco", "Proheat", "Progrip", "Proplan", "Prozap", "Purolator", "Rachael", "Rapala", "Rayovac", "Realtree", "Reebok", "Reese", "Remington", "Rinehart", "Roebic", "Rotella", "Sakrete", "Sandusky", "Sawzall", "Scalibor", "Scotts", "Seaguar", "Seaquest", "Seasense", "Sellars", "Seresto", "Seymour", "Shademaker", "Sheba", "Shelterlogic", "Shimano", "Shur", "Shur-tred", "Shur-Line", "Skechers", "Sonicare", "Sorel", "Speeco", "Spiderwire", "Standlee", "Stax", "Stearns", "Stihl", "Stik", "Stratton", "Sperry", "Sturtevant", "Suncast", "Sundolphin", "Sunfilm", "Sunjoy", "Sweepfire", "Swiffer", "Swiveleze", "Tannerite", "Teske", "T-Fal", "Thermacell", "Thompson", "Toggs", "Tonka", "Toughmax", "Tricam", "Trico", "Trilene", "Trimec", "Troy-Bilt", "Trufuel", "Truper", "Twizzlers", "Ultra-Maxx", "Uquality", "Valvoline", "Vanderbilt", "Varathane", "Ventamatic", "Vetality", "Wahl", "Weatherbeater", "Weatherguard", "Werner", "Wyoming", "Zareba", "Zecol", "ZeroXposur", "Zimecterin", "Zinsser", "Zuke's"}


------------------------------------------------------------------------------------------------------
--ENABLING SCRIPTING ADDITIONS
------------------------------------------------------------------------------------------------------

--Enabling scripting additions
--This is necessary because the spell check doesn't work without enabling additions
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"


------------------------------------------------------------------------------------------------------
--MAKING SURE WE'RE USING THE RIGHT SPELLING LANGUAGE
------------------------------------------------------------------------------------------------------

--Running the change spelling language function towards bottom of script
--my change_spelling_language() -->causes assistive access error if app is not added to Security & Privacy > Accessibility > Privacy in System Preferences


------------------------------------------------------------------------------------------------------
--CHECKING SPELLING
------------------------------------------------------------------------------------------------------

tell application "Adobe InDesign CC 2018"
	activate
	set user interaction level of script preferences to interact with all
	
	set potential_prob_words to {}
	tell active document to set my_stories to every story
	set the_doc to active document
	repeat with my_story in my_stories
		tell the_doc to set parent_text_frame to (every text frame whose contents contains (contents of my_story))
		set my_words to every word of my_story
		set word_count to count my_words
		
		set current_count to 1
		repeat word_count times
			set my_word to word current_count of my_story
			
			--Running the check_spelling function towards the bottom of the script
			set misspelled_word to (my check_spelling(my_word, ok_words))
			
			--Selecting the potentially misspelled word
			if misspelled_word is not {} then
				select parent_text_frame
				select word current_count of my_story
				set potential_prob_words to potential_prob_words & misspelled_word
				
				
				------------------------------------------------------------------------------------------------------
				--DISPLAYING THE SPELL CHECK DIALOG
				------------------------------------------------------------------------------------------------------
				
				--Creating the dialog
				set my_field_width to 200
				set dialog_name to "CHECK SPELLING FOR WORD " & misspelled_word as string
				set myDialog to make dialog with properties {name:dialog_name}
				tell myDialog
					set can cancel to false
					tell (make dialog column)
						
						--Creating the page size fields
						tell (make dialog row)
							make static text with properties {static label:"Enter the correct spelling (or hit enter, if word is ok):"}
						end tell
						tell (make dialog row)
							make static text with properties {static label:(misspelled_word as string)}
							set respell_field to make text editbox with properties {edit contents:(misspelled_word as string), min width:my_field_width}
						end tell
					end tell
				end tell
				
				--Getting the respelled word
				if (show myDialog) = true then
					set respelled_word to edit contents of respell_field
				end if
				
				--Making the dialog go away
				destroy myDialog
				
				--Replacing the problem word with the respelled word
				if misspelled_word as string is not respelled_word as string then
					my find_replace((misspelled_word as string), respelled_word)
				end if
				
			end if
			
			set current_count to current_count + 1
		end repeat
	end repeat
	
	
	------------------------------------------------------------------------------------------------------
	--DISPLAYING THE FINISHED DIALOG
	------------------------------------------------------------------------------------------------------
	
	if potential_prob_words is not {} then
		display dialog "SPELL CHECK COMPLETE" & return & "Spell check is done checking the page(s)" with icon 1 giving up after 5400
	else
		display dialog "HALLELUIAH!" & return & "No misspelled words found" with icon 1 giving up after 5400
	end if
	
end tell


------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
--FUNCTIONS
------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------

--FUNCTION NEEDED TO CHANGE SPELLING LANGUAGE TO ENGLISH SO IT CATCHES MISSPELLED ENGLISH WORDS THAT ARE REAL WORDS IN FOREIGN LANGUAGES
on change_spelling_language()
	tell application "System Preferences"
		activate
		reveal anchor "Text" of pane id "com.apple.preference.keyboard"
		delay 0.5
		tell application "System Events"
			tell pop up button 3 of tab group 1 of window 1 of application process "System Preferences"
				if (value) is not "U.S. English" then
					click
					click menu item "U.S. English" of menu 1
				end if
			end tell
		end tell
		quit
	end tell
end change_spelling_language

-------------------------------------------------------------
-------------------------------------------------------------

--FUNCTION NEEDED TO CHECK SPELLING
on check_spelling(theString, current_dictionary)
	set anNSString to (current application's NSMutableString's stringWithString:theString)
	set theChecker to current application's NSSpellChecker's sharedSpellChecker()
	theChecker's setLanguage:"en" -- optional
	
	set theProblems to (theChecker's checkString:anNSString range:{0, anNSString's |length|()} types:(current application's NSTextCheckingTypeSpelling) options:(missing value) inSpellDocumentWithTag:0 orthography:(missing value) wordCount:(missing value))
	
	--Creating blank lists to add misspelled words not in dictionary
	set susWords to {}
	
	repeat with aFind in theProblems
		set potential_prob to (anNSString's substringWithRange:(aFind's range())) as text
		
		--Adding problem words to the problem word list IF the problem word is not in the ok list
		--and the problem word doesn't contain Reg. etc.
		if potential_prob as string is not in current_dictionary then -->excluding all words in the ok list (like brand names)
			set temp_list to {} -->beginning of excluding measurements code (excluding things like 11x12x24 to keep measurements out of spell check)
			if potential_prob & return as string is not in current_dictionary then -->excluding the word if it's in the ok list but has a return after it
				set susWords to susWords & (potential_prob as string) -->adding all potential misspellings to a list
			end if
		end if
	end repeat
	return susWords
end check_spelling

-------------------------------------------------------------
-------------------------------------------------------------

--FUNCTION TO REPLACE TEXT
on find_replace(search_term, replace_term)
	
	tell application "Adobe InDesign CC 2018"
		set find text preferences to nothing
		set change text preferences to nothing
		
		set find what of find text preferences to search_term
		set change to of change text preferences to replace_term
		--set color swatch of change text preferences to "C=0 M=100 Y=0 K=0"
		--set applied character style of change text preferences to "Website Footer"
		tell selection to change text
		--change text document 1
		
		set find text preferences to nothing
		set change text preferences to nothing
	end tell
end find_replace

Browser: Safari 604.3.5
Operating System: Mac OS X (10.13 Developer Beta 3)

Hi.

This script is great, thanks. But I have one question: I work with several languages, right now, with Swedish. This script is using the system dictionary, and not Indesign’s right? Is there a way to use Indesign’s dictionary?

I’m asking because Indesign is showing some wrong words in Dynamic Spell Check, but the script do not catch them.

Thanks,
Luiz