changeset 23:36424a1081ff

Add support for boneyards.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 04 Jan 2017 23:39:13 -0800
parents 142a53d6e558
children 2ef526c301cc
files README.rst jouvence/parser.py tests/test_boneyard.yaml
diffstat 3 files changed, 60 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/README.rst	Wed Jan 04 23:03:33 2017 -0800
+++ b/README.rst	Wed Jan 04 23:39:13 2017 -0800
@@ -59,7 +59,6 @@
 are not implemented yet:
 
 * Dual dialogue
-* Boneyards
 * Sections and synopses
 * Proper Unicode support (although Fountain's spec greatly assumes English screenplays, sadly).
 
--- a/jouvence/parser.py	Wed Jan 04 23:03:33 2017 -0800
+++ b/jouvence/parser.py	Wed Jan 04 23:39:13 2017 -0800
@@ -29,8 +29,9 @@
 EOF_STATE = object()
 
 
-RE_EMPTY_LINE = re.compile(r"^$", re.M)
-RE_BLANK_LINE = re.compile(r"^\s*$", re.M)
+# Note how boneyard start/end patterns (/* */) by themselves are
+# considered an empty line.
+RE_EMPTY_LINE = re.compile(r"^(/\*|\*/)?$", re.M)
 
 RE_TITLE_KEY_VALUE = re.compile(r"^(?P<key>[\w\s\-]+)\s*:\s*")
 
@@ -404,6 +405,22 @@
         return self._state_cls()
 
 
+RE_BONEYARD_START = re.compile(r"^/\*", re.M)
+RE_BONEYARD_END = re.compile(r"\*/\s*$", re.M)
+
+
+class _BoneyardState(JouvenceState):
+    def match(self, fp, ctx):
+        return RE_BONEYARD_START.match(fp.peekline())
+
+    def consume(self, fp, ctx):
+        while True:
+            fp.readline()
+            if RE_BONEYARD_END.match(fp.peekline()):
+                break
+        return ANY_STATE
+
+
 class _EmptyLineState(JouvenceState):
     def __init__(self):
         super().__init__()
@@ -413,8 +430,13 @@
         return RE_EMPTY_LINE.match(fp.peekline())
 
     def consume(self, fp, ctx):
-        fp.readline()
-        if fp.line_no > 1:  # Don't take into account the fake blank at 0
+        line = fp.readline()
+        # Increment the number of empty lines to add to the current action,
+        # but:
+        # - don't take into account the fake blank at 0
+        # - don't take into account boneyard endings
+        if (fp.line_no > 1 and
+                not RE_BONEYARD_END.match(line)):
             self.line_count += 1
         return ANY_STATE
 
@@ -435,6 +457,7 @@
     _TransitionState,
     _PageBreakState,
     _CenteredActionState,
+    _BoneyardState,
     _EmptyLineState,   # Must be second to last.
     _ActionState,  # Must be last.
 ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_boneyard.yaml	Wed Jan 04 23:39:13 2017 -0800
@@ -0,0 +1,33 @@
+---
+in: |
+    This is something.
+    
+    /*
+    nope
+    nope
+    */
+
+    Ok.
+out:
+    - "!This is something.\n\n\nOk."
+---
+in: |
+    This is something.
+    /*
+    nope
+    nope
+    */
+    OK.
+out:
+    - "!This is something.\nOK."
+---
+in: |
+    /*
+    nope nope
+    */
+    EXT. MANSION
+
+    This is the mansion.
+out:
+    - ".EXT. MANSION"
+    - "!\nThis is the mansion."