]*>(.*?)
', fragment, flags=re.S): t = html.unescape(re.sub(r'<[^>]+>', '', p)) t = re.sub(r'\s+', ' ', t).strip() if t: paras.append(t) return paras stories = [] for i in range(1, len(parts), 2): title = html.unescape(re.sub(r'<[^>]+>', '', parts[i])).strip() if title in SKIP: continue paras = text_of(parts[i + 1]) stories.append({'volume': VOLUME, 'title': title, 'words': sum(len(p.split()) for p in paras), 'text': '\n\n'.join(paras)}) chunks = [] for si, s in enumerate(stories): buf, n = [], 0 for p in s['text'].split('\n\n'): w = len(p.split()) if n + w > TARGET and buf: chunks.append({'story': si, 'title': s['title'], 'volume': s['volume'], 'text': ' '.join(buf), 'words': n}) buf, n = [], 0 buf.append(p); n += w if buf and n >= 80: chunks.append({'story': si, 'title': s['title'], 'volume': s['volume'], 'text': ' '.join(buf), 'words': n}) pathlib.Path('stories.json').write_text(json.dumps(stories, indent=1, ensure_ascii=False), encoding='utf-8') pathlib.Path('chunks.json').write_text(json.dumps(chunks, ensure_ascii=False), encoding='utf-8') for si, s in enumerate(stories): print(f"{si:2} {s['title']:24} {s['words']:6} words {sum(c['story']==si for c in chunks):3} scenes") ws = sorted(c['words'] for c in chunks) print(f'stories {len(stories)} scenes {len(chunks)} words/scene min {ws[0]} median {ws[len(ws)//2]} max {ws[-1]} total {sum(ws):,}')