I wrote a thing which helps me write better blog postings.
After switching my blogs from S9Y to a static blogging engine (goHugo), I found a number of preventable issues. Certain syntax errors, forgot tags, or forgot a description, or forgot a preview picture, or forgot an image. This kind of things. So I wrote check-markdown-files, which now scans all my blog postings before committing the posting to git. Any known error is raised, and aborts the commit. Each problem has an override switch in case it is a false positive.
How does this work
The script check-markdown-files.py looks for a check-markdown-files.conf in the repository. This configuration file enables or disables checks for this blog - not every blog needs the same checks, or all checks for that matter.
By default, check-markdown-files.py scans every index.md which is newer than check-markdown-files.conf - this avoids re-scanning the entire blog all the time. You can force a full scan with the -a option. This relies on Hugo Page Bundles, which place every blog posting in a separate directory, with one index.md per blog posting.
Examples!
That’s nice, but show it to me!
Certainly, here’s an example from the time I was writing this blog posting:
| |
Ok, this blog posting is still in draft stage, here are the issues found:
- Whitespaces at the end of lines (this can both raise a warning as well as remove the whitespaces for you - configurable). It’s just something I don’t like, trailing white spaces in a text.
- Found
changemein tags and categories: my Archetype template haschangemein both Frontmatter fields by default, this forces me to change both fields and don’t forget about it. The fields and the blocked content are configurable. - No preview in
description: Forces me to add a proper description as blog preview. - No
thumbnailas preview image: Forces me to add a preview image and not rely on the first image in the blog posting. - No preview image in header: This check finds an image before the content summary field, which will look ugly in previews. Using
descriptionandthumbnailoverrides this problem.
Overrides?
Some of the checks and the issues raised must be resolved. Like when I forgot to add a description, or tags.
Other checks raise potential issues, which may or may not be a problem.
As example, the check_double_brackets check will scan the posting for opening (( and closing )). While this is often correct, as example when adding a Wikipedia link which includes () in a Markdown link, sometimes it’s not. My editor automatically adds a closing ) when I write an opening ( - and I might have missed that and manually added another ).
After seeing the warning, I scan the blog posting if the (( or )) are indeed correct, and add an override:
| |
Other common mistakes I make, to list a few:
- I use Markdown headers
###or####. While that is sometimes ok, I aim to stick with##. Hence the script in my configuration will raise a warning for such headers. - Missing tags: The script allows a list of words, which when appear in the blog posting also are supposed to be tags. Everything from Linux distribution names, city names to country names or whatever you add in the list. This check makes it easy for me not to forget to add tags.
- cross-linked tags: When I add one tag, I also want to have another related tag. Like
united-statesandusa. Well, in my old blog I sometimes added one, or the other. And ended up with both tags, and search engine crawlers looking for both tags. Now I enforce that blog postings have both tags, if the posting has one tag. - Something simple:
IandI'm. TheIis written uppercase in English, but I might miss it. This is a warning. http://links. Let’s make sure the web is encrypted, everyhttp://link is a warning. Can be overridden, because not every URL is available ashttps://.- Embarassing: I posted blog postings which include a local goHugo preview link (
http://localhost:1313/). Obviouslly this link does not work, therefore this is a warning. - Image sizes: scans every image in the blog posting directory, and raises a warning if it is larger than a defined threshold. Ignores files which are ignored by
git. This ensures that I resize pictures before posting a blog post. - Image does not exist: scans the blog posting and raises an error for every local image which does not exist in the filesystem.
- Forbidden words: list of words which can’t appear in a blog posting.
- Forbidden websites: list of websites which can’t appear in a posting. This helps me, in the past I posted links to crappy link aggregator websites, instead using the real link. Now the crappy website is a warning.
FIXMEare a warning: when I want to fix something later, I add aFIXME. This check helps me not to forget to actually fix the issue!- Double uppercase: I have the tendency to release the shift key too slow, and sometimes end up with TWo UPpercase CHaracters. This check finds those problems.
The GitHub repository has a full list of available checks and overrides, which can be enabled on a per-blog basis. By the time I write this blog posting, 38 different checks are available.
Installation
Your blog must live in a git repository, that’s kind of a prerequisite. And it must use Page Bundles, or at least directories for blog postings.
- Check out the git repository somewhere on your system.
- Point
.git/hooks/pre-committo thecheck-markdown-files.pyscript. - Copy
check-markdown-files.confinto your blog directory, and modify it.
Whenever you run git commit, the check-markdown-files.py script will run and check all newly modified blog postings.
You can also run it manually on one blog posting:
| |
Or
| |
Both versions work.
Feature requests
New feature requests are welcome. Please open an issue on GitHub or post a comment. Please describe what kind of checks you are looking for.
There’s also a large number of tests included which helps adding new features without breaking existing functionality.
Other tools
While posting previously on Social Media about this tool, I was pointed to Vale Linting. This is not the same though, check-markdown-files.py does a large number of additionally checks beyond simple linting of the text.
Comments
With an account on the Fediverse or Mastodon, you can respond to this post. Known replies are displayed below:
Note: This will load data from mastodon.social.
Learn how this is implemented here.
Share: