1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
"""
Demo script for PyMuPDF's `Story.write()` method.
This is a way of laying out a story into a PDF document, that avoids the need
to write a loop that calls `story.place()` and `story.draw()`.
Instead just a single function call is required, albeit with a `rectfn()`
callback that returns the rectangles into which the story is placed.
"""
import html
import pymupdf
# Create html containing multiple copies of our own source code.
#
with open(__file__) as f:
text = f.read()
text = html.escape(text)
html = f'''
<!DOCTYPE html>
<body>
<h1>Contents of {__file__}</h1>
<h2>Normal</h2>
<pre>
{text}
</pre>
<h2>Strong</h2>
<strong>
<pre>
{text}
</pre>
</strong>
<h2>Em</h2>
<em>
<pre>
{text}
</pre>
</em>
</body>
'''
def rectfn(rect_num, filled):
'''
We return four rectangles per page in this order:
1 3
2 4
'''
page_w = 800
page_h = 600
margin = 50
rect_w = (page_w - 3*margin) / 2
rect_h = (page_h - 3*margin) / 2
if rect_num % 4 == 0:
# New page.
mediabox = pymupdf.Rect(0, 0, page_w, page_h)
else:
mediabox = None
# Return one of four rects in turn.
rect_x = margin + (rect_w+margin) * ((rect_num // 2) % 2)
rect_y = margin + (rect_h+margin) * (rect_num % 2)
rect = pymupdf.Rect(rect_x, rect_y, rect_x + rect_w, rect_y + rect_h)
#print(f'rectfn(): rect_num={rect_num} filled={filled}. Returning: rect={rect}')
return mediabox, rect, None
story = pymupdf.Story(html, em=8)
out_path = __file__.replace('.py', '.pdf')
writer = pymupdf.DocumentWriter(out_path)
story.write(writer, rectfn)
writer.close()
|