My LaTeX Workflow – Spell Checking

Published on
Having many spelling mistakes in a text can greatly distract from the content of the text. Luckily, nowadays we have many great spell checkers at our disposal. Their integration in an editor like Visual Studio Code is however not trivial. This is why I wrote this blog post: To help you set up the spell checkers LTeX, Grammarly and CSpell in vscode. I will discuss the spell checkers in general, how we can add custom dictionaries, and finally how we can make further useful configurations.

After I discussed a few tools for generating LaTeX as part of my series on my LaTeX workflow, it is now time to spell check the text we have written. You might ask why?, and the reason is very simple: Every time a reader stumbles upon an unexpected formatting, inconsistency or spelling mistake, they will loose their focus. These interruptions will draw the reader away from the content and shift their attention towards the bad writing style. This is something we clearly want to avoid. Luckily there are many great spell checkers that can detect most spelling and grammar mistakes. So let me show you how you can use three of them in vscode.

Spell checkers

As every spell checker works a little differently, it is advisable to not only have one spell checker but several to detect a broader range of mistakes. Currently I am using the following three spell checkers on all of my projects.

CSpell

The CSpell is a classic spell checker based on Hunspell. It works by comparing every word in the text to a dictionary of correct words. This approach has the obvious disadvantage that it can not find grammar errors which depend on more than one word. For example, in "I likes mathematics" every word itself is correct, but the composition is wrong.

Grammarly for vscode (unofficial)

Modern spell checkers can catch mistakes like these by considering entire sentences instead of single words. The probably most famous modern spell checker is Grammarly. Grammarly is a paid product with a free plan that is sufficient for most tasks. While Grammarly works very well, the vscode extension has several bugs right now (line breaks introduce false positives, user dictionaries are ignored, ...). But despite these issues, the extension is detecting many mistakes and the developer claims that the extension will be actively developed again in the future.

LTeX

Another modern spell checker is LanguageTool, which we can use via the vscode extension LTeX. As the name suggests, LTeX is a spell checker specifically built for LaTeX. The extension works flawlessly, and I am considering it to be the best spell checker of these three.

Adding Dictionaries

The most important modification of a spell checker is using custom dictionaries. These dictionaries collect customs words, you consider correct for your writing but are flagged as false by the spell checker. So in the next few paragraphs I want to explain how you can add dictionaries to the spell checkers in vscode.

My most important goal here is to avoid duplication. This means, that

  • all spell checkers in vscode,
  • and all projects I am working on

should use the same dictionary files.

Let's see how we can (partially) achieve this: First, create a new folder named Dictionaries somewhere on your computer. As the name suggests, this is the folder where we put our dictionaries. The dictionaries are normal .txt-files, with one word per line. I choose to partition the words into multiple dictionaries like this:

Dictionaries
├─ Mathematical_Terms.txt
├─ Names.txt
└─ Programming_Terms.txt

So how can we now use theses dictionaries? Bad news first: there is currently no way (that I know) to get this working with Grammarly. I hope this will be fixed in the future, but right now it is not a big problem as Grammarly does not flag many words by mistake.

In LTeX, the configuration is straightforward: Add the following lines to your global settings.json file and adapt the paths to your dictionary location. Note the : at the beginning of the paths.

settings.json
"ltex.dictionary": {
	"en-US": [
		":/absolute/path/to/Dictionaries/Mathematical_Terms.txt",
		":/absolute/path/to/Dictionaries/Names.txt",
		":/absolute/path/to/Dictionaries/Programming_Terms.txt",
	],
},

For CSpell we need this slightly more complicated setting in the global settings.json file.

settings.json
"cSpell.dictionaryDefinitions": [
	{
		"name": "Mathematical_Terms",
		"path": "/absolute/path/to/Dictionaries/Mathematical_Terms.txt"
	},
	{
		"name": "Names",
		"path": "/absolute/path/to/Dictionaries/Names.txt"
	},
	{
		"name": "Programming_Terms",
		"path": "/absolute/path/to/Dictionaries/Programming_Terms.txt"
	},
],

"cSpell.dictionaries": [
	"Mathematical_Terms", "Names", "Programming_Terms"
],

"cSpell.languageSettings": [
	{
		"languageId": "latex",
		"dictionaries": [
			"Mathematical_Terms",
			"Names",
			"Programming_Terms",
		]
	},
	{
		"languageId": "bibtex",
		"dictionaries": [
			"Mathematical_Terms",
			"Names",
			"Programming_Terms",
		]
	}
],

Another feature that is sometimes needed is to flag words as false even though they are considered to be correct by the spell checkers. A reason for this might be that you don't want to use words like "easy", "obviously" and "trivial" as they often have a condescending tone. To mark these words as wrong, add the following lines to your settings file.

settings.json
"cSpell.flagWords": [
	"easy",
	"obviously",
	"trivial"
],

Other Settings

Now it is time to make some additional configurations. CSpell does not have many setting, so there is not much to configure. But LTeX and Grammarly can be configured, so let's go through both of them.

LTeX

Let us start with LTeX. For this spell checker I added the following settings to my settings.json file.

settings.json
"ltex.additionalRules.enablePickyRules": true,
"ltex.additionalRules.motherTongue": "de-DE",
"ltex.disabledRules": {
	"en-US": [
		"DATE_NEW_YEAR",
	]
}

enablePickyRules enables a few additional spelling rules that might increase the false positive rate. It is required for the motherTongue setting, which is set to the language you are most familiar with. For me, this is german de as spoken in Germany DE. The spell checker then highlights common mistakes in en-US made by speakers of de-DE. For example, the sentence "I become a child" is grammatically correct, but most likely it is a wrong translation of the german sentence "Ich bekomme ein Kind", which means "I get a child".

Next, ltex.disabledRules shows how you can disable certain spell checking rules. I'm disabling the DATE_NEW_YEAR rule which complains at the beginning of each year when you are writing a year other than the current one.

LTeX has many more settings with which you can configure the spell checker. Go check them out! For example, you might want to change the default language from en-US to something else.

Grammarly

The settings for Grammarly are more higher level than those for LTeX. This means we set general concepts like audience or domain instead of specific rules. Sadly some of the Grammarly settings do not work right now. I'm adding the settings nonetheless in the hope that they will be fixed some time in the future.

settings.json
"grammarly.audience": "expert", // "knowledgeable", "general"
"grammarly.dialect": "american", // "australian", "british", "canadian"
"grammarly.domain": "academic",
"grammarly.debug": true,
"grammarly.severity": {
	"BasicPunct": 2,
	"CommonlyConfused": 2,
	"Determiners": 2,
	"Formatting": 2,
	"Fragment": 2,
	"Unknown": 2
},
"grammarly.userWords": [],

Setting grammarly.audience to "expert" means that Grammarly will not complain if your sentences are a bit more complicated. With the "general" setting it tells you to simplify complex sentences. Grammarly can only check english texts, but at least we can specify which dialect we what to use. The "academic" configuration for "grammarly.domain" means that grammarly should do a rather strict checking by applying all the rules.

If Grammarly detects an error it will underline the corresponding word. Hovering it with you mouse will bring up a short explanation of the error. Sometimes, however, this description is too short making a correction rather hard. Therefore we use the setting "grammarly.debug": true. It tells Grammarly to write out all the information it has regarding the error.

The severity object configures entire classes of mistakes as errors 1, warnings 2, info 3 or hint 4. In the userWords-array you can add words that grammarly should ignore. However this feature is currently not working.

Conclusion

This wraps up the blog post on how I configured three spell checkers in vscode. I hope these instructions will help you to set up the spell checkers yourself to detect some mistakes and improve your writing. You should also have a look at the other posts in my LaTeX workflow series, that cover everything from generating LaTeX code to my literature management. Do you have any other tools that might fit in my LaTeX workflow? Please tell me on Twitter! I will update the article and add new ones as my workflow evolves. So come back regularly or subscribe to my RSS feed.