aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--screenplain/parsers/spmd.py59
-rw-r--r--screenplain/types.py6
-rw-r--r--tests/spmd_test.py20
3 files changed, 40 insertions, 45 deletions
diff --git a/screenplain/parsers/spmd.py b/screenplain/parsers/spmd.py
index 23734f4..c2a757a 100644
--- a/screenplain/parsers/spmd.py
+++ b/screenplain/parsers/spmd.py
@@ -25,6 +25,7 @@ TWOSPACE = ' ' * 2
centered_re = re.compile(r'\s*>\s*(.*)\s*<\s*$')
preprocess_re = re.compile(r'^([ \t]*)(.*?)([ \t]*)[\r\n]*$')
+dual_dialog_re = re.compile(r'^(.+?)(\s*\^)$')
def is_slug(blanks_before, line_list):
@@ -42,26 +43,22 @@ def _create_slug(line):
return Slug(_to_rich([line])[0])
-def _create_dialog(line_list):
- dual_index = None
- try:
- dual_index = line_list.index('||', 0, len(line_list) - 1)
- except ValueError:
- return Dialog(
- parse_emphasis(line_list[0]),
- _to_rich(line_list[1:])
- )
- else:
- return DualDialog(
- # character1
- parse_emphasis(line_list[0].strip()),
- # lines1
- _to_rich(line_list[1:dual_index]),
- # character2
- parse_emphasis(line_list[dual_index + 1].strip()),
- # lines2
- _to_rich(line_list[dual_index + 2:])
- )
+def _create_dialog(line_list, previous_paragraphs):
+
+ if previous_paragraphs and isinstance(previous_paragraphs[-1], Dialog):
+ dual_match = dual_dialog_re.match(line_list[0])
+ if dual_match:
+ previous = previous_paragraphs.pop()
+ dialog = Dialog(
+ parse_emphasis(dual_match.group(1)),
+ _to_rich(line_list[1:])
+ )
+ return DualDialog(previous, dialog)
+
+ return Dialog(
+ parse_emphasis(line_list[0]),
+ _to_rich(line_list[1:])
+ )
def _to_rich(line_list):
@@ -69,7 +66,7 @@ def _to_rich(line_list):
return [parse_emphasis(line.strip()) for line in line_list]
-def create_paragraph(blanks_before, line_list):
+def create_paragraph(blanks_before, line_list, previous_paragraphs):
first_line = line_list[0]
if is_slug(blanks_before, line_list):
return _create_slug(line_list[0])
@@ -82,13 +79,11 @@ def create_paragraph(blanks_before, line_list):
first_line.isupper() and
not first_line.endswith(TWOSPACE)
):
- return _create_dialog(line_list)
+ return _create_dialog(line_list, previous_paragraphs)
elif (
len(line_list) == 1 and first_line.isupper()
and (first_line.endswith(':') or first_line.startswith('>'))
):
- # Assume this is a transition. It may be changed to Action
- # later if we find that it's not followed by a slug.
if first_line.startswith('>'):
return Transition(_to_rich([first_line[1:]])[0])
else:
@@ -131,14 +126,14 @@ def parse(source):
if blank:
blank_count = sum(1 for line in preprocessed_lines)
else:
- paragraphs.append(
- create_paragraph(
- blank_count,
- [
- text + trailing
- for (leading, text, trailing) in preprocessed_lines
- ]
- )
+ paragraph = create_paragraph(
+ blank_count,
+ [
+ text + trailing
+ for (leading, text, trailing) in preprocessed_lines
+ ],
+ paragraphs
)
+ paragraphs.append(paragraph)
return paragraphs
diff --git a/screenplain/types.py b/screenplain/types.py
index d8e310d..7ef6cc9 100644
--- a/screenplain/types.py
+++ b/screenplain/types.py
@@ -34,9 +34,9 @@ class Dialog(object):
class DualDialog(object):
- def __init__(self, character1, lines1, character2, lines2):
- self.left = Dialog(character1, lines1)
- self.right = Dialog(character2, lines2)
+ def __init__(self, left_dialog, right_dialog):
+ self.left = left_dialog
+ self.right = right_dialog
class Action(object):
diff --git a/tests/spmd_test.py b/tests/spmd_test.py
index aba2e84..264995b 100644
--- a/tests/spmd_test.py
+++ b/tests/spmd_test.py
@@ -128,8 +128,8 @@ class ParseTests(unittest2.TestCase):
paras = list(parse([
'BRICK',
'Fuck retirement.',
- '||',
- 'STEEL',
+ '',
+ 'STEEL ^',
'Fuck retirement!',
]))
self.assertEquals([DualDialog], [type(p) for p in paras])
@@ -145,18 +145,18 @@ class ParseTests(unittest2.TestCase):
dual.right.blocks
)
- def test_dual_dialog_with_empty_right_dialog_is_ordinary_dialog(self):
+ def test_dual_dialog_without_previous_dialog_is_ignored(self):
paras = list(parse([
- 'BRICK',
+ 'Brick strolls down the street.',
+ '',
+ 'BRICK ^',
'Nice retirement.',
- '||',
]))
- self.assertEquals([Dialog], [type(p) for p in paras])
- dialog = paras[0]
- self.assertEqual(plain('BRICK'), dialog.character)
+ self.assertEquals([Action, Dialog], [type(p) for p in paras])
+ dialog = paras[1]
+ self.assertEqual(plain('BRICK ^'), dialog.character)
self.assertEqual([
- (False, plain('Nice retirement.')),
- (False, plain('||'))
+ (False, plain('Nice retirement.'))
], dialog.blocks)
def test_standard_transition(self):