The Composition Room's ASCII-art panel is backed
by a one-time scrape of asciiart.eu into
jaime's own database.
The app never calls asciiart.eu at runtime — every piece shown in the
panel was fetched once, ahead of time, and served from jaime's D1
database from then on. This page documents that source and the
contract jaime keeps with it.
asciiart.eu organizes its collection as a two-level tree:
animals, computers, movies,
space, video-games, …) — pure indexes, no art on the page itself,
each linking to several leaf subcategory pages.animals/aardvarks,
movies/star-wars) — each renders every piece in that subcategory
inline, with no pagination.Individual pieces also have a permalink at /art/<id>, but that route
is client-side only (for sharing a specific piece) — the scraper never
fetches it, since every field it needs is already present on the
subcategory listing page.
Each piece on a subcategory page is one .art-card element:
<div class="card art-card"
data-id="bfde1f001b31bbe7"
data-title="Sleeping aardvarko"
data-artist="Win Kang"
data-width="60"
data-height="4"
data-views="…">
<div class="art-card__ascii">…raw ASCII text…</div>
</div>
data-id is the site's own identifier — jaime reuses it verbatim as
the primary key, rather than generating a new one, so a piece's
identity matches its source. title and artist are sometimes
missing (a piece can be untitled, or credited to no one); jaime stores
those as NULL rather than inventing a placeholder string.
data-width / data-height are the piece's character-grid
dimensions — how many columns and rows of monospace text it occupies —
which the panel uses client-side to fit each piece to the available
space without measuring the text itself.
Table ascii_art in the shared PATTERNS_DB (migration
0007_ascii_gallery.sql):
| Column | Type | Notes |
|---|---|---|
id | TEXT | Primary key — the site's own data-id. |
title | TEXT | Nullable. |
artist | TEXT | Nullable. |
category | TEXT | e.g. animals. |
subcategory | TEXT | e.g. aardvarks. |
width | INTEGER | Character columns. |
height | INTEGER | Character rows. |
text | TEXT | The raw ASCII art. |
source_url | TEXT | https://www.asciiart.eu/art/<id>. |
scraped_at | TEXT | ISO timestamp of the crawl. |
As of the last crawl: 4,380 pieces across all 26 categories and 355 subcategories.
Two read endpoints serve this table: GET /api/ascii-art/random?count=<n>&category=<c>
(a batch — the panel fetches once and cycles through it locally rather
than hitting the API on every beat) and GET /api/ascii-art/[id] (a
direct lookup, mainly for the attribution link below).
asciiart.eu asks that attribution travel with any reuse of a piece.
jaime honors that in the panel itself: every piece shown carries a
small title — artist link, pinned to the bottom of the panel and
pointing at that piece's source_url — the one interactive element in
an otherwise click-through overlay. It updates on every swap, to match
whichever piece is currently shown.