Is it "email" or "e-mail"? "Log in" or "login"? "JavaScript" or "Javascript"? None of these choices matter much on their own. What matters is making the same choice every time, and that's where I used to slip. I'd write "email" in one piece and "e-mail" in the next, depending on what I'd been reading that morning.
Editors at publications solve this with a style sheet: a running list of decisions about spelling, capitalisation and terms for one project. I borrowed the idea and keep my own as a plain text file. Then I added a few lines of Python so I don't have to remember it all myself.
What goes in the file
My style sheet is a file called style.txt that sits next to my drafts. Each line holds one decision: the form I want on the left, the forms I want to catch on the right.
# preferred | variants to flag
email | e-mail, E-mail
website | web site
log in to | login to
JavaScript | Javascript, javascript
GitHub | Github, github
Lines that start with # are comments. Everything else is a rule.
I only add a word after I've caught myself being inconsistent with it. Grown like that, it stays short and personal. Mine is mostly product names, a few compound words and some British versus American spellings I keep mixing up.
Why a plain file
I've tried keeping word lists in notes apps and spreadsheets. The plain file wins for boring reasons:
- It opens in any editor, so I can check it in seconds while writing
- I can search it with the same tools I use for everything else
- It lives in the same folder as the drafts, so it moves with the project
- A script can read it without any extra libraries
A short script that reads it
Reading the list is one thing. Actually checking a draft against it by eye is tedious, and I miss things. So I wrote check_style.py:
import re
import sys
from pathlib import Path
rules = []
for line in Path("style.txt").read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
preferred, variants = line.split("|")
for variant in variants.split(","):
rules.append((preferred.strip(), variant.strip()))
for path in sys.argv[1:]:
lines = Path(path).read_text(encoding="utf-8").splitlines()
for number, text in enumerate(lines, start=1):
for preferred, variant in rules:
if re.search(r"\b" + re.escape(variant) + r"\b", text):
print(f"{path}:{number}: '{variant}' -> '{preferred}'")
It builds a list of (preferred, variant) pairs from the style sheet, then goes through every file I pass in, line by line. The \b markers mean it only matches whole words, so the rule for "web site" won't fire inside some longer word by accident. re.escape takes care of any characters in a variant that would otherwise have a special meaning in a regular expression.
I run it on a whole folder at once:
python3 check_style.py drafts/*.md
On a test draft, the output looks like this:
drafts/post.md:1: 'e-mail' -> 'email'
drafts/post.md:1: 'web site' -> 'website'
drafts/post.md:2: 'Javascript' -> 'JavaScript'
drafts/post.md:2: 'Github' -> 'GitHub'
drafts/post.md:3: 'login to' -> 'log in to'
File, line number, what it found and what I want instead. That's all I need to go and fix it.
A few things I learned using it
The match is case-sensitive on purpose. That's why "E-mail" has its own entry. I could make the search ignore case, but then a rule like "GitHub | Github" would flag the correct spelling too. Listing variants explicitly is a bit more typing and much less confusing.
Some rules need context. "Login" as a noun ("your login details") is fine in my style. "Login to your account" is not. So the rule matches "login to" rather than "login" on its own. When a word is only wrong in certain phrases, I put the phrase in the file instead of the word.
It doesn't fix anything. I like that. The script points, I decide. Sometimes a variant is correct in context, for example when I'm quoting someone, and I leave it alone.
Code blocks get flagged too. If a draft contains github.com in a code sample, the lowercase rule catches it. I just skip those lines. It hasn't bothered me enough to add code-block handling.
Keeping it alive
The style sheet only helps if it keeps growing. Whenever I hesitate over a spelling while writing, I make the decision once, add a line, and move on. The next time that word comes up, the decision is already made, and the check catches me if I forget.
It's a small habit, but my pieces read more like they came from one person now, which, well, they did.
Top comments (0)