I've released blogmore.el v5.3.0. This is a pretty small release but adds a command I realised I'd forgotten to add a couple of releases ago.
Now that BlogMore has the concept of a post series, and now that blogmore.el lets you add and remove a series from a post, it makes sense that I'd want to link to a series in a post from time to time, like I can and do with categories and tags.
So v5.3.0 adds a blogmore-link-series command. It can also be found in the transient menu.
Another quick update to blogmore.el, again to fix an issue I've run into with the new frontmatter-handling code. This time it's to address an actual crash that could happen if a property was available but empty. For example, if a post had frontmatter that looked like this:
And I then went to use blogmore-add-tag, I'd get a crash saying:
Wrong type argument: sequencep, :null
The reason being that tags was being parsed with a value of :null, rather than (as before) having a value of nil (which of course meant I had a nice empty list to do things with). It was an easy enough fix.
At this point I think I've managed to shake out any serious issues with the proper YAML-parsing approach to frontmatter, as I've used it to write a handful of posts now.
A quick little update to blogmore.el to fix a couple of issues introduced by the new YAML-parsing approach to reading frontmatter; both pretty much stemming from how falsy values are handled.
Simply put, both boolean false values, and also empty values (something that could commonly happen with tags and series) would end up showing up in the frontmatter as null. This release handles that situation.
Also, under the hood, I cleaned up some repeated boilerplate related to how the cached dump calls to BlogMore took place. The code for categories, tags and series data was almost exactly the same, save for the actual name of the thing being dumped. So I turned it all into a macro:
(defmacroblogmore--cache-dump(dump-name)"Generate a function to get DUMP-NAME from BlogMore, with caching."(let((cache-name(intern(format"blogmore--current-%s-cache"dump-name)))(getter-name(intern(format"blogmore--current-%s"dump-name))))`(progn(defvar,cache-namenil,(format"Cache for the list of %s from existing posts."dump-name))(defun,getter-name(),(format"Get a list of %s from existing posts."dump-name)(or,cache-name(setq,cache-name(blogmore--list-of,(symbol-namedump-name))))))))
and now the defvar that creates the variable that holds the cache, and the defun that creates the getter function for the data, are reduced to this for all three collections of values:
Sure, I probably could have done all of this in a single global, a central getter function, and a hash table, but the macro approach feels so much more elegant, and more... lispy.
When I released blogmore.el v4.7.0 yesterday I finished off by saying that it was my intention, at some point, to rework the frontmatter-handling code so that it did proper YAML parsing. As often happens with these sorts of things, "some point" ended up being that evening.
I've rewritten everything to do with handling properties in the frontmatter so that it now uses yaml.el. This has a number of knock-on effects. The first and most obvious effect is that anything that is a list/array in the frontmatter is actually properly treated as a list. A good example here is tags. Now you can have your tags look like:
and blogmore.el will still handle things fine. The same holds for series too.
It should be noted, however, that because I'm now using actual YAML serialisation code, most other forms of a list will all end up being transformed into this kind:
and you make an edit to the tags via blogmore.el, it will end up as the version enclosed in []. BlogMore itself supports all three versions so this works fine.
There is a breaking change here too, which in part explains the reason I bumped the version to 5.0.0: because series can now be treated as a list I've removed the blogmore-set-series command and instead replaced it with blogmore-add-series and blogmore-remove-series. Both can of course be found in the transient menu.
Another big change in this release is the way that existing values are loaded up from your blog. Previously, when you went to add a category, tag or series, blogmore.el would use ripgrep (or a combination of find and grep if rg wasn't available) to pull out values to help populate a completion list. This worked fine as long as a) the frontmatter property was all on one line and b) the body of a post didn't contain something that looked like a frontmatter property. With this release of blogmore.el I've dropped this approach in favour of calling blogmore itself and using the dump command to get the actual lists of categories, tags and series.
This does mean that BlogMore needs to be installed in a location where blogmore.el can see it, and to help with this I've added a new defcustom called blogmore-command. By default this is set to call whatever version of blogmore can be found in your exec-path; if this results in unexpected behaviour you can set blogmore-command to point to a specific copy of blogmore.
There is, however, a small downside to this beneficial1 approach: calling on blogmore and parsing all posts to get the values is generally going to be slower. With this in mind I've built in a cache for these values. The first time you load up the categories, tags or series, the values are held on to so that subsequent prompts are instantaneous (meaning there is no further call to blogmore). To ensure this doesn't confuse things, when you switch blog (blogmore-work-on) the caches are cleared. In the unlikely event that there is a problem with this approach, I've also added a blogmore-clear-caches command to force the clearing of the caches.
There are some other small QoL changes under the hood and also to the interface. I've moved some things around in the transient menu, and also ensured that a couple of options are better-disabled depending on the context.
All of this makes the package even more robust. Something that started as a quick hack back in March has turned into a tool I heavily lean on. Hopefully, for anyone who might happen to use BlogMore and GNU Emacs, it'll be a useful daily-driver for them too.
The benefits being: only values in frontmatter appear, inconsistent casing is cleaned up, etc. ↩
You can, of course, set a new one too, but the idea here (as with categories and tags) is that you can quickly find back an existing series and add the current post to it.
Also, as with tags, the expectation is that either a single series is being used, or if more than one series is in play for a post they'll be listed as a comma-separated list. The issue here is that while BlogMore supports this:
series:-Some series of posts-Some other series of posts-Yet another series of posts
the frontmatter-handling code in blogmore.el isn't very sophisticated at all; it doesn't actually handle it as actual YAML, instead just treating it as a set of key/value pairs separated by a colon.
At some point soon I want to give blogmore.el a revamp and base all of the frontmatter-handling code on something like yaml.el. I did do some experimenting last night to drop it in and handle proper lists. It worked well enough, but I abandoned the work as I realised I really wanted to start again from scratch and build blogmore.el from the bottom up using that package.
I've just realised that, somehow, I've managed to post something on this blog, every single day this month.
A large part of this is, of course, because I've been doing a lot of stuff on BlogMore, but there's no getting away from the fact that BlogMore exists and I feel compelled to make use of it, and also that blogmore.el helps make it a lot easier to kick off and edit a post.
Thinking back to other blogs I've maintained over the past couple of decades, I don't think I've ever come close to this. Last month did come close, broken only by the couple of days I was chilling in Whitby. The month before also came close, minus 2 days where I just didn't have something to write.
I don't imagine this will last; in fact, I know for sure that there will be fewer posts next month (I have a trip coming up). What I do know is that I feel more compelled to jot something down when an idea turns up, and I'm enjoying the habit of blogging more frequently. While I expect this run to calm down, I hope I don't fall back to leaving it months at a time before opening a fresh Emacs buffer and kicking off some new Markdown.
Carrying on with the theme of being lazy while editing posts, I've released blogmore.el v4.5.0. This version adds blogmore-set-as-cover. With this, if you place point on a line that is an image and run the command, it is set as the cover for the post.
Sure, it's not like it's hard to copy, move, insert a new line, type cover: and then paste the text, but this is faster and more accurate.
And I'm lazy.
And I like hacking on Emacs Lisp that makes my workflow flow faster.
I've released an update to blogmore.el, my Emacs package that helps me out when writing this blog. I've added two commands to this version which help me be lazier than ever.
The first is blogmore-become-like. When run, this prompts for another post and, once selected, it sets this post's category and tags to be the same as the other one. I added this because I'm often writing an occasional series of posts that are all about the same project, and so I always find myself copying and pasting those frontmatter properties from another post.
The second command I've added is blogmore-toggle-image-centre. Built into BlogMore is a little bit of styling that will ensure an image is placed in the centre of the page, if the URL for the image has #centre on the end. This means that, for most images I add, I have to go and edit the URL to add that. Now I can just run a single command when the cursor is on an image and it'll add (or remove, if it's already there) that styling hint.
In both cases, I've added the commands to the transient menu too.