Posts tagged with "coding"

BlogMore v2.6.0

2 min read

Yesterday I read a rather positive post about BlogMore, which was lovely to see. But... when I saw the link for it over on Mastodon I noticed something wasn't quite right about the description in the preview:

The preview of the post

See, when BlogMore makes a post, if the author of the post hasn't provided a description in the frontmatter, the first paragraph of text will be used instead. When doing this the code should strip out any markup (and also skip any initial images, that sort of thing).

But, as you can see, there are things like [Dave][davep] in that description. So I checked in with Andy and that was something that came from the underlying Markdown. After a bit of checking, it became obvious that the code in BlogMore was only looking for and removing inline links, but wasn't doing anything about reference links.

So, as usual, one prompt later and the issue was handled.

As it stands, I don't think I'll keep up with the current approach. It doesn't feel quite right to me. The whole point is that the Markdown should be rendered down to pure text and then the first actual paragraph of text is used. The code I have there now is doing some regexp-based mucking about as an approximate approach. It works, more or less, but it feels like it's implementing a poor Markdown parser when there's a Markdown parser already built in.

Given this, at some point soon, I might have a play and look at the idea of "let's have a Markdown to pure text parser" and then use that. I could see it being useful for other purposes too.

Anyway, the upshot of all of this is that BlogMore v2.6.0 is now available and it handles the stripping of reference links from the description, plus the recently-added strikethrough markup too.

BlogMore v2.5.0

1 min read

I've released BlogMore v2.5.0 out into the world. This release is the result of an observation Andy made about the Markdown library used in BlogMore (it might apply to MarkdownIT too, which would of course affect Hike): it doesn't support strikethrough markup out of the box.

I'm not sure I've ever used that markup anywhere on my blog, but I've used it often enough on GitHub (for example) that I just assume it's going to be there (and now I think about it Hike might be okay 'cos it uses Textual's Markdown widget which I know for certain uses GitHub-flavoured Markdown). But, for sure, the Markdown library doesn't implement it because it's not part of the original approach to Markdown.

On the other hand: implementing a form of strikethrough markup is one of the samples in the documentation on writing extensions, so it seemed like a very reasonable thing to add. Given this, one quick prompt to the agents later and strikethrough was added.

Now I'm going to totally have to find a reason to use this markup from time to time to time.

GitHub Copilot wants our interaction data

4 min read

I guess it was inevitable1, but yesterday GitHub announced a new opt-out approach to learning from people's interactions with Copilot. I don't have anything novel or insightful to say on this switch, and I'm sure folk with better-informed opinions have already rushed out posts and articles about this, but I did want to jot down just how curious I am to see this roll out.

For starters: for me this feels like one of those things that will get a lot of backlash, and in a day or so GitHub will say they're pausing rolling this out while they reevaluate this approach2. Then, eventually, they roll it out anyway after a "period of consultation with the community". That sort of thing.

I've not read further this morning, but before going to bed last night it wasn't a happy time in the comments section of the FAQ. I can also see why some would be cynical about this change, given the tone of some of the questions and answers in that FAQ. I'll hand it to them: they're pretty candid and honest with the FAQs, but kinda yikes too.

A bad time in the FAQ

Here's the key thing I'm curious about, and which I'll be thinking about and watching for movement on in the next few days: all the talk here seems to be about protecting the privacy of the proprietary code of businesses3. That... is understandable, from a business point of view, from a commercial adoption point of view, from a "we want all software engineering departments to use Copilot" point of view. But how the heck are they really going to manage that?

In the comments in the FAQ this explanation stood out:

We do not train on the contents from any paid organization’s repos, regardless of whether a user is working in that repo with a Copilot Free, Pro, or Pro+ subscription. If a user’s GitHub account is a member of or outside collaborator with a paid organization, we exclude their interaction data from model training.

This seems somewhat unclear to me. Let's walk this one through for a moment: my GitHub account is a member of a "paid organisation". My account is also my account, for my personal code, I've had it a long time and it's filled with a lot of FOSS repos and I keep adding more. So which scenario is the right one here?

  1. Because I'm currently a member of at least one "paid organisation" I'm always opted-out of this training no matter how the opt in/out setting is set and no matter what code I work on?
  2. Because I'm currently a member of at least one "paid organisation" I can opt in when working on code that is from a repository which is mine, but I'm opted out when I'm working on code from a repository belonging to the paid organisation?

I think it reads like it's #1. But then that seems rather odd to me because, if I go and look at my settings right now, I can elect to opt in/out of this training system. If the correct reading is #1 why not just disable that setting altogether and say below it that I'm opted-out because I'm part of a paid organisation?

Which sort of suggests we should perhaps read it as #2? If that, that raises all sorts of questions. How would Copilot know I'm working on code from such a repository? Sure, it's not impossible to infer if I am working within the context of a given repository, doing some fun stuff to work out the origin and so on, but it feels messy. It also feels like a scenario that could end up being incredibly leaky. It really would not be difficult to run into a scenario where I'm working on some non-Free code but in an environment where the licence isn't clear, or where it appears that the licence4 would permit such training.

ℹ️ Note

Editing to add: there is even a comment where it is acknowledged that someone could be working in such a way that it's impossible to know the provenance of the code: "Copilot ... can even work when you are not connected to any repo."

Or... perhaps there's a #3, or a #4, or so on, that I've not even considered yet. The fact that software engineering departments suddenly have to start thinking about this issue (yes, I know, it's been a background issue for a while but this really drags it out into the open) is going to make for a few interesting weeks, assuming people care about where their code ends up.

Who knows. Perhaps, in some strange way, this is how all software ends up being Free.


  1. And I think a bit of me is surprised that they weren't just doing it anyway. 

  2. This isn't a prediction, I'm just saying it feels like that sort of announcement. 

  3. It's not that simple, but to save getting into the deep detail... 

  4. I'm using licence here as shorthand for a lot of things to consider relating to who should have access to the code and how. 

BlogMore v2.4.0

1 min read

After adding the stats page to BlogMore yesterday I realised that the main stylesheet was starting to get fairly large. Not so big that it was a problem for downloading (and of course normally it would get cached anyway), just more that it was carrying around styles for things that only appear on one page (the styles for the stats, for example).

So I decided to break it up. Now, as well as the main style.css, there's also:

This should keep the load times for the main pages and individual posts just a wee bit faster when first encountered, leaving off all those styles that aren't necessary.

All of which means, along with a wee wording change on the stats page, BlogMore v2.4.0 is in the wild and ready to use.

Hike v1.4.0

1 min read

Hike, my wee terminal-based Markdown viewer/browser, has had an update to v1.4.0. In this update I've made a change I've been meaning to make for ages: some support for "wiki links".

By that I mean the sort of link markup you often see in Markdown documents made with Obsidian:

In other words [[this]] instead of [this](kind-of-link.md)

Personally it's something I seldom need, but on the occasion I have been delving into my Obsidian vaults with Hike I've wished the links at least rendered "correctly", even if they wouldn't fully work.

On that note, it's worth keeping in mind that this "wiki link" implementation in Hike doesn't support something that Obsidian does: find the most likely target file for a given link. If you click such a link, Hike expects the file to be exactly where the link suggests. There's no going off and finding the most likely match in the "vault", etc (Hike obviously has no concept of a "vault").

I'm open to the idea of extending this at some point, perhaps, but not yet. The intention here isn't to build a terminal-based Obsidian-a-like, but instead to build and maintain a workable Markdown browser/viewer (and occasional editor).

Hike is licensed GPL-3.0 and available via GitHub and also via PyPI. If you have an environment that has pipx installed you should be able to get up and going with:

pipx install hike

If you're more into uv:

uv tool install hike

If you don't have uv installed you can use uvx.sh to perform the installation. For GNU/Linux or macOS or similar:

curl -LsSf uvx.sh/hike/install.sh | sh

or on Windows:

powershell -ExecutionPolicy ByPass -c "irm https://uvx.sh/hike/install.ps1 | iex"

BlogMore v2.3.0

1 min read

I've just pushed BlogMore v2.3.0 up to PyPI. This release has a couple of bug fixes and a couple of significant new features.

The first new feature, which came in as a request, is to add support for control over the themes used for code blocks, including independent control of the themes used for light and dark mode. With these you can specify any of the Pygments styles to use for code blocks. Personally, I prefer to have things blend in, but this now also gives you the chance to have them really contrast (use a light mode theme for dark-mode blog, or a dark mode theme for a light-mode blog).

The other big feature popped into my head earlier today and once I thought about it I had to have it. It's similar to something I had for the photography section of the older version of my website, consisting of a bunch of useless but fun stats and facts about the content.

Things like which hour of the day I tend to post during:

Hour of day

Or the day of the week:

Day of week

Or the month of the year1:

Month of year

This is designed to be turned off by default -- I can imagine most folk would not want this sort of thing on their blog -- but it can easily be turned on with with_stats. The location of the stats can also be controlled using stats_path.


  1. Unsurprisingly March is leaping ahead as of the time of writing. 

blogmore.el v1.7

2 min read

Yes, the last time I mentioned blogmore.el it was v1.4 and now it's up to v1.7. So I tinkered a little with it last night, okay?

Anyway, the changes and additions keep happening as I have more fun writing some elisp again. Since the last post about the package I've:

  • Added a command to refresh the date frontmatter property
  • Added a command to add/refresh the modified frontmatter property
  • Added a command to insert a link to a previous post into what I'm writing
  • Made a few things defcustom rather than defconst for easier tweaking
  • Added a hook that can be run after a new post is started
  • Dropped the dependency on end-it and used the above hook to do the same thing

While this package is never intended for use by others, I guess it's not impossible someone might want to work with it (I had the same thing in mind with BlogMore itself yet someone else has started working with it!) and so I'm moving it in the direction of being my way by default but easy to modify to other requirements.

So, now, rather than forcing someone to have to use my obsession with end-of-file markers, I still have that without imposing it on anyone else by simply setting the hook.

(use-package blogmore
  :vc (:url "https://github.com/davep/blogmore.el" :rev :newest)
  :init (add-hook 'blogmore-new-post-hook #'end-it))

I think my favourite addition right now is blogmore-link-post. I like to cross-link posts in my blog as much as possible so having something that lets me do that and stay inside Emacs really speeds things up. So now I just run that command, I get speedy picker to find the post:

Picking a post to link

and the result is some Markdown inserted with the cursor between the two [] ready for me to write the text:

[](/2026/03/20/blogmore-el-v1-4.html)

Other things I link often are categories and tags, so I'm planning on adding commands that does something similar for those two.

blogmore.el v1.4

1 min read

Following on from yesterday's post, in the evening I found myself in a cafe with my MacBook Pro and an hour to kill, so I tinkered with blogmore.el a little more. The main aim here was to add a command for adding tags to a post and I now have blogmore-add-tag as of v1.4.

One thing that stood out was just how rusty my Emacs Lisp skills are. It took me a wee while to get the code working, mostly due to me being caught out by the gotchas I'd forgotten about surrounding match data and the need to make good use of save-match-data (I had a combination of re-search-forward, string-split and replace-match going on and it was chaos for a while).

I got there in the end, though, when I bothered to RTFM with a quick C-h f string-split RET.

Documentation for string-split

So now I have the following commands in Emacs when I get the urge to do something blog-related:

  • blogmore-new starts a new blog post
  • blogmore-edit lets me edit an existing post
  • blogmore-set-category lets me set the category from existing categories, or set a new one
  • blogmore-add-tag lets me add a tag from the existing tags, or add a new one

As suggested before, I think I'll probably add some other helper commands, things such as:

  • Update the date
  • Set the cover to a particular attachment
  • Insert a particular attachment as a Markdown image
  • Insert a link to another post in the blog

I'm sure more will come to me, but they seem like the most common operations I perform that would be helped with a little bit of Emacs Lisp magic.

Some BlogMore Elisp

2 min read

It's been a moment since I last wrote any Emacs Lisp code, at least anything non-trivial. I've tinkered with my Emacs configuration, I've tweaked the odd personal package here and there, but nothing fresh for ages. I actually can't remember what the last package was that I wrote.

But this morning I realised it would be handy to have a couple of functions in Emacs that let me start a new blog post, or edit an existing one. The code didn't need to be clever, just the bare minimum that gets me started; enough to reduce the friction when it comes to opening a new buffer and starting to write.

So blogmore.el happened. Like I say: nothing clever, it simply adds blogmore-new and blogmore-edit; the former starts a new post with the bare minimum frontmatter filled in, the latter lets me quickly pick an existing post and go edit it.

blogmore-edit in action

As time goes on I might expand on this. For example: it might be useful to have a command that updates the date frontmatter; perhaps another to add a modified1; one to set the category from any of the categories I've used so far would be good; ditto the tags property.

I doubt this will be useful to anyone else, although I will try my best to keep it so that it's easy to configure, so it's only ever going to stay amongst my list of personal packages.

Which reminds me... this is the first personal package I've not bothered to add to delpa. That approach to managing my own packages made a ton of sense at the time, but Emacs has moved on since then. Thanks to use-package and :vc I can easily pull blogmore.el into any of my environments with a simple declaration in my .emacs.d.

(use-package blogmore
  :vc (:url "https://github.com/davep/blogmore.el" :rev :newest))

Given how simple and clean that is I'm minded to "retire" delpa and use this approach for all of my personal packages.


  1. Note to self: did I make BlogMore support modified dates? 

BlogMore v2.0.0

3 min read

Well... I thought I was done with all the major changes with BlogMore, but then a fairly simple request came in and that kicked off a whole load of changes (which in turn ran into one or two problems with GitHub Copilot).

I dived into this because I liked the idea anyway and I think it's time that I, as much as possible, moved the layout of my blog to clean URLs almost everywhere. I can't reasonably do it for actual posts because a) lots of posts point to other posts so there's a whole editing job to do there1 and b) there are some links out there that point to my blog posts2.

The result is BlogMore v2.0.0.

Anyone who's been following the experiment with BlogMore might wonder that the version number is up to v2 already, given it's barely a month old. The answer to that is pretty simple: I'm using semver for the version number and there's a breaking change in this release with no real way of maintaining backward compatibility.

So what's changed? First the simple ones: I added some more *_path configuration options to control the locations of:

All of those keep their default values from before, and so can remain backward compatible. Personally, I've updated the configuration for this blog so that I'm using:

archive_path: "/archive/index.html"
categories_path: "/categories/index.html"
search_path: "/search/index.html"
tags_path: "/tags/index.html"

which, combined with:

clean_urls: true

results in cleaner URLs for all of those site features.

Another thing that came to mind was what to do about pagination. Things like the date-based archives, categories, tags, and so on, can all run to multiple pages and so all generated pages of content using a pagination scheme. This needed its own approach. I decided on adding a setting to control the first page of content (page_1_path) and a setting for all subsequent pages (page_n_path). But there was a problem here: to keep this approach backward compatible I'd need to have different settings per area of the blog. That would mean something like tags_page_1_path, tags_page_n_path, year_page_1_path, year_page_n_path, month_page_1_path, month_page_n_path, and so on; the reason being each one would need its own set of variables so the user can set where {tag} goes in the path, or {year}, or {month}, but one of those is no use in another context, and so on.

All of this would have been total overkill and an unnecessary explosion of things that can and might need to be modified in the configuration file; it would also be a nightmare to document.

So I decided this: the page_1_path and page_n_path settings simply describe what goes on the end of any other URL in the blog, and because of that the defaults would have to be incompatible. I think the result is a lot tidier.

This also felt like a good time to make this change because, aside from one other blog out there, I don't think anyone else other than me is using BlogMore at the moment.

This change did mean that I'd need to edit some of the posts in my blog to update for the slightly changed layout, but it was a small enough job with minimal impact so it was worth it. I also used a tweaked setting for page_n_path:

page_n_path: "/page/{page}/index.html"

so that any paginated page has a URL that ends something like .../page/2/. This holds for any page on the blog that has multiple pages.

This is the point where I'd say something about how I think that's all the big changes in this project done... but I'm starting to suspect this isn't the plan the coding gods have for BlogMore.


  1. Although I suspect I could agent the shit out of that problem

  2. Although few enough that I probably should't let it stop me doing this.