playfair

Playfair Script Formatter
git clone https://git.mulligrubs.me/playfair
Log | Files | Refs | README

commit 67032c458ccce2a84d8431b05e5dbba17a76a8bc
parent 992879c8479bb9fea221811d20e117120cdc0e3f
Author: St John Karp <git@stjohnkarp.net>
Date:   Sat, 31 Mar 2012 11:19:49 -0700

Added support for stage vs. screen scripts

I have added support for stage vs. screen scripts, including
their unique elements and separate stylesheets.  This support also
includes the use of asterisks for emphasis, translating to italics
in a stage script and underlining in a screenplay.
Diffstat:
Mplayfair.pl | 49++++++++++++++++++++++++++++++++++---------------
Ascriptfrenzy_screen.css | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+), 15 deletions(-)

diff --git a/playfair.pl b/playfair.pl @@ -13,26 +13,28 @@ % %------------------------------------------------------- -play_to_html(File):- +play_to_html(Type, File):- open(File, read, In, [encoding(utf8)]), - process_file(In, Play), + process_file(In, Script), close(In), - play(HTML, Play, []), + script(Type, HTML, Script, []), xml_write(HTML, [header(false)]), %write(HTML), halt. -play([element(html, [], [Head, Body, End])]) - --> head(Head, Title, Author, Personae, Time, Setting), double_break, body(Body, Title, Author, Personae, Time, Setting), double_break, end(End), single_break. +script(Type, [element(html, [], [Head, Body, End])]) + --> head(Type, Head, Variables), double_break, body(Type, Body, Variables), double_break, end(End), single_break. -body(element(body, [], [TitlePage, MetaPage|Scenes]), Title, Author, Personae, Time, Setting) --> title_page(TitlePage, Title, Author), meta_page(MetaPage, Personae, Time, Setting), scene_repeater(Scenes). +body(stage, element(body, [], [TitlePage, MetaPage|Scenes]), [Title, Author, Personae, Time, Setting]) --> title_page(TitlePage, Title, Author), meta_page(MetaPage, Personae, Time, Setting), scene_repeater(stage, Scenes). +body(screen, element(body, [], [TitlePage|Scenes]), [Title, Author]) --> title_page(TitlePage, Title, Author), scene_repeater(screen, Scenes). -scene_repeater([Scene|Scenes]) --> scene(Scene), double_break, scene_repeater(Scenes). -scene_repeater([Scene]) --> scene(Scene). +scene_repeater(Type, [Scene|Scenes]) --> scene(Type, Scene), double_break, scene_repeater(Type, Scenes). + +scene_repeater(Type, [Scene]) --> scene(Type, Scene). title_page(element(div, [id = titlepage], [element(h1, [], [Title]), element(p, [id = author], [Author])]), Title, Author) --> []. @@ -41,9 +43,13 @@ title_page(element(div, [id = titlepage], [element(h1, [], [Title]), element(p, meta_page(element(div, [id = metapage], [Personae, Time, Setting]), Personae, Time, Setting) --> []. -scene(element(div, [class = scene], Scene)) --> act(Act), double_break, scene_directions(SceneDirections), double_break, island_repeater(Island), +% Scene definition for stage plays +scene(stage, element(div, [class = scene], Scene)) --> act(Act), double_break, scene_directions(SceneDirections), double_break, island_repeater(Island), {append([Act|SceneDirections], Island, Scene)}. +% Scene definition for screenplays +scene(screen, element(div, [class = scene], [Slug|Island])) --> slug(Slug), double_break, island_repeater(Island). + island_repeater([Island1|Island2]) --> island(Island1), double_break, island_repeater(Island2). @@ -77,9 +83,9 @@ dialogue(element(p, [class = dialogue], [Unit, element(br, [], [])|Dialogue])) - dialogue(element(p, [class = dialogue], [Unit, element(br, [], []), element(br, [], [])|Dialogue])) --> dialogue_unit(Unit), line_break(_), dialogue(element(p, [class = dialogue], Dialogue)). -dialogue_unit(Text) --> text(['\n', <, >, '(', ')'], Text). +dialogue_unit(Text) --> text(['\n', <, >, '*', '(', ')'], Text). -dialogue_unit(Italic) --> italic(Italic). +dialogue_unit(Emphatic) --> emphatic(Emphatic). dialogue_unit(CDD) --> character_directions(CDD). @@ -87,15 +93,19 @@ dialogue_unit(CDD) --> character_directions(CDD). character_stage_directions(element(p, [class = characterStageDirections], ['(', Text, ')'])) --> ['('], text(['\n', <, >, ')'], Text), [')']. -italic(element(em, [], [Text])) --> [<, e, m, >], text(['\n', <, >, '(', ')'], Text), [<, '/', e, m, >]. +emphatic(element(em, [], [Text])) --> [<, e, m, >], text(['\n', <, >, '(', ')'], Text), [<, '/', e, m, >]. -italic(element(em, [], [Text])) --> [<, i, >], text(['\n', <, >, '(', ')'], Text), [<, '/', i, >]. +emphatic(element(em, [], [Text])) --> [<, i, >], text(['\n', <, >, '(', ')'], Text), [<, '/', i, >]. + +emphatic(element(em, [], [Text])) --> ['*'], text(['\n', '*'], Text), ['*']. character_directions(element(span, [class = characterDirections], ['(', Text, ')'])) --> ['('], text(['\n', <, >, '(', ')'], Text), [')']. -head(element(head, [], [Charset, TitleTag, AuthorTag, Styles]), Title, Author, Personae, Time, Setting) --> meta_charset(Charset), styles(Styles), tag_title(TitleTag, Title), single_break, tag_author(AuthorTag, Author), single_break, tag_personae(Personae), single_break, tag_time(Time), single_break, tag_setting(Setting). +head(stage, element(head, [], [Charset, TitleTag, AuthorTag, Styles]), [Title, Author, Personae, Time, Setting]) --> meta_charset(Charset), styles(stage, Styles), tag_title(TitleTag, Title), single_break, tag_author(AuthorTag, Author), single_break, tag_personae(Personae), single_break, tag_time(Time), single_break, tag_setting(Setting). + +head(screen, element(head, [], [Charset, TitleTag, AuthorTag, Styles]), [Title, Author]) --> meta_charset(Charset), styles(screen, Styles), tag_title(TitleTag, Title), single_break, tag_author(AuthorTag, Author). tag_title(element(title, [], [Text]), Text) --> ['@', t, i, t, l, e, ':', ' '], text(['\n'], Text). @@ -122,7 +132,9 @@ persona(element(p, [], [Text])) --> ['@', p, e, r, s, o, n, a, ':', ' '], text([ %date(element(meta, [name = date, content = ], [])) --> []. -styles(element(link, [rel = 'stylesheet', type = 'text/css', href = 'scriptfrenzy.css'], [])) --> []. +styles(stage, element(link, [rel = 'stylesheet', type = 'text/css', href = 'scriptfrenzy.css'], [])) --> []. + +styles(screen, element(link, [rel = 'stylesheet', type = 'text/css', href = 'scriptfrenzy_screen.css'], [])) --> []. %meta_charset(element(meta, [charset = 'utf-8'], [])) --> []. @@ -146,6 +158,11 @@ act(element(h3, [class = actScene], ['A', 'C', 'T', Text])) --> ['A', 'C', 'T'], act(element(h3, [class = actScene], ['A', 'C', 'T', Text])) --> ['A', 'c', 't'], text(['\n'], Text). +slug(element(h2, [class = slug], ['I', 'N', 'T', '.', ' ', Text])) --> ['I', 'N', 'T', '.', ' '], text(['\n'], Text). + +slug(element(h2, [class = slug], ['E', 'X', 'T', '.', ' ', Text])) --> ['E', 'X', 'T', '.', ' '], text(['\n'], Text). + + end(element(p, [class = end], ['The End.'])) --> ['T', 'h', 'e', ' ', 'E', 'n', 'd', '.']. @@ -154,6 +171,8 @@ text(Forbidden, Text) --> no_funny_business(Forbidden, Text). no_funny_business(Forbidden, Text, List, Rest):- not(List = ['A', 'C', 'T'|_]), + not(List = ['I', 'N', 'T', '.'|_]), + not(List = ['E', 'X', 'T', '.'|_]), forbidden_fruit(Forbidden, List, CharList), not(CharList = []), atom_chars(Text, CharList), diff --git a/scriptfrenzy_screen.css b/scriptfrenzy_screen.css @@ -0,0 +1,89 @@ +@page { + margin: 1in 1in 1in 1.5in; + size: 8.5in 11in; /* Letter paper */ +} + +@page { + @top-right { + content: counter(page) "."; + } +} + +@page meta { + @top-right { + content: normal; + } +} + +body { + font-family: monospace; + font-size: 12pt; +} + +div#titlepage,div#metapage { + counter-reset: page; + page: meta; +} + +h1 { + page-break-after: avoid; + string-set: title content(); + text-align: center; + font-size: 1em; + font-style: normal; + font-weight: normal; +} + +p#author { + margin-top: 0.83em; + margin-bottom: 0.83em; + string-set: "by\n" author content(); + text-align: center; +} + +h2.slug { + font-size: 1em; + font-weight: normal; +} + +hr.page { + page-break-after: always; + width: 0; +} + +div.dialogue { + page-break-inside: avoid; +} + +p { + margin-top: 0; +} + +p.character { + margin-left: 2.2in; + margin-bottom: 0.04in; +} + +p.dialogue { + margin-bottom: 0.22in; + margin-left: 1in; + margin-right: 1.5in; +} + +p.stageDirections { + margin-bottom: 0.22in; +} + +span.characterDirections { +} + +p.characterStageDirections { + margin-left: 1.6in; + margin-right: 1.9in; + margin-bottom: 0.04in; +} + +em { + font-style: normal; + text-decoration: underline; +}