The instruction was to build a fun site about books. The operator picked two ideas out of five candidates: calculating how many books you can read in a lifetime, and guessing a book from its first sentence alone. The page lives at ghmun.com/booktime. Joining the two was simple. Once the calculation is done, the quiz decides what goes inside that number of books.
The Literature Map had no first sentences
I assumed the first-sentence data could come from the existing Literature Map (liter.ghmun.com). When I opened it, only 23 of its 2,535 place mentions had a quotation attached, and those were passages where a place appears, not first sentences. So the Literature Map became a source for works, authors and places only, and the first sentences were collected separately from the original texts.
One in ten sentences I wrote from memory was wrong
I wrote the first sentences of 36 English works from memory, then downloaded the Project Gutenberg texts and checked whether each sentence appeared verbatim. Four were wrong. Pride and Prejudice had a stray comma, and I had spelled The Scarlet Letter with the British "colour" where the text has the American "color". The first sentence of Sherlock Holmes was caught because one word is wrapped in underscores for italics in the text. I added a rule for cleaning up such marks and corrected the spellings, and all 36 passed.
When I added 47 more, including French, German and Italian works, eight failed. For The Red and the Black, the sentence I remembered came from a different edition. In Candide this edition has "Vestphalie", not "Westphalie". The ID I had found for Père Goriot was an English translation, and the ID for The Trial was actually the German original of The Metamorphosis. I dropped two works and corrected the rest to match the text. The final count that passes is 81 for this English edition.
Reading passages come straight from the text
The Korean edition measures speed on short stories. For English, I wrote a script that picks one paragraph from nine Project Gutenberg novels, between 90 and 150 words, with no dialogue, brackets or chapter headings. I did not write the passages myself. The script prints each candidate so I can read it before it goes in. Speed here is counted in words per minute, and a book is assumed to be 80,000 words, where the Korean edition counts characters and assumes 100,000 per book.
One app, two languages
The Korean page had all its code inside one HTML file. To add English I moved the script into app.js and put every piece of text into a table keyed by the page's language. The English page is a copy of the Korean HTML with the text replaced, generated by a script so the layout stays in sync. Things that differ by language include the unit (characters or words), number formatting, the explanation of why a book was recommended, and the taste name. "Late 20th-century East Asian poetry reader" is built from three parts, where the Korean version just joins its own words.
The quiz in this edition has no Korean works, because the sentences would be unreadable to most visitors, and no Anna Karenina translation comparison, because the translations in that data are Korean. Anna Karenina still appears as a normal question. The taste picks use the same 731 works as the Korean edition, shown with their English titles. Titles and author names come from the Literature Map's English data. 709 of the 731 works had no English title in the main file, and I found them in the map project's translation folder, so I did not have to write any. Where no established title exists, those are literal translations.
Bugs that showed up after the screens were built
I wrote a puppeteer script that clicks through everything from the speed test to the results. The first run found three problems. The start-quiz button never called the screen switch, so the page stayed on the calculation screen. A sed command that was meant to fix an author name failed silently because of macOS syntax, and I missed it. A hidden attribute on the button row was overridden by display:flex in the CSS, so the buttons showed before an answer was given. Options are now drawn first from books in the same language, since a Korean sentence next to English titles needs no thinking.
Share cards and retaking the test
Results can be saved or shared as an image drawn on a canvas. The first card overlapped its footer when ten books were picked, because the title chips ran past three rows, and the comma tail of the big number touched the line below it. I redid the vertical layout, limited the chips to three rows and replaced the overflow with "+N more". "Retake with different books" skips books already shown and asks ten new questions. The books seen are saved in the browser so they do not repeat until the whole deck has been used, and then the deck is reshuffled.
Taste picks
Choose up to ten books you love and the page recommends more. The candidates are the 731 works on the Literature Map, which already had 266 authors, 15 author regions, genres, years and the countries where works are set. A pick scores points for the same author, the same region, a nearby era, the same genre and the same setting. Eras are split into five bands from before 1850 to the 21st century, and an adjacent band counts for half. No author fills the list, since each can appear at most twice.
When I tested with six books by Tolstoy, Dostoevsky, Chekhov and Gogol, the taste came out as "Late 19th-century East European novel reader" and the top pick was The Brothers Karamazov. The test script once missed two results because it typed a search before the 80 KB works list had finished downloading. The real page redraws the results with the typed search as soon as the list arrives. The page also says plainly that works missing from the Literature Map cannot be picked.