Noah Doersing


I'm Noah Doersing, and I've just finished studying media informatics (M.Sc.) in Tübingen. Before long, I'll be looking for a job – hit me up if you’ve got one to spare somewhere in southern Germany!

In my own time, I sometimes (re)tweet things, work on various open-source projects (see below), make generative art (see above), take pictures on my phone and less frequently with proper cameras, listen to music by independent artists, and grow chilis.

On my blog, dubbed Excessively Adequate, I write about programming and adjacent subjects.



No, this isn't some amazing text-recognition machine learning framework for mathematics – it's much more mundane: A JavaScript-based UnicodeMath to MathML translator that integrates with Markdeep to make UnicodeMath immediately usable in day-to-day document authoring. What's more, it's trivial to deploy UnicodeMathML in arbitrary websites (along with MathJax for rendering) or even server-side with Node.js.

UnicodeMath is an easy-to-read linear format for mathematics initially developed as an input method and interchange representation for Microsoft Office. It relies on Unicode symbols like ∮ taking the place of control words like \oint, improving plaintext readability over notations like (La)TeX. Its author, Murray Sargent III, has published a Unicode Technical Note detailing the format, based on which this translator was built.

The initial development of UnicodeMathML was part of my Master's thesis.

The UnicodeMathML Playground, originally built as a development tool, along with two well-known formulas expressed in UnicodeMath. Get familiar with it here!


Satellite imagery like the kind available on Google Maps and competing services can be extremely beautiful and interesting. Built with the goal of powering my Twitter bots @americasquared and @placesfromorbit, the Python-based ærialbot generates a random point within the bounds of a shapefile, grabs satellite imagery of a user-defined area around it at a user-defined scale, stitches the downloaded map tiles together into an image, and optionally tweets it along with geotagging metadata.

I had previously built gomati, a bash script that served as a proof-of-concept for ærialbot.

A sample of the kinds of images @americasquared tweets.

The command-line interface of ærialbot.

Several Markdeep-based "Office Applications"2019–now

Morgan McGuire's Markdeep is a JavaScript library that, when included at the bottom of a Markdown file, automatically converts it into HTML when the file is opened it in a web browser. Primarily for the purposes of writing and presenting my Master's thesis, I've built several browser-based tools that postprocess Markdeep's output:

markdeep-slides splits a document into presentation slides, provides presentation controls via keyboard shortcuts, displays presenter notes, supports different themes, and offers PDF export.

markdeep-thesis utilizes Bindery to divide a Markdeep document into pages, with footnotes, a table of contents with page numbers and other affordances. It provides an opinionated stylesheet for (under)graduate theses based on my own Master's thesis.

markdeep-diagram-drafting-board provides instant preview for Markdeep's ASCII art diagrams as the user "draws" them.

The diagram drafting board in action. Try it out here!

A scatter plot (in a way) showcasing some pages of a thesis typeset with my homebrew tool.

Crop Circles2020

Having previously built a tool for downloading aerial imagery in the form of ærialbot, I found myself drawn to depictions of center pivot irrigation – a method of efficiently watering crops that invariably produces large circles visible on satellite maps. Intending to produce a series of videos, I required some tooling for swiftly and precisely cropping center pivot irrigation fields from aerial imagery, with predefined margins and while keeping associated geotags intact.

Crop Circles is a purely-client-side web app that does exactly what I wanted while being highly configurable, user-friendly, fast, and robust – all selections made by the user are persisted in local storage across reloads (and can be exported and imported) to reduce the chance of data loss. But stop reading and try it out here – I've taken care not to limit it only to my use case!

The UI of Crop Circles. The sidebar can be scrolled, revealing many knobs and toggles. The interface element in the bottom right helps with precise alignment of the current selection.

A basic video composed of images cropped with this tool.

You can find more elaborate videos on YouTube. In order to add title cards, end cards, and geotags for each image, I wrote another program that makes use of the excellent MoviePy library.


I happen to read a bunch online. Unhappy with aspects of existing read-it-later offerings like Instapaper and Pocket, I wrote my own PHP-based tool for keeping a reading list, maintaining a searchable archive along with a list of favorites, and analyzing when, what, and how much I've read in a given time period – one insight, for example, was that the number of articles read per day follows an exponential distribution.

It's been in continuous use since 2013 and I've logged more than 20,000 articles so far while extending it to cover my varying use cases throughout the years.

The list of unread articles ReAD presents upon initial load, shown here in a desktop browser. Because I hadn't been diligent about clearing out old stuff from my unread queue at the time the screenshot was taken, a reading suggestion is shown at the top.

ReAD on mobile devices – of course there's a dark mode.

Cellular Automata Poster Generator2017

Stephen Wolfram's elementary cellular automata operate on a one-dimensional list of cells, computing future states of cells based on their neighboring cells. Drawing such states in order from top to bottom yields interesting patters, and with some color, they can make for attractive wall art. I wrote a Python script that, based on a design by Reddit user /u/collatz_conjecture, generates cellular automata posters as PDFs.

Later, I adapted this script to run the Twitter bot @sundryautomata – a sample of its outputs is shown below.

Some of the images generated by @sundryautomata.


After coming across Martin Kleppe's excellent creative coding environment, where you can animate a 16×16 grid of dots using a single JavaScript function, I had the idea of adding a third dimension by mashing it up with David DeSandro's equally-excellent pseudo-3D engine Zdog.

My tweet announcing the result, imaginatively dubbed tixyz, went slightly viral – according to Twitter analytics, more than 50,000 folks saw it in just a few days, with some of them finding pretty interesting functions.

Here's tixyz in action – try it out here!

Handwriting Recognition with SQL2018

Modern implementations of SQL (with window functions and recursive CTEs) are Turing complete, enabling the formulation of arbitrary programs. To demonstrate this, I've implemented an admittedly-ancient handwriting algorithm in SQL. This work was done as part of Torsten Grust's SQL is a Programming Language seminar at Uni Tübingen.

Earth Across Time2020–now

After coming across Google Earth Timelapse, a self-described "global, zoomable video that lets you see how the Earth has changed over the past 34 years" and having previously developed ærialbot (see further up), it seemed only logical to build @earthacrosstime – a Twitter bot that documents how randomly selected parts of the world have changed since 1984.

To this end, I had to reverse-engineer how to access the correct video tile for a given point. Dealing with some of MoviePy's intricacies in order to to automate adding annotations to the videos also took some puzzling.

An example video tweeted by @earthacrosstime, documenting the construction of Incheon Airport.

Apple Photos Export2018–now

The macOS variant of Apple's Photos app uses an unencrypted SQLite file as its metadata storage backend. Through reverse-engineering the structure of this database and the associated directory structure in which the photos themselves are located, I was able to write a Python script that exports a Photos library based on a set of conventions I prefer for my personal backups.

I use this tool for exporting photos taken with my iPhone, notably including the video components of live photos.


In early 2020, I've built myself a little BrachioGraph pen plotter. I'll readily admit that I haven't come up with the design nor devised the software that controls it, however I have written a basic turtle drawing program for it.

Dubbed Brachiosaurus, this Python-based command-line program 1. emits an SVG preview of the user-defined drawing if running on my laptop or 2. draws it on paper if running on the the Raspberry Pi driving the plotter. What's more, I've documented my escapades on Twitter.

A timelapse video of my BrachioGraph as it draws a piece of generative art specified with my Brachiosaurus tool.

Minecraft Server Utilities2016

I intermittently run a local Minecraft server on an old laptop running Ubuntu. For this purpose, I've written a couple of bash scripts that start the server on system boot in a screen session for convenient remote management, keep an up-to-date incremental backup of the world and server files, as well as daily snapshots for nostalgia purposes, with old snapshots optionally being culled whenever disk space runs low.

Tumblr Themes2012–2017

Back in the early 2010s, when the microblogging platform Tumblr hadn't yet gone the way of MySpace, I designed and coded a few themes that users could install on their blogs through the integrated Theme Garden. Collectively, my themes have been installed on thousands of blogs over the years and are still in more-or-less active use on a few hundred.

Screenshots showing how some of the themes might appear – most of them feature customizable colors.

...and more!

The above is just a selection of stuff I've been working on recently. You can find more, especially older projects and limited-scope utility scripts, on my GitHub account. Maybe there's something that will prove useful for you!


Available upon request until it becomes a bit more interesting – so far, it's really only education plus teaching assistance at the Database Systems Research Group at Uni Tübingen.


Want to get in touch? Feel free to drop me an email to the address that the following JavaScript snippet evaluates to.

((crypt) => {
    const rot13 = c => {
        c = c.codePointAt(0);
        let d = c + 13;
        if (d > (c <= 90 ? 90 : 122)) {
            d -= 26;
        return String.fromCodePoint(d);
    const backwards = s => s.split("").reverse().join("");
    return backwards(crypt.replace(/[a-z]/gi, rot13));