diff --git a/.gitignore b/.gitignore index 9e641cb..d08e308 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ *.out *.fls *.fdb_latexmk +*.zip +*.swp *.tar diff --git a/2026.05-SGH-02/latex/SGH2.epub b/2026.05-SGH-02/latex/SGH2.epub new file mode 100644 index 0000000..fe6db40 Binary files /dev/null and b/2026.05-SGH-02/latex/SGH2.epub differ diff --git a/2026.05-SGH-02/latex/epub.yaml b/2026.05-SGH-02/latex/epub.yaml new file mode 100644 index 0000000..65ea48d --- /dev/null +++ b/2026.05-SGH-02/latex/epub.yaml @@ -0,0 +1,9 @@ +title: "Stories from GrailHeart — Volume 2" +author: "William" +lang: en-US + +toc: true +toc-title: "Contents" + +rights: "Copyright © 2026 William" + diff --git a/2026.05-SGH-02/latex/latex2epub.sh b/2026.05-SGH-02/latex/latex2epub.sh new file mode 100755 index 0000000..23e6c0c --- /dev/null +++ b/2026.05-SGH-02/latex/latex2epub.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -e + +INPUT="$1" + +if [ -z "$INPUT" ]; then + echo "Usage: $0 main.tex" + exit 1 +fi + +if [ ! -f "$INPUT" ]; then + echo "ERROR: File not found: $INPUT" + exit 1 +fi + +BASENAME="${INPUT%.tex}" +OUTPUT="${BASENAME}.epub" + +echo "Converting:" +echo " $INPUT" +echo "to:" +echo " $OUTPUT" + +pandoc \ + --from=latex \ + --to=epub3 \ + --metadata-file=epub.yaml \ + --resource-path=".:$(dirname "$INPUT")" \ + "$INPUT" \ + -o "$OUTPUT" + +echo "Done: $OUTPUT" diff --git a/2026.08-PrayersForDailyLife/art/99449d83-303c-4dee-9310-5cfef8d9e764.png b/2026.08-PrayersForDailyLife/art/99449d83-303c-4dee-9310-5cfef8d9e764.png new file mode 100755 index 0000000..a119f4c Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/99449d83-303c-4dee-9310-5cfef8d9e764.png differ diff --git a/2026.08-PrayersForDailyLife/art/A+/1-Hook.af b/2026.08-PrayersForDailyLife/art/A+/1-Hook.af new file mode 100755 index 0000000..324d27f Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/1-Hook.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/1-Hook.jpg b/2026.08-PrayersForDailyLife/art/A+/1-Hook.jpg new file mode 100755 index 0000000..60caffc Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/1-Hook.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/1.af b/2026.08-PrayersForDailyLife/art/A+/1.af new file mode 100755 index 0000000..620e47b Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/1.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/1.jpg b/2026.08-PrayersForDailyLife/art/A+/1.jpg new file mode 100755 index 0000000..29ab809 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/1.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/2-Value.af b/2026.08-PrayersForDailyLife/art/A+/2-Value.af new file mode 100755 index 0000000..f4a4e24 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/2-Value.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/2-Value.jpg b/2026.08-PrayersForDailyLife/art/A+/2-Value.jpg new file mode 100755 index 0000000..43ebb18 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/2-Value.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/2.af b/2026.08-PrayersForDailyLife/art/A+/2.af new file mode 100755 index 0000000..d98d580 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/2.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/2.jpg b/2026.08-PrayersForDailyLife/art/A+/2.jpg new file mode 100755 index 0000000..2cf3712 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/2.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/3-Proof.af b/2026.08-PrayersForDailyLife/art/A+/3-Proof.af new file mode 100755 index 0000000..bf9ac7c Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/3-Proof.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/3-Proof.jpg b/2026.08-PrayersForDailyLife/art/A+/3-Proof.jpg new file mode 100755 index 0000000..61bab71 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/3-Proof.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/3.af b/2026.08-PrayersForDailyLife/art/A+/3.af new file mode 100755 index 0000000..dd0a356 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/3.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/3.jpg b/2026.08-PrayersForDailyLife/art/A+/3.jpg new file mode 100755 index 0000000..c590ec1 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/3.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/4-Close.af b/2026.08-PrayersForDailyLife/art/A+/4-Close.af new file mode 100755 index 0000000..95e273d Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/4-Close.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/4-Close.jpg b/2026.08-PrayersForDailyLife/art/A+/4-Close.jpg new file mode 100755 index 0000000..4e2d5cd Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/4-Close.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/4.af b/2026.08-PrayersForDailyLife/art/A+/4.af new file mode 100755 index 0000000..818eb88 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/4.af differ diff --git a/2026.08-PrayersForDailyLife/art/A+/4.jpg b/2026.08-PrayersForDailyLife/art/A+/4.jpg new file mode 100755 index 0000000..e7d24fa Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/4.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/A+/4741efbf-20d9-4133-91d3-5b291f3b4949.png b/2026.08-PrayersForDailyLife/art/A+/4741efbf-20d9-4133-91d3-5b291f3b4949.png new file mode 100755 index 0000000..d6ff3c7 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/A+/4741efbf-20d9-4133-91d3-5b291f3b4949.png differ diff --git a/2026.08-PrayersForDailyLife/art/Back-2026.09.16-1230.af b/2026.08-PrayersForDailyLife/art/Back-2026.09.16-1230.af new file mode 100755 index 0000000..630817f Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Back-2026.09.16-1230.af differ diff --git a/2026.08-PrayersForDailyLife/art/Back-2026.09.16-1230.jpg b/2026.08-PrayersForDailyLife/art/Back-2026.09.16-1230.jpg new file mode 100755 index 0000000..3e2a797 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Back-2026.09.16-1230.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/BackSpineFront-2026.09.16-1230.af b/2026.08-PrayersForDailyLife/art/BackSpineFront-2026.09.16-1230.af new file mode 100755 index 0000000..9d7b56f Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/BackSpineFront-2026.09.16-1230.af differ diff --git a/2026.08-PrayersForDailyLife/art/BackSpineFront-Cover-2026.09.16-1230.af b/2026.08-PrayersForDailyLife/art/BackSpineFront-Cover-2026.09.16-1230.af new file mode 100755 index 0000000..f66aa77 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/BackSpineFront-Cover-2026.09.16-1230.af differ diff --git a/2026.08-PrayersForDailyLife/art/BackSpineFront-Cover-2026.09.16-1230.jpg b/2026.08-PrayersForDailyLife/art/BackSpineFront-Cover-2026.09.16-1230.jpg new file mode 100755 index 0000000..44f1940 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/BackSpineFront-Cover-2026.09.16-1230.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/BackSpineFront-NoTitle.png b/2026.08-PrayersForDailyLife/art/BackSpineFront-NoTitle.png new file mode 100755 index 0000000..10a78e4 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/BackSpineFront-NoTitle.png differ diff --git a/2026.08-PrayersForDailyLife/art/BackSpineFront.af b/2026.08-PrayersForDailyLife/art/BackSpineFront.af new file mode 100755 index 0000000..4c2f664 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/BackSpineFront.af differ diff --git a/2026.08-PrayersForDailyLife/art/BackSpineFront.pdf b/2026.08-PrayersForDailyLife/art/BackSpineFront.pdf new file mode 100755 index 0000000..8ce52b5 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/BackSpineFront.pdf differ diff --git a/2026.08-PrayersForDailyLife/art/BackSpineFront.png b/2026.08-PrayersForDailyLife/art/BackSpineFront.png new file mode 100755 index 0000000..fe3aa68 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/BackSpineFront.png differ diff --git a/2026.08-PrayersForDailyLife/art/Barcode_979-8-17-335708-3.png b/2026.08-PrayersForDailyLife/art/Barcode_979-8-17-335708-3.png new file mode 100755 index 0000000..3105293 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Barcode_979-8-17-335708-3.png differ diff --git a/2026.08-PrayersForDailyLife/art/Front-2026.09.16-1230.jpg b/2026.08-PrayersForDailyLife/art/Front-2026.09.16-1230.jpg new file mode 100755 index 0000000..436c25d Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Front-2026.09.16-1230.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/Frontr-2026.09.16-1230.af b/2026.08-PrayersForDailyLife/art/Frontr-2026.09.16-1230.af new file mode 100755 index 0000000..b7165a5 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Frontr-2026.09.16-1230.af differ diff --git a/2026.08-PrayersForDailyLife/art/Interior-FearOfNothavingEnough.af b/2026.08-PrayersForDailyLife/art/Interior-FearOfNothavingEnough.af new file mode 100755 index 0000000..7668451 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Interior-FearOfNothavingEnough.af differ diff --git a/2026.08-PrayersForDailyLife/art/Interior-FearOfNothavingEnough.jpg b/2026.08-PrayersForDailyLife/art/Interior-FearOfNothavingEnough.jpg new file mode 100755 index 0000000..06054a1 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Interior-FearOfNothavingEnough.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/Interior-SeekingGodBeforeBigDecisions.af b/2026.08-PrayersForDailyLife/art/Interior-SeekingGodBeforeBigDecisions.af new file mode 100755 index 0000000..693ff5f Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Interior-SeekingGodBeforeBigDecisions.af differ diff --git a/2026.08-PrayersForDailyLife/art/Interior-SeekingGodBeforeBigDecisions.jpg b/2026.08-PrayersForDailyLife/art/Interior-SeekingGodBeforeBigDecisions.jpg new file mode 100755 index 0000000..fe11dd6 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Interior-SeekingGodBeforeBigDecisions.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/Interior-StarsOnAClearNight.jpg b/2026.08-PrayersForDailyLife/art/Interior-StarsOnAClearNight.jpg new file mode 100755 index 0000000..67cd90a Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/Interior-StarsOnAClearNight.jpg differ diff --git a/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US.pdf b/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US.pdf new file mode 100755 index 0000000..4118d64 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US.pdf differ diff --git a/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US.png b/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US.png new file mode 100755 index 0000000..7875be5 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US.png differ diff --git a/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/readme.txt b/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/readme.txt new file mode 100755 index 0000000..580068f --- /dev/null +++ b/2026.08-PrayersForDailyLife/art/PAPERBACK_6.000x9.000_130_BW_WHITE_en_US/readme.txt @@ -0,0 +1,9 @@ +*How to use your template* + +1. Open the PDF or PNG file for the Paperback Book Cover Template in your image editing software. +2. Create a new layer in your image editing software. This layer will serve as the design layer. +3. Design your cover in the design layer, using the template PDF or PNG file as the guide layer. The artwork should extend to the outside edge of the template's pink zone to ensure a white border will not exist within the printed work. Do not move the guide layer, as it is properly aligned for our printing specifications. +4. Ensure text and/or images that are intended to be read do not appear in the pink zones of the template. +5. The barcode area is indicated in yellow on the template. Do not place important images or text intended to be read in the barcode location. We suggest filling in this area with your background color or design. KDP will automatically generate a barcode representing your title’s ISBN when printing copies of your book. +6. Once your design is complete, you will need to turn off the guide layer so that it is not printed on your final product or rejected during the review process. If you are unable to turn off the guide layer, then you will need to format the artwork so that it completely covers the guide layer. +7. Flatten all layers, save the file as a press quality PDF with CMYK color profile, and upload the file via KDP. diff --git a/2026.08-PrayersForDailyLife/art/_BackTitleBlurb.af b/2026.08-PrayersForDailyLife/art/_BackTitleBlurb.af new file mode 100755 index 0000000..8947fea Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/_BackTitleBlurb.af differ diff --git a/2026.08-PrayersForDailyLife/art/_FrontTitle.af b/2026.08-PrayersForDailyLife/art/_FrontTitle.af new file mode 100755 index 0000000..215ae68 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/_FrontTitle.af differ diff --git a/2026.08-PrayersForDailyLife/art/_ZecharaihPress.af b/2026.08-PrayersForDailyLife/art/_ZecharaihPress.af new file mode 100755 index 0000000..3258e1a Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/_ZecharaihPress.af differ diff --git a/2026.08-PrayersForDailyLife/art/_ZechariahPress.png b/2026.08-PrayersForDailyLife/art/_ZechariahPress.png new file mode 100755 index 0000000..15ba7bd Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/_ZechariahPress.png differ diff --git a/2026.08-PrayersForDailyLife/art/back.png b/2026.08-PrayersForDailyLife/art/back.png new file mode 100755 index 0000000..a822aea Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/back.png differ diff --git a/2026.08-PrayersForDailyLife/art/cover.png b/2026.08-PrayersForDailyLife/art/cover.png new file mode 100755 index 0000000..6aa6095 Binary files /dev/null and b/2026.08-PrayersForDailyLife/art/cover.png differ diff --git a/2026.08-PrayersForDailyLife/art/prayers101_qr.pdf b/2026.08-PrayersForDailyLife/art/prayers101_qr.pdf old mode 100644 new mode 100755 index 33a39db..6f12fe6 Binary files a/2026.08-PrayersForDailyLife/art/prayers101_qr.pdf and b/2026.08-PrayersForDailyLife/art/prayers101_qr.pdf differ diff --git a/2026.08-PrayersForDailyLife/latex/PrayersForDailyLife.epub b/2026.08-PrayersForDailyLife/latex/PrayersForDailyLife.epub new file mode 100644 index 0000000..ea4d02c Binary files /dev/null and b/2026.08-PrayersForDailyLife/latex/PrayersForDailyLife.epub differ diff --git a/2026.08-PrayersForDailyLife/latex/generate_epub.py b/2026.08-PrayersForDailyLife/latex/generate_epub.py new file mode 100755 index 0000000..b748592 --- /dev/null +++ b/2026.08-PrayersForDailyLife/latex/generate_epub.py @@ -0,0 +1,680 @@ +#!/usr/bin/env python3 +""" +generate_epub.py + +Converts the same category-coded .txt files used by generate_latex.py +(CODE-CCC.VV.txt, one occasion per file) directly into a single valid +EPUB3 file, suitable for upload to KDP as the Kindle edition. + +This does NOT go through the LaTeX/PDF pipeline -- print-specific +formatting (drop caps, lettrine, fixed page breaks, hard \\ line breaks +mid-stanza) doesn't translate to Kindle's reflowable text, where the +reader controls font size and line spacing. Instead, this script parses +the .txt files directly (same parser shape as generate_latex.py) and +emits clean, semantic XHTML -- one file per category chapter, containing +all of that chapter's prayers -- with a proper EPUB3 nav document AND a +legacy NCX (older Kindle "Go To" menus still expect NCX; including both +costs nothing and avoids navigation complaints). + +Within each prayer, stanza breaks (blank lines in the source) become +

boundaries; single line breaks WITHIN a stanza become
, so the +poem's line structure is preserved without relying on print-only +line-break macros. + +Usage: + python generate_epub.py txt output.epub \\ + --title "Prayers for Daily Life" \\ + --subtitle "101 Devotional Prayers for Every Occasion" \\ + --author "George Marin" \\ + --publisher "Zechariah Press" \\ + --cover cover.jpg \\ + --uuid urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + +If --uuid isn't given, a random one is generated each run -- fine for +testing, but pick ONE fixed UUID for the real book and pass it every +time (this is the file's permanent identity; changing it between +uploads can confuse KDP/retailers into treating updates as a new book). +""" + +import argparse +import html +import re +import sys +import uuid +import zipfile +from pathlib import Path + +from categories import CATEGORIES, VALID_CODES, category_name + +# --- Parsing (same shape as generate_latex.py) ------------------------------ + +HEADER_RE = re.compile( + r"^(?P##\s*\S+)[ \t]*\n" + r">(?!>)[ \t]*(?P[^\n]*)\n" + r">>[ \t]*(?P<quote>[^\n]*)\n" +) +OCCASION_LINE_RE = re.compile(r"(?m)^Occasion:[ \t]*(?P<text>.+)$") +FILENAME_RE = re.compile(r"^(?P<code>[A-Z]+)-(?P<chapter>\d{3})\.(?P<verse>\d{2,3})(?:-[a-z])?\.txt$") +REF_RE = re.compile(r"^(?P<chapter>\d+):(?P<verse>\d+)") + + +def strip_comment_lines(text: str) -> str: + lines = text.split("\n") + out = [] + in_block = False + for ln in lines: + stripped = ln.strip() + if not in_block and stripped == "%v": + in_block = True + continue + if in_block: + if stripped == "%^": + in_block = False + continue + if ln.lstrip().startswith("%"): + continue + out.append(ln) + return "\n".join(out) + + +def parse_ref(ref_line: str) -> str: + return ref_line.lstrip("#").strip() + + +def ref_sort_key(ref: str): + m = REF_RE.match(ref) + if not m: + return (9999, 9999) + return (int(m.group("chapter")), int(m.group("verse"))) + + +def parse_file(text: str): + text = strip_comment_lines(text) + stripped = text.lstrip("\n") + m = HEADER_RE.match(stripped) + if not m: + return None + ref = parse_ref(m.group("ref")) + title = m.group("title").strip() + quote = m.group("quote").strip() + body = text[m.end():] + matches = list(OCCASION_LINE_RE.finditer(body)) + if len(matches) != 1: + return None + mo = matches[0] + occasion = mo.group("text").strip() + prayer_text = body[mo.end():].strip() + if not prayer_text: + return None + return {"ref": ref, "title": title, "quote": quote, "occasion": occasion, "text": prayer_text} + + +_MINOR_WORDS = { + "a", "an", "and", "as", "at", "but", "by", "en", "for", "if", "in", + "nor", "of", "on", "or", "per", "the", "to", "v", "via", "vs", +} + + +def _title_case_word(word: str) -> str: + i = 0 + while i < len(word) and not word[i].isalpha(): + i += 1 + if i >= len(word): + return word + return word[:i] + word[i].upper() + word[i + 1:].lower() + + +def title_case(text: str) -> str: + words = text.split(" ") + out = [] + for idx, w in enumerate(words): + bare = re.sub(r"[^a-zA-Z']", "", w).lower() + if 0 < idx < len(words) - 1 and bare in _MINOR_WORDS: + out.append(w.lower()) + else: + out.append(_title_case_word(w)) + return " ".join(out) + + +# --- HTML rendering ---------------------------------------------------------- + +def esc(text: str) -> str: + return html.escape(text, quote=False) + + +def convert_latex_typography(text: str) -> str: + """Converts this project's LaTeX-only typographic conventions into + real Unicode characters, since none of them mean anything to an + EPUB reader: "---" (em dash ligature) -> em dash; ``...'' (curly + quote ligature) -> real curly quotes.""" + text = text.replace("---", "\u2014") + text = text.replace("``", "\u201c").replace("''", "\u201d") + return text + + +def render_foreword_from_latex(tex_text: str) -> str: + """Parses an ACTUAL template_forward.tex file (not a separate plain-text + copy -- single source of truth, same file that feeds the print + pipeline) into foreword HTML. Handles this project's specific + foreword conventions: + - \\chapter*{...} and \\addcontentsline{...} lines are dropped (the + EPUB foreword gets its own <h1> here instead) + - \\medskip and \\bigskip mark paragraph breaks + - \\noindent is stripped + - wrapped lines within one paragraph are joined with spaces (the + LaTeX source hard-wraps for readability; those line breaks + aren't meaningful the way a prayer's stanza line breaks are) + - \\textit{...} becomes <em>...</em> + - "---" / ``...'' typography converted via convert_latex_typography() + """ + text = tex_text + text = re.sub(r"\\chapter\*\{[^}]*\}", "", text) + text = re.sub(r"\\addcontentsline\{[^}]*\}\{[^}]*\}\{[^}]*\}", "", text) + + # \medskip and \bigskip both mark a paragraph break + chunks = re.split(r"\\(?:med|big)skip", text) + paragraphs = [] + for chunk in chunks: + chunk = chunk.replace("\\noindent", "") + # collapse hard-wrapped source lines into one flowing paragraph + joined = " ".join(ln.strip() for ln in chunk.split("\n") if ln.strip()) + if not joined: + continue + joined = convert_latex_typography(joined) + # \textit{...} -> <em>...</em>, done via sentinel markers so the + # em-tags themselves survive the HTML-escape step untouched + joined = re.sub(r"\\textit\{([^}]*)\}", lambda m: "\uE000" + m.group(1) + "\uE001", joined) + joined = esc(joined) + joined = joined.replace("\uE000", "<em>").replace("\uE001", "</em>") + paragraphs.append(f"<p>{joined}</p>") + return "\n".join(paragraphs) + + +def render_prayer_html(entry: dict, anchor_id: str) -> str: + """One prayer as semantic XHTML: heading, verse blockquote, body + paragraphs (stanza = <p>, in-stanza line break = <br/>). + + A dagger (†) follows the final line (always "Amen.") of every + prayer, matching the print edition's "Amen.\\enspace$\\dagger$" + convention. + + See convert_latex_typography() -- the source files use LaTeX-only + ligature conventions for em dashes and curly quotes that need + converting to real Unicode characters outside the LaTeX pipeline.""" + stanzas = [b.strip() for b in re.split(r"\n\s*\n", entry["text"].strip()) if b.strip()] + para_html = [] + for i, stanza in enumerate(stanzas): + lines = [esc(convert_latex_typography(ln.strip())) for ln in stanza.split("\n") if ln.strip()] + joined = "<br/>\n".join(lines) + if i == len(stanzas) - 1: + joined += " †" + para_html.append(f"<p>{joined}</p>") + body = "\n".join(para_html) + + title = esc(title_case(entry["occasion"])) + quote = esc(convert_latex_typography(entry["quote"])) + ref = esc(entry["ref"]) + + return f"""<section class="prayer" id="{anchor_id}"> +<h3>{title}</h3> +<blockquote class="verse"><p>{quote} <span class="ref">(Ps. {ref})</span></p></blockquote> +{body} +</section>""" + + +def render_chapter_xhtml(code: str, entries: list, title_prefix: str, flourish_img: str | None = None): + """Returns (html, toc_items) where toc_items is a list of + (anchor_id, prayer_title) pairs -- used by the caller to build the + nested chapter->prayer TOC (nav.xhtml, toc.ncx, AND the visible + in-book toc.xhtml page all share this same structure). + + flourish_img, if given, is the filename (already placed under + OEBPS/images/) of a decorative divider shown under the chapter + title -- same graphic as the print edition's chapter openers.""" + name = esc(category_name(code)) + sections = [] + toc_items = [] + for i, e in enumerate(entries): + anchor = f"{code.lower()}-{i+1:03d}" + sections.append(render_prayer_html(e, anchor)) + toc_items.append((anchor, title_case(e["occasion"]))) + body = "\n\n".join(sections) + flourish_html = "" + if flourish_img: + flourish_html = f'<p class="flourish"><img src="../images/{esc(flourish_img)}" alt="" role="presentation"/></p>' + html_out = f"""<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="en"> +<head> +<title>{name} + + + +

{name}

+{flourish_html} +{body} + +""" + return html_out, toc_items + + +def render_simple_xhtml(title: str, body_html: str) -> str: + return f""" + + + +{esc(title)} + + + +{body_html} + +""" + + +DEFAULT_CSS = """ +body { font-family: serif; margin: 1em; line-height: 1.4; } +h1 { text-align: center; margin-top: 1.5em; margin-bottom: 1em; page-break-before: always; } +h2 { text-align: center; } +h3 { margin-top: 2em; page-break-before: always; } +.prayer { margin-bottom: 2em; } +.verse { font-style: italic; margin: 1em 2em; } +.verse .ref { font-style: normal; } +.titlepage { text-align: center; margin-top: 3em; } +.titlepage h1 { page-break-before: avoid; font-size: 1.8em; margin-bottom: 0.2em; } +.titlepage .subtitle { font-size: 1.1em; margin-bottom: 2em; } +.titlepage .author { font-size: 1.2em; margin-top: 2em; } +.copyright { font-size: 0.85em; } +.foreword p { margin-bottom: 1em; } +.center { text-align: center; } + +/* Chapter-opening divider graphic, sized relative to text width so it + scales with the reader's font size / screen, not a fixed pixel size. */ +p.flourish { text-align: center; margin: 0.5em 0 1.5em 0; } +p.flourish img { width: 30%; max-width: 220px; height: auto; } +""" + +# --- EPUB packaging ----------------------------------------------------------- + +CONTAINER_XML = """ + + + + + +""" + + +def _manifest_item_line(iid: str, href: str, mtype: str, is_nav: bool) -> str: + # Kept as a plain function (not inlined in the f-string below) because + # a backslash-escaped quote inside an f-string's {} expression part is + # only legal on Python 3.12+ (PEP 701) -- this needs to run on older + # Python too. + nav_attr = ' properties="nav"' if is_nav else "" + return f' ' + + +def build_opf(book_uuid: str, title: str, subtitle: str, author: str, publisher: str, + manifest_items: list, spine_ids: list, cover_id: str | None, + toc_page_href: str | None) -> str: + meta_cover = f'' if cover_id else "" + manifest = "\n".join(_manifest_item_line(iid, href, mtype, is_nav) for iid, href, mtype, is_nav in manifest_items) + spine = "\n".join(f' ' for sid in spine_ids) + full_title = f"{title}: {subtitle}" if subtitle else title + # is EPUB2-era, but Kindle's conversion pipeline and older + # reading apps still use it to find the table of contents -- costs + # nothing to include alongside the EPUB3 nav doc. + guide = "" + if toc_page_href: + guide = f""" + + +""" + return f""" + + + {esc(book_uuid)} + {esc(full_title)} + {esc(author)} + {esc(publisher)} + en + 2026-01-01T00:00:00Z + {meta_cover} + + + +{manifest} + + +{spine} + +{guide} +""" + + +def build_nav(title: str, toc_entries: list) -> str: + """toc_entries: list of dicts {href, label, children: [(href, label), ...]}.""" + items = [] + for entry in toc_entries: + li = f'
  • {esc(entry["label"])}' + if entry["children"]: + sub = "\n".join(f'
  • {esc(l)}
  • ' for h, l in entry["children"]) + li += f'\n
      \n{sub}\n
    \n ' + li += "" + items.append(li) + items_str = "\n".join(items) + return f""" + + +{esc(title)} + + + +""" + + +def render_psalm_index_xhtml(title: str, all_entries: list) -> str: + """all_entries: list of (ref, href_with_anchor, prayer_title), already + sorted by ref_sort_key. Unlike the print index (ref -> page number, + meaningless in reflowable text with no fixed pages), each entry here + is a direct clickable link to that prayer -- arguably MORE useful + than the print version, since it's one tap instead of a page flip. + href_with_anchor is relative to OEBPS/text/ (where this file lives), + same convention as render_toc_page_xhtml.""" + items = "\n".join( + f'
  • {esc(ref)} — {esc(prayer_title)}
  • ' + for ref, href, prayer_title in all_entries + ) + body = f'

    Index of Psalm References

      \n{items}\n
    ' + return render_simple_xhtml(title, body) + + +def render_toc_page_xhtml(title: str, toc_entries: list) -> str: + """A real, visible in-book Contents page (unlike nav.xhtml, which + most reading apps treat as sidebar-menu metadata, not a page you + actually read through). This is what was missing -- KDP/Kindle + conversion and many EPUB readers expect an actual TOC page in the + reading order, not just the EPUB3 nav doc. + + IMPORTANT: this file itself lives at OEBPS/text/toc.xhtml, alongside + the chapter files -- so unlike nav.xhtml (which lives at the OEBPS/ + root and needs "text/..." prefixed hrefs), links here must be + relative to the text/ directory, i.e. with that prefix stripped.""" + def strip_prefix(href: str) -> str: + return href[len("text/"):] if href.startswith("text/") else href + + items = [] + for entry in toc_entries: + href = strip_prefix(entry["href"]) + li = f'
  • {esc(entry["label"])}' + if entry["children"]: + sub = "\n".join(f'
  • {esc(l)}
  • ' for h, l in entry["children"]) + li += f'\n
      \n{sub}\n
    \n ' + li += "" + items.append(li) + items_str = "\n".join(items) + body = f'

    Contents

      \n{items_str}\n
    ' + return render_simple_xhtml(title, body) + + +def build_ncx(book_uuid: str, title: str, toc_entries: list) -> str: + points = [] + counter = [0] + + def next_order(): + counter[0] += 1 + return counter[0] + + for entry in toc_entries: + parent_order = next_order() + child_points = [] + for h, l in entry["children"]: + child_order = next_order() + child_points.append(f""" + {esc(l)} + + """) + child_str = "\n".join(child_points) + points.append(f""" + {esc(entry['label'])} + +{child_str} + """) + points_str = "\n".join(points) + return f""" + + + + + {esc(title)} + +{points_str} + + +""" + + +def write_epub(out_path: Path, files: dict, image_paths: list): + """files: dict of archive-path -> str content (text files) OR bytes. + image_paths: list of local Path objects to copy in under + OEBPS/images/ (cover, flourish, etc.) -- their manifest entries are + added by the caller; this just physically copies the bytes in. + mimetype MUST be first and MUST be stored (not deflated).""" + if out_path.exists(): + out_path.unlink() + with zipfile.ZipFile(out_path, "w") as z: + z.writestr("mimetype", "application/epub+zip", compress_type=zipfile.ZIP_STORED) + for path, content in files.items(): + data = content if isinstance(content, bytes) else content.encode("utf-8") + z.writestr(path, data, compress_type=zipfile.ZIP_DEFLATED) + for img_path in image_paths: + z.write(img_path, f"OEBPS/images/{img_path.name}", compress_type=zipfile.ZIP_DEFLATED) + + +# --- Main --------------------------------------------------------------------- + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument("txt_dir", type=Path) + ap.add_argument("output_epub", type=Path) + ap.add_argument("--title", default="Prayers for Daily Life") + ap.add_argument("--subtitle", default="101 Devotional Prayers for Every Occasion") + ap.add_argument("--author", default="George Marin") + ap.add_argument("--publisher", default="Zechariah Press") + ap.add_argument("--cover", type=Path, default=None, help="Cover image (jpg/png). Strongly recommended for KDP.") + ap.add_argument("--flourish", type=Path, default=None, help="Optional decorative divider image (jpg/png) shown under each chapter title -- same graphic as the print edition's chapter openers, if you want it.") + ap.add_argument("--foreword", type=Path, default=None, help="Your actual template_forward.tex file -- parsed directly (paragraph breaks on \\medskip/\\bigskip, \\textit{} to italics, etc.), not a separate plain-text copy.") + ap.add_argument("--review-url", default=None, help="If given, adds a back-matter review-request page with a clickable link to this URL (NOT a QR code -- pointless in an ebook, since the reader's already on the device).") + ap.add_argument("--no-psalm-index", action="store_true", help="Omit the back-matter Index of Psalm References (on by default). Unlike the print version, this is a page of CLICKABLE LINKS, not page numbers -- reflowable text has no fixed pages to index.") + ap.add_argument("--uuid", default=None, help="Fixed book UUID (e.g. urn:uuid:...). Random if omitted -- fine for testing, but pin one for the real release.") + ap.add_argument("--category-order", default=None, help="Comma-separated category codes, e.g. WON,WWF,CRI,...") + args = ap.parse_args() + + # Fail loudly and immediately if an optional file path was actually + # GIVEN but doesn't resolve -- silently skipping it (the old + # behavior) is exactly the kind of mistake that ships a KDP EPUB + # with no embedded cover and nobody notices until much later. + for flag_name, path in [ + ("--cover", args.cover), + ("--flourish", args.flourish), + ("--foreword", args.foreword), + ]: + if path is not None and not path.exists(): + sys.exit(f"{flag_name} was given as {path!s}, but that file doesn't exist. Fix the path or drop the flag.") + + book_uuid = args.uuid or f"urn:uuid:{uuid.uuid4()}" + + order = args.category_order.split(",") if args.category_order else list(CATEGORIES.keys()) + for c in order: + if c not in VALID_CODES: + sys.exit(f"Unknown category code in --category-order: {c}") + + txt_files = sorted(args.txt_dir.glob("*.txt")) + by_category: dict[str, list] = {c: [] for c in order} + skipped = [] + for path in txt_files: + m = FILENAME_RE.match(path.name) + if not m or m.group("code") not in VALID_CODES: + continue + parsed = parse_file(path.read_text(encoding="utf-8")) + if parsed is None: + skipped.append(path.name) + continue + code = m.group("code") + if code not in by_category: + by_category[code] = [] + by_category[code].append(parsed) + + if skipped: + print(f"Skipped {len(skipped)} file(s) that didn't parse:") + for s in skipped: + print(f" {s}") + + for code in by_category: + by_category[code].sort(key=lambda e: ref_sort_key(e["ref"])) + + total = sum(len(v) for v in by_category.values()) + print(f"Building EPUB from {total} entries across {sum(1 for v in by_category.values() if v)} categories.") + + # --- Assemble files --- + files: dict[str, object] = {} + files["META-INF/container.xml"] = CONTAINER_XML + files["OEBPS/css/style.css"] = DEFAULT_CSS + + manifest_items = [] # (id, href, media-type, is_nav) + spine_ids = [] + toc_entries = [] # list of {href, label, children: [(href#anchor, label), ...]} + + # Title page + title_html = f"""
    +

    {esc(args.title)}

    +

    {esc(args.subtitle)}

    +

    {esc(args.author)}

    +
    """ + files["OEBPS/text/titlepage.xhtml"] = render_simple_xhtml(args.title, title_html) + manifest_items.append(("titlepage", "text/titlepage.xhtml", "application/xhtml+xml", False)) + spine_ids.append("titlepage") + + # Copyright page + copyright_html = f"""""" + files["OEBPS/text/copyright.xhtml"] = render_simple_xhtml("Copyright", copyright_html) + manifest_items.append(("copyright", "text/copyright.xhtml", "application/xhtml+xml", False)) + spine_ids.append("copyright") + + # Table of Contents -- a REAL visible page in the reading order, not just + # the EPUB3 nav.xhtml (which most reading apps only use for their own + # sidebar menu, not as an actual page). Placed here as a spine_ids + # placeholder; the id "toc-page" is inserted once its file is written + # below, once we know the full nested structure -- so reserve its + # position in the spine now, fill in content after the loop. + TOC_PAGE_POS = len(spine_ids) + spine_ids.append("toc-page") # placeholder, replaced below once content is built + + # Foreword (optional) -- parsed directly from the real template_forward.tex + if args.foreword: # existence already validated above + fw_html = "

    Foreword

    \n" + render_foreword_from_latex(args.foreword.read_text(encoding="utf-8")) + files["OEBPS/text/foreword.xhtml"] = render_simple_xhtml("Foreword", f'
    {fw_html}
    ') + manifest_items.append(("foreword", "text/foreword.xhtml", "application/xhtml+xml", False)) + spine_ids.append("foreword") + toc_entries.append({"href": "text/foreword.xhtml", "label": "Foreword", "children": []}) + + # One XHTML file per category chapter, plus its nested prayer-level + # TOC entries (anchor links within that chapter's file) + for code in order: + entries = by_category.get(code, []) + if not entries: + continue + chapter_html, prayer_toc_items = render_chapter_xhtml( + code, entries, args.title, + flourish_img=args.flourish.name if args.flourish else None, # existence already validated above + ) + fname = f"{code.lower()}.xhtml" + files[f"OEBPS/text/{fname}"] = chapter_html + cid = f"chap-{code.lower()}" + manifest_items.append((cid, f"text/{fname}", "application/xhtml+xml", False)) + spine_ids.append(cid) + children = [(f"text/{fname}#{anchor}", label) for anchor, label in prayer_toc_items] + toc_entries.append({"href": f"text/{fname}", "label": category_name(code), "children": children}) + + # Review request (optional) -- a real hyperlink, not a QR code; see + # --review-url help text for why a QR code doesn't make sense here. + if args.review_url: + review_html = f"""
    +

    Did this book meet you somewhere?

    +

    If it did, a review helps the next reader find their way here too.

    +

    {esc(args.review_url)}

    +
    """ + files["OEBPS/text/review.xhtml"] = render_simple_xhtml("A Request", review_html) + manifest_items.append(("review", "text/review.xhtml", "application/xhtml+xml", False)) + spine_ids.append("review") + + # Index of Psalm References (optional, on by default) -- flat list + # across ALL categories, sorted by verse reference, each entry + # linking directly to its prayer. Built here (after every chapter's + # anchors are known) rather than during the per-category loop above, + # since it needs the complete cross-category picture. + if not args.no_psalm_index: + all_entries = [] + for code in order: + for i, e in enumerate(by_category.get(code, [])): + anchor = f"{code.lower()}-{i+1:03d}" + href = f"{code.lower()}.xhtml#{anchor}" + all_entries.append((e["ref"], href, title_case(e["occasion"]))) + all_entries.sort(key=lambda t: ref_sort_key(t[0])) + files["OEBPS/text/psalm-index.xhtml"] = render_psalm_index_xhtml("Index of Psalm References", all_entries) + manifest_items.append(("psalm-index", "text/psalm-index.xhtml", "application/xhtml+xml", False)) + spine_ids.append("psalm-index") + toc_entries.append({"href": "text/psalm-index.xhtml", "label": "Index of Psalm References", "children": []}) + + # Now that toc_entries is fully built, write the actual TOC page and + # fill in the spine placeholder reserved above. + files["OEBPS/text/toc.xhtml"] = render_toc_page_xhtml("Contents", toc_entries) + manifest_items.append(("toc-page", "text/toc.xhtml", "application/xhtml+xml", False)) + spine_ids[TOC_PAGE_POS] = "toc-page" + + # Cover + cover_id = None + image_paths = [] # local files to physically copy into OEBPS/images/ + if args.cover: # existence already validated above + image_paths.append(args.cover) + media_type = "image/jpeg" if args.cover.suffix.lower() in (".jpg", ".jpeg") else "image/png" + cover_id = "cover-image" + manifest_items.append((cover_id, f"images/{args.cover.name}", media_type, False)) + cover_xhtml = f'
    Cover
    ' + files["OEBPS/text/cover.xhtml"] = render_simple_xhtml("Cover", cover_xhtml) + manifest_items.append(("cover-page", "text/cover.xhtml", "application/xhtml+xml", False)) + spine_ids.insert(0, "cover-page") + + if args.flourish: # existence already validated above + image_paths.append(args.flourish) + media_type = "image/jpeg" if args.flourish.suffix.lower() in (".jpg", ".jpeg") else "image/png" + manifest_items.append(("flourish-image", f"images/{args.flourish.name}", media_type, False)) + + # Nav + NCX -- both reference the SAME nested toc_entries as the + # visible toc.xhtml page above, so the reader-UI sidebar and the + # in-book Contents page always agree. + manifest_items.append(("nav", "nav.xhtml", "application/xhtml+xml", True)) + manifest_items.append(("ncx", "toc.ncx", "application/x-dtbncx+xml", False)) + files["OEBPS/nav.xhtml"] = build_nav(args.title, toc_entries) + files["OEBPS/toc.ncx"] = build_ncx(book_uuid, args.title, toc_entries) + + files["OEBPS/content.opf"] = build_opf( + book_uuid, args.title, args.subtitle, args.author, args.publisher, + manifest_items, spine_ids, cover_id, toc_page_href="text/toc.xhtml", + ) + + write_epub(args.output_epub, files, image_paths) + print(f"Wrote {args.output_epub} ({total} prayers, {sum(1 for v in by_category.values() if v)} chapters)") + + +if __name__ == "__main__": + main() diff --git a/2026.08-PrayersForDailyLife/latex/main.tex b/2026.08-PrayersForDailyLife/latex/main.tex index 74b0233..2e8d45e 100644 --- a/2026.08-PrayersForDailyLife/latex/main.tex +++ b/2026.08-PrayersForDailyLife/latex/main.tex @@ -147,7 +147,7 @@ No permission is required for its use. \noindent Published by Zechariah Press -\noindent ISBN: 000-0-000000-00-0 % TODO: replace with the assigned ISBN before publication +\noindent ISBN: 979-8-1733570-08-3 % 000-0-000000-00-0 \medskip \noindent First Edition diff --git a/2026.08-PrayersForDailyLife/latex/make-epub.sh b/2026.08-PrayersForDailyLife/latex/make-epub.sh new file mode 100755 index 0000000..552005b --- /dev/null +++ b/2026.08-PrayersForDailyLife/latex/make-epub.sh @@ -0,0 +1,10 @@ +python3 generate_epub.py ../txt PrayersForDailyLife.epub \ + --title "Prayers for Daily Life" \ + --subtitle "101 Devotional Prayers for Every Occasion" \ + --author "George Marin" \ + --publisher "Zechariah Press" \ + --cover ../art/BackSpineFront-Cover-2026.09.16-1230.jpg \ + --foreword ./template-foreward.tex \ + --review-url "https://zechariahpress.com/q/PrayersForDailyLife" \ + --uuid "1460ac0b-4f40-4645-b12b-2c78aee89d34" \ + --flourish ../art/o01.png diff --git a/2026.08-PrayersForDailyLife/latex/make.sh b/2026.08-PrayersForDailyLife/latex/make-pdf.sh old mode 100644 new mode 100755 similarity index 83% rename from 2026.08-PrayersForDailyLife/latex/make.sh rename to 2026.08-PrayersForDailyLife/latex/make-pdf.sh index d3d2ac6..6309761 --- a/2026.08-PrayersForDailyLife/latex/make.sh +++ b/2026.08-PrayersForDailyLife/latex/make-pdf.sh @@ -4,11 +4,12 @@ set -e rm -f main.aux main.idx main.ilg main.ind main.ind main.log main.pdf main.toc $DEPOT/main.pdf for p in CON CRI DRY GRA GUI LOS MIL REL TMP WON WWF do - rm $p*.tex + rm -f $p*.tex done python3 generate_latex.py ../txt . --template template-prayer.tex --main-template template-main.tex pdflatex main makeindex main pdflatex main pdflatex main -cp main.pdf "$DEPOT/main-$(date +%Y.%m.%d-%H%M).pdf" + +cp main.pdf "Prayers-$(date +%Y.%m.%d-%H%M).pdf" diff --git a/2026.08-PrayersForDailyLife/latex/template-foreward.tex b/2026.08-PrayersForDailyLife/latex/template-foreward.tex index 645c82c..681ab31 100644 --- a/2026.08-PrayersForDailyLife/latex/template-foreward.tex +++ b/2026.08-PrayersForDailyLife/latex/template-foreward.tex @@ -4,24 +4,24 @@ \noindent I didn't set out to write a hundred and one prayers. I set out to write the ones I needed and couldn't find --- short enough to pray before the day got away, -plain enough to skip the churchier language. +plain enough to skip churchy language. \medskip \noindent It didn't take long to notice a pattern: -that every prayer +every prayer rhymed with something a psalmist had already said three thousand years ago. Weariness, wonder, gratitude, grief --- none of it is new. \medskip \noindent This book borrows their voice. Each prayer opens with a verse from the Psalms and stays close to it, -but with present-day concerns --- a hospital wristband, a gurney, plastic bins after a storm. +but with present-day concerns --- a hospital wristband, plastic bins after a storm. A prayer too general, ``Lord, help me in my trouble,'' rarely moves anyone; -it asks for nothing you can picture. +it asks for nothing you can wrap your hands around. But one too specific runs a different risk: what if your trouble doesn't look like mine? \medskip -\noindent So hold these loosely. Think of each one less as a script +\noindent So hold these loosely. Think of them less as a script and more as an aperture --- a way of opening your imagination onto something you already recognize. Let your words take over where mine leave off. @@ -33,7 +33,7 @@ since it's what most of us are used to. \medskip \noindent Wherever you are today --- weary, waiting, grateful, undone --- -my prayer is that you'll find something here that meets you there. +my prayer is that you'll find something here that meets you where you are. \bigskip \noindent \textit{George Marin} \ No newline at end of file diff --git a/2026.08-PrayersForDailyLife/latex/template-main.tex b/2026.08-PrayersForDailyLife/latex/template-main.tex index 74b0233..2e8d45e 100644 --- a/2026.08-PrayersForDailyLife/latex/template-main.tex +++ b/2026.08-PrayersForDailyLife/latex/template-main.tex @@ -147,7 +147,7 @@ No permission is required for its use. \noindent Published by Zechariah Press -\noindent ISBN: 000-0-000000-00-0 % TODO: replace with the assigned ISBN before publication +\noindent ISBN: 979-8-1733570-08-3 % 000-0-000000-00-0 \medskip \noindent First Edition diff --git a/2026.08-PrayersForDailyLife/latex/template-review.tex b/2026.08-PrayersForDailyLife/latex/template-review.tex index f2c1342..a5e016e 100644 --- a/2026.08-PrayersForDailyLife/latex/template-review.tex +++ b/2026.08-PrayersForDailyLife/latex/template-review.tex @@ -13,5 +13,10 @@ find their way here too.} \vspace{1em} {\small zechariahpress.com/reviews/PrayersForDailyLife} + +\vspace{1.5em} +{\itshape \large Thank you.} + \end{center} + \vspace*{\fill} diff --git a/2026.08-PrayersForDailyLife/txt/DRY-084.02.txt b/2026.08-PrayersForDailyLife/txt/DRY-084.02.txt index 7ccf024..280fa26 100644 --- a/2026.08-PrayersForDailyLife/txt/DRY-084.02.txt +++ b/2026.08-PrayersForDailyLife/txt/DRY-084.02.txt @@ -3,7 +3,7 @@ > My soul longs, and even faints for the courts of the LORD >> My soul longs, and even faints for the courts of the LORD; my heart and my flesh cry out for the living God. -Occasion: Restless after getting what you wanted +Occasion: Restless after getting what I wanted Lord, I got the thing I asked for, and nothing changed. diff --git a/2026.08-PrayersForDailyLife/txt/DRY-143.08.txt b/2026.08-PrayersForDailyLife/txt/DRY-143.08.txt index 7744c3a..8547e13 100644 --- a/2026.08-PrayersForDailyLife/txt/DRY-143.08.txt +++ b/2026.08-PrayersForDailyLife/txt/DRY-143.08.txt @@ -1,7 +1,7 @@ ## 143:8 %% 4 > Your Lovingkindness in the Morning ->> Cause me to hear your lovingkindness in the morning, for I trust in you. Cause me to know the way in which I should walk, for I lift up my soul to you. +>> Cause me to hear your lovingkindness in the morning, for I trust in you. Occasion: Praying first thing @@ -11,16 +11,12 @@ before I speak to anyone else, Lord, let me speak with You. I am here, though part of me is still waking, -and part of me has already begun -to carry the weight of the day. -Yesterday is not entirely gone. -Today is already asking things of me. +and today is already asking things of me. -Let Your kindness be the first thing I hear this morning. +Let Your lovingkindness be the first thing I hear this morning. Teach me to bring You my soul -before I hand this day to habit, -hurry, +before I hand this day to habit, hurry, or whatever shouts the loudest. One thought follows another, @@ -30,16 +26,14 @@ where I am going or who I am becoming along the way. So make this first turning toward You plain. -A chair. -A breath. +A breath. A whisper. A few honest words. I don't need to sound wise --- as if You didn't already know me. I don't need the whole way mapped --- -one step is what You've promised. -Only show me how to walk faithfully -into the hours before me, +one step is all You've promised. +Only show me how to walk faithfully into the hours before me, and give me grace enough for the next thing. @@ -48,4 +42,4 @@ be first. Before the screen lights up, be first. -Amen. +Amen. \ No newline at end of file diff --git a/2026.08-PrayersForDailyLife/txt/GRA-023.01.txt b/2026.08-PrayersForDailyLife/txt/GRA-023.01.txt index bdb770f..190bbc9 100644 --- a/2026.08-PrayersForDailyLife/txt/GRA-023.01.txt +++ b/2026.08-PrayersForDailyLife/txt/GRA-023.01.txt @@ -14,7 +14,7 @@ trying to secure tomorrow with my own hands. One unanswered question becomes ten, and soon I am living inside a future that has not even arrived. -And likjely never will. +And likely never will. I am tired of carrying it, but I am afraid of what will happen if I let it go. diff --git a/2026.08-PrayersForDailyLife/txt/GRA-116.12.txt b/2026.08-PrayersForDailyLife/txt/GRA-116.12.txt index 6b23274..91ada60 100644 --- a/2026.08-PrayersForDailyLife/txt/GRA-116.12.txt +++ b/2026.08-PrayersForDailyLife/txt/GRA-116.12.txt @@ -6,7 +6,6 @@ Occasion: When I'm grateful but don't quite know how to say it Lord, thank You. - Saying that seems too small, but it's what I have. @@ -43,4 +42,4 @@ these inadequate words will have to suffice: Thank You. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/GRA-118.24.txt b/2026.08-PrayersForDailyLife/txt/GRA-118.24.txt index 63f0315..61d6ee1 100644 --- a/2026.08-PrayersForDailyLife/txt/GRA-118.24.txt +++ b/2026.08-PrayersForDailyLife/txt/GRA-118.24.txt @@ -6,7 +6,6 @@ Occasion: When I've had a good day Lord, today was good. - Nothing spectacular. No sea parted. No mountain moved. @@ -42,4 +41,4 @@ I was here for it. And I am glad. And grateful. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/GUI-090.12.txt b/2026.08-PrayersForDailyLife/txt/GUI-090.12.txt index 3e415eb..7116b95 100644 --- a/2026.08-PrayersForDailyLife/txt/GUI-090.12.txt +++ b/2026.08-PrayersForDailyLife/txt/GUI-090.12.txt @@ -3,7 +3,7 @@ > Teach Us To Count Our Days >> So teach us to count our days, that we may gain a heart of wisdom. -Occasion: Choosing how to spend your time +Occasion: Choosing how to spend my time There are too many tasks in front of me, Lord --- the message to answer, diff --git a/2026.08-PrayersForDailyLife/txt/LOS-139.13.txt b/2026.08-PrayersForDailyLife/txt/LOS-139.13.txt index 866ac98..291f3dc 100644 --- a/2026.08-PrayersForDailyLife/txt/LOS-139.13.txt +++ b/2026.08-PrayersForDailyLife/txt/LOS-139.13.txt @@ -6,7 +6,6 @@ Occasion: Miscarriage Lord, You knit together what I never got to hold. - I don't have a photograph. I don't have a name everyone else got to use. Just a due date I still know by heart, @@ -34,4 +33,4 @@ be someone You carry still. Hold what I never got to hold. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/MIL-068.06.txt b/2026.08-PrayersForDailyLife/txt/MIL-068.06.txt index 5f78263..0e5e79f 100644 --- a/2026.08-PrayersForDailyLife/txt/MIL-068.06.txt +++ b/2026.08-PrayersForDailyLife/txt/MIL-068.06.txt @@ -39,3 +39,6 @@ one ordinary moment at a time. Be the first guest in this house, the one who never leaves, the one who makes it a home. + +Amen. + diff --git a/2026.08-PrayersForDailyLife/txt/REL-103.10.txt b/2026.08-PrayersForDailyLife/txt/REL-103.10.txt index 016e759..fd247c7 100644 --- a/2026.08-PrayersForDailyLife/txt/REL-103.10.txt +++ b/2026.08-PrayersForDailyLife/txt/REL-103.10.txt @@ -6,7 +6,6 @@ Occasion: When I need to forgive Lord, I know I need to forgive. - I also know I cannot make the hurt disappear by deciding that I should. diff --git a/2026.08-PrayersForDailyLife/txt/REL-141.03.txt b/2026.08-PrayersForDailyLife/txt/REL-141.03.txt index 5017463..aca20c3 100644 --- a/2026.08-PrayersForDailyLife/txt/REL-141.03.txt +++ b/2026.08-PrayersForDailyLife/txt/REL-141.03.txt @@ -6,7 +6,6 @@ Occasion: When I need courage for an ordinary conversation Lord, I need to say something. - It is not a speech. No crowd is waiting. The world will go on afterward. @@ -41,4 +40,4 @@ be acceptable to You. Help me open my mouth and begin. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/TMP-055.22.txt b/2026.08-PrayersForDailyLife/txt/TMP-055.22.txt index 56163ec..640001a 100644 --- a/2026.08-PrayersForDailyLife/txt/TMP-055.22.txt +++ b/2026.08-PrayersForDailyLife/txt/TMP-055.22.txt @@ -6,7 +6,6 @@ Occasion: When I can't let something go Lord, here it is again. - The memory. The conversation. The mistake. @@ -44,4 +43,4 @@ I am putting it down again. And if I pick it up tomorrow, I will bring it back again. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/TMP-090.17.txt b/2026.08-PrayersForDailyLife/txt/TMP-090.17.txt index 30d9e0c..d8097f4 100644 --- a/2026.08-PrayersForDailyLife/txt/TMP-090.17.txt +++ b/2026.08-PrayersForDailyLife/txt/TMP-090.17.txt @@ -6,7 +6,6 @@ Occasion: When I don't want to do what needs doing Lord, I know what needs doing. - I simply don't want to do it. I'd rather postpone it, @@ -42,4 +41,4 @@ This is today's work. Establish it. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/TMP-103.14.txt b/2026.08-PrayersForDailyLife/txt/TMP-103.14.txt index 4bc1b92..8760fa8 100644 --- a/2026.08-PrayersForDailyLife/txt/TMP-103.14.txt +++ b/2026.08-PrayersForDailyLife/txt/TMP-103.14.txt @@ -6,7 +6,6 @@ Occasion: When I'm disappointed in myself Lord, I expected better of myself. - I thought I would handle this differently. I thought I had grown past this. I thought by now I would be wiser, @@ -42,4 +41,4 @@ You have not mistaken me for someone already finished. Let's begin again. -Amen \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/WON-024.01.txt b/2026.08-PrayersForDailyLife/txt/WON-024.01.txt index c59e51f..d52f4de 100644 --- a/2026.08-PrayersForDailyLife/txt/WON-024.01.txt +++ b/2026.08-PrayersForDailyLife/txt/WON-024.01.txt @@ -5,7 +5,7 @@ Occasion: Caring for the natural world -MMorning light on the leaves, Lord. +Morning light on the leaves, Lord. Water running over stone. The smell of rain on warm earth. This world is precious, @@ -45,4 +45,4 @@ Keep me in that light, attentive and humble, careful with what is Yours. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/txt/WWF-023.02.txt b/2026.08-PrayersForDailyLife/txt/WWF-023.02.txt index 815e271..daba551 100644 --- a/2026.08-PrayersForDailyLife/txt/WWF-023.02.txt +++ b/2026.08-PrayersForDailyLife/txt/WWF-023.02.txt @@ -6,10 +6,8 @@ Occasion: When I'm bone tired Lord, I'm bone tired. - Nothing terrible has happened. No crisis to solve. - I've simply reached the end of what I have for today. diff --git a/2026.08-PrayersForDailyLife/txt/WWF-131.02.txt b/2026.08-PrayersForDailyLife/txt/WWF-131.02.txt index 50924fe..339eabe 100644 --- a/2026.08-PrayersForDailyLife/txt/WWF-131.02.txt +++ b/2026.08-PrayersForDailyLife/txt/WWF-131.02.txt @@ -5,7 +5,6 @@ Occasion: When I can't stop worrying Lord, my mind will not leave this alone. - I turn it over, then turn it over again, looking for something I missed, @@ -32,4 +31,4 @@ Still my soul beside You, like a child who no longer needs to understand --- all that matters is where home is. -Amen. \ No newline at end of file +Amen. diff --git a/2026.08-PrayersForDailyLife/verbiage/TOC.txt b/2026.08-PrayersForDailyLife/verbiage/TOC.txt new file mode 100755 index 0000000..4107fce --- /dev/null +++ b/2026.08-PrayersForDailyLife/verbiage/TOC.txt @@ -0,0 +1,122 @@ +Wonder & Thanksgiving +* Feeling small in a big world +* After a close call +* Thanking God for creation +* Caring for the natural world +* Wonder at how I'm made +* The stars on a clear night +* Wonder at absolutely everything + +Weariness, Worry & Fear +* Waiting for the right season +* Trouble falling asleep +* Waking up worried +* Slow recovery from illness +* Fearing joy won't last +* Before speaking in public +* When I'm bone tired +* Fear of not having enough +* After losing a job +* When I have to wait +* When I can't stop worrying +* During a lonely season + +Guidance \& Decisions +* Bringing dreams before God +* Making a big move +* Facing an important morning +* Seeking God before decisions +* When I reach for the wrong refuge +* Making the most of today +* Stress from too many decisions +* Choosing how to spend your time +* Taking one step at a time +* Needing moral clarity + +Crisis \& Emergency +* Waiting for test results +* When panic takes over +* Before a big surgery +* Bad news from far away +* Bad news from the doctor +* Starting over after disaster +* After hearing bad news +* Facing the end of life + +Loss +* A loss of something important +* Loss of a pet +* Grieving a broken family +* Loss of a child +* Miscarriage +* Loss of a friend +* Loss of parents +* Loss of a spouse +* Grieving a suicide + +Milestones +* Starting a new job +* Moving into a new home +* Graduation +* Wedding +* The arrival of a new child +* The arrival of a new grandchild +* Retirement + +Temptation \& Self-Examination +* Envy over someone else's success +* After a failure +* Letting go of control +* Asking forgiveness for hurtful words +* When I can't let something go +* When shame keeps me away +* When I don't want to do what needs doing +* Wanting wholehearted worship +* Confessing hidden wrongdoing +* When I'm disappointed in myself +* Wanting to break old habits +* When my motives are mixed + +Spiritual Dryness \& Discontent +* A distracted heart +* Coming back after drifting +* When today feels wasted +* Restless after getting what you wanted +* Discouraged by slow growth +* Inner turmoil +* When God's goodness feels distant +* When gratitude feels hard +* Praying first thing + +Relationships +* After being let down +* After hurting someone deeply +* When you have no one to talk to +* Teaching a child about God +* Children afraid of the dark +* When I need to forgive +* Building a marriage +* When I need courage for an ordinary conversation + +Conflicts +* Joining in cruel jokes +* Stress over unfair treatment +* When I'm angry with someone I love +* Walking into a hard meeting +* Trouble that follows you home +* A church split healing + +Gratitude +* Learning to trust God's provision +* Thanking God for answered prayer +* Coming out of a hard season +* Seeking contentment in God +* Giving thanks for enough +* Thankfulness for this morning +* Waking up grateful +* Singing with joy again +* Remembering past help +* Staying faithful in old age +* When blessings feel ordinary +* When I'm grateful but don't quite know how to say it +* When I've had a good day