summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoop Kiefte <ikojba@gmail.com>2018-12-31 17:53:02 +0100
committerJoop Kiefte <ikojba@gmail.com>2018-12-31 17:53:02 +0100
commit20be238175eecc5e68b74d0e98e5ec428610a904 (patch)
tree6332fbaa903275990a87aacd57dd31161e3b00e6
parent22fab0a8bc6ae7f468c91ed2835a55226270afad (diff)
Beginning of the new structure under the Lexington name
-rw-r--r--fountain/parse.go95
-rw-r--r--lex/type.go23
-rw-r--r--pdf/create.go52
-rw-r--r--readme.md6
-rw-r--r--rules/rules.go63
5 files changed, 239 insertions, 0 deletions
diff --git a/fountain/parse.go b/fountain/parse.go
new file mode 100644
index 0000000..dc4602f
--- /dev/null
+++ b/fountain/parse.go
@@ -0,0 +1,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})
+ }
+}
diff --git a/lex/type.go b/lex/type.go
new file mode 100644
index 0000000..47439f4
--- /dev/null
+++ b/lex/type.go
@@ -0,0 +1,23 @@
+package lex
+
+import (
+ "io"
+ "fmt"
+)
+
+type Screenplay []Line
+
+type Line struct{
+ Type string
+ Contents string
+}
+
+func Parse(file io.Reader) (out Screenplay) {
+ var err error
+ line := Line{}
+ for err == nil {
+ _, err = fmt.Fscanf(file, "%s: %s", &line.Type, &line.Contents)
+ out = append(out, line)
+ }
+ return out
+}
diff --git a/pdf/create.go b/pdf/create.go
new file mode 100644
index 0000000..abf0284
--- /dev/null
+++ b/pdf/create.go
@@ -0,0 +1,52 @@
+package pdf
+
+import (
+ "github.com/lapingvino/lexington/lex"
+ "github.com/lapingvino/lexington/rules"
+
+ "github.com/jung-kurt/gofpdf"
+)
+
+var tr func(string) string
+
+type Tree struct {
+ PDF *gofpdf.Fpdf
+ Rules rules.Set
+ F lex.Screenplay
+}
+
+func (t Tree) pr(a string, text string) {
+ line(t.PDF, t.Rules.Get(a), text)
+}
+
+func (t Tree) Render() {
+ for _, row := range t.F {
+ if t.Rules.Get(row.Type).Hide {
+ continue
+ }
+ t.pr(row.Type, row.Contents)
+ }
+}
+
+func line(pdf *gofpdf.Fpdf, format rules.Format, text string) {
+ pdf.SetFont(format.Font, format.Style, format.Size)
+ pdf.SetX(format.Left)
+ pdf.MultiCell(format.Width, 0.19, tr(text), "", "aligned", false)
+}
+
+func Create(file string, format rules.Set, contents lex.Screenplay) {
+ pdf := gofpdf.New("P", "in", "Letter", "")
+ tr = pdf.UnicodeTranslatorFromDescriptor("")
+ pdf.AddPage()
+ pdf.SetMargins(1, 1, 1)
+ pdf.SetXY(1, 1)
+ f := Tree{
+ Rules: format,
+ F: contents,
+ }
+ f.Render()
+ err := pdf.OutputFileAndClose(file)
+ if err != nil {
+ panic(err)
+ }
+}
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..dc87e0d
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,6 @@
+Lexington commandline tool for screenwriters
+============================================
+
+Lexington helps you convert between Final Draft, Fountain and its own lex file formats, and output to PDF, HTML and ebook formats.
+
+At the moment the tool is not yet usable, please come back later or fork and contribute!
diff --git a/rules/rules.go b/rules/rules.go
new file mode 100644
index 0000000..07fe588
--- /dev/null
+++ b/rules/rules.go
@@ -0,0 +1,63 @@
+package rules
+
+type Format struct{
+ Width float64
+ Left float64
+ Font string
+ Style string
+ Size float64
+ Hide bool
+}
+
+type Set map[string]Format
+
+func (s Set) Get(action string) (f Format) {
+ f, ok := s[action]
+ if !ok {
+ f = s["action"]
+ f.Hide = true
+ }
+ if f.Font == "" {
+ f.Font = "courier"
+ }
+ if f.Size == 0 {
+ f.Size = 12
+ }
+ return f
+}
+
+var Default = Set{
+ "action": {
+ Left: 1.5,
+ Width: 6,
+ },
+ "speaker": {
+ Left: 4.2,
+ Width: 3.3,
+ },
+ "dialog": {
+ Left: 2.9,
+ Width: 3.3,
+ },
+ "scene": {
+ Left: 1.5,
+ Width: 6,
+ Style: "b",
+ },
+ "paren": {
+ Left: 3.6,
+ Width: 2,
+ },
+ "trans": {
+ Left: 6,
+ Width: 1.5,
+ },
+ "note": {
+ Left: 1.5,
+ Width: 6,
+ },
+ "allcaps": {
+ Left: 1.5,
+ Width: 6,
+ },
+}