From 7e38d1f2cce7c3417ac1d710de4a80f58d1ac777 Mon Sep 17 00:00:00 2001 From: John Malone Date: Wed, 8 Apr 2026 18:14:33 -0500 Subject: [PATCH] Deepen Frost and Blake coverage (#219) --- meta/robert-frost/dust-of-snow.yml | 13 ++ meta/robert-frost/fire-and-ice.yml | 13 ++ meta/robert-frost/nothing-gold-can-stay.yml | 13 ++ .../stopping-by-woods-on-a-snowy-evening.yml | 13 ++ ...need-of-being-versed-in-country-things.yml | 13 ++ meta/william-blake/infant-joy.yml | 7 +- .../william-blake/the-clod-and-the-pebble.yml | 13 ++ meta/william-blake/the-garden-of-love.yml | 13 ++ meta/william-blake/the-schoolboy.yml | 13 ++ poems/robert-frost/dust-of-snow.txt | 9 ++ poems/robert-frost/fire-and-ice.txt | 9 ++ poems/robert-frost/nothing-gold-can-stay.txt | 8 ++ .../stopping-by-woods-on-a-snowy-evening.txt | 19 +++ ...need-of-being-versed-in-country-things.txt | 29 ++++ .../william-blake/the-clod-and-the-pebble.txt | 14 ++ poems/william-blake/the-garden-of-love.txt | 14 ++ poems/william-blake/the-schoolboy.txt | 35 +++++ scripts/ingest-gutenberg-frost-depth.mjs | 130 ++++++++++++++++++ scripts/ingest-gutenberg-romantic-depth.mjs | 45 ++++++ site/src/lib/authors.ts | 7 + 20 files changed, 426 insertions(+), 4 deletions(-) create mode 100644 meta/robert-frost/dust-of-snow.yml create mode 100644 meta/robert-frost/fire-and-ice.yml create mode 100644 meta/robert-frost/nothing-gold-can-stay.yml create mode 100644 meta/robert-frost/stopping-by-woods-on-a-snowy-evening.yml create mode 100644 meta/robert-frost/the-need-of-being-versed-in-country-things.yml create mode 100644 meta/william-blake/the-clod-and-the-pebble.yml create mode 100644 meta/william-blake/the-garden-of-love.yml create mode 100644 meta/william-blake/the-schoolboy.yml create mode 100644 poems/robert-frost/dust-of-snow.txt create mode 100644 poems/robert-frost/fire-and-ice.txt create mode 100644 poems/robert-frost/nothing-gold-can-stay.txt create mode 100644 poems/robert-frost/stopping-by-woods-on-a-snowy-evening.txt create mode 100644 poems/robert-frost/the-need-of-being-versed-in-country-things.txt create mode 100644 poems/william-blake/the-clod-and-the-pebble.txt create mode 100644 poems/william-blake/the-garden-of-love.txt create mode 100644 poems/william-blake/the-schoolboy.txt create mode 100644 scripts/ingest-gutenberg-frost-depth.mjs diff --git a/meta/robert-frost/dust-of-snow.yml b/meta/robert-frost/dust-of-snow.yml new file mode 100644 index 0000000..99f72a2 --- /dev/null +++ b/meta/robert-frost/dust-of-snow.yml @@ -0,0 +1,13 @@ +id: robert-frost/dust-of-snow +slug: dust-of-snow +author: Robert Frost +author_slug: robert-frost +title: Dust of Snow +century: 20 +text_path: poems/robert-frost/dust-of-snow.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/ebooks/58611 +public_domain_rationale: 'Public domain in the United States: first published 1923 (pre-1931); text via Project Gutenberg eBook #58611.' +collection_title: New Hampshire +collection_source_url: https://www.gutenberg.org/ebooks/58611 diff --git a/meta/robert-frost/fire-and-ice.yml b/meta/robert-frost/fire-and-ice.yml new file mode 100644 index 0000000..4078591 --- /dev/null +++ b/meta/robert-frost/fire-and-ice.yml @@ -0,0 +1,13 @@ +id: robert-frost/fire-and-ice +slug: fire-and-ice +author: Robert Frost +author_slug: robert-frost +title: Fire and Ice +century: 20 +text_path: poems/robert-frost/fire-and-ice.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/ebooks/58611 +public_domain_rationale: 'Public domain in the United States: first published 1923 (pre-1931); text via Project Gutenberg eBook #58611.' +collection_title: New Hampshire +collection_source_url: https://www.gutenberg.org/ebooks/58611 diff --git a/meta/robert-frost/nothing-gold-can-stay.yml b/meta/robert-frost/nothing-gold-can-stay.yml new file mode 100644 index 0000000..069a07a --- /dev/null +++ b/meta/robert-frost/nothing-gold-can-stay.yml @@ -0,0 +1,13 @@ +id: robert-frost/nothing-gold-can-stay +slug: nothing-gold-can-stay +author: Robert Frost +author_slug: robert-frost +title: Nothing Gold Can Stay +century: 20 +text_path: poems/robert-frost/nothing-gold-can-stay.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/ebooks/58611 +public_domain_rationale: 'Public domain in the United States: first published 1923 (pre-1931); text via Project Gutenberg eBook #58611.' +collection_title: New Hampshire +collection_source_url: https://www.gutenberg.org/ebooks/58611 diff --git a/meta/robert-frost/stopping-by-woods-on-a-snowy-evening.yml b/meta/robert-frost/stopping-by-woods-on-a-snowy-evening.yml new file mode 100644 index 0000000..eb24b6e --- /dev/null +++ b/meta/robert-frost/stopping-by-woods-on-a-snowy-evening.yml @@ -0,0 +1,13 @@ +id: robert-frost/stopping-by-woods-on-a-snowy-evening +slug: stopping-by-woods-on-a-snowy-evening +author: Robert Frost +author_slug: robert-frost +title: Stopping by Woods on a Snowy Evening +century: 20 +text_path: poems/robert-frost/stopping-by-woods-on-a-snowy-evening.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/ebooks/58611 +public_domain_rationale: 'Public domain in the United States: first published 1923 (pre-1931); text via Project Gutenberg eBook #58611.' +collection_title: New Hampshire +collection_source_url: https://www.gutenberg.org/ebooks/58611 diff --git a/meta/robert-frost/the-need-of-being-versed-in-country-things.yml b/meta/robert-frost/the-need-of-being-versed-in-country-things.yml new file mode 100644 index 0000000..cc60465 --- /dev/null +++ b/meta/robert-frost/the-need-of-being-versed-in-country-things.yml @@ -0,0 +1,13 @@ +id: robert-frost/the-need-of-being-versed-in-country-things +slug: the-need-of-being-versed-in-country-things +author: Robert Frost +author_slug: robert-frost +title: The Need of Being Versed in Country Things +century: 20 +text_path: poems/robert-frost/the-need-of-being-versed-in-country-things.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/ebooks/58611 +public_domain_rationale: 'Public domain in the United States: first published 1923 (pre-1931); text via Project Gutenberg eBook #58611.' +collection_title: New Hampshire +collection_source_url: https://www.gutenberg.org/ebooks/58611 diff --git a/meta/william-blake/infant-joy.yml b/meta/william-blake/infant-joy.yml index ec04f99..0262869 100644 --- a/meta/william-blake/infant-joy.yml +++ b/meta/william-blake/infant-joy.yml @@ -4,11 +4,10 @@ author: William Blake author_slug: william-blake title: Infant Joy century: 18 -text_in_repo: true text_path: poems/william-blake/infant-joy.txt +text_in_repo: true source_label: Project Gutenberg -source_url: https://www.gutenberg.org/ebooks/1934 -public_domain_rationale: Public domain (author died 1827; distributed by Project Gutenberg as public-domain text). +source_url: https://www.gutenberg.org/cache/epub/1934/pg1934.txt +public_domain_rationale: 'Public domain in the United States: first published 1789 (pre-1929); text via Project Gutenberg eBook #1934.' collection_title: Songs of Innocence and of Experience collection_source_url: https://www.gutenberg.org/ebooks/1934 -featured: false diff --git a/meta/william-blake/the-clod-and-the-pebble.yml b/meta/william-blake/the-clod-and-the-pebble.yml new file mode 100644 index 0000000..7555b65 --- /dev/null +++ b/meta/william-blake/the-clod-and-the-pebble.yml @@ -0,0 +1,13 @@ +id: william-blake/the-clod-and-the-pebble +slug: the-clod-and-the-pebble +author: William Blake +author_slug: william-blake +title: The Clod and the Pebble +century: 18 +text_path: poems/william-blake/the-clod-and-the-pebble.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/cache/epub/1934/pg1934.txt +public_domain_rationale: 'Public domain in the United States: first published 1794 (pre-1929); text via Project Gutenberg eBook #1934.' +collection_title: Songs of Innocence and of Experience +collection_source_url: https://www.gutenberg.org/ebooks/1934 diff --git a/meta/william-blake/the-garden-of-love.yml b/meta/william-blake/the-garden-of-love.yml new file mode 100644 index 0000000..9d81992 --- /dev/null +++ b/meta/william-blake/the-garden-of-love.yml @@ -0,0 +1,13 @@ +id: william-blake/the-garden-of-love +slug: the-garden-of-love +author: William Blake +author_slug: william-blake +title: The Garden of Love +century: 18 +text_path: poems/william-blake/the-garden-of-love.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/cache/epub/1934/pg1934.txt +public_domain_rationale: 'Public domain in the United States: first published 1794 (pre-1929); text via Project Gutenberg eBook #1934.' +collection_title: Songs of Innocence and of Experience +collection_source_url: https://www.gutenberg.org/ebooks/1934 diff --git a/meta/william-blake/the-schoolboy.yml b/meta/william-blake/the-schoolboy.yml new file mode 100644 index 0000000..a0c96f7 --- /dev/null +++ b/meta/william-blake/the-schoolboy.yml @@ -0,0 +1,13 @@ +id: william-blake/the-schoolboy +slug: the-schoolboy +author: William Blake +author_slug: william-blake +title: The Schoolboy +century: 18 +text_path: poems/william-blake/the-schoolboy.txt +text_in_repo: true +source_label: Project Gutenberg +source_url: https://www.gutenberg.org/cache/epub/1934/pg1934.txt +public_domain_rationale: 'Public domain in the United States: first published 1789 (pre-1929); text via Project Gutenberg eBook #1934.' +collection_title: Songs of Innocence and of Experience +collection_source_url: https://www.gutenberg.org/ebooks/1934 diff --git a/poems/robert-frost/dust-of-snow.txt b/poems/robert-frost/dust-of-snow.txt new file mode 100644 index 0000000..7f4431f --- /dev/null +++ b/poems/robert-frost/dust-of-snow.txt @@ -0,0 +1,9 @@ +The way a crow + Shook down on me + The dust of snow + From a hemlock tree + + Has given my heart + A change of mood + And saved some part + Of a day I had rued. diff --git a/poems/robert-frost/fire-and-ice.txt b/poems/robert-frost/fire-and-ice.txt new file mode 100644 index 0000000..f6a27c9 --- /dev/null +++ b/poems/robert-frost/fire-and-ice.txt @@ -0,0 +1,9 @@ +Some say the world will end in fire, + Some say in ice. + From what I've tasted of desire + I hold with those who favor fire. + But if it had to perish twice, + I think I know enough of hate + To say that for destruction ice + Is also great + And would suffice. diff --git a/poems/robert-frost/nothing-gold-can-stay.txt b/poems/robert-frost/nothing-gold-can-stay.txt new file mode 100644 index 0000000..a807f1a --- /dev/null +++ b/poems/robert-frost/nothing-gold-can-stay.txt @@ -0,0 +1,8 @@ +Nature's first green is gold, + Her hardest hue to hold. + Her early leaf's a flower; + But only so an hour. + Then leaf subsides to leaf. + So Eden sank to grief, + So dawn goes down to day. + Nothing gold can stay. diff --git a/poems/robert-frost/stopping-by-woods-on-a-snowy-evening.txt b/poems/robert-frost/stopping-by-woods-on-a-snowy-evening.txt new file mode 100644 index 0000000..ddd0682 --- /dev/null +++ b/poems/robert-frost/stopping-by-woods-on-a-snowy-evening.txt @@ -0,0 +1,19 @@ +Whose woods these are I think I know. + His house is in the village though; + He will not see me stopping here + To watch his woods fill up with snow. + + My little horse must think it queer + To stop without a farmhouse near + Between the woods and frozen lake + The darkest evening of the year. + + He gives his harness bells a shake + To ask if there is some mistake. + The only other sound's the sweep + Of easy wind and downy flake. + + The woods are lovely, dark and deep, + But I have promises to keep, + And miles to go before I sleep, + And miles to go before I sleep. diff --git a/poems/robert-frost/the-need-of-being-versed-in-country-things.txt b/poems/robert-frost/the-need-of-being-versed-in-country-things.txt new file mode 100644 index 0000000..925e673 --- /dev/null +++ b/poems/robert-frost/the-need-of-being-versed-in-country-things.txt @@ -0,0 +1,29 @@ +The house had gone to bring again + To the midnight sky a sunset glow. + Now the chimney was all of the house that stood, + Like a pistil after the petals go. + +The barn opposed across the way, + That would have joined the house in flame + Had it been the will of the wind, was left + To bear forsaken the place's name. + +No more it opened with all one end + For teams that came by the stony road + To drum on the floor with scurrying hoofs + And brush the mow with the summer load. + +The birds that came to it through the air + At broken windows flew out and in, + Their murmur more like the sigh we sigh + From too much dwelling on what has been. + +Yet for them the lilac renewed its leaf, + And the aged elm, though touched with fire; + And the dry pump flung up an awkward arm; + And the fence post carried a strand of wire. + +For them there was really nothing sad. + But though they rejoiced in the nest they kept, + One had to be versed in country things + Not to believe the phoebes wept. diff --git a/poems/william-blake/the-clod-and-the-pebble.txt b/poems/william-blake/the-clod-and-the-pebble.txt new file mode 100644 index 0000000..14378f2 --- /dev/null +++ b/poems/william-blake/the-clod-and-the-pebble.txt @@ -0,0 +1,14 @@ +‘Love seeketh not itself to please, + Nor for itself hath any care, +But for another gives its ease, + And builds a heaven in hell’s despair.’ + +So sung a little clod of clay, + Trodden with the cattle’s feet, +But a pebble of the brook + Warbled out these metres meet: + +‘Love seeketh only Self to please, + To bind another to its delight, +Joys in another’s loss of ease, + And builds a hell in heaven’s despite.’ diff --git a/poems/william-blake/the-garden-of-love.txt b/poems/william-blake/the-garden-of-love.txt new file mode 100644 index 0000000..7f8f508 --- /dev/null +++ b/poems/william-blake/the-garden-of-love.txt @@ -0,0 +1,14 @@ +I went to the Garden of Love, + And saw what I never had seen; +A Chapel was built in the midst, + Where I used to play on the green. + +And the gates of this Chapel were shut, + And ‘Thou shalt not’ writ over the door; +So I turned to the Garden of Love + That so many sweet flowers bore. + +And I saw it was filled with graves, + And tombstones where flowers should be; +And priests in black gowns were walking their rounds, + And binding with briars my joys and desires. diff --git a/poems/william-blake/the-schoolboy.txt b/poems/william-blake/the-schoolboy.txt new file mode 100644 index 0000000..dea918c --- /dev/null +++ b/poems/william-blake/the-schoolboy.txt @@ -0,0 +1,35 @@ +I love to rise in a summer morn, + When the birds sing on every tree; +The distant huntsman winds his horn, + And the skylark sings with me: + O what sweet company! + +But to go to school in a summer morn,— + O it drives all joy away! +Under a cruel eye outworn, + The little ones spend the day + In sighing and dismay. + +Ah then at times I drooping sit, + And spend many an anxious hour; +Nor in my book can I take delight, + Nor sit in learning’s bower, + Worn through with the dreary shower. + +How can the bird that is born for joy + Sit in a cage and sing? +How can a child, when fears annoy, + But droop his tender wing, + And forget his youthful spring! + +O father and mother if buds are nipped, + And blossoms blown away; +And if the tender plants are stripped + Of their joy in the springing day, + By sorrow and care’s dismay,— + +How shall the summer arise in joy, + Or the summer fruits appear? +Or how shall we gather what griefs destroy, + Or bless the mellowing year, + When the blasts of winter appear? diff --git a/scripts/ingest-gutenberg-frost-depth.mjs b/scripts/ingest-gutenberg-frost-depth.mjs new file mode 100644 index 0000000..25ce32e --- /dev/null +++ b/scripts/ingest-gutenberg-frost-depth.mjs @@ -0,0 +1,130 @@ +import fs from "node:fs/promises"; +import path from "node:path"; +import yaml from "../site/node_modules/js-yaml/dist/js-yaml.mjs"; + +const SOURCE = { + author: "Robert Frost", + author_slug: "robert-frost", + century: 20, + source_ebook: "58611", + collection_title: "New Hampshire", +}; + +const EXTRACT_SPECS = [ + { + slug: "fire-and-ice", + title: "Fire and Ice", + published_year: 1923, + start: "Some say the world will end in fire,", + end: "IN A DISUSED GRAVEYARD", + }, + { + slug: "dust-of-snow", + title: "Dust of Snow", + published_year: 1923, + start: "The way a crow", + end: "TO E. T.", + }, + { + slug: "nothing-gold-can-stay", + title: "Nothing Gold Can Stay", + published_year: 1923, + start: "Nature's first green is gold,", + end: "THE RUNAWAY", + }, + { + slug: "stopping-by-woods-on-a-snowy-evening", + title: "Stopping by Woods on a Snowy Evening", + published_year: 1923, + start: "Whose woods these are I think I know.", + end: "FOR ONCE, THEN, SOMETHING", + }, + { + slug: "the-need-of-being-versed-in-country-things", + title: "The Need of Being Versed in Country Things", + published_year: 1923, + start: "_The house had gone to bring again", + end: "FOOTNOTES", + }, +]; + +function normalizeText(raw) { + return raw.replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, ""); +} + +function stripBoilerplate(raw) { + const start = raw.match(/\*\*\*\s*START OF[\s\S]*?\*\*\*/i); + const end = raw.match(/\*\*\*\s*END OF[\s\S]*?\*\*\*/i); + const startIdx = start ? start.index + start[0].length : 0; + const endIdx = end ? end.index : raw.length; + return raw.slice(startIdx, endIdx).trim(); +} + +function extractPoem(text, { start, end, title }) { + const startIndex = text.indexOf(start); + if (startIndex === -1) throw new Error(`Start marker not found for ${title}`); + + const fromStart = text.slice(startIndex); + const endIndex = fromStart.indexOf(end); + if (endIndex === -1) throw new Error(`End marker not found for ${title}`); + + return fromStart + .slice(0, endIndex) + .replace(/^[ \t]*_+/gm, "") + .replace(/_+[ \t]*$/gm, "") + .replace(/\n{3,}/g, "\n\n") + .trim(); +} + +function buildMeta(spec) { + return yaml.dump( + { + id: `${SOURCE.author_slug}/${spec.slug}`, + slug: spec.slug, + author: SOURCE.author, + author_slug: SOURCE.author_slug, + title: spec.title, + century: SOURCE.century, + text_path: `poems/${SOURCE.author_slug}/${spec.slug}.txt`, + text_in_repo: true, + source_label: "Project Gutenberg", + source_url: `https://www.gutenberg.org/ebooks/${SOURCE.source_ebook}`, + public_domain_rationale: + `Public domain in the United States: first published ${spec.published_year} ` + + `(pre-1931); text via Project Gutenberg eBook #${SOURCE.source_ebook}.`, + collection_title: SOURCE.collection_title, + collection_source_url: `https://www.gutenberg.org/ebooks/${SOURCE.source_ebook}`, + }, + { lineWidth: 1000 }, + ); +} + +async function main() { + const poemsDir = path.join("poems", SOURCE.author_slug); + const metaDir = path.join("meta", SOURCE.author_slug); + await fs.mkdir(poemsDir, { recursive: true }); + await fs.mkdir(metaDir, { recursive: true }); + + const response = await fetch(`https://www.gutenberg.org/cache/epub/${SOURCE.source_ebook}/pg${SOURCE.source_ebook}.txt`); + if (!response.ok) { + throw new Error(`Failed to fetch Gutenberg ebook ${SOURCE.source_ebook}: ${response.status}`); + } + const ebookText = normalizeText(stripBoilerplate(await response.text())); + + for (const spec of EXTRACT_SPECS) { + const poem = extractPoem(ebookText, spec); + const poemPath = path.join(poemsDir, `${spec.slug}.txt`); + const metaPath = path.join(metaDir, `${spec.slug}.yml`); + + await fs.writeFile(poemPath, `${poem}\n`, "utf8"); + await fs.writeFile(metaPath, buildMeta(spec), "utf8"); + console.log(`${SOURCE.author}: created ${spec.slug}`); + } + + console.log(`Total created: ${EXTRACT_SPECS.length}`); +} + +main().catch((error) => { + console.error(error.stack || error.message); + process.exit(1); +}); diff --git a/scripts/ingest-gutenberg-romantic-depth.mjs b/scripts/ingest-gutenberg-romantic-depth.mjs index b3601d8..0e0caeb 100644 --- a/scripts/ingest-gutenberg-romantic-depth.mjs +++ b/scripts/ingest-gutenberg-romantic-depth.mjs @@ -65,6 +65,51 @@ const POETS = [ end_line: "THE LILY", force: true, }, + { + heading: "SPRING", + slug: "spring", + title: "Spring", + published_year: 1789, + start_line: " Sound the flute!", + end_line: "NURSE’S SONG", + force: true, + }, + { + heading: "INFANT JOY", + slug: "infant-joy", + title: "Infant Joy", + published_year: 1789, + start_line: "‘I have no name;", + end_line: "A DREAM", + force: true, + }, + { + heading: "THE CLOD AND THE PEBBLE", + slug: "the-clod-and-the-pebble", + title: "The Clod and the Pebble", + published_year: 1794, + start_line: "‘Love seeketh not itself to please,", + end_line: "HOLY THURSDAY", + force: true, + }, + { + heading: "THE GARDEN OF LOVE", + slug: "the-garden-of-love", + title: "The Garden of Love", + published_year: 1794, + start_line: "I went to the Garden of Love,", + end_line: "THE LITTLE VAGABOND", + force: true, + }, + { + heading: "THE SCHOOLBOY", + slug: "the-schoolboy", + title: "The Schoolboy", + published_year: 1789, + start_line: "I love to rise in a summer morn,", + end_line: "THE VOICE OF THE ANCIENT BARD", + force: true, + }, ], }, { diff --git a/site/src/lib/authors.ts b/site/src/lib/authors.ts index 6d918a6..fc8edad 100644 --- a/site/src/lib/authors.ts +++ b/site/src/lib/authors.ts @@ -190,6 +190,13 @@ export const AUTHOR_INFO: Record = { source_label: "Wikipedia", source_url: "https://en.wikipedia.org/wiki/Robert_Browning", }, + "robert-frost": { + birth_year: 1874, + death_year: 1963, + bio: "American poet whose plainspoken New England lyrics and meditative dramatic monologues include 'Stopping by Woods on a Snowy Evening' and 'Mending Wall'.", + source_label: "Wikipedia", + source_url: "https://en.wikipedia.org/wiki/Robert_Frost", + }, "samuel-taylor-coleridge": { birth_year: 1772, death_year: 1834,