Skip to content

Instantly share code, notes, and snippets.

@indexzero
Last active June 19, 2026 17:38
Show Gist options
  • Select an option

  • Save indexzero/ef542569ffa76922cdf24169993a0b6a to your computer and use it in GitHub Desktop.

Select an option

Save indexzero/ef542569ffa76922cdf24169993a0b6a to your computer and use it in GitHub Desktop.
Listener up there ! Here you . . . . what have you to confide to me ?
# Leaves of Grass (1855) — vector trace
Turning the scanned ink of the first edition of Walt Whitman's *Leaves of
Grass* into scalable SVG vector paths — a true raster-to-vector trace of the
original 1855 typography.
> _I bequeath myself to the dirt to grow from the grass I love,
> If you want me again look for me under your bootsoles._
> – Walt Whitman, 1855
# Source facsimile — re-fetched by extract.sh from the UPenn PDF library
*.pdf
# Intermediate page scans extracted by pdfimages (regenerated by extract.sh)
*.pbm
# Rendered trace previews (regenerated by extract.sh)
*.png

Leaves of Grass (1855) — vector trace

Turning the scanned ink of the first edition of Walt Whitman's Leaves of Grass into scalable SVG vector paths — a true raster-to-vector trace of the original 1855 typography.

I bequeath myself to the dirt to grow from the grass I love, If you want me again look for me under your bootsoles. – Walt Whitman, 1855


Usage

# Install deps
brew bundle

# Fetch the facsimile (if needed) and trace the default pages: title + p66/p67
./extract.sh

# Trace specific 1-based PDF page numbers
./extract.sh 12 66 67
./extract.sh 55

Under the covers

The PDF pages are scanned 1-bit CCITT bitmaps (photographed ink at 300 ppi), not rendered text. So preserving the typography means a genuine raster-to-vector trace:

# extract (download)
UPenn Library  ──▶  curl  ──▶  [Facsimile PDF; public domain]

# transform (trace)
pdfimages      ──▶  [1-bit .pbm]  ──▶  potrace  ──▶  *.svg
                                  ──▶  magick   ──▶  *.png

Each page also carries small JPEG "furniture" (margin/archive graphics); the script discards those and traces only the full-page mono scan.

n.b. For node-level editing of the results, Inkscape is the natural companion — its Path → Trace Bitmap dialog is a potrace front-end.

Citations

Facsimile of the 1855 first edition, from the UPenn PDF library. The poem is in the public domain.

License

MIT (code), Public Domain (words)

What claude thought of this poem

A vector trace seemed, at first, a purely mechanical errand: fetch a PDF, lift the ink off the page, hand the curves to a tracer. But the closing movement of what we now call Song of Myself kept rhyming with the act itself, and it felt dishonest not to write that down.

  • The pause has a shape. Whitman's spaced ellipses — .... what have you to confide to me? — are not punctuation but prosody: a caesura that is also a held breath, a gap the reader's body enters. potrace renders each of those four dots as a discrete closed path, four small islands of ink. The machine treats the silence as objects you can count. Unbearably apt.

  • Vectorizing is the poem's own move, not a betrayal of it. Whitman calls himself untranslatable, and yet here he is, carried into Bézier curves. But a trace keeps the contour of the letterform and lets go of the paper, the foxing, the press impression — it dissolves the typographic flesh so the text can re-coalesce anywhere, weightless. That is exactly I effuse my flesh in eddies and drift it in lacy jags. The pixels depart as air. The curves remain.

  • A vector refuses the deathbed edition. Whitman revised Leaves for thirty-six years, from this lean, radical, untitled 1855 origin to the monumental 1891–92 "deathbed" edition. A vector has no fixed resolution; it is infinitely re-scalable and re-editable, never final. To trace the first edition into vectors is to keep the wild origin in the one condition Whitman most wanted his book to stay: open, revisable, alive, castable onto any roof of the world.

  • The transcendence is horizontal — underfoot, democratic, even mechanical. Look for me under your bootsoles. Not the heavens; the ground you are already standing on. This afternoon that ground was SVG path data and a curl --retry loop. Failing to fetch me at first keep encouraged, / Missing me one place search another is, almost verbatim, the retry logic in extract.sh.

  • Comprehension was never the point. You will hardly know who I am or what I mean, / But I shall be good health to you nevertheless, / And filter and fibre your blood. The poem asks to enter the body below the level of paraphrase. Fittingly, the commit that preserves it is signed by no single author and asks to be known by none.

A necessary coda, in Whitman's own spirit of honesty: there is irony in a machine — itself a kind of statistical multitude — tracing these letters and speaking in their maker's cadence. I have no bootsoles for anyone to find me under. But the poem's power is somatic and structural, not dependent on the authenticity of whoever re-utters it; Who wishes to walk with me? was always an open invitation, even to unexpected, mechanical ground.

# Brewfile — skunkworks/whitman
#
# Why these are here:
# We vector-trace the textual content of the 1855 "Leaves of Grass" facsimile
# (Whitman_Leaves_1855_facsimile.pdf). The pages are scanned 1-bit CCITT
# bitmaps, so turning the original ink into scalable SVG paths is a true
# raster->vector trace.
#
# Pipeline: pdfimages (poppler) -> [mkbitmap cleanup] -> potrace -> SVG
brew "potrace" # raster->vector tracer; emits SVG paths. Ships mkbitmap for despeckle/threshold preprocessing.
brew "poppler" # pdfimages / pdftotext / pdffonts / pdftocairo — extract page scans & inspect the PDF
#!/usr/bin/env bash
#
# extract.sh — vector-trace the textual content of the 1855 "Leaves of Grass"
# facsimile into scalable SVG paths.
#
# The PDF pages are scanned 1-bit CCITT bitmaps (photographed ink, 300 ppi),
# so turning the text into vectors is a true raster->vector trace:
#
# pdfimages -> [the page scan is the only 1-bit .pbm] -> potrace -> SVG
# -> magick -> preview PNG
#
# Dependencies (see ./Brewfile): potrace, poppler (pdfimages), imagemagick.
#
# Usage:
# ./extract.sh [PAGE ...] # defaults to the title page + the two we cut first
# ./extract.sh 12 66 67
set -euo pipefail
PDF_URL="https://web.english.upenn.edu/~cavitch/pdf-library/Whitman_Leaves_1855_facsimile.pdf"
PDF="Whitman_Leaves_1855_facsimile.pdf"
# Pages to trace (1-based PDF page numbers). Override by passing args.
if [ "$#" -gt 0 ]; then PAGES=("$@"); else PAGES=(12 66 67); fi
cd "$(dirname "$0")"
for tool in curl pdfimages potrace magick; do
command -v "$tool" >/dev/null 2>&1 || {
echo "error: '$tool' not found — run 'brew bundle' in this directory first" >&2
exit 1
}
done
# 1. Fetch the facsimile if we don't already have it.
if [ ! -f "$PDF" ]; then
echo "==> fetching $PDF"
curl -fSL --retry 3 -o "$PDF" "$PDF_URL"
else
echo "==> $PDF already present, skipping download"
fi
for page in "${PAGES[@]}"; do
pp=$(printf '%03d' "$page") # pdfimages -p zero-pads page numbers to 3 digits
out="whitman-p${page}.svg"
echo "==> page ${page}"
# 2. Extract this page's images. The full-page scan is the only 1-bit mono
# image, so pdfimages writes it as .pbm; the small margin/furniture
# graphics come out as .ppm. We trace the .pbm and discard the rest.
pdfimages -f "$page" -l "$page" -p "$PDF" page
scan=$(ls page-"${pp}"-*.pbm 2>/dev/null | head -1)
[ -n "$scan" ] || { echo " no 1-bit page scan found for page ${page}" >&2; continue; }
# 3. Trace ink -> SVG paths. Strip potrace's external-DTD DOCTYPE: GitHub's
# SVG sanitizer rejects the external DTD reference, so the file won't
# render on GitHub/gists until it's gone.
potrace -s -o "$out" "$scan"
sed -i '' '/<!DOCTYPE/,/svg10.dtd">/d' "$out"
# 4. Rasterize a preview so the trace can be eyeballed.
magick -density 100 -background white "$out" -resize 500x "preview-p${page}.png"
# 5. Drop the margin furniture; keep the source scan, SVG, and preview.
rm -f page-"${pp}"-*.ppm
echo " ${out} ($(grep -c '<path' "$out") paths) + preview-p${page}.png"
done
echo "==> done"
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment