Check the Spelling of Text on the Clipboard

Hi All,

I'm looking for suggestions about how to check spelling of any document that I copy to a clipboard. In particular, I do a lot of proof reading and give feedback. I'd like to be able to check a document and have the number of misspelled words set as a variable (i.e. 14 if there were 14 spelling errors). I'm open to any suggestions!

Thanks for your time,
Scott

Hey Scott,

To do this you'll have to install a command line program like Aspell.

To do that you'll need to install Homebrew or MacPorts – unless you have the skills to make it yourself.

Think about it, and holler if you need help.

-Chris

Hi @Scott_Matkovich,

Another way might be to use a dictionary API, such as The Oxford Dictionaries API.

This, is course, would require an internet connection to perform the API calls each time you performed a spell check.

I actually think @ccstone's suggestion is better, but I thought I'd make you aware of the options.

Thanks! I'd always have internet when I'm doing this, so that's not an issue. When it comes to running this with KM, how would I integrate one with the other? Is there a specific workflow that would be best to use?

Thanks, Chris! I appreciate the help - I'm going to tinker around with this and see what I can do...can you help me understand how I would integrate this with Keyboard Maestro?

I think the best, and probably only way, to integrate API calls into your macro is through cURL by way of a shell script, AppleScript, or another language.

The Oxford Dictionaries API, upon brief perusal, looks fairly basic and doesn’t have any complex authentication processes to go through, which can be programmatically challenging if doing it from scratch.

But all you need here, it seems, is an API key and app ID (which they provide you), and these just get sent as headers when you make your API request to whichever endpoint (URL) you pick from their documentation.

I just did a quick one to translate a word to Spanish, and it seemed to go through OK.

You might have a small learning curve in constructing a cURL request if you aren’t already familiar with it, but it’s simple when you do it three or four times, after which it’s just switching out parameters.

If you need any specific input, let me know.

This is super helpful - thank you. Honestly, I'm clueless when to comes to programming languages. I'm going to experiment with this information and see if I can get it running! Thanks again!

Okay - I got the API key and app ID as well as the endpoint URL. I also have cURL installed, but I'm having trouble with the applescript to make the API request. Also, if I'm able to incorporate this into KM, will it conduct an API request for every word on the clipboard or is it one call per document? I guess I'm not clear on how this would work with the text that I'm proof reading. Sorry for all the questions - this is an entirely new frontier for me!

All the best,
Scott

1 Like

I've just been having a play around with the API on their website, which features an interactive utility (as most do) that allows you to make test calls to each of the endpoints and retrieve sample data.

Oxford Dictionaries API Documentation

So, in fact, it even constructs the cURL request for you, which makes it simple.

It seems you're right, in that there doesn't seem to be a document checker that can spell check chunks of text all in one go. But there will be other APIs out there that provide that function, I've no doubt, so I'll just do a short demonstration here to address your AppleScript queries.

This is the endpoint I'll be testing:

LEMMATRON
/inflections/{source_lang}/{word_id}
"Check a word exists in the dictionary and retrieve its root form"

The URL takes two parameters: {source_lang} and {word_id}, corresponding respectively to the language choice (en in our case) and the word selection (for which I'll choose maestro).

To save a headache, I'm just going to copy the cURL request from their online utility:

curl -X GET --header "Accept: application/json" \
            --header "app_id: d0552f68" \
            --header "app_key: ac4a6bedb474f5f321b41c09a2c6cd01" \
"https://od-api.oxforddictionaries.com/api/v1/inflections/en/maestro"

To try it out, you can copy/paste this into Terminal using your own app_id and app_key. I immediately get this response back:

{
    "metadata": {
        "provider": "Oxford University Press"
    },
    "results": [
        {
            "id": "maestro",
            "language": "en",
            "lexicalEntries": [
                {
                    "grammaticalFeatures": [
                        {
                            "text": "Singular",
                            "type": "Number"
                        }
                    ],
                    "inflectionOf": [
                        {
                            "id": "maestro",
                            "text": "maestro"
                        }
                    ],
                    "language": "en",
                    "lexicalCategory": "Noun",
                    "text": "maestro"
                }
            ],
            "word": "maestro"
        }
    ]
}

So we know it works. If I perform the same cURL request using a different word_id for a word that shouldn't exist, I can preview the response in that situation too:

curl -X GET --header "Accept: application/json" \
            --header "app_id: d0552f68" \
            --header "app_key: ac4a6bedb474f5f321b41c09a2c6cd01" \
"https://od-api.oxforddictionaries.com/api/v1/inflections/en/foozlebum"

which returns:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>No lemmas found matching supplied source_lang and word</p>

Getting Keyboard Maestro to perform these calls for you is easy enough. All of this is shell script, so these commands can actually plonk straight into an Execute a Shell Script action and the result can be stored in a variable:

An Example Keyboard Maestro Word Checker Macro

Result:

But, it can also be done quite easily in AppleScript as well:

set word_id to "example"

set cURL to "curl -X GET" & ¬
	" --header 'Accept: application/json'" & ¬
	" --header 'app_id: 0b57ad70'" & ¬
	" --header 'app_key: 8aca301f5bddd190bc7c3a5fcd9ce78d'" & ¬
	" 'https://od-api.oxforddictionaries.com/api/v1/inflections/en/" & word_id & "'"

do shell script cURL

if the result contains "\"results\": [" then
	return true
else
	return false
end if
The AppleScript Executing in Script Editor


To finish, I think we can say that this specific API isn't properly suited to word checking an entire document, but the principles are the same across different APIs that are available on the web.

Although, if you were forced to check each word individually, it would very easy to implement, but take a bit of time due to bottlenecking. AppleScript conveniently has some functions that can deal with text quite nicely. If your document is on the clipboard, one can command:

repeat with w in every word of (get the clipboard)
	
	# Execute your cURL request here
	
end repeat

Hope this helps. APIs are pretty damn awesome, and I use many for different things: one to automate taking screenshots of webpages; one that retrieves geolocation info based on my IP address; one that updates my web domain dynamically to point to my external IP address; one to automatically download media from websites; and one that provides access to lots of scientific and mathematical data resources.

2 Likes

This is fantastic - thank you!! It will take me a little time to work through this but when I copied your example and entered my own id and key, it worked!! Thanks for taking the time to type this out and to reply, I really appreciate it!
Scott

I'm curious if you think a solution like this would work to check the entire document? It looks like there's a small fee, but from the sounds of it, it will check the entire document:

Hey Scott,

Once you have things set up it's as simple as this:

image

This will give me a sorted list of misspelled words, and from there I can count them or process them in other ways.

For instance I can count how many instances there are of each misspelled word.

This is fast, easy, and local.

Kudos to @CJK for looking at online solutions. I happily use them when they're the best tool for the job.

In this case I'd prefer a local solution for speed if nothing else, but if the right API was available I'd change my mind.

I'm willing to walk you through installing the tools you need if you like.

-Chris

3 Likes

I agree with @ccstone: I think his suggestion makes the most sense here, and, of course, it's free.

The Bing Spell Check API looks excellent but, as you said, there is a fee, and it does have the following limitation that I noted when I skimmed the API's documentation:

The maximum URL length is 2,048 characters. To ensure that your URL length does not exceed the limit, the maximum length of your query parameters should be less than 1,500 characters. If the URL exceeds 2,048 characters, the server returns 404 Not found.

This means you have to split up your document into chunks of text no longer than 1500 characters and process each chunk by itself.

So, on balance, my personal preference if this were my task would be to use Aspell.

Okay, I'm going to give this a go and see if I can get it to work and report back. :slight_smile:

Okay - I think I got both homebrew and Aspell installed correctly, but when I tried to "Execute Shell Script" using the clipboard that I use to proofread, I get this error:

image

Is this a problem with referencing a folder for Aspell?

Not sure what you mean.

@ccstone’s macro from above works fine here. But, as posted, it takes the system clipboard content, not one of KM’s named clipboards.

This is the macro that works for me: [Test] Aspell.kmmacros (1.8 KB)

Download it and try.
To use it with a particular named clipboard just set the action to “With input from Named Clipboard [name of the clipboard]”.

Make sure the path of the Homebrew programs is known to KM. If not already done, create a variable with the name ENV_PATH (Keyboard Maestro > Preferences > Variables > Plus (+) button) with this content:

/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin

If it still doesn’t work, then post your macro. (Select the macro in KM Editor, then File > Export Macros, then upload the file to a forum post.)

Awesome! This works, I was missing the ENV_PATH. Once I added that and ran your test Aspell script, it worked! I'm getting a few false positives, which I'll have to explore. For example, I'm getting:

ok
parentâ
questionâ
skepticismâ

I'm not sure why the â is showing up after the word, but this isn't a KM question. Many, many thanks to all of you who have helped me through this!! Very appreciated!
Scott

What is the output when you run it in the Terminal?

In the Terminal you have to use the command in this form:

pbpaste | aspell list | sort

Make sure your sample text is on the clipboard before running the command.

Those words with the appended “â”, are they placed at the end of a line in the input text?

Another possibility is that those words are followed by non-ASCII chars in the input text, for example a non-breaking space.

Create a new variable in KM (as you have done with the ENV_PATH), with the name
ENV_LC_ALL and this content:

en_US.UTF-8

See if it works better then.


PS:

ENV_LANG (as variable name) should work also and is probably sufficient.

This worked like a charm! It got rid of all of the â words on the list!! Amazing work - thank you!