Posts tagged with "Gemini Protocol"

Rogallo v3.2.0

1 min read; 7 GFI

I've just bumped Rogallo to v3.2.0. This release has one small new feature and one wee bug fix.

The new feature is something I found myself wanting a short while ago. I was copying some URIs and then turning them back into Gemtext links in another document; after doing that a few times, I realised that it might be handy to extend the "copy URI" facility in the viewer so that there's a "copy URI as Gemtext" version. To this end, I've added gemtext_link.copy_link_as_gemtext as a viewer widget binding, bound to Shift+c by default.

The fix is a small one to how MIME type checks are done. In one particular case, Rogallo wasn't stripping off any parameters where it should have. This is now fixed.

Rogallo v3.1.0

2 min read; 10 GFI

Rogallo v3.1.0 is now available. This release is in response to a recent user request.

Right from the start of the development of Rogallo, I ensured that any MIME types that the application couldn't handle were correctly handed off to the operating system, to allow it to work out what to do. While it is possible for me to do some work to allow images inline -- something I might explore at some point in the future -- Rogallo doesn't currently support this and, accordingly, when faced with image/jpeg or image/png, etc, it delegates to the wider environment.

The problem, of course, is that the user might not have a tool in their environment that's capable of taking over the duties of downloading an image from a gemini URI and displaying it. So the next best thing is that Rogallo itself offers to download the file for you. With v3.1.0 this is now an option.

If you encounter a MIME type that hasn't already been marked for always opening in an external tool, there's a new Download button.

Download as an option

If selected, you'll be asked for a location to save the file.

The download dialog

To augment this, I've also added downloading support for links in the viewer. It might be, for example, that you've already marked image/jpeg and image/png as MIME types that should always be handed off to the operating system (perhaps you have a GUI-based client such as Lagrange or Major Tom installed and it's configured to pick up the URI and handle it). In that case, you'd never be shown the dialog that would allow for downloading. So now, on the occasion that you do want to download within Rogallo, you can navigate to the link and press d. The download dialog will then appear, and you can save the content of the link that way.

ℹ️ Note

If you want to change the binding for the link-based download, you can use the recently added UI element binding facility to bind gemtext_link.download_link to something else.

For now, at least, the download process is pretty simple. It follows the same approach as acquiring the content of a URI for display purposes, but instead writes it to the file you picked. There's no "download manager" or similar and no sticky "download directory". These are things I might consider adding in the future.

Rogallo v3.0.0

3 min read; 10 GFI

It's been a while since I last published an update to Rogallo. In part this is because I've had other distractions, but also in part because I've not had a huge need to add any new features of late. For the most part I feel Rogallo is "done"1.

I haven't, however, been doing nothing with the code. On and off, over the last handful of weeks, I've been addressing something that I've wanted to tidy up since the early days of development: application configuration. The majority of my Textual-based applications use a simple JSON configuration file, and that's generally good enough. When I started Rogallo I used the same approach. Rogallo has since grown quite a lot and there's much that can be configured and so the "honking great pile-o-JSON" approach was starting to feel quite untidy.

So Rogallo v3.0.0 addresses this. The headline change is that the single JSON file has been replaced with a number of focused YAML files, and some items that were in the original configuration file have been moved out to either the data directory or the state directory, depending on their purpose.

Now for some details on the changes.

❗ Important

There are a lot of changes to how Rogallo is configured. As is mentioned at the end of this post, Rogallo will make a best effort to migrate your old configuration to the new format. However, as a precaution, you might want to think about making a backup copy of your configuration.json file before upgrading Rogallo.

Focused configuration files

As mentioned above, whereas before Rogallo kept all of its configuration in a single file, it now looks to a number of different YAML files that focus on a different aspect of configuration. These include:

General configuration

For the configuration items that remain, that aren't exactly focused on a particular Rogallo feature, the settings have moved to general.yaml.

Removal of some application commands

Rogallo's design is based around the idea of some "actions" being application-wide commands, and some actions being UI-control-specific. As I worked through the configuration changes I decided that it was time to "demote" some application-wide commands to either being UI-control-specific bindings or just simple configuration properties. With this in mind I've removed the following commands:

  • ChangeCommandLineLocation
  • StripeLinks
  • ToggleANSIEscapeSequenceHandling
  • ToggleCosyLinkNumbers
  • ToggleEmojiRemoval
  • ToggleLinkNumbers

All but ChangeCommandLineLocation are now keyboard shortcuts specific to the viewer widget itself (press F1 when the viewer has focus to get more details). ChangeCommandLineLocation is now a simple configuration property in general.yaml.

UI element action keyboard bindings

From the very start, Rogallo has supported some degree of control over keyboard bindings. As mentioned above, there's a split between "application-wide commands" and "UI-element-specific" actions. Until now it's always been possible to configure the bindings for the former, but never the latter.

In other words: you could always configure the binding for the HandOffToOperatingSystem application command (hands the URI of the currently-viewed document to your OS), but you couldn't change the in-viewer binding for the o key, which opens the URI of the focused link in the OS.

Rogallo v3.0.0 adds support for changing the bindings of the latter. So if you wanted to change o to b for opening a URI externally:

gemtext_link.open_link_externally: b

You can find the bindable IDs for each of the UI controls at the bottom of each page for each of the controls.

New Gophermap badges

Not directly a configuration setup change, but something I noticed while doing the work, was the fact that Rogallo (and the underlying Gophermap library) didn't handle PNG and RTF item types. They're now directly supported.

Conclusion

I believe all of the above changes make it easier to configure Rogallo, and more importantly easier to backup and share the configuration. Technically all of this is one huge breaking change -- everything that was in configuration.json now lives elsewhere. However, I've added some code to Rogallo that detects when you still have a pre-v3.0.0 configuration active, loads up the values, creates the new files, and then renames the old file to configuration.migrated.json. As mentioned near the start of this post, you might want to think about making a backup copy of configuration.json before upgrading.


  1. One last big thing I do want to add is support for tabs. Still to come. ↩

Rogallo v2.4.0

1 min read; 10 GFI

I've released Rogallo v2.4.0, which contains two new features.

The first is the addition of a feature related to the Gemini Protocol, and it's something I've been meaning to add for a wee while: a trusted host browser/manager. It's a simple enough idea: you might want to have a look at all the host/port pairs that exist in your trusted hosts list and, perhaps, revoke the trust for one or more.

The trusted host browser

From the dialog you can either visit the host/port combination (perhaps you got curious about what you've trusted in the past and want to see what was there), or you can forget the trust. This also somewhat follows on from work done in Rogallo v2.1.0, except rather than having to make the decision when you visit a capsule, you can review all the capsules you currently trust.

If this seems useful, it's called up with the new BrowseTrustedHosts command, bound to Ctrl+Shift+t by default.

The second new feature is something that's been on my TODO list for quite a while, and has mainly been sat there because I wanted the viewer widget in the application to settle down a bit before I tackled this. I'm talking here about in-viewer search. It's a simple enough requirement, but one that's not that straightforward when you're dealing with views of different kinds of text files, views of the source of such documents, and also having to handle things like embedded ANSI escape sequences.

The work is now done, so if the viewer itself is focused, you can press Ctrl+f, enter some text to search for, and then press Ctrl+n to keep moving through all the hits. Once you hit the last match, you'll be told there are no more matches, but then the search will start again from the top.

Performing a text search

You can also cancel an ongoing search with Ctrl+Shift+f.

I'm glad to finally get this added to Rogallo as it's a feature I've been finding myself needing on a good few occasions.

Rogallo v2.3.0

2 min read; 8 GFI

Rogallo v2.3.0 is now available. The main addition to this release is support for the Titan Protocol.

First up, there's a small fix. The other day I discovered Scriptonite. While looking at the examples I noticed none of them worked with Rogallo. This struck me as odd because the whole point of Scriptonite is that it all happens on the server-side; nothing on the client-side should affect how well it works.

It turns out that Wasat had a bug when it came to slicing and dicing Gemini URIs, where parts of a URI that followed a ; were being lost. Somewhat amusingly, I didn't even need to do any work on a fix because it had already been taken care of in the branch that existed to support Titan.

The point here being: as of v2.3.0, Rogallo now works fine with the Scriptonite examples.

As I mentioned, the main change in this release is support for the Titan protocol. It's been on the TODO list for a wee while, partly because I was struggling to follow the idea of it, and also partly because I'd not played with it and just didn't see the purpose. The other day I sat down and properly dived in and it finally all clicked.

With v2.3.0, if you now visit a titan:// URI, you will be presented with a rich input dialog. It is a tabbed view, with one tab being for text input/upload:

Titan text entry

and the other being a file attachment and upload:

Titan file upload

As per the Titan specification, there is support for setting the MIME type for the attached data. If using the text view, this will always be set to text/plain. If using a file attach/upload, you have full control over it, but it will default to the best guess based on the file selected.

There is also support for entering an upload token.

As well as supporting the core Titan specification, I've also added support for the proposed ;edit extension. This means that it is safe to enable Titan-based editing on bbs.geminispace.org, making it easier to modify text you've already written.

Editing a post with Titan

One final change in this release of Rogallo also relates to user input. I've given the Gemini-based input dialog an overhaul. Originally this was, by design, as simple and as bare-bones as possible. It was simply a free-text input box that would grow as you added lines, and the prompt from the server was shown as a title in the border of that box. While testing out editing on BBS, I realised that this doesn't always work so well; most of the time the prompt would get truncated.

The input prompt being truncated

Not a great user experience. The redesigned input box works more or less the same, but now ensures that the prompt is fully visible.

The new version of the input box

Between this change and the new Titan edit/upload dialog, I feel Rogallo is now in a good position to act as a near-zero-compromise daily driver when it comes to wandering around the small web.

I guess adding tabs will get it closer to zero. Perhaps in-terminal image viewing. Okay, perhaps a sprinkle of http(s) support too? Also...

Wasat v1.9.0

1 min read; 10 GFI

The work to add Titan support to Rogallo is going well, and I've been able to test it out fine on bbs, doing additions of "long text" and performing file uploads. In doing so, though, I was reminded that there is a proposed "edit" extension to Titan, which is supported there (and I believe on a couple of other capsules too). That got me thinking...

Wasat v1.9.0 is now available, which adds support for this extension. Of most use is the is_edit property which has been added to TitanURI, giving a well-defined approach to testing whether a Titan URI is for editing a resource. The Client class has also grown an edit method to handle the request for the raw content which will then be used as the basis for a subsequent edit by the user, before being uploaded.

All of this, of course, pushes back the work I'm doing on Rogallo, just a little. As I said above, the Titan support is pretty much there and working, but now I want to try and really dial it in and get it working "just so". While the edit support is probably pretty niche, it seems worth adding and, I hope, might delight someone one day when they try it out and it "just works".

Wasat v1.8.0

1 min read; 7 GFI

Another quick little update to Wasat, bumping the version to v1.8.0. This version is in support of some work I'm about to do on Rogallo: Titan support.

This release adds TitanURI and makes a number of changes to handle such URIs alongside GeminiURI. A lucky side-effect is that a problem was uncovered and corrected with how Gemini URIs are sliced and diced in the library. This first showed up for me when I was having a look at the Scriptonite examples. None of them were working for no obvious reason. Eventually it became clear that parts of the URIs were being lost as they travelled through Wasat's code.

So v1.8.0 clears up that problem (fixing the bug in Rogallo by simply upgrading the library).

As of now, I can move on to actually adding Titan support.

Rogallo v2.2.0

3 min read; 10 GFI

Rogallo v2.2.0 is available. This release contains a handful of small new features and also a very minor cosmetic change.

First to the small cosmetic change: the overall design behind the UI of Rogallo is that it's split into a couple of key panels -- the side-panel and the main viewer. The styling of a panel when focus is within it, and when it is outwith it, is different; the idea being that your eye should be drawn to the active panel. This is an approach I take with all my Textual applications.

Part of this styling is to have a thin border to the left of the active panel, which also helps signify that the panel is the one you should be paying attention to. In applications where there's always two or more panels on the screen all the time, this makes sense -- you want the line between the panels anyway to help break up the content. In Rogallo, however, it's going to be normal to only ever have the one panel in view (the viewer).

The other day I realised that, when it's just the viewer available, I should remove that left-hand border. So that's how Rogallo works now. If the viewer is the only panel visible: no border. If the side-panel is also visible: borders. I think it makes the display look a little cleaner; for what it's worth it also saves one column of the display for something more useful.

I've also added a couple of useful features to the active link in the viewer. Now, when a link is selected, you can press c to copy the URI of that link to the clipboard. You can also press o to open the URI by passing it to the operating system. Both these changes should make it easier to take a link out of a document and go and do something else with it.

The last couple of changes are around visiting finger:// URIs. The first is a quick and simple change: any finger content now makes use of Rogallo's document cache, so if you find yourself navigating back and forth between finger responses, there should be fewer requests made in a short period of time.

I added caching partly in anticipation of another change to finger responses: making them interactive where possible. Having created finger2gemtext, I've updated Rogallo so that, where possible, the response is turned into Gemtext and anything that can be turned into a link is now interactive. This means that some finger services should be easier to navigate, no longer requiring that you copy/edit/paste text to get a fresh finger:// URI to follow.

This can be seen if you visit somewhere like finger://plan.cat or finger://redterminal.org/. Whereas before you would just be shown some plain text:

A plain text finger response

Now you get a version that lets you follow the implied links in the response:

A richer finger response

This is, of course, going to be reasonably brittle. If any of the services change their output format such that the "links" can't be detected any more, the output won't be turned into Gemtext. Likewise, it's not impossible that false positives might turn up. I'm going to run with this for a while and see how it works out. I also have a vague plan for how the detection and smarter rendering of finger responses could be made configurable by the user.

Anyway, that's it for this release of Rogallo. Now I can return to the main change I was making a start on this week: Titan support. I've not so much been putting it off as I have been allowing myself to get distracted by the above changes -- mostly because I don't quite get Titan support yet and I don't have a good location to play around with it. Time to solve that problem...

finger2gemtext - A library for converting finger responses to Gemtext

1 min read; 11 GFI

I've just released the first version of another library in the collection of libraries that support the development of Rogallo: specifically, another one that helps convert text in other formats into Gemtext so Rogallo's display can be a little richer. In effect, this is a sibling to md2gemtext and html2gemtext.

This time it's a library to convert finger responses into Gemtext, where it makes sense. For the most part, finger responses are free-form plain text, but there are times when there's information in the response that would be of most use if you could interact with it. For example, if you get a user list from plan.cat1, that's a lot of data that could be turned into finger:// URIs that can be subsequently followed.

With this in mind, finger2gemtext can take a body of text, look at it to see if it might be possible to convert it to useful Gemtext, and will convert it if that's the case. Given that there's no standard to be had here, and given that any given response could be of any form the author desires, I'm making the conversion pretty conservative.

What I have done, though, is make it so that the conversion process can be extended. The finger_to_gemtext function can be given a collection of additional filtering classes; if the built-in classes can't find anything to convert, the additional classes get a go. There is a base class to inherit from.

I've not fully planned it out yet, but the vague idea I have here is that Rogallo could, at some point, have "finger plugins" which will handle various special cases and site-specific formats.

For now, though, this gives me the basics that let me turn this:

A plain finger response

into something where I can follow finger:// links without the need to copy/paste/edit:

A richer finger response

Now I need to find a few more online finger resources that respond with things worth making linkable...


  1. finger @plan.cat ↩

The effort police

3 min read; 10 GFI

Earlier today I saw a comment on a post on BBS that was really quite disappointing. The post itself was announcing a new Gemini client, in this case a fully-native macOS one called MajorTom. It's early days for the project, but it looks fun. It also looks like the author is having a ton of fun building it.

I can relate. I've been obsessing over building Rogallo since June this year and it's been an absolute blast. I don't see myself getting bored of it any time soon.

The comment that irked me was this:

Got excited, then I saw the AGENTS.md :(

It’s hard to get excited about new software when everything is just AI generated. I miss the old times when you got excited that someone built something. Now it’s just someone wrote a prompt to make a computer build something.

It comes over like some messed-up Calvinist puritanical work ethic thing. Yes, I know all the arguments against the use of AI, you'll find that I agree with a good few of them; but there's something wild about this "you didn't work hard enough to produce the software I might otherwise consider using so I've dismissed it" attitude. I'd say enough with this nonsense, but it's been going on for as long as I've been writing code and I doubt it'll stop any time soon. At every step in the evolution of software development there's always been someone, sat on the sidelines, tutting and judging because someone is using a new tool that makes it easier or quicker to do a thing.

Yes, we know, back in our day...

What also bothers me is how easily the author of the comment belittles and diminishes the work of the author of the application. Sure, there are some folk who will try and one-shot something with a prompt or two, and who might then pass it off as something carefully considered and designed; but it's unfair, perhaps even dishonest, to attribute that to someone when you don't know what process they've gone through.

If I look at Rogallo, for example... AI has been involved along the way. To be clear: 100% of Rogallo is hand-written code, AI has not been involved in writing any of it. I have used Antigravity as an occasional rubber duck to hash out some ideas, but there's zero chance I'd let it anywhere near the code itself1. On the other hand, some of the protocol-based support libraries I've built have heavily involved AI. Even then, I didn't just slap in a prompt and run with the result. I did research, I followed the docs, I read more and more about Gemini and Spartan and Nex, etc. I used an agent to get the code going based on my understanding of the source material and I then used that code to support the main work I actually wanted to be doing.

ℹ️ Note

Thinking about it, here's roughly how it breaks down in terms of actual code written, so far:

  • Rogallo: zero AI
  • bagofstuff: pre-existing but zero AI
  • gemtext: zero AI
  • gophermap: zero AI
  • html2gemtext: zero AI
  • md2gemtext: mostly AI
  • port1900: mostly AI
  • port70: mostly AI
  • port79: mostly AI
  • sybaritic: mostly AI
  • textual_enhanced: pre-existing but zero AI
  • textual_fspicker: pre-existing but zero AI
  • wasat: mostly AI

There's zero chance I could have built Rogallo and all the support code from a position of ignorance. None of it was "just a prompt". Looking at what's gone into MajorTom so far, I doubt that's the case there either.

Anyway, back to the main topic...

I also find an element of entitlement in this comment. It reminds me somewhat of the person who felt they were owed something by FOSS authors. Excitement is not something a FOSS author owes you. You are, of course, welcome to go looking for excitement, but if something you discover doesn't do it for you... it's not for you, move on, go find something else. Announcing that you didn't get excited because someone else got creative in a way you don't approve of just makes you look like you want to centre the discussion around you.

Someone made a thing. Someone shared a thing. Someone posted a thing. You turned up and made it about you. That's kind of rubbish. Don't do that.

It's totally fine to not like the use of AI. It's totally fine to want to avoid anything built with AI or which is somewhat AI-adjacent. I get it: it's good to have your own standards and to stick to them. I would suggest, however, that it starts getting problematic when you need to tell someone having fun with their own free time that they're not doing so in a way that meets your standards. Doing that is kind of weird.

Doing that makes you look like the effort police.


  1. I've yet to see an agent write Textual code I'd consider reasonable. ↩