Forum How do I...?

Faster style iteration?

schneems
Hello,

I'm new to the prince ecosystem. I was previously using pandoc to build PDFs and I was able to use the HTML output of pandoc to approximate styling for the PDF so that I could use normal browser inspection and manipulation tools. I'm wanting a similar flow (or maybe suggestions on alternatives) with prince.

With Prince when I've got my styles and I've got my HTML, but viewing it in the browser looks wildly different than the PDF (See attached comparison). The only way I've found to reliably edit styles is to re-generate the whole PDF, scroll to the page I wanted to style, see that it's not what I wanted and go again. With pandoc it was instant feedback and a very familiar CSS toolchain.

Is there a way to better approximate prince output when viewing my document in the browser? It doesn't need to be perfect, but for now it's not even close. Maybe there are some default values for max-width etc. that someone has found that bring it closer? Any tips are appreciated.
  1. Screen Shot 2021-10-16 at 8.12.23 PM.png328.1 kB
    prince doc with styles in my browser
  2. Screen Shot 2021-10-16 at 8.12.48 PM.png1.7 MB
    Same doc in PDF
jpavel
I've found that browsers and Prince have significantly different default values for their User Agent stylesheet, the biggest of which applies to lists. You can use a thorough CSS normalizer, or at least the minimum of

ul, ol {
  padding-left: 0;
  margin-left: 40px;
}


To keep lists consistent.

One thing you can do to avoid trial and error is to open your HTML page in Chrome devtools and just copy everything in an element's User Agent Stylesheet section into your CSS file, to ensure Prince is using the same values.

Edited by jpavel

schneems
> copy everything in an element's User Agent Stylesheet section into your CSS file

That's an interesting strategy, instead of getting my browser to mimic prince...have prince mimic my browser. Thanks for the idea. I wonder if anyone has reverse-engineered prince's "defaults".
mikeday
The Prince default style sheets can be found in the "style" directory of the Prince installation.
phillipgessert
For a long time, I used a PDF viewer called Skim for this kind of review, because it can update live. You still have to regenerate the PDF, but at least you don't have to find your place again afterward. Skim is macOS only, but I'm sure there are PDF viewers for other platforms that have the feature.
schneems
> The Prince default style sheets can be found in the "style" directory of the Prince installation.

Awesome, thanks! I'll check that out.

> Skim is macOS only

Good tip too, thanks I'm on a mac so that works for me!
pjrm
A few ideas for those cases where you do still need to see specifically Prince's output (e.g. styling footnotes or something else not supported by browsers), the following might help:
  • Apply display:none to all but one element and its descendants & ancestors:
    :not(#foo, #foo *, :has(#foo)) { display:none !important }

  • For books where each chapter begins on a new page, split the input into one HTML file per chapter, to make it easy to run Prince on just one chapter, while still being able to produce the whole book by simply passing all HTML files at once on the command line. (Thus, it's simply a special case of the above, but more convenient, and slightly faster too.)
  • Start Prince sooner after each change by having it run automatically each time the document is changed: e.g. if using a Linux-based operating system, then
    while :; do (prince foo.html -o foo.pdf.tmp$$ && mv foo.pdf.tmp$$ foo.pdf); inotifywait foo.html; until [ -f foo.html ]; do sleep 0.1; done; done
    (The temporary file is in case your pdf viewer watches the pdf file for changes; while the "until" loop is in case your text editor is configured to rename the existing document before writing a new copy.)
The following stylesheet will speed up rendering, at the cost of changing line breaks and page breaks, and (in normal Prince) changing text-align. Thus, it isn't always suitable, because it might invalidate whatever visual evaluation you're trying to do.
* {
    hyphens: none !important;
    widows: 1 !important;
    orphans: 1 !important;
    break-inside: auto !important;
    break-before: auto !important;
    break-after: auto !important;
    column-fill: auto !important;
}

/* Avoid searching for optimal line breaks. */
@supports not (prince-line-break-choices:fast) {
    /* Normal Prince: only justified text involves search. */
    * { text-align: start !important }
}
@supports (prince-line-break-choices:fast) {
    * { prince-line-break-choices: fast !important }

    /* Avoid pagination adjustment. */
    @page { prince-page-fill: prefer-fill !important }
}

The last bit of that stylesheet is for Prince for Books, though I'd guess that you aren't using that. For those that do use Prince for Books, note that normal Prince is noticeably faster than Prince for Books (though again with the possibility of changes to rendering that affect the visual evaluation).

[The reason for my guess that you aren't using Prince for Books is simply that the styling in this book doesn't benefit much from Prince for Books: 12 words per line and no hyphenation means that line breaking isn't very challenging, while using paragraph spacing means that it's simply expected that lines on facing pages won't align with each other.]