A programming book fails in ways a novel cannot: a listing that wraps, a command that was copied with a smart quote, a font that turned l and 1 into the same glyph on someone else's machine. Markdown is a good format for this kind of book, because the listing is still just text — but only if the rendering step treats it as code rather than as a paragraph in a fancy face.
Fenced blocks, not indented ones
CommonMark has two ways to mark a listing. Use the fence:
```python
def greet(name: str) -> str:
return f"hello, {name}"
```The language tag is optional for the PDF and useful for you. Indented code blocks — four spaces, no fence — look the same in a preview and then collide with nested lists, with block quotes, and with anyone who pastes from an email client that ate the leading spaces. Fences survive that.
Do not put a listing in a screenshot unless the point of the figure is the IDE around it. Screenshots of code are how a book becomes unsearchable, uncopyable, and blurry on a retina display the author did not own.
The line-length problem
Prose wants 60 to 75 characters on a line. Code often wants 80 or 100, and wrapping a listing is not the same as wrapping a paragraph — the break is now in the wrong place in the program. The measure is still the constraint; the listing has to live inside it, not the other way around.
- Keep listings short. A 40-line function on one page is readable; the same function across a page break, with the signature on the previous sheet, is how readers lose the thread.
- Wrap the source, not the output. If a line is 120 characters, break it in the manuscript the way you would in a codebase with a linter, not with a CSS
pre-wrapsurprise in the PDF. - Elide the boring bits with a comment (
# ... setup from chapter 3) rather than pasting three pages of imports so the listing is "complete". Completeness that nobody reads is not a virtue.
The typeface has to be in the file
If the PDF says "Courier" and Courier is not embedded, the machine that opens it will substitute something else. On a developer’s laptop that something else might be fine. On a Kindle app, a corporate Windows image, or a printer, it might map 0/O and 1/l on top of each other. Embedding is not optional for a book whose meaning sits in the punctuation.
Pick a monospace with a real italic and a real bold if you will use those — many "coding" fonts have only one weight, and a renderer that is asked for bold will fake a stroke that looks worse than staying regular. 9 or 10 point, on a slightly looser line-height than the body, is the range that stays readable without shouting.
Structure that technical readers actually use
| Element | Markdown | Why |
|---|---|---|
| Chapter | ## plus a page break | One topic, start on a fresh page |
| Section | ### | The unit people skip to |
| Listing | Fenced block, kept on one page | The thing they will copy |
| Command the reader runs | Its own fence, no wrapping, no smart quotes | If this is wrong, nothing else matters |
| Output | A separate fence, or a block quote | So it cannot be mistaken for input |
| Warning / aside | A paragraph you label, not a colour you cannot see in print | Print is still how a lot of these books are read |
Number the listings if the prose will refer back to them ("see Listing 4"). Do it in the heading above the fence, not in a caption system the Markdown flavour does not have. Cross-references that depend on a plugin are the first thing that breaks when you change renderer.
What Markdown will not do for you
Syntax highlighting in the PDF is renderer-specific and often uglier in print than in a dark IDE. A book can live without it; it cannot live with a highlight theme that turns comments the same colour as the paper. If you highlight, proof a printed page, not a preview on a screen.
Line numbers in listings, callouts (① ② ③) into a block, and "start at line 40 of a 400-line file" are all layout features. Pandoc plus a listing package can do them; a lightweight Markdown-to-PDF tool generally cannot. Write so you need them less: shorter blocks, more words around them, a repository the reader can clone.
Mathematics is the other fork. If the book is really a maths book with some Python, Pandoc and LaTeX is still the correct stack. If it is a programming book with the occasional expression, Unicode and a fenced block will do.
In bukpress
bukpress renders fenced blocks in a 10pt monospace face, padded, with break-inside: avoid so a listing tries to stay on one page rather than splitting through the signature. Long lines wrap (pre-wrap) — which is the safety net described above, not a reason to stop shortening them. There is no syntax highlighting and no line-number gutter; a listing is type on the page.
Body, title and subtitle are chosen separately, so the prose can be a serif at 11pt while the listings stay monospace. Whatever you pick is embedded in the PDF and packaged into the EPUB, which is the difference between a book that still reads on a machine that has never seen your font, and one that does not.