summaryrefslogtreecommitdiff
path: root/fountain/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'fountain/parse.go')
-rw-r--r--fountain/parse.go57
1 files changed, 41 insertions, 16 deletions
diff --git a/fountain/parse.go b/fountain/parse.go
index ae3ed7a..2d0b0b7 100644
--- a/fountain/parse.go
+++ b/fountain/parse.go
@@ -71,6 +71,28 @@ func CheckSection(row string) (bool, string, string) {
return section, "section", row
}
+func CheckForce(row string) (bool, string, string) {
+ var force = true
+ var ftype string
+ if len(row) < 1 {
+ return false, "", ""
+ }
+ switch row[0] {
+ case '@':
+ ftype = "speaker"
+ case '~':
+ ftype = "lyrics"
+ case '!':
+ ftype = "action"
+ default:
+ force = false
+ }
+ if force {
+ row = row[1:]
+ }
+ return force, ftype, row
+}
+
// This is a Fountain parser, trying to be as close as possible to the description
// found at https://fountain.io/syntax but it can be incomplete.
// Over time more and more parts should be configurable here, e.g. INT/EXT translatable to other languages.
@@ -94,22 +116,6 @@ func Parse(file io.Reader) (out lex.Screenplay) {
titlepage = false
action = "newpage"
}
-
- // Backtracking for elements that need a following empty line
- checkfuncs := []func(string) (bool, string, string){
- CheckScene,
- CheckCrow,
- CheckEqual,
- CheckSection,
- }
- for _, checkfunc := range checkfuncs {
- check, element, contents := checkfunc(last(&out, 1).Contents)
- if check && last(&out, 2).Contents == "" {
- last(&out, 1).Type = element
- last(&out, 1).Contents = contents
- break
- }
- }
}
if last(&out, 1).Type != "action" {
last(&out, 1).Contents = strings.TrimSpace(last(&out, 1).Contents)
@@ -136,6 +142,25 @@ func Parse(file io.Reader) (out lex.Screenplay) {
dialog = true
}
+ checkfuncs := []func(string) (bool, string, string){
+ CheckScene, // should actually check for empty lines, but doing that creates more problems than it solves
+ CheckCrow,
+ CheckEqual,
+ CheckSection,
+ CheckForce,
+ }
+ for _, checkfunc := range checkfuncs {
+ check, element, contents := checkfunc(row)
+ if check {
+ action = element
+ row = contents
+ if action == "speaker" {
+ dialog = true
+ }
+ break
+ }
+ }
+
if titlepage {
if titletag == "" {
out = append(out, lex.Line{Type: "titlepage"})