aboutsummaryrefslogtreecommitdiff
path: root/epubgen.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-17 21:22:46 -0400
committerhistoria <historiavg@proton.me>2026-08-17 21:22:46 -0400
commitf739fc28776eff0465c2f9577b0c2e1fa3d7dea2 (patch)
tree544c5fcaaebdaa249dfef7e3670a29e88bdcd359 /epubgen.py
parent1c8c7fcfe4b8df461763f82be6c3ed860b583d52 (diff)
downloadepub-generator-f739fc28776eff0465c2f9577b0c2e1fa3d7dea2.tar.gz
feat: lorem ipsum flag
Diffstat (limited to 'epubgen.py')
-rwxr-xr-xepubgen.py46
1 files changed, 37 insertions, 9 deletions
diff --git a/epubgen.py b/epubgen.py
index 8599b35..6b60693 100755
--- a/epubgen.py
+++ b/epubgen.py
@@ -33,12 +33,6 @@ VERSION = "1.0"
HERE = os.path.dirname(os.path.abspath(__file__))
DEFAULT_FILE = os.path.join(HERE, "paragraphs.txt")
-EMBEDDED = [
- "The wind carried the smell of rain across the valley, and the last light of the afternoon lingered on the hills.",
- "She opened the ledger and began to read, though the words had been written in another hand long ago.",
- "It was not the first time the old clock had stopped, but it was the first time anyone had noticed.",
-]
-
NS = 'xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"'
# Hostile-but-valid Unicode (all fine in XML 1.0 / UTF-8)
@@ -74,6 +68,33 @@ def first_word(texts, rng):
# ---------------------------------------------------------------------------
+# lorem ipsum generator
+# ---------------------------------------------------------------------------
+
+LOREM_WORDS = ("lorem ipsum dolor sit amet consectetur adipiscing elit sed do "
+ "eiusmod tempor incididunt ut labore et dolore magna aliqua enim ad "
+ "minim veniam quis nostrud exercitation ullamco laboris nisi aliquip "
+ "ex ea commodo consequat duis aute irure in reprehenderit in voluptate "
+ "velit esse cillum dolore eu fugiat nulla pariatur excepteur sint "
+ "occaecat cupidatat non proident sunt in culpa qui officia deserunt "
+ "mollit anim id est laborum").split()
+
+
+def lorem_sentence(rng, min_w=8, max_w=20):
+ words = [rng.choice(LOREM_WORDS) for _ in range(rng.randint(min_w, max_w))]
+ words[0] = words[0].capitalize()
+ return " ".join(words) + "."
+
+
+def lorem_paragraph(rng, min_s=3, max_s=7):
+ return " ".join(lorem_sentence(rng) for _ in range(rng.randint(min_s, max_s)))
+
+
+def lorem_texts(rng, count):
+ return [lorem_paragraph(rng) for _ in range(count)]
+
+
+# ---------------------------------------------------------------------------
# torture helpers
# ---------------------------------------------------------------------------
@@ -393,14 +414,18 @@ def build_zip(out, files):
"STORED" if i.compress_type == zipfile.ZIP_STORED else "DEFLATED"))
-def load_texts(path):
+def load_texts(path, lorem, rng, count):
+ if lorem:
+ return lorem_texts(rng, count)
for p in (path, DEFAULT_FILE):
if p and os.path.exists(p):
with open(p, encoding="utf-8") as f:
lines = [ln.strip() for ln in f if ln.strip()]
if lines:
return lines
- return EMBEDDED
+ print("WARNING: no paragraph text file found; generating lorem ipsum instead",
+ file=sys.stderr)
+ return lorem_texts(rng, count)
def generate(out, rng, texts, title, author, mode, nchap, npar, ncx, seed):
@@ -471,6 +496,9 @@ def main():
ap.add_argument("-a", "--author", default="Test Author")
ap.add_argument("--seed", type=int, default=None, help="RNG seed for reproducibility")
ap.add_argument("--texts", default=None, help="file with one paragraph per line")
+ ap.add_argument("--lorem", action="store_true",
+ help="generate lorem ipsum text instead of reading a file "
+ "(default source: paragraphs.txt)")
ap.add_argument("--no-ncx", action="store_true", help="omit the EPUB2 NCX fallback")
ap.add_argument("-v", "--version", action="version", version="epubgen %s" % VERSION)
args = ap.parse_args()
@@ -480,7 +508,7 @@ def main():
sys.exit(1)
rng = random.Random(args.seed)
- texts = load_texts(args.texts)
+ texts = load_texts(args.texts, args.lorem, rng, args.chapters * args.paragraphs)
ncx = not args.no_ncx
modes = ["normal", "torture"] if args.mode == "both" else [args.mode]
for mode, path in zip(modes, resolve_out_paths(args.out, args.mode)):