aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--screenplain/parsers/spmd.py31
-rw-r--r--screenplain/richstring.py17
-rw-r--r--screenplain/types.py22
-rw-r--r--tests/richstring_test.py3
-rw-r--r--tests/spmd_test.py15
5 files changed, 72 insertions, 16 deletions
diff --git a/screenplain/parsers/spmd.py b/screenplain/parsers/spmd.py
index 0183376..27778c3 100644
--- a/screenplain/parsers/spmd.py
+++ b/screenplain/parsers/spmd.py
@@ -1,5 +1,6 @@
import itertools
from screenplain.types import Slug, Action, Dialog, DualDialog, Transition
+from screenplain.richstring import parse_emphasis
slug_prefixes = (
'INT. ',
@@ -29,17 +30,35 @@ def is_slug(blanks_before, line_list):
def _create_dialog(line_list):
+ dual_index = None
try:
- dual_index = line_list.index('||')
+ dual_index = line_list.index('||', 0, len(line_list) - 1)
except ValueError:
- return Dialog(line_list)
+ return Dialog(
+ parse_emphasis(line_list[0]),
+ _to_rich(line_list[1:])
+ )
else:
- return DualDialog(line_list[:dual_index], line_list[dual_index + 1:])
+ 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 _to_rich(line_list):
+ """Converts a line list into a list of RichString."""
+ return [parse_emphasis(line.strip()) for line in line_list]
def create_paragraph(blanks_before, line_list):
if is_slug(blanks_before, line_list):
- return Slug(line_list)
+ return Slug(_to_rich(line_list))
if (
len(line_list) > 1 and
line_list[0].isupper() and
@@ -52,9 +71,9 @@ def create_paragraph(blanks_before, line_list):
):
# Assume this is a transition. It may be changed to Action
# later if we find that it's not followed by a slug.
- return Transition(line_list)
+ return Transition(_to_rich(line_list))
else:
- return Action(line_list)
+ return Action(_to_rich(line_list))
def clean_line(line):
diff --git a/screenplain/richstring.py b/screenplain/richstring.py
index f48f54b..39b4999 100644
--- a/screenplain/richstring.py
+++ b/screenplain/richstring.py
@@ -34,6 +34,21 @@ class RichString(object):
result += segment.to_html()
return result
+ def to_plain(self):
+ result = ''
+ for segment in self.segments:
+ if isinstance(segment, basestring):
+ result += segment
+ else:
+ result += segment.to_plain()
+ return result
+
+ def startswith(self, prefix):
+ return self.to_plain().startswith(prefix)
+
+ def endswith(self, prefix):
+ return self.to_plain().endswith(prefix)
+
def __unicode__(self):
return self.to_html()
@@ -44,6 +59,8 @@ class RichString(object):
)
def __eq__(self, other):
+ if isinstance(other, basestring):
+ return self.to_plain() == other
return (
self.__class__ == other.__class__ and
self.segments == other.segments
diff --git a/screenplain/types.py b/screenplain/types.py
index d7d5c7c..7c71b1e 100644
--- a/screenplain/types.py
+++ b/screenplain/types.py
@@ -6,7 +6,7 @@ class Slug(object):
top_margin = 1
def __init__(self, lines):
- self.lines = [self.indent + line.strip() for line in lines]
+ self.lines = lines
def format(self):
return self.lines
@@ -23,15 +23,14 @@ class Dialog(object):
top_margin = 1
- def __init__(self, lines):
- self.character = lines[0]
+ def __init__(self, character, lines):
+ self.character = character
self.blocks = [] # list of tuples of (is_parenthetical, text)
- self._parse(lines[1:])
+ self._parse(lines)
def _parse(self, lines):
inside_parenthesis = False
for line in lines:
- line = line.rstrip()
if line.startswith('('):
inside_parenthesis = True
self.blocks.append((inside_parenthesis, line))
@@ -63,9 +62,12 @@ class Dialog(object):
class DualDialog(object):
top_margin = 1
- def __init__(self, left_lines, right_lines):
- self.left = Dialog(left_lines)
- self.right = Dialog(right_lines)
+ def __init__(self,
+ character1, lines1,
+ character2, lines2
+ ):
+ self.left = Dialog(character1, lines1)
+ self.right = Dialog(character2, lines2)
def format(self):
# FIXME: I haven't checked yet how dual dialog is supposed to look.
@@ -83,7 +85,7 @@ class Action(object):
top_margin = 1
def __init__(self, lines):
- self.lines = [line.strip() for line in lines]
+ self.lines = lines
def format(self):
for logical_line in self.lines:
@@ -97,7 +99,7 @@ class Transition(object):
top_margin = 1
def __init__(self, lines):
- self.lines = [line.strip() for line in lines]
+ self.lines = lines
def format(self):
for logical_line in self.lines:
diff --git a/tests/richstring_test.py b/tests/richstring_test.py
index 258cdb1..b442f90 100644
--- a/tests/richstring_test.py
+++ b/tests/richstring_test.py
@@ -32,6 +32,9 @@ class RichStringOperatorTests(unittest2.TestCase):
class RichStringTests(unittest2.TestCase):
+ def test_plain_to_html(self):
+ self.assertEquals('hello', RichString('hello').to_html())
+
def test_to_html(self):
s = RichString(
Bold('bold'),
diff --git a/tests/spmd_test.py b/tests/spmd_test.py
index d4e8c5d..1c25f05 100644
--- a/tests/spmd_test.py
+++ b/tests/spmd_test.py
@@ -104,6 +104,21 @@ class ParseTests(unittest2.TestCase):
self.assertEquals('STEEL', dual.right.character)
self.assertEquals([(False, 'Fuck retirement!')], dual.right.blocks)
+ def test_dual_dialog_with_empty_right_dialog_is_ordinary_dialog(self):
+ paras = list(parse([
+ 'BRICK',
+ 'Nice retirement.',
+ '||',
+ ]))
+ self.assertEquals([Dialog], [type(p) for p in paras])
+ dialog = paras[0]
+ self.assertEqual('BRICK', dialog.character)
+ self.assertEqual([
+ (False, 'Nice retirement.'),
+ (False, '||')
+ ], dialog.blocks)
+
+
def test_standard_transition(self):
paras = list(parse([