Laying Out a Print Book with CSS
iangmcdowell.com
iangmcdowell.com
As he mentions, unfortunately the CSS3 Paged Media spec is not very well-supported by major browsers, though other tools do implement it.
I actually started to love CSS much more when I had to use another code-based solution: LaTeX. LaTeX is great for equations and automatic bibliography, but not for much else. If you ever tried to merely style a minimally complex table in LaTeX, you know what I mean. You actually see in major research papers that people sometimes just give up and include a screenshot of their table. LaTeX has no inherent distinction between structure and design, like HTML+CSS, which generates incredibly inelegant bloat code, like writing and styling a website in pure HTML without any CSS. Moreover, there often is no consistent syntax in LaTeX, and most everything can only be achieved with some sort of hackish package someone put together years ago without proper documentation. HTML and CSS are a breeze in comparison. CSS features like Flexbox or Grid let you do complex dynamic layouts in a few minutes, which are so difficult in LaTeX that most users would just throw the towel.
- widows/orphans
- running paragraphs one or more line longer or shorter
- setting a page spread to be one (or possibly two) lines deeper or shallower
- adjusting the size/cropping of an image/figure/table so as to influence pagination
- adjusting the placement of an image/figure/table so as to influence pagination
In my decades of doing typesetting, I've had exactly _one_ chapter come out perfectly on import w/ no need to adjust _anything_ --- fastest 40 minutes of my life.
It's an polyfil for the unimplemented CSS paged specification, which is exactly that is needed for laying out pages. https://www.w3.org/TR/css-page-3/
Weasyprint looks nice, I have yet to use it. It probably has the advantage of not using an actual browser document (with all the relayouting problems), and may use fewer resources in terms of time and memory (I'd have to check though). The disadvantage is also it's not an actual browser document, meaning you need to render the html and css in some form before passing it to weasyprint.
Using a headless browser makes it easier in general to do some fancy stuff like music sheets or embed js chart libraries and so on.
I'm not sure I understand this part. WeasyPrint is a rendering engine; it takes an HTML file as input and outputs a PDF.
I can't speak to resource usage, since this was very ad-hoc. For my needs, it was very simple to set up, and worked on the first try. I was testing with about five pages of content, and on my M1 MBP it rendered out the PDF pretty close to instantaneously, which was nice for the edit/refresh cycle. Preview on MacOS actually live reloaded when the PDF changed, which was a pleasant surprise.
With a headless browser you can use for example react to generate the document, you can just insert any chart library and so on.
And regarding resource usage I had scenarios of "pdf as a service" in mind, where you need to generate pdfs dynamically. Reporting, invoices, what have you.
If your charting library runs server-side and outputs HTML/CSS, then it'd work fine, but most of that stuff requires javascript, and yeah, WeasyPrint doesn't have an interpreter. Once you're already paying the overhead of a browser, you're probably better off using a JS polyfill than piping through another tool, unless paged.js is an insane resource hog (which seems unlikely).
Something to check out next time I do this.
I haven't looked at wider distribution, but I believe most of the print on demand publishers accept a PDF file. I think some (all?) also take InDesign, which is Adobe's thing.
They will handle the typesetting themselves.
You need to do it all only if you are self-publishing.
This example from the article says it all: https://iangmcdowell.com/blog/book_breaks.png
I understand that LaTeX is convoluted and other software is expensive, but when offering an alternative, there should at least be a comparison based on the quality of typesetting.
Perfect is the enemy of the good, they say.
I looked into CSS hyphenation because I was curious about controlling hyphenation in ebooks. CSS hyphenation appears to be based around the principle that you manually insert HTML entities representing potential hyphen locations into every word, which is obviously insane.
hy­phen­ation
hy­phen­ation
hy­phen­ation
hy­phen­ation
The TeX way is to provide a set of hyphenation points once, such that, if a word needs to be hyphenated, that list can be consulted and the word can be hyphenated appropriately without each instance of it needing to be entered with several invisible HTML entities. \hyphenation{hy-phen-ation}
hyphenation
hyphenation
hyphenation
hyphenation
I can't think of any use case where I'd prefer what is apparently the only way to do it in CSS. Do epubs have a bespoke non-CSS way to handle this?(I looked into this in the first place because the Kindle mobile app is godawful at hyphenating words, and I wanted to know what it would take to write an ebook that didn't have obvious howlers. The errors occur in foreign words, but they violate the rules of hyphenating English -- I've seen the app place a hyphen before the first vowel in a word, and I've seen it render "Qis-han", which is exactly equivalent to a hypothetical English "fis-hing" -- so it seems like they must be using a lookup table for all English words and falling back on something completely ridiculous for words that aren't in the table.)
In CSS, automatic hyphenation must be explicitly turned on, see [3].
In TeX and in CSS, hyphenation points can be marked explicitly: in TeX with the \- macro and in CSS with the ­ or U+00AD character. In TeX you can also override the automatic division with \hyphenation{}.
The splitting algorithm in CSS is worse than the one in TeX, because it has to work in real time and because (good) splitting patterns are often missing.
[1]: https://www.tug.org/docs/liang/
[2]: https://www.fi.muni.cz/usr/sojka/papers/euro01.pdf
[3]: https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens
And that is what the algorithm you refer to does! Your links [1] and [2] speak specifically in terms of the patterns being a form of data compression that is applied to lighten the storage requirements of a big list of correct hyphenation points. The hyphenation algorithm is just that you check the word you want to hyphenate against the Master List Of All Words and learn where hyphenation is allowed. The patterns are a form of data preprocessing that makes that algorithm more efficient (here, in terms of space requirements) without changing the output.
So what we need is a way to extend the set of precomputed rules whenever we want to use a word that wasn't in the original dictionary. As noted, TeX provides this with the \hyphenation{} command. Why is this not available in CSS?
Suppose I want to write an ebook that doesn't make mistakes on the level of "fis-hing" and "f-orest". [Another example I'm not making up; the Kindle app is convinced that "Ts-inghua" is correct hyphenation.] How do I include the hyphenation information in my document?
Surely that's only the case for real-time renderers like web browsers.
If you're creating a layout engine for printed media that uses CSS as the way for authors/setters to specify style, couldn't it implement a better, slower splitting algorithm? Using an internal (or pluggable?) dictionary of hyphenations?
What does it say? I read lots of book and... it looks like every other book. What am I missing?
You start to see how in the first line it’s fairly widely spaced but the second line starts to look like the line was crammed in to fit the line.
It’s subtle but those are the kinds of things that proper print layout tools help with. It’s weird looking at one page in a vacuum you won’t notice as much but after a few pages it starts getting “harder” to read. I’ve noticed this with some E-books and started to pick up on it.
In fact, the spaces are all over the place.
I'm also guilty of picking Baskerville as the default classic look to printable font-family and even had resorted to it for screen.
Besides the tools mentioned in the article (Vellum and Atticus), Ulysses also has a good option for print-ready output.
The part that seemed hardest to get just right with CSS was text justification. I can specify inter-word justification, but there are cases where getting the spacing just right is impossible without breaking a long word using a hyphen. As far as I can tell, there's no programmatic way to do this with just CSS.
I addressed widows and orphans in my ePub layout, but for some reason forgot it in the print layout (d'oh). The nice thing about print on demand is it's easy to make updates, which I will. So thanks for pointing that one out! I'll also read up on using a baseline grid, I suspect CSS will work fine for that, since my content is all text with little variation between sizes.
Leanpub accepts standard Markdown (though does have its own markdown format now) and gives you an "export for printing" button that you can upload to Lulu. The cover was kind of tricky and I got some professional design help both to design it and to get the margins and bleeds exactly as Lulu wanted them, but the result was way better than I expected.
I haven't tried the other professional tools mentioned in this article so I can't really compare quality or ease, but might be worth a look if anyone is looking for something in between "do it all yourself" and "pay for fancy tools". (I have a lifetime LeanPub license from back when they still offered them but the monthly subscription fees are a lot lower than some of the tools mentioned here and you can easily get a printing done in a single month).
Also, towards the end, this gave me a chuckle!
> It’s like Linux: free so long as your time has no value.
The article has the air of a hack done just for the fun of it because the author can. This was popular once upon a time but these days, it's mostly stuff written to promote certain things or as marketing copy.
I'll give you a peek inside my head, and you can decide if you trust me to be telling the truth.
I did this silly hack because I wanted to hold a copy of my book. I knew it was crazy when I was doing it, and that there were simpler/better ways of accomplishing the same goal. But I was surprised that (1) it worked at all, and (2) it came out as well as it did – though you can certainly find people in the comments here who can identify the flaws.
I did not do this silly hack because I wanted to use it to write a marketing post. That would be an extraordinarily convoluted way of going about things, even for me.
Anyhow, I like writing, and I like sharing my writing, so I put together this post about something I did that I found interesting. I don't expect everyone to enjoy it, but it seems like some people found it entertaining and/or learned a little bit about CSS.
And yes, I included two links to my book. Given that the existence of the book is central to my motivation to pursue the project, it would be silly not to at least mention it. So I did, one link at the top where I think it's relevant context, and an actual "pitch" at the bottom, separated from the other content/called out explicitly so anyone allergic to marketing could bail. I'm not being snarky; I personally dislike marketing and hate most of the ways it's done.
And even still, I do feel conflicted. I grew up in the 90s, and I miss that old, pre-commerce internet populated by hobbyists. Maybe I should have left the pitch out.
My evaluation was based on my own subjective feeling so it could be wrong but I still don't feel any different even after reading the counters to my initial post.
I would guess a handful at most.
And I am not saying that to criticise the author. Marketing is genuinely difficult. Hell I even did a marketing campaign with paid ads on Reddit to get more people to use one of my pieces of open source, free of charge, pieces of software and even with a bunch of ad impressions and clicks I can still count the amount of new stars on just a few hands
7 ebooks ordered as of 10:15 PST, and 10 subscribers for the free novella.
I have no idea how many people read the post, I assume lots? I'm hosting on Github pages and haven't added any tracking. It seems like anecdotally a front-page post gets ~20k views, so some tiny fraction of a percent of readers went on to purchase.
Honestly, this small number of sales is still far more than I was expecting. I wrote a longer response on my motivations higher in the thread, but my primary impulse was sharing, not marketing. I tacked a marketing pitch at the end, figuring I might as well, but I did not expect the post to spend any time at all on the front page of HN.
It is also probably true that this "marketing" was worse than ineffective, it was likely detrimental. I'm guessing that substantially more people clicked through to Amazon to see what the book was, despite being a poorly targeted audience that is unlikely to convert. From Amazon's point of view, the book just got a ton of traffic and very few sales, which is probably treated as the signal "this book is not a good seller, don't show it to people."
Similarly, the members of this poorly targeted audience that did buy the book are unlikely to be typical readers in the genre. This will degrade the "also bought" signal for the book, and to the extent that Amazon does organically show my book to other readers, it will likely show it to the wrong readers, further hurting organic performance.
I would assume they were typical readers in the genre, which obviously some percentage of readers from HN would have to be.
A post of mine on criticism https://news.ycombinator.com/item?id=32392070 went to front page for a bit and got 4.7K hits according to medium.
I would think if Amazon has any sort of decent traffic analysis ranking it would have the understanding of unknown/random spikes and discount negative data from that as noise (unless it led to a bunch of negative reviews etc. in that spike) but maybe I'm just too hopeful about stuff.
Wish I could sell some books though but as I don't ever it seems unlikely I know what I'm talking about anyway. :)
Traffic spikes are actually a common occurrence in book sales. My understanding is that some of the most effective marketing is through paid newsletter inclusion – sites like BookBub/Freebooksy/Fussy Librarian. These newsletters absolutely drive big spikes in traffic, and the conversion rate is going to correlate well with how well the book will sell overall. It's possible Amazon does something with the referrer to try to segment these kinds of traffic, but impossible to know from the outside.
If you just want to move copies, you should look at the Facebook group 20BooksTo50k. It has lots of informative posts by self-published authors doing six figures in annual sales. I can distill it down for you though. The people finding "quit your job" levels of success generally:
- write to market
- in a consistent genre
- for several years
- and publish five or more books per year, mostly in a series.
Some people reach that level of success faster, though they tend to be in the largest genres (mainly romance), or publishing at truly breakneck speed (a book or more per month).
Personally, I write things that don't slot quite cleanly into a genre, and I have a tendency to genre hop. I know it's sub-optimal, but I'm pretty sure I'd just burn out trying to do it the other way.
I'm also not yet at the point where I can write work I'm proud of at that velocity; the last book I wrote took me two months to get a first draft, and it's probably going to take another two months to get it to a "finished" state. So I'm on a "three books a year" pace, and it already feels exhausting/I may need to slow down.
(1) It has a pretty good idea about Layouts, Pages and other elements one would need for printing
(2) It supported all the graphics formats that I ever needed in the past and automatically fetches images by URL when it stumbles upon them.
(3) It is easily embeddable into some custom Java app.
(4) It is based on W3C open standard (which though doesn't seem to be developed anymore)
(5) It does PDF/A.
(6) XML/XSLT is a bit annoying to write for your template, so I used a common templating engine (e.g. Thymeleaf) to render the XML/XSLT that I passed on to FOP. Worked like a breeze and gives you the possibility to create your own little DSL.
(7) I'm still happily generating my invoices through FOP put behind an API that takes input data and uploads the generated documents into a bucket.
(8) I don't have the exact numbers but last time I checked and compared output sizes of browser printed pdfs vs "generated by Fop", I saw smaller PDFs with Fop. It doesn't mangle the input images though
All in all, I trust FOP better to generate printable documents than any CSS/Headless Browser thing. It comes with an arcane template format which, as said, can be abstracted away but therefore has much smaller infrastructure footprint than spawning headless browsers.
It's FOSS, mature, and actively used for book layouts by others. It comes up in searches for "free InDesign alternative" and "foss book layout" (it's mentioned in every search result that I viewed [not many]).
I mean, perhaps it didn't fit the story that showed the blog post to be used to trail the book, but I'd have thought it would be mentioned.
For a project like this, I think it's a good choice to go with something more declarative over a WYSIWYG tool. Latex would have been a very good choice, but only if you already happen to know it or have an interest in learning.
Probably about 3 years since I used it last for this type of work.
I follow one of their support groups and people mention they publish newsletters, pamphlets, and books with it.
For a book I'd just throw it in latex for sure.
You can tell it was built from the ground up for books, and not scholarly publications. In that respect it’s actually closer to plain TeX.
It doesn’t try to be overly semantic because books are complex beasts, and there really is no useful-but-wrong simple model that doesn’t handicap you.
Like, not all books have chapters. Some have hundred of very short chapters, with multiple on a single page.
It’s also much more “batteries included”.
Basically; trying to do a book in LaTeX you end up fighting the defaults, and for some there are NO good reliable overrides.
Take a look at the manual (http://www.pragma-ade.nl/general/manuals/ma-cb-en.pdf) page 83 (numbered) 87 in the pdf. Imagine trying To the that in LaTeX.
I agree that ConTeXt would be a better fit than LaTeX.
Yeah, agree, but a work of fiction doesn't usually have tables, figures, references, equations, etc which can be painful in LaTeX.
It does have kerning, ligatures, orphan/widow management, runs/ladder management, page numbering, chapter numbering, margins (larger closer to the spine), rules, struts, etc that all come for free without the author having to know any of that stuff.
IOW, for a work of fiction, the learning curve for LaTeX is likely limited to setting the font, setting the size, setting the output type (book, article, etc) and using bold, emphasis, underline and possible verbatim.
The learning curve for LaTeX is a cliff if you're writing a thesis, it's simply markup if you're not.
Anyway, I am happier creating native (desktop) applications than webapps, except that I don't think that there is a market anymore for them. How well is your native desktop app doing? Is there a large enough market for applications that need to be installed locally only? How do you market these?
Book layout is a very complicated topic. If you look at that image and step away a bit it leaves a chaotic visual impression. Reason behind that is that if you want a visually pleasing look, all the paragraphs have to have a similar "density". That is defined by how long the words are, the spacing in the words (kerning, ligatures, font), and the spacing between the words. Latter is all across the board, even changes within the same paragraph! LaTeX has all that typesetting knowledge included, and it will actively hyphenate words to accomplish its goal. I see exactly one word being hyphenated there.
Another thing that stuck out immediately was the font selection for the all uppercase paragraph. Some fonts are just not made to be used that way and this is one of them. These curvy uppercase letters are nice to start words, but used together it is ... ugh.
Last is that leftover sentence at the top of the right side. It "validates" the separator image, so this is somewhat of a pro/contra mixed bag situation.
Professionals could probably say even more about all this, I just used LaTeX for a couple years more often and these are things I learned (to see) on the way.
Didn't know Serif had made a third product. Be wary of them - Designer and Photo are both buggy minefields and their support forum is full of snobby jerks. Crashes have been reported and present for years, with little or no response from Serif. Their developers all seem either disgruntled or burnt out. Some of the employer review sites confirm this.
They're cheap but you certainly get what you pay for. Save often, back up often. I say this as an avid Designer user.
Functionality, also yes, but not by much. Only thing I miss from Photoshop in Affinity Photo is content aware tooling. I don't remember anything I miss from Illustrator in Affinity Design and I actually think they have better features than Illustrator (admittedly haven't used Illustrator in almost a decade so maybe they've caught up).
You really can't beat Affinity's price though unless you use GIMP/Inkscape of course, but I like neither of those programs.
https://taoofmac.com/space/notes/2023/03/19/1849#tuesday-202...
Just to point out, in the original post, the author does end up using weasyprint, as the tools he began with did not support the required CSS features.
Then I realized that I could just have generated HTML and printed it via some headless chrome script. The rendering was more consistent, and the printing was much faster (IIRC it took about 1/3 the time.)
Using macros and defining your own functions in LaTeX is a game changer, and when it came time to make my second book, I was up and running typing content in about five minutes, and it has the precise same look and feel.
[1] http://theroadchoseme.com/how-i-self-published-a-professiona...
Shame really, because IMO a web-aligned document writing tool chain would be awesome.
A better phrase would be: Free software is "free" as long as you value your free time, more then you value your time at work.
Then someone recommended AsciiDoc and AsciiDoctor. It was a much better experience compared to Markdown. Sure, not for pixel perfect tweaking. Still enough parameters to play with. Easy to create PDFs and EPUBs.
-webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-variant-ligatures: contextual common-ligatures;
Give them a try and let me know if they help :-)
Sure, browser support isn’t there yet, and this is still draft work, but it’s coming.
It is a printed book... there is no color in the process.
that's where I gave up.