Skip to content

Simplify updates to oft-updated text documents

Here on my blog, I've been tracking macOS release dates and rates for nearly 15 years—if I'm doing my math right, I've edited and republished the post 115 times since then. Until the most recent update, all 115 of those updates were pretty much done like this:

  1. Update a Keynote document that calculates the release rate data and contains the two charts in the blog post.
  2. Edit the text of the blog post in a text editor, with Keynote visible, replacing all instances of variable data—dates, numbers, size, rates, etc.—wherever they appear.
  3. Upload the graphs and publish the updated post.

While this isn't an overly complex task by any measure, the second step in particular has gotten more time consuming over the years, because of the length of the post: It now contains over 50,000 characters. That's lots of scrolling and looking for the few bits that change—and I'd often miss a date or a number in some portion of the post.

I thought there had to be a better way, and there is…and of course, the better way uses BBEdit. In particular, BBEdit's support for including one file in another—and using variables in the included file—makes my update task much simpler. If you have text files that receive regular updates, you may find this method of interest, as it can be a big timesaver.

I use BBEdit for a ton of stuff, but I'd never learned about include files and variables until I dug into the manual this morning. Basically, the combination of include files and variables let me create a system that greatly eases updating the release dates blog post. Here's how it works…

An include file is just what its name says it is: A file that gets included in another file. The way you do that is via a reference, like this:

<!-- #bbinclude "filename.txt" -->
<!-- end bbinclude -->

To insert the include file, you use the Markup > Update > Document menu item (or just press ⌃⌘U). When you do, BBEdit inserts the referenced file between the two comment markers, like this:

<!-- #bbinclude "filename.txt" -->
The contents of filename.txt appear here.
More lines here, etc.
<!-- end bbinclude -->

By itself, that doesn't really help me at all. But if you combine include files with variables, then it's a perfect solution. To use variables in include files, you define them in the same comment block where you call the include file. Here's a bit of the one I created this morning:

<!-- #bbinclude "releases_include.html"
#RELEASE#      = "10.15.7"
#REL_DATE#     = "September 23rd, 2020"
#REL_NUM#      = "138"
#REL_SUFFIX#   = "th"
#AVG_REL_RATE# = "53.0"
...
-->
<!-- end bbinclude -->

Once the variables have been defined, the next step is to insert them into the include file. I copied the text from the blog post (excluding the huge data table itself) into an include file ("releases_include.html" in the above code snippet), and then replaced any changeable data with variable references.

As an example, here's the lead-in text from the current version of the blog post:

Updated and republished for macOS 10.15.7; skip it unless you really really care about all the macOS releases. Originally published on November 14th, 2005.

Below the break is a table showing all major releases of macOS (previously Mac OS X) from the public beta through the latest public version, which is macOS 10.15.7, as of September 23rd, 2020—the 138th release in total.

Those lines have three separate items*One is repeated, so they appear four times (shown in red) that need updating. In my include file, I replaced the static text with variable references that match those I created in the include file:

Updated and republished for macOS #RELEASE#; skip it unless you really really care about all the macOS releases. Originally published on November 14th, 2005.

Below the break is a table showing all major releases of macOS (previously Mac OS X) from the public beta through the latest public version, which is <b>#RELEASE#</b>, as of <b>#REL_DATE#</b>—the #REL_NUM##REL_SUFFIX# release in total.

I repeated the process for any other lines with variable data, and saved both files. Now when I use the Update > Document function, the above lines (along with the rest of the variabilized include file) is inserted into my main file (the one where the variables are defined), and the variables are replaced with their defined values:

I can update nearly the entire blog post by just filling in my variable values from Keynote and then using the Update > Document function.

The one bit that's not fully automated is the data table—my update file creates a row for the newest release, which I copy and paste into the right spot. But I then need to edit the second row with a very minor change (removing the column that shows the year), so I do that by hand.*I could spend hours figuring out how to automate this edit, but it's not worth the time investment.

With this method, my editing now takes very little time: I enter the values from Keynote in my main file, use the Update > Document function, then copy and paste three sections into the blog post. I make the one minor table edit by hand, and I'm done. Not only is this much faster and easier, but I won't forget to update one of the always-changing parts again, as they're all defined in the include file.

If you have a text document that gets updated regularly with changing data, you might find BBEdit's includes with variable replacement to be an ideal solution.