Calculating true three-fold PDF in Python
I created a three-column PDF format using frames and reportlab in the article Multi-column PDFs. However, the document I used as an example was meant to be folded, and that was not a true three-fold layout. All of the columns were the same width and they were distributed evenly within the available printing area of the page. In order to make it truly foldable, the borders between each frame need to be distributed evenly across the entire paper width. This means that, unless there are only two columns, the outer frames need to be sized differently than the inner frames.
I divided this into four basic steps:
- Add an inner margin size.
- Set the frame width to be the first fold point, minus the inner margin size.
- Adjust the first and last frame appropriately.
- Draw guides for folding.
I modified the frame code to handle steps one through three:
[toggle code]
- #create the basic page
- pagesize =reportlab.lib.pagesizes.landscape(reportlab.lib.pagesizes.letter)
- pagewidth, pageheight = pagesize
- leftMargin = .25*inch
- rightMargin = .25*inch
- topMargin = .25*inch
- bottomMargin = .25*inch
- innerMargin = .25*inch
- document = platypus.BaseDocTemplate(destination, pagesize=pagesize, leftMargin=leftMargin, rightMargin=rightMargin, topMargin=topMargin, bottomMargin=bottomMargin)
- #create the frames
- frameCount = 3
- foldAt = pagewidth/frameCount
- frameWidth = foldAt-innerMargin
- #leave space for the header
- frameHeight = document.height-.25*inch
- frames = []
- #construct the column frames
- #Note that if the frame width is less than twice the document margin, this will fail
-
for frame in range(frameCount):
- leftMargin = foldAt*frame
- thisWidth = frameWidth
- #adjust the margins appropriately
-
if frame == 0:
- leftMargin = leftMargin + document.leftMargin
- thisWidth = thisWidth - document.leftMargin + innerMargin/2
-
else:
- leftMargin = leftMargin + innerMargin/2
-
if frame == frameCount-1:
- thisWidth = thisWidth - document.rightMargin + innerMargin/2
- column = platypus.Frame(leftMargin, document.bottomMargin, thisWidth, frameHeight)
- frames.append(column)
- document.addPageTemplates(platypus.PageTemplate(frames=frames, onPage=addHeader))
- document.build(parts)
In this version, the leftmost and rightmost column are likely to be a different size than the rest of the columns, because they are also affected by the outer margins. Also, if you’re making pages with a lot of columns, you’ll want to make sure that your columns don’t start hitting negative widths after you apply the margin adjustments.
Drawing a fold guide
We can make it easier for people to fold the sheet by adding a dashed vertical line exactly at the fold.
[toggle code]
-
def addHeader(canvas, document):
- canvas.saveState()
- …
- #draw lines where the paper should be folded
- foldguidestart = pageheight*.48
- foldguideend = pageheight*.52
- #set to 25% gray
- canvas.setStrokeColorRGB(.75, .75, .75)
- #set to a 3-point dotted line
- canvas.setDash(3, 3)
-
for fold in range(1, frameCount):
- foldpoint = foldAt*fold
- canvas.line(foldpoint, foldguidestart, foldpoint, foldguideend)
- canvas.restoreState()
There’s nothing particularly special about this. It creates a line that is about 4% the height of the page, right in the middle of the page, and it does so at each fold point.
- ReportLab Toolkit
- “The ReportLab Open Source PDF library is a proven industry-strength PDF generating solution, that you can use for meeting your requirements and deadlines in enterprise reporting systems.”
More Python
- Parsing JSKit/Echo XML comments files
- While I’m not a big fan of remote comment systems for privacy reasons, I was willing to use JSKit as a temporary solution because they provide an easy XML dump of posted comments. This weekend, I finally moved my main blog to custom comments; here’s how I parsed JSKit’s XML file.
- Put a relative clock on your Desktop with GeekTool
- There are a lot of desktop clocks that show the absolute time. But sometimes you just want to know if the time is today, or yesterday, or two days ago. Here’s how to do it with Python and GeekTool.
- Multiple tables on the same command
- The way the “random” script currently stands, it does one table at a time. Often, however, you have more than one table you know you’re going to need. Why not use one command to rule them all?
- Easier random tables
- Rather than having to type --table and --count, why not just type the table name and an optional count number?
- Programming for Gamers: Choosing a random item
- If you can understand a roleplaying game’s rules, you can understand programming. Programming is a lot easier.
- 24 more pages with the topic Python, and other related pages
More PDF
- Adding links to PDF in Python
- It is very easy to add links to PDF documents using reportlab or platypus in Python.
- Multiple column PDF generation in Python
- You can use ReportLab’s Platypus to generate multi-column PDFs in Snakelets, Django, or any Python app.
- Embedding Mako into Django
- You got Mako in my Django! You got Django on my Mako! Two great templates that template great together.
- Python PDF generation with Snakelets
- One of the things I need to do to move my current web site over to Django is be able to automatically generate PDF documents. Step is to learn how to generate PDF using Python.
- Combining multiple PDF files into a single file
- Automator allows you to combine multiple PDF files into a single file.
- One more page with the topic PDF, and other related pages
