WeasyPrint icon indicating copy to clipboard operation
WeasyPrint copied to clipboard

Dynamic page height, fit to content

Open kujiu opened this issue 10 years ago • 4 comments

Add an option on page size (for example for height) to adapt the size of the page to fit to its content. The document will have a dynamic size and not fixed-size pages.

kujiu avatar May 13 '14 13:05 kujiu

Is the goal to disable pagination entirely, or would forced page breaks (e.g. page-break-after: always) still apply?

SimonSapin avatar May 13 '14 13:05 SimonSapin

For a grading tool, we're actually hoping to do something similar so that each page in a PDF is only as tall as it needs to be to contain the page's content. Inspired by @SimonSapin's comments and @sebasmagri's comments at https://github.com/Kozea/WeasyPrint/issues/274, we've figured out how to get the actual height of the content in the body of a page, as via document.pages[0]._page_box.children[0].children[0].height. But to keep everything on one page, is there perhaps a more elegant solution than

  1. initially specifying a very large height and then cutting it down as needed (for which we'd need to guess a max possible height), or
  2. letting the content span multiple pages initially, summing the pages' heights, and creating a brand-new document whose @page height equals that sum (which feels a bit inefficient)?

Many thanks!

dmalan avatar Dec 24 '17 16:12 dmalan

Hi,

I've been working on this because I need to have dynamic height documents and I've found a workaround that works well for me.

Generating a 1cm height pages and then counting the result.

I hope this could help anybody.

Best Regards.


css_1cm = [CSS(string="@page {height: 1cm; page-break-inside: always;}}}")]
render = html.render(stylesheets=css + css_1cm)
css += [ CSS(string="@page {height: " + str(len(render.pages)) + "cm}}}")
html.write_pdf(stylesheets=css)



josesanch avatar Jun 21 '21 18:06 josesanch

I'll add here my use case for which I think I want the same feature: I'm generating images of syntax-colored code, for viewing on screens.

  • I don't want the lines to wrap, though it's not so bad that they do.
  • The generated image has a transparent border I don't want, but I trim that post-creation with graphicsmagick.
  • The generated image is extra long when the code is short, but I trim a second time with the same graphicsmagick invocation.
  • When the code more than 50 lines, I get a transparent gap between what I guess are pages, but I'm confused by the notion of "pages" in an image file altogether.

My current usage looks like this:

from plumbum import local
from weasyprint import HTML
try:
    convert = local['gm']['convert']
except CommandNotFound:
    convert = local['convert']


def mk_png(html: str, folder=None) -> str:
    """Return generated PNG file path"""
    folder = (local.path(folder) if folder else local.path('/tmp/ccb_png')) / uuid4()
    folder.mkdir()
    png = folder / 'code.png'
    (
        convert['-trim', '-trim', '-', png]
        <<HTML(
            string=html,
            media_type='screen'
        ).write_png(resolution=384)
    )()
    return png

AndydeCleyre avatar Jun 28 '21 19:06 AndydeCleyre