• Blog
  • Categories
    • App Store
    • Benchmarks
    • iOS
    • Objective-C
    • OS X
    • PHP
    • RV
    • Swift
    • tvOS
    • Web
  • Apps
    • Portfolio
    • Studio Pro
    • Sun & Moon
  • Photography

Projects

Remote Working, iOS, Mac OS X, and more

Computer Science

Detours: When the Best Way Forward Isn’t Forward

Scope creep is Nemesis to software development, yet it is also responsible for some of the best tools and features I’ve built. The danger, though, is not taking detours but failing to recognize the difference between a distraction and an investment.

Every once in a while, you run into a problem that isn't really part of your project, but solving it first makes everything afterward better. Sometimes you hit unexpected bugs, sometimes priorities change, and occasionally, something surfaces so glaringly obvious that it would be stupid to ignore. Those are detours worth taking.

I ran into exactly that while writing the announcement post for Sun & Moon 2.0. It was an unusually visual update with much of the story in the contrast between the old interface and the new one: how information had been reorganized, how the hierarchy had changed, and how the same data had become easier to understand at a glance. Presenting each screenshot at full width, one after another, would communicate the individual changes, but not necessarily the relationships between them.

I had the content, but what I didn't have was a way to lay out the post as I wanted it within the Markdown syntax I've been using. As I've increasingly been doing lately, and somewhat ironically because traditional web searches have become increasingly cluttered with AI-generated SEO spam, I asked an LLM what options existed for adding layout support to Markdown.

Comparison of the post in Markdown and Quarto

The Limits of Markdown

I've written my blog posts in Markdown for years. It's difficult to beat for long-form writing, and I like it in particular because the source is clean, readable, and, best of all, portable. That is, until you want to do something beyond paragraphs, lists, and images.

Need two images side by side? A callout? What about a multi-column section? Standard Markdown intentionally avoids those kinds of layout features. Its original goal was not the layout of the content but the markup itself: formatting choices like bold, italic, lists, links, and so on.

Technically, you can always drop into raw HTML — that's one of Markdown's strengths — but after adding enough <div>s, CSS classes, and nested markup, something starts to feel backwards. The document slowly transforms from Markdown with a little HTML into HTML with a little Markdown sprinkled throughout. At that point, it loses much of what makes Markdown enjoyable to write in the first place.

MARKDOWN ONLY

Sun & Moon 2.0 is a major refresh focused on modernizing the app and
making conditions easier to read at a glance. Nearly every part of the
experience has been revisited, from the daily dashboard and widgets to
the artwork, location management, and support for unusual astronomical
events around the world.

[![Download on the App
Store](https://assets.ryanbritton.com/wp-content/uploads/2026/07/10082810/appstore.svg)](https://itunes.apple.com/us/app/sun-moon-sunrise-sunset-moonrise/id1063155431?ls=1&mt=8&at=1l3uZQL)

----------------

## A Cleaner Dashboard

The Today view puts the essentials front and center. A refined forecast
list makes upcoming sun and moon events easy to scan, whether you're at
home or halfway around the world. ![Today at a Glance: Sunrise, sunset,
moonrise, and moonset right at the top, Smarter Forecast: denser,
cleaner list that handles unusual days with ease, Built for Everywhere:
accurate times for places and seasons with extreme sun and moon
events](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130105/features.png)

![See the current moon phase and illumination at a glance, plus the next
full or new
moon](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130115/moon.png)

MARKDOWN WITH HTML

Sun & Moon 2.0 is a major refresh focused on modernizing the app and making conditions easier to read at a glance. Nearly every part of the experience has been revisited, from the daily dashboard and widgets to the artwork, location management, and support for unusual astronomical events around the world.

<div class="text-center">
[![Download on the App Store](https://assets.ryanbritton.com/wp-content/uploads/2026/07/10082810/appstore.svg)](https://itunes.apple.com/us/app/sun-moon-sunrise-sunset-moonrise/id1063155431?ls=1&mt=8&at=1l3uZQL)
</div>

----------------

<div class="post-columns post-columns-align-middle">
<div class="post-column-33">
<div class="header-flair">
NEW
</div>
## A Cleaner Dashboard

The Today view puts the essentials front and center. A refined forecast list makes upcoming sun and moon events easy to scan, whether you're at home or halfway around the world.
</div>
<div class="post-column-67">
![Today at a Glance: Sunrise, sunset, moonrise, and moonset right at the top, Smarter Forecast: denser, cleaner list that handles unusual days with ease, Built for Everywhere: accurate times for places and seasons with extreme sun and moon events](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130105/features.png)
</div>
</div>

![See the current moon phase and illumination at a glance, plus the next full or new moon](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130115/moon.png)

This is not really a failure of Markdown: avoiding layout is part of its appeal. Markdown gives text enough structure to be useful without burying it beneath layout instructions.

The trouble begins when the presentation itself carries meaning. Two screenshots placed beside each other communicate comparison differently than the same screenshots stacked across a scroll. A callout visually separates an aside from the main narrative. Columns can establish relationships that ordinary document flow cannot.

In the Sun & Moon post, layout wasn't just decoration; it was part of how I wanted to explain the update.

Discovering Quarto

One of the first suggestions after asking for alternatives was Quarto. I had never heard of it before, but the LLM provided a syntax example that looked like a natural extension of Markdown, so I dug in.

Screenshot of a log showing the initial Quarto recommendation

What caught my attention was not simply that Quarto supported columns. HTML already supported columns. It was that the source still looked like a plain-text Markdown document, now with a vocabulary for layout.

Quarto is something of a superset of Markdown. It preserves the familiar Markdown syntax for text, links, lists, images, and code while adding a richer vocabulary for structuring documents. Fenced divs and attributes make it possible to express richer structures such as columns, callouts, tabbed content, figures, captions, cross-references, citations, and more sophisticated code blocks. Beyond layout, it can also execute embedded code, generate computational output and charts, and publish the same source into formats ranging from HTML and PDF to presentations and entire websites.

Not all of that is desirable for web-based publishing, for obvious reasons, but the layout features were exactly what I wanted. More importantly, they still felt like textual markup, and the source remains readable as a document rather than gradually turning into a collection of nested HTML elements.

MARKDOWN ONLY

## A Cleaner Dashboard

The Today view puts the essentials front and center. A refined forecast list makes upcoming sun and moon events easy to scan, whether you're at home or halfway around the world.

![Today at a Glance](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130105/features.png)

![The current moon phase](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130115/moon.png)

Markdown-only preview

QUARTO

::::: {.post-columns .post-columns-align-middle}
:::: {.post-column-33}
::: {.header-flair}
NEW
:::
## A Cleaner Dashboard

The Today view puts the essentials front and center. A refined forecast list makes upcoming sun and moon events easy to scan, whether you're at home or halfway around the world.
::::
:::: {.post-column-67}
![](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130105/features.png){alt="Today at a Glance"}
::::
:::::

![](https://assets.ryanbritton.com/wp-content/uploads/2026/07/09130115/moon.png){alt="The current moon phase"}

Quarto preview

One Problem Remained

There was just one catch: WordPress didn't understand Quarto.

Quarto’s normal rendering path runs through its command-line tooling. That is reasonable for local publishing, static-site generation, or a controlled build pipeline. It is much less attractive inside a general-purpose WordPress installation, introducing an executable dependency that both complicates deployment and provides a potential vulnerability vector.

One option was to render everything externally using that Quarto CLI tool and paste generated HTML into WordPress. It works, but it's clunky — every edit becomes an export, copy, and paste cycle. It felt like replacing one annoyance with another.

A better option was to implement the portions of Quarto that could live within a web environment. There are plenty of Markdown plugins available, but I couldn't find a single WordPress plugin that let me write Quarto and publish it the same way I'd been publishing Markdown for years.

There was an obvious question at this point: was any of this actually worth doing? I was trying to publish a blog post. I had somehow arrived at the conclusion that the next logical step was to analyze a publishing system and write a parser for a subset of its syntax in PHP.

This is exactly how software projects spiral out of control.

The easy solution was still sitting there; I could write some HTML, finish the announcement, and move on. It would probably take less time than building even the first version of a plugin.

But I also knew this wasn't the first time I'd been frustrated by the limitations of my publishing workflow. The Sun & Moon post was just the latest reminder of a problem that I had encountered before. I wasn't inventing a hypothetical need or building infrastructure for some imagined future project. I had a real document open in front of me that I couldn't present the way I wanted.

More importantly, the solution wouldn't disappear when I clicked Publish; every future post would gain the same layout tools. The work had an immediate use, a recurring use, and a reasonably well-defined scope.

That was enough to turn it from a distraction into an investment.

The Unexpected Project

At that point, the blog post quietly stopped being my active project. Instead, I started building a new publishing plugin.

The goal was simple:

  • Write posts in Quarto.
  • Let WordPress render them automatically much as existing Markdown plugins do.
  • Preserve the clean authoring experience.
  • Keep my existing publishing workflow intact.

The first question was one of scope. Quarto is more than a Markdown layout extension, supporting executable code cells, notebooks, chart rendering, citations, multiple output formats, project profiles, and an entire publishing system. Reimplementing Quarto in PHP would have been both impractical and completely unnecessary for what I wanted to accomplish.

So, again, I turned to an LLM.

This time, I asked it to analyze Quarto's source and identify the parts of its syntax and rendering behavior that were practical to implement inside a web-based rendering engine. The goal wasn't to clone Quarto but to find a useful boundary: the subset of functionality that could reasonably be interpreted during WordPress post publishing without external processes or a separate build pipeline.

It came back with a practical boundary between what made sense to port into PHP and what should remain the responsibility of Quarto itself.

Initial LLM response for its first pass on implementing the Quarto renderer subset in PHP

Document and layout features such as fenced divs, attributes, columns, callouts, figures, captions, tabsets, and similar structural elements were reasonable candidates. Executable code cells, computational output, chart generation, project profiles, and other features dependent on Quarto's broader toolchain were not.

With that scope defined, I had the LLM take an initial pass at the implementation. Well-defined parser and transformation code is a natural fit for AI-assisted development. Much of the work involves recognizing documented structures, tracking delimiters and attributes, transforming one representation into another, and handling a long list of defined cases. It's tedious code to write manually but is the sort of work an LLM can produce quickly, especially when given an existing implementation to study.

I reviewed the implementation, looking for faulty assumptions, semantic differences, and obvious flaws. Once I was satisfied that the general approach was sound, I started writing the Sun & Moon post with it. I dogfooded it — I wrote the actual article, rendered it, looked at the result, and fixed or adapted the plugin whenever the output didn't match what I expected.

As I went, gaps in the first implementation appeared: image behavior was different in the two markup languages. In ordinary Markdown, the text inside ![...] is treated as alternative text for the image. Quarto gives that same syntax additional presentation semantics and will render it as a visible figure caption. My previous posts had been written with the Markdown interpretation, so it was a surprise when images in the new post suddenly began displaying text beneath them that had been written as accessibility metadata and was never intended to appear visually.

Screenshot of the undesired caption rendering

The parser wasn't broken. It was faithfully reproducing behavior I hadn't fully accounted for, and the solution was already part of Quarto’s design. I expanded the renderer’s attribute support so it worked consistently across every supported element, including explicit alternative text for images. That allowed captions to behave as Quarto intended while preserving accessibility metadata separately.

There were also several tag structures that simply hadn't been covered. These were the kinds of omissions that are easy to miss when analyzing a specification abstractly, and something I've found AI-generated implementations particularly prone to given limited working context. Knowing that, I was already looking for them and caught the gaps early.

This became the development cycle for the plugin:

Diagram of the Quarto plugin dev cycle

In a way, the Sun & Moon announcement became both the reason for the plugin and its first real-world test suite. That process also reinforced a tactic I've increasingly found useful when working with AI-generated code: the initial implementation doesn't need to anticipate every edge case to be valuable. In this case, getting the broad parser structure in place quickly meant I could spend my time evaluating actual behavior and identifying concrete failures early in the process. The initial implementation was inexpensive to produce, so substantial refactoring doesn't carry the same psychological weight as throwing away several days of manually-written code.

It changes the economics of experimentation — I was more willing to alter the parser's structure when real-world use exposed a better approach because I hadn't invested days manually constructing every part of it. Code is code once it exists, but historically the cost of arriving at it has affected how reluctant we are to throw portions away.

The sunk cost of implementation has influenced architecture more than we'd like to admit. After spending several days writing a subsystem, it's difficult to objectively decide that half of it should be rewritten. When the initial implementation takes an hour instead, those decisions become easier to make. The code still deserves scrutiny, but it becomes emotionally cheaper to improve.


The LLM was very good at producing the machinery. My role increasingly shifted toward deciding whether that machinery behaved correctly: defining expected behavior, recognizing semantic differences, and deciding when compatibility was more important than convenience. Writing the parser by hand would have consumed much of my attention with implementation details. Generating that structure quickly moved the difficult part of the work elsewhere.

The end result preserved the workflow I wanted from the beginning: write the source, publish it through WordPress, and let the renderer handle the conversion automatically

Diagram of the Quarto WordPress publishing flow

The plugin now supports the subset of Quarto I needed for the article. It is not, and isn't intended to be, a PHP reimplementation of Quarto. It supports the document and layout features that make sense when rendering a WordPress post while deliberately leaving Quarto's computational and project-oriented features to the real tool.

It's not something I'm ready to call finished, though. At the moment, I'd describe it as somewhere between alpha and beta quality. It works well for the syntax I've exercised while writing real content, but the supported subset still needs broader testing and more time spent probing combinations I haven't personally needed yet.

I do intend to release it once I'm confident the boundaries are clearly documented and the functionality it claims to support has been adequately tested.

For now, though, it does exactly what this particular detour required: it let me get back to writing the blog post.

The Value of Good Detours

Software development is a discipline where progress isn't always measured by moving directly toward the finish line. Sometimes the best way to complete a project is to stop working on it — not because you've become distracted, but because you've recognized another route worth taking.

There are detours that are just procrastination in disguise. I've taken plenty of those, too. Sometimes, though, a project exposes a weakness in your tools, or an idea occurs that can vastly improve future undertakings. When that happens, inventing a tool, fixing a bug, or adding a new feature idea can become the highest-value work you can do.

It requires judgment to know which detours to take, the kind of judgment that develops with experience. The original project still waits, and when you come back, the work is easier and better. Not just this time, but every time afterward.

Developers are particularly good at convincing ourselves that tool-building is productive. Why spend ten minutes doing something manually when you can spend three days automating it?

Sometimes that’s a joke. Sometimes it’s the correct decision. The difference is whether you’re solving demonstrated friction or imagined friction. In this case, the friction was sitting directly in front of me. I had an article I wanted to present a certain way, a publishing workflow that repeatedly got in the way, and a solution that would remain useful after the article was finished.

If you'd looked over my shoulder, it probably would have seemed like I'd abandoned a nearly finished announcement to wander into an unrelated plugin project. I hadn't. I was still working toward the same result; the path just wasn't straight.

The finished blog post is better because of a plugin that didn't exist when I started writing it, and that's often how many worthwhile projects actually unfold. Many posts on this site have stemmed from those projects, one idea begetting another.

It's not always a straight road from idea to completion. Sometimes it is. Sometimes inspiration hits, randomly. With worthwhile detours, when you finally return to the original road, you find you've improved the road itself.

Scope creep will likely always be Nemesis to software development. Most of the time, she's right. Every so often, though, she accidentally points you toward a better way of building the thing you were trying to build all along.

  • 1
  • 2
  • 3
  • …
  • 110
  • Older Posts

Copyright 2026 Ryan Britton