How is a .lol or .fun domain more expensive than a .com domain? Is there some discount for being serious I’m not aware of? 🤨
🔗 100 quotes that helped me write
Wish I could remember where I saw this so I can give them a HT. But there are some excellent quote here in this list prepared by Austin Kleon.
Started rewatching Andor last night. Wow, it’s such a great series.
Saw my headphone doppelgänger on the train this morning. In a world where pretty much everyone else is wearing AirPods, it was unexpected to see another wear black JBL E45BT Bluetooth headphones.
I’ve been using UCL a lot recently, which is driving additional development on it. Spent a fair bit of time this evening fixing bugs and adding small features like string interpolation. Fix a number of grammar bugs too, that only popped up when I started writing multi-line scripts with it.
It’s said that “short cuts make long delays”. The beauty of software is that you get to experience those delays over and over again. 😏
Like the Australian Open. Not because of the tennis, but because for two weeks, the tram I take home is rerouted to go directly to Southern Cross station, saving me from making a large road crossing. A very small improvement to my day.
Oof, my Python skills have atrophied quite badly. I’m trying to write a script and I’m forgetting fundamental things like how to interpolate variables within strings, or which standard library packages are used to do what. It’s not like I can’t look this stuff up, but it’s really slowing me down.
On Slash Pages Verses Blog Posts
Interesting discussion on ShopTalk about slash pages and whether blog posts may make more sense for some of them. Chris and Dave makes the point that blog posts have the advantage of syndicating updates, something that static pages lack on most CMSs. It’s a good point, and a tension I feel occasionally. Not so much on this site, but there’ve been several attempts where I tried to make a site for technical knowledge, only to wonder whether a blog or a wiki makes more sense. I’d like the pages to be evergreen yet I also like to syndicate updates when I learn new stuff.
I’ve currently settled on the blog format for now, and it’s fine — tags tend to help here — but I wonder if something smarter could be useful here. One idea I have is to have a page with “sections” where each one could be seen as a mini blog post. You add and modify sections over time, and when you do, each section would be syndicated individually. Yet the page will be rendered as a whole when viewing it in the browser. It’s almost like the RSS feed contains diffs for the page, albeit something self contained and readable by humans. There might be a CMS that does this already, I haven’t looked. But I get the sense that most RSS feeds of wiki pages actually contain a diff, or a simple message saying “this page has been updated.” There’s nothing to suggest that what’s out there has this sections semantics.
In lieu of that, I like the idea proposed by Chris and Dave where you basically new versions of these slash pages as blog posts and redirect the slash URL to the latest one, kind of like a bookmark. I may start doing these for some of them, starting with /defaults which is, conveniently, already a blog post.
One crummy thing about the move to SPAs is that website’s no longer expose query URLs. I wanted to add a Raycast quick link to search for a 2-letter country code, but ISO’s search uses AJAX or something, and there’s no way to run a search directly from a URL. Or at least I didn’t see one.
Oh dear. I’m eying a domain that’s priced at $370.00 /year. Not sure the revenue from my idea — currently estimated to be $0.00 /year — will cover that cost. I think there’s a business word for such discrepancies. 😬
I only just discovered that you can use your finger to annotate screenshots in iPadOS. Go to the options menu and turn on “Draw with Finger”. I actually had no idea it was possible to make annotations without using a pencil. Why this is off by default when there’s no pencil nearby is beyond me.
I kinda feel for UI designers. If you were asked to come up with a menu icon for showing reading mode, font size settings, and accessing the page menu with other miscellanea, which gliph would you use? I’d say that the one chosen for Safari is a little confusing, but I really cannot blame them.
Project Update: DSL Formats For Interactive Fiction
Still bouncing around things to work on at the moment. Most of the little features have been addressed, and I have little need to add anything pressing for the things I’ve been working on recently. As for the large features, well apathy’s taking care of those. But there is one project that is tugging at my attention. And it’s a bit of a strange one, as part of me just wants to kill it. Yet it seems to be resisting.
About 6 months ago, I started working on some interactive fiction using Evergreen. I got most of the story elements squared away but much of the interactive elements were still left to be done. And as good as Evergreen is for crafting the story, I found it a little difficult tracking down all the scripts I needed to write, debug and test.
So in early November, I had a look at porting this story over to a tool of my own, called Pine Needle (yes, the name is a bit of a rip-off). Much like Evergreen, the artefact of this is a choose-your-own-adventure story implemented as a static webpage. Yet the means of building the story couldn’t be more different. Seeing that I’m more comfortable working with code and text files, I eschewed building any UI in favour of a tool that simply ran from the command line.
But this meant that I needed someway to represent the story in text. Early versions simply had the story hard coded in Go, but it wasn’t long before I started looking a using a DSL. My first attempt was a hand-built one based on Markdown with some additional meta-elements. The goal was to keep boilerplate to a minimum, with the meta-elements getting out of the way of the prose. Here’s a sample of what I had working so far:
// Three dashes separate pages, with the page ID following on.
// Also these are comments, as the hash is reserved for titles.
--- tulips-laundry-cupboard
You open the cupboard door and look at the shelf
above the brooms. There are a couple of aerosol cans up there,
including a red one that says "Begone Insecticide".
You bring it out and scan the active ingredients. There are a
bunch of letters and numbers back there, and none of them have
the word "organic."
\choice 'Take Insecticide' to=tulips-take-insecticide
\choice 'Leave Insecticide' to=tulips-leave-insecticide
--- tulips-take-insecticide
You return to the tulips with the insecticide, and start
spraying them. The pungent odour of the spray fills the air,
but you get the sense that it's helping a little.
\choice 'Continue' to=tulips-end
--- tulips-leave-insecticide
You decide against using the can of insecticide. You put the
can back on the shelf and close the cupboard door.
\choice 'Look Under The Trough' to=tulips-laundry-trough
\choice 'Exit Laundry' to=tulips-exit-laundry
The goal was to have the meta-elements look like LaTeX macros — for example, \option{Label}{target-screen}
— but I didn’t get far in finishing the parser for this. And I wasn’t convinced it had the flexibility I wanted. LaTeX macros relies pretty much on positional arguments, but I knew I wanted key-value pairs to make it easier to rely on defaults, plus easier to extend later.
I did imagine a fully LaTeX inspired DSL for this, but I quickly dismissed it for how “macro-heavy” it would be. For reference, here’s how I imagined it:
\screen{tulips-laundry-cupboard}{
You open the cupboard door and lo ok at the shelf
above the brooms. There are a couple of aerosol cans up there,
including a red one that says "Begone Insecticide".
You bring it out and scan the active ingredients. There are a
bunch of letters and numbers back there, and none of them have
the word "organic."
\choice{Take Insecticide}{to=tulips-take-insecticide}
\choice{Leave Insecticide}{to=tulips-leave-insecticide}
}
\screen{tulips-take-insecticide}{
You return to the tulips with the insecticide, and start
spraying them. The pungent odour of the spray fills the air,
but you get the sense that it's helping a little.
\choice{Continue}{to=tulips-end}
}
\screen{tulips-leave-insecticide}{
You decide against using the can of insecticide. You put the
can back on the shelf and close the cupboard door.
\choice{Look Under The Trough}{to=tulips-laundry-trough}
\choice{Exit Laundry}{to=tulips-exit-laundry}
}
I wasn’t happy with the direction of the DSL, so I looked for something else. I briefly had a thought about using JSON. I didn’t go so far as to try it, but the way this could work is something like this:
{"screens": {
"id": "tulips-laundry-cupboard",
"body": "
You open the cupboard door and look at the shelf
above the brooms. There are a couple of aerosol cans up
there, including a red one that says \"Begone Insecticide\".
You bring it out and scan the active ingredients. There
are a bunch of letters and numbers back there, and none of
them have the word \"organic.\"
",
"options": [
{
"screen":"tulips-take-insecticide",
"label":"Take Insecticide",
},
{
"screen":"tulips-leave-insecticide",
"label":"Leave Insecticide",
}
]
}, {
"id":"tulips-take-insecticide",
"body":"
You return to the tulips with the insecticide, and start
spraying them. The pungent odour of the spray fills the air,
but you get the sense that it's helping a little.
",
"options": [
{
"screen":"tulips-end",
"label":"Continue"
}
]
}}
I generally like JSON as a transport format, but it didn’t strike me as a format that suited the type of data I wanted to encode. Most of what this format would contain would be prose, which I’d prefer to keep as Markdown. But this would clash with JSON’s need for explicit structure. Setting aside the additional boilerplate this structure would require, all the prose would have to be encoded as one big string, which didn’t appeal to me. Also no comments, especially within string literals, which is a major deal breaker.
So, the current idea is to use something based on XML. This has some pretty significant benefits: editors have good support for XML, and Go has an unmarshaller which can read an XML directly into Go structures. JSON has this too, but I think it’s also a pretty decent format for at editing documents by hand, so long as you keep your XML elements to a minimum.
I think one aspect that turned people off XML back in the day was format designer’s embrace of XML’s ability to represent hierarchical data without leaning into it’s use as a language for documents. The clunky XML documents I had to deal with were purely used to encode structure, usually in a way that mapped directly to an domain’s class model. You had formats where you need 10 nested elements to encode a single bit of information that were a pain to read or edit by hand. These were usually dismissed by the designers with promises like, “Oh, you won’t be editing this by hand most of the time. You’ll have GUI design tools to help you.” But these were awful to use too, and that’s if they were available, which they usually were not (did you know building GUIs are hard?)
If you have an XML format that skews closer to HTML rather than something that’s representable in JSON, I think it could be made to work. So yesterday I had a go at seeing whether it this could work for Pine Needle. Here’s what I’ve got so far:
<?xml version="1.0">
<story>
<screen id="tulips-laundry-cupboard">
You open the cupboard door and look at the shelf
above the brooms. There are a couple of aerosol cans up
there, including a red one that says "Begone Insecticide".
You bring it out and scan the active ingredients. There
are a bunch of letters and numbers back there, and none of
them have the word "organic."
<option screen="tulips-take-insecticide">Take Insecticide</option>
<option screen="tulips-leave-insecticide">Leave Insecticide</option>
</screen>
<screen id="tulips-take-insecticide">
You return to the tulips with the insecticide, and start
spraying them. The pungent odour of the spray fills the air,
but you get the sense that it's helping a little.
<option screen="tulips-end">Continue</option>
</screen>
<screen id="tulips-leave-insecticide">
You decide against using the can of insecticide. You put the
can back on the shelf and close the cupboard door.
<option screen="tulips-laundry-trough">Look Under The Trough</option>
<option screen="tulips-exit-laundry">Exit Laundry</option>
</screen>
</story>
The idea is that the prose will still be Markdown, so things like blank lines will still be respected (the parser strips all the leading whitespace, allowing one to easily indent the prose). Attributes satisfy the key/value requirement for the elements, and I get the features that make this easy to modify by hand, such as comments and good editor support.
I think it’s going to work. It would require some custom code, as Go’s unmarshaller doesn’t quite like the mix of prose and declared <option>
elements, but I think it’s got the bones of a decent format for this interactive fiction. Already I’m coming up with ideas of how to add script elements and decompose fragments into sub-files to make it easier to test.
I’ll talk more about this project in the future if I’m still working on it. I don’t know if the story that started all this will see the light of day. I’ve gone through it a few times, and it’s not great. But shipping stuff you’re proud of comes from shipping stuff you’re not proud of, and given how far along it is, it probably deserved to be release in one form or another. That’s probably why it’s been saved from the chopping block so far1.
-
Yes, this is probably just a rationalisation for trying to minimise sunk-costs, but I’ve got nothing else to work on, so why not this? ↩︎
Trying out the use of XML over a home made domain-specific language and… I must concede, it might be a better fit. As clunky as the DOM is, XML can be made to be good, as long as you use it in moderation.
Finally putting some money into a decent chair for my desk at home. The one I have is showing its age, not to mention loosing its comfort. Who would’ve though a sub $100 desk chair from Officeworks would be lacking in quality? 😛
Interesting odometer reading this evening.
Gallery of Fake Logo For Test Organisations
In lieu of anything else, I thought I’d put together a gallery of the logos I use for test organisations. I occasionally need to create fake organisations for testing at work, and to add a bit of amusement to the mix, I sometimes make fake logo for them. These logos are typically made using ChatGPT, although if I’m particularly bored, I sometimes touched them up by hand (nothing too drastic, usually things like cropping or adding titles). Most of the fake organisation are film and media production studios, as that’s typically the client base of our product.
I do this mainly for fun, but there is some utility to it. A user can be a member of zero or more organisations, and can change the one they’re acting in at any time. Having a unique avatar for each one helps in distinguishing which one I have active. I do get cute with the names, and for that, I make no apologies. 🙂
Had another look at how I could export an Obsidian kanban board as an actual kanban board today. I thought I’d through ChatGTP at the problem, and see whether it could produce a Go program that took the markdown representation of a kanban board and reproduce it as a HTML file.
Here was the prompt I used:
Please write a Go program which will take a Markdown version of an Obsidian kanban note, parse it, and convert it into a HTML page.The markdown representation of a kanban note is as follows:
- A H2 header represents a column, with the H2 text value representing the column name.
- Between each successive H2 header are the cards for that column. Each one begins as a TODO item. The card contents is indented and can be any arbitrary Markdown.
The generated HTML must have the following traits:
- Each column must be wrapped within a div.
- Each card within that column must be wrapped with a separate div.
- The body of each card must be rendered from Markdown as HTML.
The tool must take the Markdown as standard in, and write the HTML to standard out.
ChatGPT came up with something, and after checking it for obvious errors, I prepared a test board and gave it a run. Here’s the test board I used:
Here’s how it was rendered in HTML:
A good first attempt, and I was impressed at how it actually styled the page to actually display the columns as columns1. I was not expecting that. There were a few things that were missing, such as rendering card bodies. In fact, a keen observer may note that some of the TODOs that appear in the In Progress column actually come from the card body itself.
I requested these changes from ChatGPT and it had another go. And this is where it ran into trouble:
One issue was that the generated code decided to scan the input line-by-line, and maintain state as to whether it’s parsing a column heading, card title, or a card body. But it was not properly resetting this state when encountering the next column header (note how “#blocked Will not do” appears below the In Progress heading when it should be in the card above it). This also explains why the columns no longer showed up — there were divs that weren’t being closed.
So it was time for me to take over. I fixed a few bugs and added handling of the card body indentation. The end results looks like this:
Good enough for what I need.
All in all, it was an interesting experiment getting ChatGPT to start this off, and I’m impressed on how much it managed to do from the jump. But I’d be hesitant to say that what it produced is high quality, maintainable code. It was a little difficult to change, and it’s certainly wouldn’t be the way I’d choose to do it. If this was anything more than something for my own use, I probably would’ve junked it and started from scratch2. But hey, it works. And for what I need, it’s better than not existing at all.
If anyone’s interested in seeing the code, you can check it out here.
Saw hot air balloons out flying this morning. Usually I see them in autumn, yet we’re not even half way through summer. Probably the earliest in the calendar year I’ve seem them operate. That said, it’s pretty good conditions for them this morning, if not a little warm.