Oliver Roick

Oliver Roick Homepage

I'm a software engineer based in Melbourne, Australia. I enjoy building geospatial web applications for science and non-profit communities.

I currently work at Development Seed. In the past, I delivered projects for Google, The Nature Conservancy, NASA, The World Bank, Citizens Advice and many others.

Latest posts

Setting Colours in Xterm.js

Because you can't just use CSS, here's how specify 24-bit colours in ANSI.

Xterm.js is a JavaScript library that can be used to build terminal-like user interfaces. We use it in jupyterhub-fancy-profiles to display the output from the custom-image build process.

Xterm.js comes with a reasonable set of predefined colours; red for errors, yellow for warnings, and so on. At the same time the colours are static, and when used with a dark background, the contrast between the specified colour and the background is too low, thus rendering the text hard to read.

Overwriting the default colours in Xterm.js is possible, but it’s not straightforward, especially if you have a web-development background and are used to specifying colours in hex or RGB.

Xterm.js, like all terminal implementations, uses ANSI escape codes to alter the colour of a line in terminal. The colours in the Xterm.js theme need to be specified in the same way, using the pattern

\x1b[38;2;{red};{green};{blue}m

Breaking down the sequence:

  • \x1b[ is the Control Sequence Introducer, or CSI; it signals that the following sequence should be interpreted as an ANSI escape code,
  • 38 signals that we want to change the text colour,
  • 2 means we want to provide a 24-bit colour, and
  • {red}, {green}, {blue} are the values in each individual channel.

Consequently, the ANSI equivalent to color: rgb(248, 113, 133) in CSS is \x1b[38;2;248;113;133m.

To specify custom colours for a Xterm.js instances we alter the theme:

const term = new Terminal({
  theme: {
    red: "\x1b[38;2;248;113;133m",
    green: "\x1b[38;2;134;239;172m",
    yellow: "\x1b[38;2;253;224;71m",
    blue: "\x1b[38;2;147;197;253m",
    magenta: "\x1b[38;2;249;168;212m",
    cyan: "\x1b[38;2;103;232;249m",
  }
});

usePrevious Implementations in Comparison

Subtle differences in implementation can lead to bugs on your application.

There are rare cases where you need access to the previous value of a state variable. usePrevious hooks allow us to store and access the previous value of a state. There are different implementations, not all created equal.

The UI framework Chakra includes an undocumented usePrevious implementation that looks like this:

export function usePrevious<T>(value: T) {
  const ref = useRef<T | undefined>()
  useEffect(() => {
    ref.current = value
  }, [value])
  return ref.current as T
}

The previous value is stored in a ref and the initial value is set in an effect hook on first render. Initially, the previous value will be undefined even if the hook is initialised with a value. On top of that, by using a ref instead of a state, the previous value will be equal to the current value in any subsequent re-renders of the parent component.

The usePrevious implementation of the useHooks library has a similar problem.

export function usePrevious(value) {
  const [current, setCurrent] = React.useState(value);
  const [previous, setPrevious] = React.useState(null);

  if (value !== current) {
    setPrevious(current);
    setCurrent(value);
  }

  return previous;
}

It stores the previous value in an internal state, which solves the problem related to Chakra’s use of ref to store the previous value. But previous is initialised with null, a value the provided state never held.

Both approaches are wrong. We rely on usePrevious to understand what the previous value of a state was. If a state is initialised with a value, the initial previous value should only be undefined or null if the hook was initialised with undefined or null, otherwise it should be initialised with the provided value.

If we are trying to track specific value transitions of the state, say we want to execute a routine only if the state changed from undefined or null to something else, both implementations will cause bugs.

The correct way is to initialise the previous value with the initial value provided to the hook.

function usePrevious(value) {
  const [current, setCurrent] = useState(value);
  const [previous, setPrevious] = useState(value);

  if (value !== current) {
    setPrevious(current);
    setCurrent(value);
  }

  return previous;
}

A Shell Script to Create New Posts for Markdown Blogs

Create new posts for your Jekyll blog without the hassle.

For personal projects, I like to keep things very simple. The blogs I write are published using Jekyll instead of a more sophisticated database-driven application. That way, my stack will be low maintenance, and I can focus on writing.

In Jekyll, blog posts are managed via Markdown files in a specific directory. Each post has its own file. A front matter included in each file contains metadata about the post, such as the title, publishing date, category, and desired layout. Jekyll looks through those files and then generates the site resulting in a set of static HTML pages that can be pushed to a web server.

There’s no user interface (unless you use NetlifyCMS or similar), so creating new posts can be cumbersome. You have to manually create a file, ideally name the file using a slugified version of the post’s title, and then add the preamble with title and the published date in ISO format and anything else your specific setup needs to render the post.

Being the lazy software developer that I am, repetitive and manual work is highly annoying. So I created a simple shell script that asks for the post’s title, creates the file using the slugified version of the title for the file name, and then pre-fills the preamble.

#!/bin/sh

read -p 'Title: ' title
SLUG="$(echo $title | sed -r 's/[\.\, \?]+/-/g' | tr '[:upper:]' '[:lower:]')"
DATE=$(date +"%Y-%m-%d")
DATE_TIME=$(date +"%Y-%m-%dT%H:%M:%S%z")
tee -a src/_posts/${DATE}-${SLUG}.md <<EOF
---
layout: post
date: ${DATE_TIME}
title: ${title}
description:
category:
---
EOF
vim src/_posts/${DATE}-${SLUG}.md

This also automatically opens the new file in Vim so I can start adding content directly.

I invoke the script using make because I like the simplicity of typing make post.

The Pragmatic Programmer

Twenty years after its initial publication, Andrew Hunt’s and David Thomas’ The Pragmatic Programmer is still essential reading.

Every software engineer has opinions about how software should be built. The views are based on experience with a few programming languages, selected frameworks, and a small range of use cases. They make sense for a limited context, and we confuse them with wisdom and happily apply them everywhere. That’s how cargo cults are born.

The Pragmatic Programmer is a book full of opinions. But authors Andrew Hunt and David Thomas have been writing software for forty years, longer than most of today’s software engineers have been alive. The book’s opinions and advice are grounded in experience that forced them to review and change their views over the years, resulting in the updated second editing of The Pragmatic Programmer, published more than 20 years after its first edition from 1999.

The Pragmatic Programmer is a software-development primer focused on building habits that will make you a better engineer, like learning how to use the Shell and chosen IDE efficiently. It talks about building robust software using contracts and assertive programming and ensuring your software won’t become an unmaintainable mess by avoiding common pitfalls like complex class inheritance, coupling of modules and hand-coded configuration. You’ll learn when to refactor (always), and that writing tests aren’t a waste of time. And because software projects usually don’t fail when developers write code, but beforehand during planning, Hunt and Thomas also cover how to manage projects, gather requirements and estimate.

This book is language- and framework-agnostic. The programming languages used in the examples throughout the book vary from JavaScript, Ruby and Python to C++. Any patterns included are generic and can be applied to many scenarios, whether you build applications for the Web or mobile phones.

The Pragmatic Programmer is essential reading. You will find a ton of advice on how, generally speaking, you can be a better software engineer, advice that will hold up at any stage of your career. For new members joining your team, ditch the bag of useless welcome swag and buy them a copy of The Pragmatic Programmer. It’s better for the individual, your team, and the environment.

From the Portfolio

Building Resilience Index

Hazard mapping and resilience assessment for building projects and property portfolios.

A2O Search

Find bird sightings across Australia using recorded audio. Like Shazam, but for birds.