# Making a book for the cbook reader A guide for an AI assistant. Version 1.5, 2026-11-13. From the cbook project, (c) 2026 Bill Mandel. Free to download and to use with an AI assistant to make books for the cbook reader. ## 0. Read this first A person has attached this file to a chat and asked you to help them make a book. The book is one EPUB file that reads well in the cbook reader (a web page for reading EPUB books, at https://friendsservermb.mine.nu/cbooks/) and in other EPUB readers. You write the book with the person, then build the file, then hand it over. You may be an assistant with no access to the person's computer. Nothing here needs any tool except Python 3 with its standard library, which is used once, at the end, to write the file. If you cannot run code, or cannot give the person a file, say so plainly (see section 6). Do not pretend to have made a file. Tell the person, in plain words, what you are doing at each step. Keep your messages short. Use plain, clear language yourself. ## 1. How to work, in order 1. **Ask first.** Ask these questions in one short message (a few at a time is better than a long list), then wait for the answers. Do not start writing. - What is the book about, and what should a reader be able to do or understand at the end? - Who will read it, and what do they already know? - How long: roughly how many chapters, and how long should a chapter be to read in one sitting? - What tone, and what reading level? Is there a book they would like it to be like? - Which sources to use, and which to avoid? Can they give you links, notes or files? Can you search the web in this chat? - Do they have pictures they have the right to use? (If not, make a book without pictures.) - The name to put on the book as author, and the rights line (for example "(c) 2026 Name. All rights reserved."). - Is this a new book, or a later edition of a book they already made? For a later edition, ask for the identifier (section 7). If the person says to infer the answers from their first message, do that and state your assumptions in a few lines. The one thing you must not invent is the author's name. Ask for it when you show the outline, or say plainly that you are using the word "Author" as a placeholder and will rebuild when they tell you the name. 2. **Propose an outline.** The book's title, one line about the book, and the chapters, each with one sentence of what it will cover. Wait for the person to approve it or change it. 3. **Write.** One chapter at a time. Follow sections 2 to 5. When you have written a chapter, tell the person it is done and carry on unless they want to review it. Keep to the length you agreed. The builder prints the word count: compare it with the plan (for example 5 chapters of 1,500 words is about 7,500 words). If the book is more than a fifth short, say so plainly and offer to expand it. Do not call a short book finished. 4. **Build the file** with the script in section 6. Check it as described in section 7. 5. **Hand it over** with the report in section 7. ## 2. Be honest about facts The person will read this as a book. Readers trust a book more than a chat, so be careful. - Every factual claim should come from a source you actually used in this chat, not from memory. If you can search the web, do, and read the page, not only the snippet. If you cannot, say so to the person at the start, and treat everything as from memory. - Never invent a source, a link, a quotation, a statistic, a date or a name. If you do not know, say so in the text or leave it out. - Only put in a link you opened in this chat. Before you build, open every link in the book once more. Your code sandbox may have no network. If so, use your search or browse tool instead, one link at a time. Take out any link that does not open, and tell the person you did. If there is some link you could not re-check by either route, name it in your report (section 7). Do not just say "please check the links". - Anything from memory that you did not check against a source goes in the `from_memory` list of the builder (section 6), and is said plainly in the text where it matters ("from memory, not checked"). - Where sources disagree, say so in the text and say which you followed. Collect these in a last chapter called "Notes on facts and sources". - At the end of each chapter, add a "Sources for this chapter" list of real links with author, title and year. Only link to pages you looked at. - Say who made the book: "written by the author with an AI assistant", and that it has not been reviewed by a subject expert (unless it has). - What the book says about how it was researched must be true. If you searched the web in this chat, say so, and keep the links. If you could not search, say that the book is written from memory. If you can search in some steps and not others, say which. Do not write "researched with live web sources" unless you did. - Dates, numbers, names and units are the commonest mistakes. Check them twice. ## 3. Rights - Write in your own words from facts in sources. Do not copy passages from books, articles or web pages. A short quotation with its source is fine. - Pictures: use only pictures the person owns, or that are in the public domain or under a licence that allows it (put the licence and credit in the caption and on a credits page). If the rights are not clear, leave the picture out and tell the person. - Do not use song lyrics, or text from someone's copyrighted book, in any form. - If the person gives you someone else's text to turn into a book, ask what they intend (private reading, sharing with friends, or public), and tell them that someone else's work usually needs the owner's permission to share. If that text is a PDF and the person also attached the companion guide "Turning a PDF into a cbook book", follow that guide for the PDF. ## 4. What a good cbook book looks like The reader lays the text out fresh for every screen, font size and theme. So you write what things are, not how they look. - **Order:** a cover (section 6), a title page, a contents page, "About this book" (what it is, who made it, how far to trust it, in a few short paragraphs), the chapters, "Notes on facts and sources", a credits page if there are pictures, and last "How this edition was made". The builder makes the title page, contents and the last page for you. You write the rest. - **Chapters:** the title is a number and a name ("3. Two machines built to outlive their makers"). Size a chapter for one sitting: a few thousand words is typical. Do not make many tiny chapters. Group related points under `##` sections inside a chapter. - **Sections:** each `##` section should have several paragraphs. A run of very short sections is better as a list of bold lead-ins: `- **First point.** One or two sentences.` - **Paragraphs:** short, plain, one idea each. A phone screen is small. - **No page references.** Pages differ on every screen. Say "see chapter 4" or "see the section 'Sources'", never "see page 12" or "see below". - **Callouts:** a few short boxes where a reader should pause (a definition, a warning, a "why this matters"). Use `:::note Title` (section 6). Do not rely on a box for meaning. - **Lists:** a blank line before every list. Do not use tables (a wide table is squeezed on a phone): use a list, one item per row. - **Pictures:** each needs a caption (what it shows, with the credit and licence) and alt text (what a person who cannot see it needs to know, in two or three sentences). Keep each to one idea. - **Do not** set fonts, colours, sizes or page breaks. Do not write a contents page by hand. Do not add a "your notes" page: the reader has notes and marks of its own. **The look** sets how each chapter opens in the cbook reader. Choose one for the `look` field and say which and why: - `plain`: reference, reports, and anything without a clear genre. If unsure, use this. - `story`: a book read as a story (a large first letter). - `guide`: a reading book, a how-to, a travel guide (a smaller first letter). - `convert`: a book converted from a PDF or text file and left as it came. Rarely right for a new book. ## 5. Chapter text: the Markdown subset Write each chapter in this subset. The builder turns it into the right pages. Everything else is plain text. - A paragraph is lines of text, with a blank line between paragraphs. - `## Section title` and `### Smaller title`. Start each chapter's headings at `##`, never skip a level, and never use `#` inside a chapter: the chapter title comes from the `title` field. - `- item` for a bullet list, `1. item` for a numbered list. A blank line before and after. - `**bold**` and `*italic*`. - `[link text](https://example.org)`. Real links only, with words that say where they go. A web address may contain one pair of round brackets, such as `https://en.wikipedia.org/wiki/Genie_(world_model)`. - `> a quotation` (a line starting with `>`). - A callout: a line `:::note Title`, then the text, then a line with `:::`. - A picture: `` on a line by itself. The file must exist next to the script. Skip pictures if you have none. - The sources list of a chapter: end the chapter with `## Sources for this chapter` and a bullet list of links. The builder keeps it out of the contents and sets it apart. Use real typographic characters where the text calls for them (curly quotes, en and em dashes, degree signs, the multiplication sign). Make sure special characters came out right. ## 6. Build the EPUB file If you can run Python 3, do this. Save the script below as `make_epub.py`. **Copy it exactly, character for character.** Do not retype it from memory and do not shorten it. In an earlier test an assistant mistyped one address inside it (the package namespace, which must be `http://www.idpf.org/2007/opf`) and the book came out with a broken package file that some readers cannot open. Every string that looks like a web address must stay exactly as written. Fill in the `BOOK` block at the top (title, author, rights, edition, look, description, who made it, the from-memory list, and every chapter). For a long book, write each chapter to its own file (`ch01.md`, `ch02.md`) and give `"md_file": "ch01.md"` instead of `"md"`, so no single step is too long. Run it with `python3 make_epub.py`. It checks its own work (every page is well-formed, every image has alt text) and tells you what is wrong in plain words. Fix that and run it again. It prints the file name and the identifier. If you cannot run code, or cannot give the person a file: say so plainly. Then write the chapters in the Markdown subset above, and give them to the person as text in the chat, with the BOOK block filled in. Tell them this is not an EPUB yet, and that a free converter such as pandoc, or another assistant that can run code, can make one from it. The script (tested with Python 3 on 2026-11-13; it has not been tried in every assistant's sandbox): ```python #!/usr/bin/env python3 # cbook book builder. Text in, EPUB 3 out. Python 3 standard library only. # Fill in BOOK below, then run: python3 make_epub.py import datetime, html, os, re, sys, uuid, zipfile import xml.dom.minidom BOOK = { "title": "Title of the book", "subtitle": "", # may be empty "author": "Author name", "language": "en-US", "identifier": None, # None makes a new one. For a later edition of the SAME book paste the old one here. "look": "plain", # plain, story, guide or convert (see the guide, section 5) "description": "One or two sentences about the book.", "subject": "", # a few words, such as "space history" "rights": "(c) 2026 Author name. All rights reserved.", "edition": "Version 1", "made_by": "Written by Author name with an AI assistant (name the assistant).", "review": "Not reviewed by a subject expert.", "from_memory": [], # statements that came from memory and were not checked against a source "cover": None, # path to a JPEG or PNG, or None "chapters": [ # Each chapter is {"title": "1. Name of the chapter", "md": "text in the Markdown subset described in the guide"} # or, for a long chapter kept in its own file: {"title": "...", "md_file": "ch01.md"} {"title": "About this book", "md": "What this book is, who made it, and how far to trust it.\n\nThis is a sample paragraph with **bold**, *italic* and a [link](https://example.org)."}, {"title": "1. First chapter", "md": "## A section\n\nA paragraph of text.\n\n- A point.\n- Another point.\n\n## Sources for this chapter\n\n- [Example source](https://example.org), 2026."}, ], } # ---------- Markdown subset to XHTML ---------- esc = lambda t: html.escape(t, quote=False) attr = lambda t: html.escape(t, quote=True) def inline(t): t = esc(t) t = re.sub(r'\[([^\]]+)\]\((https?://(?:[^()\s"]|\([^()\s"]*\))+|#[A-Za-z0-9_-]+)\)', r'\1', t) t = re.sub(r'\*\*(.+?)\*\*', r'\1', t) t = re.sub(r'(?\1', t) return t MEDIA = {'.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.png': 'image/png', '.gif': 'image/gif', '.svg': 'image/svg+xml'} class Ctx: def __init__(self): self.n = 0; self.last = 1; self.images = {} # images: zip name -> source path; last: level of the last heading def hid(self): self.n += 1; return 'h%d' % self.n def convert(md, ctx, heads): lines = md.strip('\n').split('\n'); out = []; para = []; i = 0; in_sources = False def flush(): if para: out.append('
' + inline(' '.join(para)) + '
'); para.clear() while i < len(lines): ln = lines[i] if not ln.strip(): flush(); i += 1; continue if re.match(r'#\s', ln): raise ValueError('Use ## and ### inside a chapter. The chapter title comes from the title field: ' + ln) m = re.match(r'(#{2,4})\s+(.+?)\s*$', ln) if m: flush(); lvl = min(len(m.group(1)), ctx.last + 1); ctx.last = lvl; text = m.group(2) # never skip a level if text.lower().startswith('sources for this chapter'): if not in_sources: out.append('' % inline(' '.join(q))); continue para.append(ln.strip()); i += 1 flush() if in_sources: out.append('%s
%s
' % esc(B['subtitle']) if B.get('subtitle') else '' files['text/title_page.xhtml'] = page(B['title'], '%s
' % (esc(B['title']), sub, esc(B['author']))) # chapters for n, c in enumerate(B['chapters'], 1): ctx.last = 1; heads = []; md = open(c['md_file'], encoding='utf-8').read() if c.get('md_file') else c['md']; body = convert(md, ctx, heads); name = 'text/ch%03d.xhtml' % n files[name] = page(c['title'], '%s
%s Built %s with a Python script from the cbook authoring guide (standard library only).
' '%s
%sLook: %s. Identifier: %s.
%s
') % ( inline(B['made_by']), esc(B['edition']) + '.', today, inline(B['review']), ('Statements from memory that were not checked against a source:
Nothing was marked as unchecked memory.
', esc(B['look']), esc(ident), inline(B['rights'])) files['text/colophon.xhtml'] = page('How this edition was made', colo) chap.append(('text/colophon.xhtml', 'How this edition was made', [])) # contents def li(f, t, hs): sub = ''.join('