diff options
author | Martin Vilcans <martin@librador.com> | 2011-08-22 21:35:39 +0200 |
---|---|---|
committer | Martin Vilcans <martin@librador.com> | 2011-08-22 21:35:39 +0200 |
commit | 0f4d62b151d230e22065b917d09d6826a517d140 (patch) | |
tree | 092816e382361fa7b4ea3b4ace8a021b90333e1c | |
parent | 89b90c77400c6788604812a1253f17c2cf235087 (diff) | |
download | screenplain-0f4d62b151d230e22065b917d09d6826a517d140.tar.gz |
First work towards SPMD support.
-rw-r--r-- | README.markdown | 129 | ||||
-rw-r--r-- | screenplain/export/text.py | 8 | ||||
-rw-r--r-- | screenplain/main.py | 4 | ||||
-rw-r--r-- | screenplain/parse.py | 28 |
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.""" |