Files
TheLadder/tools/story-to-pack/probe/lorimer/split_gutenberg.py
T
JesseMarkowitzandClaude Opus 5.5 3a4758172d story-to-pack: add the corpora and the catalogue v2/v3
Fourteen corpora split and classified: aesop, bierce, chekhov, holmes,
keefe, lawson, lorimer, maupassant, nobody, plaintales, poe, torchy,
wallingford and winesburg, each with its splitter and the hand-written
groups and pages; catalogue v2 and v3; and the shared splitters
gutenberg_chunks.py, se_split.py and se_build.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019rwKTmug58sEsJ72AuWsEi
2026-10-07 06:05:51 -04:00

27 lines
1.6 KiB
Python

"""Split the Project Gutenberg text of George Horace Lorimer, *Letters from a Self-Made Merchant to His Son*
(1902, eBook #21959), one story per letter. The body heads each letter with a centred roman numeral on its
own line; there must be 20, numbered 1..20. Each letter's title is its contents synopsis (the italic line
saying what occasioned it), which is the closest thing the book has to a story title."""
import re, sys
sys.path.insert(0, '..')
from gutenberg_chunks import gutenberg_body, paragraphs, write
VOLUME = 'Letters from a Self-Made Merchant to His Son (George Horace Lorimer, 1902)'
ROMAN = {'I': 1, 'V': 5, 'X': 10, 'L': 50}
def roman(s): return sum(-ROMAN[a] if ROMAN[a] < ROMAN.get(b, 0) else ROMAN[a] for a, b in zip(s, s[1:] + ' '))
lines = gutenberg_body('corpus/letters-from-a-self-made-merchant.txt')
c0 = next(i for i, l in enumerate(lines) if l.strip().startswith('CONTENTS'))
heads = [i for i, l in enumerate(lines) if i > c0 and re.fullmatch(r' {20,}[IVXL]+\s*', l)]
assert [roman(lines[i].strip()) for i in heads] == list(range(1, 21)), [lines[i].strip() for i in heads]
toc = '\n'.join(lines[c0 + 1:heads[0]])
synopses = [re.sub(r'\s+', ' ', s).strip() for s in re.findall(r'_([^_]+)_', toc)]
assert len(synopses) >= 20, len(synopses)
stories = []
for n, a in enumerate(heads):
body = lines[a + 1:(heads[n + 1] if n + 1 < len(heads) else len(lines))]
paras = paragraphs('\n'.join(body), drop=(r'THE END\.?', r'\[Illustration[^\]]*\]'))
stories.append({'volume': VOLUME, 'title': f'Letter {n + 1}: {synopses[n]}', 'words': sum(len(p.split()) for p in paras),
'text': '\n\n'.join(paras)})
write('.', stories)