Skip to content

Commit

Permalink
PDF page shouldn't break heading from scene, or character name from d…
Browse files Browse the repository at this point in the history
…ialog.
  • Loading branch information
Charney Kaye committed Sep 18, 2015
1 parent 8152cdb commit 6952014
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 1 deletion.
17 changes: 16 additions & 1 deletion screenplain/export/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
top_margin = 1 * inch
bottom_margin = page_height - top_margin - frame_height

# If the current page has below this many pixels remaining,
# break before starting a new scene / dialogue
pixels_threshold_page_break = 100

character_width = 1.0 / 10 * inch

default_style = ParagraphStyle(
Expand Down Expand Up @@ -142,7 +146,14 @@ def add_paragraph(story, para, style):
story.append(Paragraph(line.to_html(), style))


def add_slug(story, para, style):
protect_page_break(story)
for line in para.lines:
story.append(Paragraph(line.to_html(), style))


def add_dialog(story, dialog):
protect_page_break(story)
story.append(Paragraph(dialog.character.to_html(), character_style))
for parenthetical, line in dialog.blocks:
if parenthetical:
Expand All @@ -157,6 +168,10 @@ def add_dual_dialog(story, dual):
add_dialog(story, dual.right)


def protect_page_break(story):
story.append(platypus.CondPageBreak(pixels_threshold_page_break))


def get_title_page_story(screenplay):
"""Get Platypus flowables for the title page
Expand Down Expand Up @@ -236,7 +251,7 @@ def to_pdf(screenplay, output_filename, template_constructor=DocTemplate):
centered_action_style if para.centered else action_style
)
elif isinstance(para, Slug):
add_paragraph(story, para, slug_style)
add_slug(story, para, slug_style)
elif isinstance(para, Transition):
add_paragraph(story, para, transition_style)
elif isinstance(para, types.PageBreak):
Expand Down
58 changes: 58 additions & 0 deletions tests/files/awkward-page-breaks.fountain
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
INT. SOMEWHERE - DAY

Stuff happens.

So much stuff happens, that this scene takes up exactly one page.

And when we export this as a PDF with 55 "lines per page" and 61 "characters per line" (unless we protect against it) the next scene heading will end up being orphaned at the bottom of this page, with nothing below it. The contents of the next scene will appear on the following page, without any heading.

ALPHA
Bravo.

CHARLIE
Delta.

ECHO
Foxtrot.

GOLF
Hotel.

INDIA
Juliet.

KILO
Lima.

MIKE
November.

OSCAR
Papa.

QUEBEC
Romeo.

SIERRA
Tango.

UMBRELLA
Victor.

Whiskey X-ray. Yankee Zulu. Whiskey X-ray. Yankee Zulu.Whiskey X-ray. Yankee Zulu.Whiskey X-ray. Yankee Zulu.Whiskey X-ray. Yankee Zulu.Whiskey X-ray.

INT. SOMEWHERE ELSE, TO BE CERTAIN - NIGHT

Exported as a PDF with 55 "lines per page" and 61 "characters per line", this scene will appear at the top of a page, with no heading above it.

ALPHA
Bravo.

CHARLIE
Delta.

ECHO
Foxtrot.

GOLF
Hotel.
24 changes: 24 additions & 0 deletions tests/pdf_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright (c) 2011 Martin Vilcans
# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license.php

from testcompat import TestCase
from StringIO import StringIO

from screenplain.export.pdf import to_pdf
from screenplain.richstring import plain, bold, italic


class OutputTests(TestCase):

def setUp(self):
self.out = StringIO()
# TODO: figure out how to test PDF export

def test_scene_heading_page_break_threshold(self):
self.assertEqual(1, 1)
# TODO: test PDF export should not break heading from scene

def test_scene_heading_page_break_threshold(self):
self.assertEqual(1, 1)
# TODO: test PDF export should not break character name from dialog

0 comments on commit 6952014

Please sign in to comment.