aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Vilcans <martin@librador.com>2011-08-22 21:35:39 +0200
committerMartin Vilcans <martin@librador.com>2011-08-22 21:35:39 +0200
commit0f4d62b151d230e22065b917d09d6826a517d140 (patch)
tree092816e382361fa7b4ea3b4ace8a021b90333e1c
parent89b90c77400c6788604812a1253f17c2cf235087 (diff)
downloadscreenplain-0f4d62b151d230e22065b917d09d6826a517d140.tar.gz
First work towards SPMD support.
-rw-r--r--README.markdown129
-rw-r--r--screenplain/export/text.py8
-rw-r--r--screenplain/main.py4
-rw-r--r--screenplain/parse.py28
4 files changed, 26 insertions, 143 deletions
diff --git a/README.markdown b/README.markdown
index 1fea850..a561dcb 100644
--- a/README.markdown
+++ b/README.markdown
@@ -35,131 +35,4 @@ Thanks for the inspiration goes to:
Input format
============
-The format of the text input is very much like how you would write a
-screenplay on and old typewriter, only that you don't have to worry about tab
-stops and line breaks.
-
-Here's an example:
-
- EXT. CASTLE WALLS - DAY
-
- Mist. Several seconds of it swirling about.
- Silence possibly, atmospheric music. SUPERIMPOSE "England AD 787".
- After a few more seconds we hear hoofbeats in
- the distance.
- They come slowly closer. Then out of the mist comes KING ARTHUR
- followed by a SERVANT who is banging two half coconuts
- together. ARTHUR raises his hand.
-
- ARTHUR
- Whoa there!
-
-
- SERVANT makes noises of horses halting, with a flourish. ARTHUR
- peers through the mist. CUT TO shot from over his shoulder:
- castle (e.g. Bodium) rising out of the mist. On the castle
- battlements a SOLDIER is dimly seen. He peers down.
-
- SOLDIER
- Halt! Who goes there?
-
- ARTHUR
- It is I, Arthur, son of Uther Pendragon,
- from the castle
- of Camelot.
- King of all Britons, defeator of the Saxons,
- sovereign of all England!
-
-Note the free (that is, pretty ugly) format of this input.
-After Screenplain has digested it, it will appear correctly formatted like this:
-
- EXT. CASTLE WALLS - DAY
-
- Mist. Several seconds of it swirling about. Silence possibly,
- atmospheric music. SUPERIMPOSE "England AD 787". After a few more
- seconds we hear hoofbeats in the distance. They come slowly closer.
- Then out of the mist comes KING ARTHUR followed by a SERVANT who is
- banging two half coconuts together. ARTHUR raises his hand.
-
- ARTHUR
- Whoa there!
-
- SERVANT makes noises of horses halting, with a flourish. ARTHUR
- peers through the mist. CUT TO shot from over his shoulder: castle
- (e.g. Bodium) rising out of the mist. On the castle battlements a
- SOLDIER is dimly seen. He peers down.
-
- SOLDIER
- Halt! Who goes there?
-
- ARTHUR
- It is I, Arthur, son of Uther
- Pendragon, from the castle of
- Camelot. King of all Britons,
- defeator of the Saxons, sovereign
- of all England!
-
-As you can see, you can write your screenplay without keeping formatting rules in your head.
-As Screenplain is just a piece of software, and not a mind-reading robot, it does have rules,
-but they are designed to be intuitive and shouldn't distract from the writing.
-
-Basically, what Screenplain does with your plain text file is to split it into paragraphs.
-A paragraph is simply one or more lines of text. Paragraphs are separated by one or
-more empty lines. The example above contains six paragraphs.
-
-After splitting the text into paragraphs, Screenplain decides what type each paragraph has.
-It can be one of:
-
- * Slug line
- * Dialogue
- * Action
-
-The paragraph type decides how the paragraph will look in the output. See
-below for how Screenplain figures out which one of these types each paragraph has.
-
-Slug lines
-----------
-
-If a paragraph contains *one single line* written in *capital letters*, Screenplain
-assumes it is a slug line.
-
-A slug line is a line that starts a scene. An example of a slug line is `EXT.
-EIFFEL TOWER - DAY`, but Screenplain does not care about the format. Screenplain
-assumes `SOMEWHERE IN SPACE` is a slug line too.
-
-Dialogue
---------
-
-If a paragraph consists of two or more lines, and the first line is written
-only in *capital letters*, Screenplain assumes it is a piece of dialogue. The
-first line should contain the name of the speaking character. The rest is
-whatever that character says. Simple isn't it? Well, there is an exception: If
-a line starts with an opening parenthesis, "(", it starts a parenthetical
-block, which is a screenwriter's way of telling the actor how the line is to
-be delivered (something that pisses directors off). Parentheticals are
-formatted differently from the spoken lines.
-
-Action
-------
-
-Any paragraph that is not one of the other types contains descriptions about
-what happens in the scene.
-
-TO DO
-=====
-
- * Specify options on the command line. Duh.
-
- * Installation package.
-
- * Margins in PDF output.
-
- * Support for transitions. A `CUT TO:` line is interpreted as a slug line.
- Fixing this should be simple: any single-line paragraph that starts with one
- or more spaces and does not contain lower-case characters should be a
- transition. Any pitfalls with that? What about left-aligned transitions like
- `FADE IN:`?
-
- * Good support for national characters. It works on my system, but I'm not so
- sure if it will work for everyone. Should we just support UTF-8, or allow
- other encodings?
+See http://prolost.com/storage/downloads/spmd/SPMD_proposal.html
diff --git a/screenplain/export/text.py b/screenplain/export/text.py
index 49a1f23..e135646 100644
--- a/screenplain/export/text.py
+++ b/screenplain/export/text.py
@@ -1,11 +1,11 @@
import sys
from screenplain.parse import parse, get_pages
-def to_text(input):
- out = sys.stdout
+def to_text(input, out):
paragraphs = parse(input)
- for page_no, page in enumerate(get_pages(paragraphs), 1):
- if page_no != 1:
+ for page_no, page in enumerate(get_pages(paragraphs)):
+ # page_no is 0-based
+ if page_no != 0:
out.write('\f')
for line in page:
out.write(line)
diff --git a/screenplain/main.py b/screenplain/main.py
index 948914c..bbe6450 100644
--- a/screenplain/main.py
+++ b/screenplain/main.py
@@ -7,9 +7,9 @@ import fileinput
import sys
if __name__ == '__main__':
- if False:
+ if True:
from screenplain.export.text import to_text
- to_text(fileinput.input())
+ to_text(fileinput.input(), sys.stdout)
else:
from screenplain.export.pdf import to_pdf
to_pdf(fileinput.input())
diff --git a/screenplain/parse.py b/screenplain/parse.py
index c4cadb5..a872f7e 100644
--- a/screenplain/parse.py
+++ b/screenplain/parse.py
@@ -1,10 +1,14 @@
import itertools
import textwrap
+import re
# Numbers from http://www.emacswiki.org/emacs/ScreenPlay
# According to http://johnaugust.com/2004/how-many-lines-per-page
lines_per_page = 56
+slug_re = re.compile('^(EXT\.|INT\.|EXT/INT\.|I/E) ', re.IGNORECASE)
+
+
class _ParentheticalFlipFlop(object):
def __init__(self):
self.inside = False
@@ -85,24 +89,30 @@ class Action(object):
yield self.indent + line
def is_blank(string):
- return string == '' or string.isspace()
+ return string == '' or string.isspace() and string != ' '
-def create_paragraph(line_list):
- if line_list[0].isupper():
- if len(line_list) == 1:
- return Slug(line_list)
- else:
- return Dialog(line_list)
+def is_slug(blanks_before, string):
+ return blanks_before >= 2 or slug_re.match(string)
+
+def create_paragraph(blanks_before, line_list):
+ if is_slug(blanks_before, line_list[0]):
+ return Slug(line_list)
+ if len(line_list) > 1 and line_list[0].isupper():
+ return Dialog(line_list)
else:
return Action(line_list)
def parse(source):
"""Reads raw text input and generates paragraph objects."""
+ blank_count = 0
for blank, lines in itertools.groupby(
(line.rstrip() for line in source), is_blank
):
- if not blank:
- yield create_paragraph(list(lines))
+ if blank:
+ blank_count += 1
+ else:
+ yield create_paragraph(blank_count, list(lines))
+ blank_count = 0
def get_pages(paragraphs):
"""Generates one list of lines per page."""