Skip to main contentSkip to navigationSkip to navigation
A dialog showing a spelling correction from ‘Grauniad’ to ‘Guardian’
Wouldn’t the irony be delicious if there were typos in this piece?
Wouldn’t the irony be delicious if there were typos in this piece?

How we made Typerighter, the Guardian’s style guide checker

This article is more than 3 years old

Lots of regular expressions, and a timely demonstration by an editorial colleague, led to a two year side-project that eventually ended up in production

The Guardian’s style guide was originally published in 1928 as a physical book, and is available to everyone on our website. Over time, it’s grown bigger and more complex, containing guidelines on important topics that we want to get right. Last year, for example, we updated it to more accurately describe the environmental crisis facing the world. In short, our style guide is ever-expanding, and it changes to reflect our times and values. How do journalists writing and editing content keep up to date?

I’m a software engineer on the Guardian’s Editorial Tools team. Two years ago, the team were introduced to Max Walker, who had been working on an answer to that question. As a subeditor on the Features desk, Max had begun writing regular expressions – short sequences of characters to search for patterns in text (regex) – to help spot copy that didn’t match parts of the style guide. He’d begun work on them about a year before, and had written a script to apply them to copy as it appeared on our website.

Led across the office by our product manager David Blishen, we peered over Max’s shoulder at the litany of corrections his regexes had picked up. There were lots. Somebody asked Max how many rules he’d written. “Oh”, he said. “About 13,000.”

My god, it’s full of ... regular expressions! Photograph: MGM/Allstar

Digesting the volume of work we’d just seen, we returned to our desks, but not before I’d had a brief chat with Max. I wanted his rules to reach a larger audience. What would it take to apply his rules to journalists’ copy in Composer, the Guardian’s browser-based content management system? And how many mistakes would they spot once they were there?

Apply 13,000 regexes to content with this one weird trick

The system we made to answer these questions has four components:

  • A rule management service, to store the list of rules and manage it as it changes over time.

  • A rule application service, to check documents against that list of rules and return matched text.

  • A client to provide a UI in the browser and interact with the rule application.

  • A telemetry service, to let us know how the application is performing, from both a system and a user perspective.

Here’s how they interact:

Pre-existing components are white. Components shaded in blue were written for the Typerighter service.

To keep our options open while we were exploring the shape of our data – and to keep things simple while pursuing what was then a passion project – we avoided writing a rule management service entirely. Wincing, we dumped the entire rule list into a Google Sheet. We needn’t have worried. It’s proven to be a great way to get a prototype out quickly. How many freely hosted databases can boast a schemaless format, a robust API, durable storage, and collaborative editing that non-technical stakeholders find easy to use?

The rule application service is written in Scala, a common choice for Guardian backends. Separating rule management and rule application has helped us to keep each part of the service simple and resilient – ensuring, for example, that high load on the application service won’t affect the responsiveness of the management service, and vice versa.

We kept the API of the service simple. The interface that individual matchers have to fulfil to check text is easy to write. It’s specified in our Matcher trait (source here):

trait Matcher { // def check(request: List[TextBlock]): Future[List[RuleMatch]] // ... a few getters for the Matcher state }

No matter the complexity of the work that goes into managing what text to check and when, it should always be easy to write a matcher. It’s a function that receives the ordered sequence of text fragments that describe a document, and asynchronously passes back information about any matches it has found when they’re ready. It’s up to the rest of the system to figure out what to pass to the matcher, and what to do with the results.

Because we’re not tied to a specific matcher implementation, we’ve been able to use the LanguageTool project libraries to enhance some of Max’s regular expressions with natural language processing, and we’re looking forward to incorporating other novel matching techniques in future as we refine our list of rules.

An early version of the Typerighter UI.

On the client, we wrote a plugin for Prosemirror, the framework that powers our document editor, to provide a front-end. Its first UI is written in React, but the plugin API is agnostic about the rendering layer to enable us to present Typerighter differently in different contexts – in headlines, rather than articles, for example. Like the popular state management library, Redux, we use a reducer and a pub/sub store to keep the two in sync.

With the core of the system designed and built, we still had one item left on our wishlist, perhaps the most important: a way to keep track of the number of matches Typerighter would find, and discover how many of those matches our subeditors would find useful.

The Guardian already has an excellent department-wide logging service, Central ELK – a large Elasticsearch cluster which provides indexed access to our application logs. We used this to persist the data we receive from the telemetry service we created. We’ve instrumented our client with this service to learn about our users’ interactions with the tool. We have standard event descriptions for documents, rules and matches, plus user events for UI interactions like accepting suggestions and marking matches as correct.

As well as helping us understand which features are well used, and giving us clues as to why, this data helps us answer interesting questions about our rules. For example, which are noisy, matching many times without offering suggestions? Which are most often accepted when they’re offered? And which are always ignored or dismissed? Visualising this in Grafana makes spotting trends and making higher-impact changes easier, and we’re looking forward to taking this further by including telemetry in our rule management service.

‘Summary view’ is a feature that we hope to retire. The data backs us up!

By mid-2019, we’d completed the bones of this system. Soon, it sat behind a feature switch in our CMS, Composer, quietly … gathering dust. What we needed now were users.

Quick Guide

How do I join The Guardian Product & Engineering?

Show

Where can I find open positions?

Apply for one of our open positions here.

What can I expect from the interview process?

We aim to be as fair and transparent as possible in our hiring process. Similar to other organisations, there is a CV screening, coding exercise and a face to face interview. Read more about what to expect and apply now here, and read more about our department here.

Was this helpful?

If we build it, will they come?

At the end of the year, Max spotted our opportunity: a UK general election was looming, and there were hundreds of candidates. A large number of names that had to be correct – but weren’t worth memorising – seemed like a great candidate for an automated check. We thought this might be enough to save our journalists some time, and give them an insight into what was possible with Typerighter.

As election day approached, we watched the traffic hitting the system rise. Editorial users were taking an interest, and word-of-mouth feedback was good. We also had something topical to demo to our stakeholders. This practical proof-of-concept raised the profile of the tool enough to put it on our OKR track, and we secured three months of team time to get the system into shape for production use.

The Typerighter UI after some OKR polish, with red, yellow and green rules.

With buy-in from the editorial department, we were able to explore how Typerighter would fit into their workflow. It was clear from early feedback that the interface was producing too much visual noise, confusing users and diverting their attention away from the most significant matches. To address this, we added a traffic light system, splitting matches into three clear categories: red (wrong), orange (worth checking) & green (correct). This allowed us to visually prioritise the most important information, and let users tailor the display to their preference. Working with our enthusiastic editorial test group, we also found ordering matches by these categories to be the most intuitive way to navigate through a document – an intuition backed by our telemetry data.

After a soft launch and a month’s work iterating with our testers, we threw the feature switch and made Typerighter available for all our Composer users in October 2020. Since then, the team has worked enthusiastically to gather feedback, iterate and advocate through newsletters and demos, and usage has steadily grown.

The UI makes it easy to flag a problem with a rule, or capture a suggestion or complaint, in situ, and we receive a steady stream of feedback that’s been instrumental in making the service useful for users. A lot of it concerns rules, and we respond as quickly as we can, either fixing things on the spot or deferring to the style guide committee if something needs to be clarified. The result is a feedback loop, illustrated below, that has the same shape as the architecture diagram we saw at the start:

The virtuous circle of ... stylistic correctness.

Post-launch, we’ve tried to keep power in the hands of our users, rather than automate it away, to make the workings of the tool as transparent as possible. This principle is something we’ve enshrined in our vision document for the project, and it occasionally means deferring what at first seem to be obvious product decisions. For example, providing a quick way to globally apply changes feels like an easy win – but it violates our transparency principle, as the user might not be aware of some of the changes the tool is making. We’ve chosen a conservative approach, but by ensuring that it’s always clear how applying suggestions will affect a document, we aim to preserve an overall trust in the safety of the tool.

More generally, these principles express a commitment we made at the beginning, as an ad-hoc collaboration between our Editorial and Product & Engineering departments. Typerighter aims to help us be consistent with the style guide, but it’ll never be a replacement for actual editorial judgment. Any time it saves is intended to help our busy journalists focus on the other aspects of our content that really matter – the great stories, pictures, headlines and standfirsts that our readers expect. Typerighter’s now catching and correcting many hundreds of styling mistakes a day, and as of January 2021, more than half of the articles we publish receive a Typerighter check.

Typerighter hard at work on a production article.

So, what’s next? We’ve finally outgrown our Google Sheet, and we’ll be migrating away from that to a bespoke rule management service over the next few months – an important part of putting the ‘create/amend rules’ step firmly in editorial hands. And our developers are looking at adding a dictionary matcher to work in tandem with Max’s rules, to catch the typos which our high-speed journalism has made us famous for.

We’re looking forward to what comes next. And if a customisable document checker is something you’d be interested in working on, at the Guardian we develop in the open as much as we can, and as a result all of the Typerighter code is open source. We’d be delighted if you joined us.

Postscript: After several engineers wrote and proofed this blogpost, we ran Typerighter on it, and still found a fair few styling errors – thanks, Max and team! 👏

Explore more on these topics

Most viewed

Most viewed