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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
import unittest2
from screenplain import parse
from screenplain.parse import Slug, Action, Dialog, DualDialog, Transition
class ParseTests(unittest2.TestCase):
# Without this, the @skip decorator gives
# AttributeError: 'ParseTests' object has no attribute '__name__'
__name__ = 'ParseTests'
# A Scene Heading, or "slugline," is any line that has a blank
# line following it, and either begins with INT or EXT, or has
# two empty lines preceding it. A Scene Heading always has at
# least one blank line preceding it.
# NOTE: Actually the list used in Appendix 1
def test_slug_with_prefix(self):
paras = list(parse.parse([
'INT. SOMEWHERE - DAY',
'',
'THIS IS JUST ACTION',
]))
self.assertEquals([Slug, Action], [type(p) for p in paras])
def test_action_is_not_a_slug(self):
paras = list(parse.parse([
'',
'THIS IS JUST ACTION',
]))
self.assertEquals([Action], [type(p) for p in paras])
def test_two_lines_creates_a_slug(self):
types = [type(p) for p in parse.parse([
'',
'',
'This is a slug',
'',
])]
self.assertEquals([Slug], types)
# A Character element is any line entirely in caps, with one empty
# line before it and without an empty line after it.
def test_all_caps_is_character(self):
paras = [p for p in parse.parse([
'SOME GUY',
'Hello',
])]
self.assertEquals(1, len(paras))
dialog = paras[0]
self.assertEquals(Dialog, type(dialog))
self.assertEquals('SOME GUY', dialog.character)
# SPMD would not be able to support a character named "23". We
# might need a syntax to force a character element.
def test_nonalpha_character(self):
paras = list(parse.parse([
'23',
'Hello',
]))
self.assertEquals([Action], [type(p) for p in paras])
# See
# http://prolost.com/storage/downloads/spmd/SPMD_proposal.html#section-br
def test_twospaced_line_is_not_character(self):
paras = list(parse.parse([
'SCANNING THE AISLES... ',
'Where is that pit boss?',
]))
self.assertEquals([Action], [type(p) for p in paras])
def test_simple_parenthetical(self):
paras = list(parse.parse([
'STEEL',
'(starting the engine)',
'So much for retirement!',
]))
self.assertEquals(1, len(paras))
dialog = paras[0]
self.assertEqual(2, len(dialog.blocks))
self.assertEqual((True, '(starting the engine)'), dialog.blocks[0])
self.assertEqual((False, 'So much for retirement!'), dialog.blocks[1])
def test_dual_dialog(self):
paras = list(parse.parse([
'BRICK',
'Fuck retirement.',
'||',
'STEEL',
'Fuck retirement!',
]))
self.assertEquals([DualDialog], [type(p) for p in paras])
dual = paras[0]
self.assertEquals('BRICK', dual.left.character)
self.assertEquals([(False, 'Fuck retirement.')], dual.left.blocks)
self.assertEquals('STEEL', dual.right.character)
self.assertEquals([(False, 'Fuck retirement!')], dual.right.blocks)
def test_standard_transition(self):
# Need clarification of the spec here, see
# http://prolost.com/blog/2011/8/9/screenplay-markdown.html?lastPage=true#comment14865294
paras = list(parse.parse([
'Jack begins to argue vociferously in Vietnamese (?)',
'',
'CUT TO:',
'',
"EXT. BRICK'S POOL - DAY",
]))
self.assertEquals([Action, Transition, Slug], [type(p) for p in paras])
if __name__ == '__main__':
unittest2.main()
|