Argonaut Projects' Blog

More Layout

Over time I’ve been working to extend CatTrap more of the modern CSS3 layout formulas, and have now reached a point where I’ve implemented all the main ones I care about! So now’s as good as any to discuss these CatTrap enhancements!

Webform Possibilities

The way I’ve chosen to approach webforms is quite peculiar! I believe in the value of letting readers communicating back to a website & its audience, but rendering these controls inline incurs significant complexity which actively gets in the way of exploring the broader possibilities of browser-design. In exploring how readers can best communicate back via speech or a TV remote I decided to separate webforms out into their own webpage(s) to be handled by a dedicated codepath. I may still render (fully-stylable) form controls inline using the same logic as any other element, but once they’re clicked (like a link) I switch to the separate mode.

Laying out rich, bidirectional text

Between versions and, Balkón was majorly upgraded to support a new range of variation within a paragraph. Text within the same paragraph can now be laid out in a combination of two directions (left-to-right and right-to-left), different fonts with different line heights can be mixed and matched, and parts of the text can be wrapped in inline boxes with added spacing, such as that required for drawing inline borders.

Diagnosing FontConfig

Resuming my struggles to integrate the Argonaut Stack into a “Haphaestus” executable without it freezing or crashing… required some additional tooling! Plus trial and error.

Reading 30MiB of Output

Continuing my efforts to obtain decent performance as I integrate the Argonaut Stack to form the Haphaestus web browser, I’ve now tackled my Harfbuzz language bindings, cutting down on the amount of time copying data into & out of the C library.

Ease of Haskell Concurrency

As I strive to assemble “The Argonaut Stack” together into the “Haphaestus” web browser, I am facing serious performance problems. One thing that made a big difference (even if its not enough on its own) is to parallelize layout calculation accross multiple CPU cores! Because Haskell made this unusually trivial!

Mondrian GPU-Accelerated Rendering

I’ve recently finished implementing Haphaestus’s rendering engine which I named Mondrian, after a dutch artist who liked drawing boxes. This is a GPU-accelerated library for drawing the surrounding backgrounds & borders CSS allows webdevs to add to their pages. Hardware-accelerated text rendering is handled by Typograffiti.


Lists are a powerful way to making complex ideas easier to digest, better than caramel. Auditorily I defined them via a thunk earcon, with or without the insertion of tiered numbering. Visually they’re denoted by preceding each list item by a symbol () or number.

Pagination in text layout

Now that Balkón implements line breaking, the next step is to implement page breaking.

Box Layout

Whereas speech, like for Rhapsode, positions text only in the single dimension of time, Haphaestus positions text in 2-dimensional space. This requires a choice of non-trivial formulas across several tree traversals. In a back & forth negotiation regarding how to size elements for your device.

Building a text layout engine in Haskell

For about two months now, I have been building Balkón, a Haskell library for inline text layout to become part of the Argonaut Stack.

Text Rendering Corrections

Quick note today after having gone back & fixed Typograffiti to work for more text than my demo.

Analytics thoughts

NOTE This is a personal blogpost from Adrian Cochrane, the opinions expressed within are not necessarily endorsed by other contributors to the Argonaut project. And yes, I wrote this one quickly.

Project Services

In developing Haphaestus the sites which gives me the most trouble to support are the silos creatives feel expected to publish on. As such it is in my vested interest to question the value of these silos, leading me to self-hosting our own codeforge.

Writing Language Bindings

I may be striving for simplicity in my browserengine development, but I will not do so at the cost of inclusivity. As such I’ve spent the past couple months (alongside coordinating a growing project) developing pure-functional language bindings for the best available font libraries covering the widest breadth of written langauges. Namely FontConfig & Harfbuzz. Excellent bindings already existed for LibICU, and I wrapped FreeType in an OpenGL-accelerated renderer.

Haphaestus has NLnet Funding!

I am excited to announce: Haphaestus TV web browser has received NLnet funding!

Anonymous/Archived Retweet Regarding Web Complexity

Anonymously retweeting a Twitter thread, which despite its truth got harassed into deletion:

International Day Against DRM

As an upstart browserengine it is my privilege to promise on this International Day Against DRM 2022: Haphaestus will never support Encrypted Media Extensions or any other form of DRM.

Operator Parsing in Haskell

Plenty has happened since I last blogged here, including banging my head against Haskell’s text rendering libraries (hoped to be blogging about that…) & rejigging my plans for Rhapsode & similar browser engines. Now I’m actively taking steps towards turning Rhapsode into a decent browser you can install as an app from your package repositories, as opposed to a browser engine waiting for others to build upon. As part of that I’m commisioning art to have something to display onscreen!

Introducing Amphiarao!

I’ve now implemented the core featureset of (save for a HURL crash which badly needs addressing) a Rhapsode bug-compatible webpage debugger, compatible with Selenium & whatever your favourite web browser is. Even Rhapsode, once I’ve implemented forms for it (coming soon)! All the features Selenium expects are implemented, though where they’re not supported by Rhapsode I wrote noops.

Voice Input Supported in Rhapsode 5!

Not only can Rhapsode read pages aloud to you via eSpeak NG and it’s own CSS engine, but now you can speak aloud to it via Voice2JSON! All without trusting or relying upon any internet services, except ofcourse for bogstandard webservers to download your requested information from. Thereby completing my vision for Rhapsode’s reading experience!

Why (Mostly-)Standard HTTP/HTML/optional CSS?

Modern web browsers are massively complex beasts, implementing an evergrowing mountain of supposedly-open standards few can keep up with. So why do I think I can do better whilst adhering to the same standards? Why do I think that’s valuable?

How Does CSS Work?

Rendering a webpage in Rhapsode takes little more than applying a useragent stylesheet to decide how the page’s semantics should be communicated. In addition to any installed userstyles and optionally author styles.

Why an Auditory Browser?

I thought I might start a blog to discuss how and why Rhapsode works the way it does. And what better place to start than “why is Rhapsode an auditory web browser?”