Booki User Guide

More CSS Book Design

Contributed by James Simmons

One of the things that attracted me to the Booki project was the possibility of creating a printed book. I learned about Booki through the FLOSS Manuals website, which hosts several manuals written by Sugar Labs and the One Laptop Per Child project. These manuals had been written using an software which became the prototype for Booki.

I had been involved with Sugar Labs and OLPC for several years, and had written several Activities that run under Sugar, the operating environment used by the One Laptop Per Child project. I had learned to do this by reading Wiki posts, asking questions on mailing lists, looking at other people's code, etc. It had been a long, frustrating process. There was only one manual for making Sugar Activities, created by OLPC Austria, and it wasn't something that you could give to a new programmer. I program computers for a living and I still had to learn a lot before I could make my first Activity.

One of the goals of OLPC and Sugar Labs is to have teachers and students write their own Activities, and we really needed a manual aimed at that audience. It needed to be a manual that anyone could read for free on the web or as a downloadable e-book, but I wanted a printed book to be available too.

Booki has a lot to offer an author, even without the possibility of creating a bound and printed book, but there is something real about a printed volume that is a great motivator. Authors of printed books get invited on Oprah, are given respect, and get to trade wisecracks over lunch at the Algonquin Hotel. You don't get all that from making websites and e-books.

I have a pretty good collection of old books in my home and have a great deal of respect for the people who design books. I never bargained for being one of them, though. When we submitted my first book to Lulu I just used the default style sheet of OBJAVI (the part of Booki that generates PDFs from your HTML) and I was not too happy with the copy of the book I received. The font for the body text was too small, the font used for the formatted code samples was even smaller, chapter headings and subheadings were ALL CAPS, and there were some odd page breaks. For instance, subheadings would appear at the bottom of a page with the content for the subheading on the following page.

I really should have caught all this before submitting my PDF to the printer, but I didn't for a couple of reasons:

  • Adobe Reader displays pages in a PDF magnified 160% or whatever it takes to fill the screen. At that magnification it looked OK.
  • Lulu actually shrinks the pages in the PDF a bit to create a book. "Crown Quarto" actually prints out larger than the size of the published book.

Fortunately Lulu is print on demand so you don't have a warehouse full of books to deal with, and we were able to remove it from Lulu while I worked on these problems. This meant creating my own style sheet.

Anyone who has ever printed out a web page knows that the state of HTML printing is lamentable. (At times as a professional web developer I've used stronger words, but "lamentable" gets the idea across.) The W3C has created some standards for style sheets that are used specifically for printing. No web browser actually implements all of these, and the "Webkit" browser engine used by OBJAVI doesn't either, but it does enough that you can use HTML and style sheets to create a usable and attractive book. There are some tricks involved, which I'll explain. First let's have a look at my style sheet:

body {
  "Palatino Linotype", Georgia, Serif;
  
  background: #fff;
  
}

h1, h2, h3, h4, h5, h6{
  "Gentium Book Basic";
  page-break-after: avoid;
}

.unseen{
  z-index: -66;
  margin-left: -1000pt;

}

.objavi-chapter{
  
}

h1 .initial{
  
  
}

.objavi-subsection{
  display: block;
  page-break-before: always;
  
}

body .objavi-subsection:first-child{
  page-break-before: avoid;
}

.objavi-forcebreak {
  page-break-after: always;
}

.objavi-subsection .initial {
  
  
}

.objavi-subsection-heading{
  
  font-weight: bold;
}

h1 {
  page-break-before: always;
  background: white;
}

table {
  float: none;
}

h1.frontpage{
  
  text-align: center;
  page-break-after: always;
  page-break-before: avoid;
  max-width: 700px;
}

div.copyright{
  padding: 1em;
}

table.toc {
  /*border: 1px dotted #999;*/
  
  width: 95%;
}

td.chapter {
  padding-left: 2em;
  text-align: right;
}

td.pagenumber {
  text-align: right;
}

td.section {
  
  font-weight: bold;
}

p, ul, ol {
  page-break-inside: avoid;
}

pre, code, tt {
  "Courier New", "Courier", monospace;
  
}

pre {
  max-width:700px;
  overflow: hidden;
}

img {
  max-width: 700px;
  height: auto;
}

This style sheet is mostly the same as the default one, with the following changes:

  • I changed the fonts used for headings and body text to be the same ones used by the Collaborative Futures book.
  • I changed the font sizes for body text and preformatted text to be point sizes rather than "ems". I used 14 points for the Palatino body text and 12 point Courier for the formatted code examples. For some reason Serif fonts look smaller in the same point size than Sans Serif fonts. At 12 points the Palatino text was actually about the same size as the text I was trying to correct.
  • I removed the style that made headings, etc. ALL CAPS.
  • I temporarily put a border around the PRE tag text. (I don't show the border style in the example above, but it's similar to the commented out entry for table.toc). When I made my formatted text larger some of it got chopped off. I needed a way to easily spot when that happens and the border did that. Since most of the book was formatted code samples I spent a LOT of time reformatting Python code to fit on the page.
  • Last but not least I created my own style for class "objavi-forcebreak". I needed this to force page breaks into the PDF where needed.

The last point needs some explanation. Ideally OBJAVI would know better than to put a subsection header at the bottom of a page and have the paragraph following on the next page. If Webkit supported the keep-with-next property of CSS this would be possible, but it doesn't. We need to give Webkit some help by inserting page breaks where they are needed. To do this we need to edit raw HTML.

Fortunately, this is not too awful. You need to turn on HTML mode in the page editor, then look for the heading you want to move down. It will look like this:

<h2>My Badly Placed Heading</h2>

Insert a DIV tag like this to force a page break:

<div class="objavi-forcebreak"></div>
<h2>My Badly Placed Heading</h2>

When you use the new stylesheet this DIV will force a page break wherever you put it.