summaryrefslogtreecommitdiff
path: root/fountain/parse.go
blob: dc4602ff1dc6de482521babc46b43cb84d123659 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package parse

import (
	"strings"
)

var example = `
INT. HOUSE - DAY

MARY
I can't believe how easy it is to write in Fountain.

TOM
(typing)
Look! I just made a parenthetical!

SOMETHING HAPPENS!

(what? I don't know...)

EXT. GARDEN

TOM
What am I doing here now?
To be honest, I have absolutely no idea!
  
And that means really no idea!
`

var action = map[string]struct {
	Left, Width float64
}{
	"action":  {1.5, 6},
	"speaker": {4.2, 3.3},
	"dialog":  {2.9, 3.3},
	"scene":   {1.5, 6},
	"paren":   {3.6, 2},
	"trans":   {6, 1.5},
	"note":    {1.5, 6},
	"allcaps": {1.5, 6},
	"empty":   {1.5, 6},
}

var tr func(string) string

type Tree struct {
	PDF *gofpdf.Fpdf
	F   []struct {
		Format string
		Text   string
	}
}

func (t Tree) pr(a string, text string) {
	line(t.PDF, action[a].Left, action[a].Width, text)
}

func (t Tree) Render() {
	for _, row := range t.F {
		t.pr(row.Format, row.Text)
	}
}

func line(pdf *gofpdf.Fpdf, jump, width float64, text string) {
	pdf.SetX(jump)
	pdf.MultiCell(width, 0.19, tr(text), "", "aligned", false)
}

func (t *Tree) ParseString(play string) {
	toParse := strings.Split(play, "\n")
	for i, row := range toParse {
		action := "action"
		if row == strings.ToUpper(row) {
			action = "allcaps"
		}
		if row == "" {
			action = "empty"
		} else {
			if i > 0 {
				switch t.F[i-1].Format {
				case "allcaps":
					t.F[i-1].Format = "speaker"
					if row[0] == '(' && row[len(row)-1] == ')' {
						action = "paren"
					} else {
						action = "dialog"
					}
				case "paren", "dialog":
					action = "dialog"
				}
			}
		}
		t.F = append(t.F, struct{ Format, Text string }{action, row})
	}
}