I typeset a little book :-) (and postmortem thoughts)

I’m getting into typesetting books! I’m starting by taking some shorter ones out of project gutenberg (common domain) for some practice. It also happens that I really enjoyed omats in high school! Here’s my current draft:

omats.pdf (284.8 KB)

Code
#set text(
  font: "EB Garamond",
  number-type: "old-style",
  size: 12pt,
)

#set page(
  width: 4.25in,
  height: 5.5in,
  margin: (top: 0.7in, bottom: 0.7in),
  numbering: "1",
)

#set par(
  first-line-indent: 1em,
  spacing: 0.65em,
  justify: true,
  // justification-limits: (
  //   spacing: (min: 100% * 2 / 3, max: 150%), // default
  //   tracking: (min: -0.01em, max: 0.01em), // recommended
  // ),
)

#show heading: it => {
  pagebreak(weak: true)
  set text(weight: "regular", size: 2em)

  it
  v(0.3in)
}

#set document(
  title: [The Old Man and the Sea],
  author: "Ernest Hemingway"
)

#let title-card() = {
  v(0.5in)
  set text(weight: "regular", size: 1.5em, font: "Castellar")
  set par(justify: false)
  align(title(), center)
}

#{
  // front matter
  set page(numbering: none)

  // {
  //   // half-title page, alt ver
  //   title-card()
  //   pagebreak()
  // }

  {
    // half-title page
    v(0.5in)
    align(smallcaps[the old man\ and the sea], center)
    pagebreak()
  }

  // blank
  pagebreak()

  // title page
  {
    title-card()

    image("white-marlin.gif")
    // alternatively can consider
    // https://etc.usf.edu/clipart/58100/58191/58191_seine-boat.htm
    // https://etc.usf.edu/clipart/4700/4794/fishing_boat_1.htm

    v(0.25in)
    align(center)[Ernest Hemingway]

    pagebreak()
  }

  // copyright page
  {
    set text(size: 0.7em)
    set par(
      first-line-indent: 0em,
      spacing: 2em,
    )

    let section(body) = par(body, hanging-indent: 1.5em)

    [
      _The Old Man and the Sea_\
      Ernest Hemingway\

      A work in the public domain, well, in Canada apparently. 

      // First published 1952\
      #section[
        Edition:\ 
        New York: Charles Scribner's Sons, 1952\ 
        Sourced from Project Gutenberg at\ 
        #link("https://gutenberg.ca/ebooks/hemingwaye-oldmanandthesea/")\
      ]

      #smallcaps[isbn-10]: 0-684-16326-8\
      #smallcaps[isbn-13]: 978-0-684-16326-0\

      Marlin  clipart from #link("https://etc.usf.edu/clipart/188300/188316")

      #section[
        Book design by saffronner\
        Body text in EB Garamond\
        Title in Castellar
      ]

      #pagebreak()
    ]
  }

  // blank
  pagebreak()

  // blank
  pagebreak()

  // dedication page + blank
  // table of contents
  [
    // foreword
    = Foreword
    I read this book in high school. I thought it was really good, so I wanted to typeset and so have it for myself. But what bad luck---I found while looking for clipart such an awe-inspiring marlin that I couldn't not use it.

    Unfortunately, if you somehow happen to read this book, and are not saffronner, you have been spoiled. There is a marlin. There is a sick-as-hell marlin. The first time I read this book, I did not know there would be an outstandingly awesome fish, and my experience was better for it; the rising action was all the more pronounced.

    Oh well. Anyhow, let's get on with it.

    \

    #align(right, [-- saffronner])

    #place(text(size:0.8em, fill: gray)[\ \ P.S. Erm. It appears this book is not actually public domain everywhere. So uh. Alice in Wonderland jumpscare!])
    #pagebreak()
  ]
  // preface
  // acknowledgements
  // introduction
  // abbreviations

  // blank
  pagebreak()
}

#counter(page).update(1)

#v(1in)

#include "alice-jumpscare.typ"
#pagebreak()

#set page(numbering: none)
#pagebreak()
#pagebreak()

#align(center)[
  #smallcaps[books by ernest hemingway]
  #v(0.1in)

  The Old Man and the Sea

  Across the River and into the Trees

  For Whom the Bell Tolls

  The Fifth Column and the First Forty-Nine Stories

  To Have and Have Not

  Green Hills of Africa

  Winner Take Nothing

  Death in the Afternoon

  A Farewell to Arms

  Men without Women

  The Sun Also Rises

  The Torrents of Spring

  In Our Time
]

In no particular order, I’d like to thank and mention the people at the Renegade Bookbinding Guild, memdesign authors, the Typst community, books on my shelves, etc.

process

Not necessarily in order:

  • Take the main matter source document. Regex the hell out of it to mold it into a Typst document. I wrote and use a CLI tool with a DSL at https://github.com/wade-cheng/regexer.
  • Write front and back matter.
  • #include main matter.
  • Write styling.

design notes (nonexhaustive)

The page size is quarter-letter. This is because physical books are best folded along the paper grain, and printer paper (most paper) is manufactured grain-long. That is, by taking a letter sized paper and cutting it in half, folding that half-sheet is along the grain.

Also, there weren’t enough pages to make the book an interesting thickness if it were half-letter.

postmortem

It was interesting setting a book, because it feels like there’s no really good way to wrap much of the styling into a library the way we usually do. That is, via a function that we call with show template.with(...): Such a function would basically need to re-wrap every parameter in par, text, and so on, just in case the author would need to use it. I wonder how Latex’s memoir does it…

On the topic of library API design, I recall a thread somewhere around here about separating styling and content into different functions. Couldn’t find it, but the interesting problem people noted was that the current pattern show template.with(abstract: [...]) leads to difficulty in changing the styling of that abstract.[1] So, show template; set text(size:1.2em); abstract[...] could be easier.

If I were to write a package for making books, or some other content-focused package, I’d probably follow this idiom. There could be functions for “spawning” individual specialized pages at a time or something, maybe… A separate function for the title page, half title page, etc etc.


  1. I believe there is some design work under way regarding this? ↩︎

7 Likes

Nice work!

Could you give a couple of concrete examples to show what the problem is?

I wonder if work like this could be contributed back to project gutenberg. Personally I’d love to see .pdfs available for some of their books, especially if they offer multiple page sizes. A nicely typeset book is usually going to easily beat the .epub.

2 Likes

I think the styling comments you have are those typst want to solve using custom types, in the future. Typst’s style system is designed to be composable in a layers, and it should be possible to use show abstract: set text(..) in the future case where the abstract is a custom type.

That’s only possible to partially simulate today, for example using a system with labels, but style using labels is discouraged. Another way is to use the elembic package.

4 Likes