├── .nojekyll ├── testdata ├── sample-01.fadein ├── sample-02.fadein ├── sample-03.fadein ├── sample-04.fadein ├── sample-05.fadein ├── sample-06.fadein ├── testplay-02.fountain ├── sample-01.fountain ├── sample-01.txt ├── testplay-02.txt ├── sample-03.fountain ├── sample-03.txt ├── sample-02.txt ├── sample-07-characters.txt ├── sample-05.fountain ├── testplay-01.fountain ├── sample-02.fountain ├── sample-05.txt ├── sample-04.fountain ├── testplay-01a.fdx ├── sample-04.txt ├── sample-06.txt ├── sample-06.fountain ├── sample-08.fountain ├── testplay-01b.fdx ├── sample-01.osf ├── sample-02.osf ├── testplay-02.trelby ├── sample-03.osf ├── Screenplay_Sample.osf ├── testplay-01.trelby ├── sample-05.osf └── sample-04.osf ├── pagefind ├── wasm.en-US.pagefind ├── wasm.en-us.pagefind ├── wasm.unknown.pagefind ├── index │ ├── en-US_c851c0a.pf_index │ └── en-us_7a45ff4.pf_index ├── pagefind-entry.json ├── fragment │ ├── en-US_2fca589.pf_fragment │ ├── en-US_39c0fba.pf_fragment │ ├── en-US_63f2f15.pf_fragment │ ├── en-US_72eae2c.pf_fragment │ ├── en-US_75d7b97.pf_fragment │ ├── en-US_8aed591.pf_fragment │ ├── en-US_a138d21.pf_fragment │ ├── en-US_afb3777.pf_fragment │ ├── en-US_ba81728.pf_fragment │ ├── en-US_e85f6ad.pf_fragment │ ├── en-us_39c0fba.pf_fragment │ ├── en-us_55e866e.pf_fragment │ ├── en-us_75d7b97.pf_fragment │ ├── en-us_8aed591.pf_fragment │ ├── en-us_9072f84.pf_fragment │ ├── en-us_a138d21.pf_fragment │ ├── en-us_afb3777.pf_fragment │ ├── en-us_ba81728.pf_fragment │ └── en-us_e85f6ad.pf_fragment ├── pagefind.en-US_525e4f4a22aee.pf_meta ├── pagefind.en-us_6c129dcf4b83a.pf_meta ├── pagefind-modular-ui.css └── pagefind-ui.css ├── user_manual.md ├── links-to-html.lua ├── go.mod ├── NOTES.md ├── .gitignore ├── page.tmpl ├── get-optional-testdata.bash ├── CITATION.cff ├── user_manual.html ├── codemeta-cff.tmpl ├── search.md ├── codemeta-version-go.tmpl ├── website.mak ├── go.sum ├── codemeta-md.tmpl ├── NOTES.html ├── snap └── snapcraft.yaml ├── codemeta.json ├── release-notes.md ├── about.md ├── release.bash ├── publish.bash ├── publish.ps1 ├── search.html ├── release.ps1 ├── INSTALL.md ├── testdata.md ├── cli_test.go ├── about.html ├── release-notes.html ├── codemeta-about.tmpl ├── README.md ├── codemeta-ps1-installer.tmpl ├── convertions.go ├── testdata.html ├── cmd └── scripttool │ └── main.go ├── installer.ps1 ├── INSTALL.html ├── TODO.md ├── index.html ├── scripttool_test.go ├── codemeta-bash-installer.tmpl ├── installer.sh ├── fountain-example.css ├── css └── site.css ├── scripttool.1.md ├── cli_docs.go ├── man └── man1 │ └── scripttool.1 ├── cli.go ├── TODO.html ├── scripttool.1.html └── Makefile /.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testdata/sample-01.fadein: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/testdata/sample-01.fadein -------------------------------------------------------------------------------- /testdata/sample-02.fadein: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/testdata/sample-02.fadein -------------------------------------------------------------------------------- /testdata/sample-03.fadein: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/testdata/sample-03.fadein -------------------------------------------------------------------------------- /testdata/sample-04.fadein: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/testdata/sample-04.fadein -------------------------------------------------------------------------------- /testdata/sample-05.fadein: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/testdata/sample-05.fadein -------------------------------------------------------------------------------- /testdata/sample-06.fadein: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/testdata/sample-06.fadein -------------------------------------------------------------------------------- /pagefind/wasm.en-US.pagefind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/wasm.en-US.pagefind -------------------------------------------------------------------------------- /pagefind/wasm.en-us.pagefind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/wasm.en-us.pagefind -------------------------------------------------------------------------------- /pagefind/wasm.unknown.pagefind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/wasm.unknown.pagefind -------------------------------------------------------------------------------- /pagefind/index/en-US_c851c0a.pf_index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/index/en-US_c851c0a.pf_index -------------------------------------------------------------------------------- /pagefind/index/en-us_7a45ff4.pf_index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/index/en-us_7a45ff4.pf_index -------------------------------------------------------------------------------- /pagefind/pagefind-entry.json: -------------------------------------------------------------------------------- 1 | {"version":"1.3.0","languages":{"en-US":{"hash":"en-US_525e4f4a22aee","wasm":"en-US","page_count":10}}} -------------------------------------------------------------------------------- /pagefind/fragment/en-US_2fca589.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_2fca589.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_39c0fba.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_39c0fba.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_63f2f15.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_63f2f15.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_72eae2c.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_72eae2c.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_75d7b97.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_75d7b97.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_8aed591.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_8aed591.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_a138d21.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_a138d21.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_afb3777.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_afb3777.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_ba81728.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_ba81728.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-US_e85f6ad.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-US_e85f6ad.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_39c0fba.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_39c0fba.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_55e866e.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_55e866e.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_75d7b97.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_75d7b97.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_8aed591.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_8aed591.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_9072f84.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_9072f84.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_a138d21.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_a138d21.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_afb3777.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_afb3777.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_ba81728.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_ba81728.pf_fragment -------------------------------------------------------------------------------- /pagefind/fragment/en-us_e85f6ad.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/fragment/en-us_e85f6ad.pf_fragment -------------------------------------------------------------------------------- /pagefind/pagefind.en-US_525e4f4a22aee.pf_meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/pagefind.en-US_525e4f4a22aee.pf_meta -------------------------------------------------------------------------------- /pagefind/pagefind.en-us_6c129dcf4b83a.pf_meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/scripttool/HEAD/pagefind/pagefind.en-us_6c129dcf4b83a.pf_meta -------------------------------------------------------------------------------- /testdata/testplay-02.fountain: -------------------------------------------------------------------------------- 1 | .FADE IN: 2 | 3 | A PROGRAMMER typing at on old laptop. 4 | 5 | PROGRAMMER 6 | (excited) 7 | Eureka! 8 | 9 | FADE TO BLACK. -------------------------------------------------------------------------------- /user_manual.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: fountain user manual 3 | --- 4 | 5 | user manual 6 | =========== 7 | 8 | - [Overview](index.md) 9 | - [scripttool](scripttool.1.md) 10 | 11 | -------------------------------------------------------------------------------- /testdata/sample-01.fountain: -------------------------------------------------------------------------------- 1 | !FADE IN: 2 | 3 | EXT. LIBRARY - DAY 4 | 5 | A PROGRAMMER typing at an old laptop 6 | 7 | PROGRAMMER 8 | (excited) 9 | Eureka! 10 | 11 | > FADE TO BLACK. 12 | 13 | -------------------------------------------------------------------------------- /testdata/sample-01.txt: -------------------------------------------------------------------------------- 1 | 2 | FADE IN: 3 | 4 | Ext. Library - day 5 | 6 | A PROGRAMMER typing at an old laptop 7 | 8 | PROGRAMMER 9 | (excited) 10 | Eureka! 11 | 12 | FADE TO BLACK. 13 | 14 | 15 | -------------------------------------------------------------------------------- /links-to-html.lua: -------------------------------------------------------------------------------- 1 | -- links-to-html.lua converts links to local Markdown documents to 2 | -- there respective .html counterparts. 3 | function Link(el) 4 | el.target = string.gsub(el.target, "%.md", ".html") 5 | return el 6 | end 7 | -------------------------------------------------------------------------------- /testdata/testplay-02.txt: -------------------------------------------------------------------------------- 1 | FADE IN: 2 | 3 | A PROGRAMMER typing at on old laptop. 4 | 5 | PROGRAMMER 6 | (excited) 7 | Eureka! 8 | 9 | FADE TO BLACK. 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/rsdoiel/scripttool 2 | 3 | go 1.22.0 4 | 5 | require ( 6 | github.com/rsdoiel/fdx v1.0.2 7 | github.com/rsdoiel/fountain v1.0.1 8 | github.com/rsdoiel/osf v0.0.7 9 | ) 10 | 11 | require gopkg.in/yaml.v3 v3.0.1 12 | -------------------------------------------------------------------------------- /NOTES.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: scripttool, a program for converting screen play formats 3 | --- 4 | 5 | # Misc dev notes 6 | 7 | + [Courier Prime](https://quoteunquoteapps.com/courierprime/) - 8 | + [Scrippets](https://wordpress.org/plugins/wp-scrippets/) - a WP plugin for fountain fragments 9 | + John Augusts's Scrippets [Call to Coders](https://johnaugust.com/2008/scrippets-php-and-a-call-to-coders) 10 | -------------------------------------------------------------------------------- /testdata/sample-03.fountain: -------------------------------------------------------------------------------- 1 | Title: SAMPLE 03 2 | Author: Jane Doe 3 | Draft date: 2018-01-01 4 | Copyright: Copyright (c) 2018 5 | Contact: 6 | ACME Examples Productions 7 | 1234 5th Avenue 8 | Anytown, Planet Earth, 12345-7890 9 | 10 | 11 | !FADE IN: 12 | 13 | INT. STUDIO APARTMENT - NIGHT 14 | 15 | The AUTHOR sits at a desk. 16 | 17 | AUTHOR 18 | (anguished) 19 | Writers block again! 20 | 21 | DISSOLVES TO: 22 | 23 | -------------------------------------------------------------------------------- /testdata/sample-03.txt: -------------------------------------------------------------------------------- 1 | 2 | SAMPLE 03 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Written By 11 | 12 | Jane Doe 13 | 14 | 15 | 16 | Source by 17 | 18 | The JD 19 | 20 | 1/1/2018 21 | 22 | 23 | 24 | ACME Examples Productions 25 | 26 | 1234 5th Avenue 27 | 28 | Anytown, Planet Earth, 12345-7890 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | FADE IN: 37 | 38 | INT. STUDIO APARTMENT - NIGHT 39 | 40 | The AUTHOR sits at a desk. 41 | 42 | AUTHOR 43 | (anguished) 44 | Writers block again! 45 | 46 | DISSOLVES TO: 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /testdata/sample-02.txt: -------------------------------------------------------------------------------- 1 | 2 | FADE IN: 3 | 4 | EXT. INDUSTRIAL PARK - DAY 5 | 6 | A low slung industrial building in an industrial center. The last car leaves the lot. Parking lot lights switch off. 7 | 8 | CROSSFADE TO: 9 | 10 | INT. OFFICE - NIGHT 11 | 12 | A PROGRAMMER stares at the screen. 13 | 14 | PROGRAMMER 15 | (drowsy) 16 | What algorithm is this? 17 | 18 | CUT TO: 19 | 20 | EXT. COURTYARD - DAY 21 | 22 | A programmer lounges by a fountain. 23 | 24 | PROGRAMMER 25 | (drowsy) 26 | This is what I remember. 27 | 28 | FADE TO BLACK. 29 | 30 | THE END 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | 16 | # Project ignores 17 | bin/ 18 | dist/ 19 | testout/ 20 | testdata/Big-Fish.fdx 21 | testdata/Big-Fish.fountain 22 | testdata/Brick-&-Steel.fdx 23 | testdata/Brick-&-Steel.fountain 24 | testdata/The-Last-Birthday-Card.fdx 25 | testdata/The-Last-Birthday-Card.fountain 26 | *.bak 27 | -------------------------------------------------------------------------------- /testdata/sample-07-characters.txt: -------------------------------------------------------------------------------- 1 | 1ST DIPLOMATIC TYPE 2 | 2ND DIPLOMATIC TYPE 3 | ADAM 4 | ATTENDANT 5 | BARTHOLOMEW 6 | BRITISH DELEGATE 7 | CARSON 8 | CLERK 9 | CRUIKSHANK 10 | DRIVER 11 | DYLE 12 | EMCEE 13 | FÉLIX 14 | FRENCH DELEGATE 15 | GENDARME 16 | GIDEON 17 | GRANDPIERRE 18 | GUARD 19 | ITALIAN DELEGATE 20 | JEAN-LOUIS 21 | MAN 22 | MANAGER 23 | MARINE 24 | NIGHT CLERK 25 | OPERATOR 26 | PETER 27 | REAL BARTHOLOMEW 28 | REGGIE 29 | SCOBIE 30 | SECRETARY 31 | SYLVIE 32 | TEX 33 | THÉOPHILE 34 | TOURIST 35 | TRAIN GUARD 36 | VOICE 37 | WAITER 38 | WOMAN 39 | ADAM AND REGGIE 40 | GIDEON, TEX & SCOBIE 41 | TEX & GIDEON 42 | -------------------------------------------------------------------------------- /page.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 | ${body} 22 |
23 | 24 | -------------------------------------------------------------------------------- /testdata/sample-05.fountain: -------------------------------------------------------------------------------- 1 | Title: Troubled Sleep 2 | Author: Jane Doe 3 | Draft date: 2018-01-01 4 | Copyright: Copyright (c) 2018 5 | Contact: 6 | ACME Examples Production 7 | 1234 5th Avenue 8 | Anytown, Planet Earth, 12345-7890 9 | 10 | 11 | EXT. APARTMENT - DAY 12 | 13 | AUTHOR wakes standing on the stoop in pajamas head against door. 14 | 15 | AUTHOR 16 | (concern, to self) 17 | Snap, sleep walking again. 18 | 19 | CUT TO: 20 | 21 | EXT. PARK - DAY 22 | 23 | Author is jogging, checking her fitness watch. Small DOG approaches and speaks to her in a human voice. 24 | 25 | DOG 26 | It's not the watch or the jog. You haven't woken up yet. 27 | 28 | > FADE TO BLACK. 29 | 30 | !>THE END.< 31 | 32 | -------------------------------------------------------------------------------- /testdata/testplay-01.fountain: -------------------------------------------------------------------------------- 1 | Title: Testplay-01 2 | Credit: written by 3 | Author: R. S. Doiel 4 | Notes: 5 | 6 | This is a test file for scripttool 7 | 8 | === 9 | 10 | **FADE IN:** 11 | 12 | A low slung industrial building in an industrial center. 13 | The last car leaves the lot. Parking lot lights switch off. 14 | 15 | CROSSFADE TO: 16 | 17 | INT. OFFICE - NIGHT 18 | 19 | A PROGRAMMER stares at the screen. 20 | 21 | PROGRAMMER 22 | (drowsy) 23 | What algorithm is this? 24 | 25 | CUT TO: 26 | 27 | EXT. COURTYARD - DAY 28 | 29 | A programmer lounges by a fountain. 30 | 31 | PROGRAMMER 32 | (drowsy) 33 | This is what I remember. 34 | 35 | FADE TO BLACK. 36 | 37 | > _**THE END**_ < 38 | 39 | -------------------------------------------------------------------------------- /get-optional-testdata.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | START=$(pwd) 4 | cd testdata 5 | curl -L -O "https://fountain.io/_downloads/Big-Fish.fountain" 6 | curl -L -O "https://fountain.io/_downloads/Big-Fish.fdx" 7 | #curl -L -O "https://fountain.io/_downloads/Big-Fish.pdf" 8 | curl -L -O "https://fountain.io/_downloads/Brick-&-Steel.fountain" 9 | curl -L -O "https://fountain.io/_downloads/Brick-&-Steel.fdx" 10 | #curl -L -O "https://fountain.io/_downloads/Brick-&-Steel.pdf" 11 | curl -L -O "https://fountain.io/_downloads/The-Last-Birthday-Card.fountain" 12 | curl -L -O "https://fountain.io/_downloads/The-Last-Birthday-Card.fdx" 13 | #curl -L -O "https://fountain.io/_downloads/The-Last-Birthday-Card.pdf" 14 | cd "$START" 15 | -------------------------------------------------------------------------------- /testdata/sample-02.fountain: -------------------------------------------------------------------------------- 1 | Title: TITLE 2 | Author: Author's Name 3 | Draft date: 4 | Draft 5 | information 6 | Copyright: Copyright (c) 2018 7 | Contact: 8 | Contact 9 | information 10 | 11 | 12 | !FADE IN: 13 | 14 | EXT. INDUSTRIAL PARK - DAY 15 | 16 | A low slung industrial building in an industrial center. The last car leaves the lot. Parking lot lights switch off. 17 | 18 | CROSS FADE TO: 19 | 20 | INT. OFFICE - NIGHT 21 | 22 | A PROGRAMMER stares at the screen. 23 | 24 | PROGRAMMER 25 | (drowsy) 26 | What algorithm is this? 27 | 28 | CUT TO: 29 | 30 | EXT. COURTYARD - DAY 31 | 32 | A programmer lounges by a fountain. 33 | 34 | PROGRAMMER 35 | (drowsy) 36 | This is what I remember. 37 | 38 | > FADE TO BLACK. 39 | 40 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | 2 | cff-version: 1.2.0 3 | message: "If you use this software, please cite it as below." 4 | type: software 5 | title: scripttool 6 | abstract: "A library and command line program for working with fdx (Final Draft XML), osf, Fade In and Fountain formatted Screen Play files." 7 | authors: 8 | - family-names: Doiel 9 | given-names: Robert 10 | orcid: https://orcid.org/0000-0003-0900-6903 11 | email: rsdoiel@gmail.com 12 | 13 | contacts: 14 | - family-names: 15 | given-names: 16 | 17 | repository-code: "https://github.com/rsdoiel/scripttool" 18 | version: 0.0.10 19 | 20 | 21 | license-url: "https://spdx.org/licenses/AGPL-3.0-or-later" 22 | keywords: 23 | - Github 24 | - text markup 25 | - screen play 26 | 27 | -------------------------------------------------------------------------------- /testdata/sample-05.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Troubled Sleep 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Written By 21 | 22 | 23 | 24 | Jane Doe 25 | 26 | 2018-01-01 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | ACME Examples Production 37 | 38 | 1234 5th Avenue 39 | 40 | Anytown, Planet Earth, 91350 41 | 42 | EXT. APARTMENT - DAY 43 | 44 | AUTHOR wakes standing on the stoop in pajamas head against door. 45 | 46 | AUTHOR 47 | (concern, to self) 48 | Snap, sleep walking again. 49 | 50 | CUT TO: 51 | 52 | EXT. PARK - DAY 53 | 54 | Author is jogging, checking her fitness watch. Small DOG approaches and speaks to her in a human voice. 55 | 56 | DOG 57 | It's not the watch or the jog. You haven't woken up yet. 58 | 59 | FADE TO BLACK. 60 | 61 | THE END. 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /testdata/sample-04.fountain: -------------------------------------------------------------------------------- 1 | Title: SAMPLE 04 2 | Author: Jane Doe 3 | Draft date: 2018-01-01 4 | Copyright: Copyright (c) 2018 5 | Contact: 6 | ACME Examples Productions 7 | 1234 5th Avenue 8 | Anytown, Planet Earth, 12345-7890 9 | 10 | 11 | > FADE IN: 12 | 13 | INT. STUDIO APARTMENT - NIGHT 14 | 15 | The AUTHOR sits at a desk. 16 | 17 | AUTHOR 18 | (anguished) 19 | Writers block again! 20 | 21 | DISSOLVES TO: 22 | 23 | EXT. PARK - DAY 24 | 25 | Author is jogging. DOG runs up to her and speaks in a human voice. 26 | 27 | DOG 28 | Bark! Bark! Roof! Your not blocked. You're trying to write the story from the wrong character's viewpoint. 29 | 30 | AUTHOR 31 | (disbelief) 32 | You spoke? 33 | 34 | DOG 35 | That goes without saying, better run along before you loose your cardio moment. 36 | 37 | > FADE TO BLACK. 38 | 39 | !>THE END.< 40 | 41 | -------------------------------------------------------------------------------- /user_manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

user manual

22 | 26 |
27 | 28 | -------------------------------------------------------------------------------- /codemeta-cff.tmpl: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this software, please cite it as below." 3 | type: software 4 | ${if(name)}title: "${name}"${endif} 5 | ${if(description)}abstract: "${description}"${endif} 6 | ${if(author)}authors: 7 | ${for(author)} 8 | - family-names: ${it.familyName} 9 | given-names: ${it.givenName} 10 | orcid: "${it.at__id}" 11 | ${endfor}${endif} 12 | ${if(maintainer)}maintainers: 13 | ${for(maintainer)} 14 | - family-names: ${it.familyName} 15 | given-names: ${it.givenName} 16 | orcid: "${it.at__id}" 17 | ${endfor}${endif} 18 | ${if(codeRepository)}repository-code: "${codeRepository}"${endif} 19 | ${if(version)}version: ${version}${endif} 20 | ${if(license)}license-url: "${license}"${endif} 21 | ${if(keywords)}keywords: [ ${for(keywords)}"${it}"${sep}, ${endfor} ]${endif} 22 | ${if(datePublished)}date-released: ${datePublished}${endif} 23 | -------------------------------------------------------------------------------- /testdata/testplay-01a.fdx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FADE IN: 6 | 7 | 8 | A PROGRAMMER typing at on old laptop. 9 | 10 | 11 | PROGRAMMER 12 | 13 | 14 | (excited) 15 | 16 | 17 | Eureka! 18 | 19 | 20 | FADE TO BLACK. 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /search.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # scripttool 4 | 5 | 6 | 7 | 8 | 31 | -------------------------------------------------------------------------------- /codemeta-version-go.tmpl: -------------------------------------------------------------------------------- 1 | package $package$ 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | const ( 8 | // Version number of release 9 | Version = "$version$" 10 | 11 | // ReleaseDate, the date version.go was generated 12 | ReleaseDate = "$release_date$" 13 | 14 | // ReleaseHash, the Git hash when version.go was generated 15 | ReleaseHash = "$release_hash$" 16 | 17 | LicenseText = ` 18 | $body$ 19 | ` 20 | ) 21 | 22 | // FmtHelp lets you process a text block with simple curly brace markup. 23 | func FmtHelp(src string, appName string, version string, releaseDate string, releaseHash string) string { 24 | m := map[string]string { 25 | "{app_name}": appName, 26 | "{version}": version, 27 | "{release_date}": releaseDate, 28 | "{release_hash}": releaseHash, 29 | } 30 | for k, v := range m { 31 | if strings.Contains(src, k) { 32 | src = strings.ReplaceAll(src, k, v) 33 | } 34 | } 35 | return src 36 | } 37 | 38 | -------------------------------------------------------------------------------- /testdata/sample-04.txt: -------------------------------------------------------------------------------- 1 | 2 | SAMPLE 03 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Written By 11 | 12 | Jane Doe 13 | 14 | 15 | 16 | Source by 17 | 18 | The JD 19 | 20 | 1/1/2018 21 | 22 | 23 | 24 | ACME Examples Productions 25 | 26 | 1234 5th Avenue 27 | 28 | Anytown, Planet Earth, 12345-7890 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | FADE IN: 37 | 38 | INT. STUDIO APARTMENT - NIGHT 39 | 40 | The AUTHOR sits at a desk. 41 | 42 | AUTHOR 43 | (anguished) 44 | Writers block again! 45 | 46 | DISSOLVES TO: 47 | 48 | EXT. PARK - DAY 49 | 50 | Author is jogging. DOG runs up to her and speaks in a human voice. 51 | 52 | DOG 53 | Bark! Bark! Roof! Your not blocked. You're trying to write the story from the wrong chacacter's viewpoint. 54 | 55 | AUTHOR 56 | (disbelief) 57 | But you spoke? 58 | 59 | DOG 60 | That goes without saying, better run along before you loose your cardio moment. 61 | 62 | 63 | 64 | FADE TO BLACK. 65 | 66 | THE END. 67 | 68 | 69 | -------------------------------------------------------------------------------- /testdata/sample-06.txt: -------------------------------------------------------------------------------- 1 | >_**SAMPLE 06**_< 2 | >Written by< 3 | 4 | >Jane Doe< 5 | 6 | >Story by <>JD< 7 | 1/1/2018 8 | 9 | ACME Example Productions 10 | 1234 5th Avenue 11 | Anytown, SOMESTATE 012345-1234 12 | 13 | 14 | 15 | INT. STUDIO APARTMENT - NIGHT 16 | 17 | The AUTHOR sits at a desk. 18 | 19 | AUTHOR 20 | (anguished) 21 | Writers block again! 22 | 23 | DISSOLVES TO: 24 | 25 | EXT. PARK - DAY 26 | 27 | Author is jogging. DOG runs up to her and speaks in a human voice. 28 | 29 | DOG 30 | Bark! Bark! Roof! Your not blocked. You're trying to write the story from the wrong chacacter's viewpoint. 31 | 32 | AUTHOR 33 | (disbelief) 34 | But you spoke? 35 | 36 | DOG 37 | That goes without saying, better run along before you loose your cardio moment. 38 | 39 | === 40 | 41 | INT. STUDIO APARTMENT - NEXT DAY 42 | 43 | The author is sprawled on the couch. 44 | 45 | AUTHOR 46 | (refreshed) 47 | Shall we try? 48 | 49 | FADE TO BLACK. 50 | 51 | THE END. 52 | 53 | -------------------------------------------------------------------------------- /testdata/sample-06.fountain: -------------------------------------------------------------------------------- 1 | Title: SAMPLE 06 2 | Author: Jane Doe 3 | Draft date: 2018-01-01 4 | Copyright: Copyright (c) 2018 5 | Contact: 6 | ACME Examples Production 7 | 1234 5th Avenue 8 | Anytown, Planet Earth, 012345-1234 9 | 10 | 11 | INT. STUDIO APARTMENT - NIGHT 12 | 13 | The AUTHOR sits at a desk. 14 | 15 | AUTHOR 16 | (anguished) 17 | Writers block again! 18 | 19 | DISSOLVES TO: 20 | 21 | EXT. PARK - DAY 22 | 23 | Author is jogging. DOG runs up to her and speaks in a human voice. 24 | 25 | DOG 26 | Bark! Bark! Roof! Your not blocked. You're trying to write the story from the wrong character's viewpoint. 27 | 28 | AUTHOR 29 | (disbelief) 30 | But you spoke? 31 | 32 | DOG 33 | That goes without saying, better run along before you loose your cardio moment. 34 | === 35 | 36 | INT. STUDIO APARTMENT - NEXT DAY 37 | 38 | The author is sprawled on the couch. 39 | 40 | AUTHOR 41 | (refreshed) 42 | Shall we try? 43 | 44 | > FADE TO BLACK. 45 | 46 | !>THE END.< 47 | 48 | -------------------------------------------------------------------------------- /website.mak: -------------------------------------------------------------------------------- 1 | 2 | # generated with CMTools 0.0.10 b59480b 3 | 4 | # 5 | # Makefile for running pandoc on all Markdown docs ending in .md 6 | # 7 | PROJECT = scripttool 8 | 9 | PANDOC = $(shell which pandoc) 10 | 11 | MD_PAGES = $(shell ls -1 *.md) 12 | 13 | HTML_PAGES = $(shell ls -1 *.md | sed -E 's/.md/.html/g') 14 | 15 | build: $(HTML_PAGES) $(MD_PAGES) pagefind 16 | 17 | $(HTML_PAGES): $(MD_PAGES) .FORCE 18 | if [ -f $(PANDOC) ]; then $(PANDOC) --metadata title=$(basename $@) -s --to html5 $(basename $@).md -o $(basename $@).html \ 19 | --lua-filter=links-to-html.lua \ 20 | --template=page.tmpl; fi 21 | @if [ $@ = "README.html" ]; then mv README.html index.html; fi 22 | 23 | pagefind: .FORCE 24 | # NOTE: I am not including most of the archive in PageFind index since it doesn't make sense in this case. 25 | pagefind --verbose --glob="{*.html,docs/*.html}" --force-language en-US --exclude-selectors="nav,header,footer" --output-path ./pagefind --site . 26 | git add pagefind 27 | 28 | clean: 29 | @rm *.html 30 | 31 | .FORCE: 32 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/rsdoiel/fdx v1.0.2 h1:TMBGgYdG7CaPbnM6kMAkRebYyCfWK9dK/qooPhEITU8= 2 | github.com/rsdoiel/fdx v1.0.2/go.mod h1:hXJBkY2UoujfU1EZ1tiR8aa3AZgcReOydZZ7dAuyg9o= 3 | github.com/rsdoiel/fountain v1.0.1 h1:m5JZbnasFendZbYzoTsOsJ/gcup7VNTUjJGTANshQck= 4 | github.com/rsdoiel/fountain v1.0.1/go.mod h1:Sd3MZuWObP+tssyGIuUUfl3+nslvRVndkEEpBVsWAJU= 5 | github.com/rsdoiel/osf v0.0.6 h1:5ijMEfFH1zzBsYTeChyCi06sYQhboMBX7rSr/gW7ZnY= 6 | github.com/rsdoiel/osf v0.0.6/go.mod h1:UzyqbsRFk5rL3WTiFvlfvL4jsqgt/EPHVlbs9FShFwI= 7 | github.com/rsdoiel/osf v0.0.7 h1:woMTMPktKWhQJdPGVt1zmVbq9jJFmPiq0lqzWNnmR/s= 8 | github.com/rsdoiel/osf v0.0.7/go.mod h1:jmOePx0mqICIH+G7GuIFnWGckQB7XWovQhdGMp9dPgE= 9 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 10 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 11 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 12 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 13 | -------------------------------------------------------------------------------- /codemeta-md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | title: $name$ 3 | --- 4 | 5 | About this software 6 | =================== 7 | 8 | $name$ $version$ 9 | ---------------- 10 | 11 | $if(author)$ 12 | ### Authors 13 | 14 | $for(author)$ 15 | - $it.givenName$ $it.familyName$ 16 | $endfor$ 17 | $endif$ 18 | 19 | $if(description)$ 20 | $description$ 21 | $endif$ 22 | 23 | 24 | $if(license)$- License: $license$$endif$ 25 | $if(codeRepository)$- GitHub: $codeRepository$$endif$ 26 | $if(issueTracker)$- Issues: $issueTracker$$endif$ 27 | 28 | 29 | $if(programmingLanguage)$ 30 | ### Programming languages 31 | 32 | $for(programmingLanguage)$ 33 | - $programmingLanguage$ 34 | $endfor$ 35 | $endif$ 36 | 37 | $if(operatingSystem)$ 38 | ### Operating Systems 39 | 40 | $for(operatingSystem)$ 41 | - $operatingSystem$ 42 | $endfor$ 43 | $endif$ 44 | 45 | $if(softwareRequirements)$ 46 | ### Software Requiremets 47 | 48 | $for(softwareRequirements)$ 49 | - $softwareRequirements$ 50 | $endfor$ 51 | $endif$ 52 | 53 | $if(relatedLink)$ 54 | ### Related Links 55 | 56 | $for(relatedLink)$ 57 | - [$it$]($it$) 58 | $endfor$ 59 | $endif$ 60 | -------------------------------------------------------------------------------- /NOTES.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

Misc dev notes

22 | 31 |
32 | 33 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: scripttool # you probably want to 'snapcraft register ' 2 | base: core20 # the base snap is the execution environment for this snap 3 | version: '0.0.9' # just for humans, typically '1.2+git' or '1.3.2' 4 | summary: scripttool, a program for converting screen play formats 5 | description: | 6 | scripttool can be used to convert common "plain text" style 7 | screenplay markups such as Fountain, OSF (Open Screenplay Format), 8 | FadeIn and FinalDraft's fdx XML format. 9 | 10 | See https://github.com/rsdoiel/scripttool 11 | 12 | grade: devel # must be 'stable' to release into candidate/stable channels 13 | confinement: strict # use 'strict' once you have the right plugs and slots 14 | 15 | apps: 16 | scripttool: 17 | command: bin/scripttool 18 | plugs: 19 | - home 20 | - desktop 21 | - removable-media 22 | 23 | parts: 24 | scripttool: 25 | # See 'snapcraft plugins' 26 | plugin: go 27 | go-channel: stable 28 | build-environment: 29 | - "CGO_ENABLED" : "1" 30 | source-type: git 31 | source: https://github.com/rsdoiel/scripttool 32 | -------------------------------------------------------------------------------- /codemeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "https://doi.org/10.5063/schema/codemeta-2.0", 3 | "@type": "SoftwareSourceCode", 4 | "description": "A library and command line program for working with fdx (Final Draft XML), osf, Fade In and Fountain formatted Screen Play files.", 5 | "name": "scripttool", 6 | "codeRepository": "https://github.com/rsdoiel/scripttool", 7 | "issueTracker": "https://github.com/rsdoiel/scripttool/issues", 8 | "license": "https://spdx.org/licenses/AGPL-3.0-or-later", 9 | "releaseNotes": "updated license", 10 | "version": "0.0.10", 11 | "author": [ 12 | { 13 | "@type": "Person", 14 | "givenName": "Robert", 15 | "familyName": "Doiel", 16 | "email": "rsdoiel@gmail.com", 17 | "@id": "https://orcid.org/0000-0003-0900-6903" 18 | } 19 | ], 20 | "developmentStatus": "active", 21 | "keywords": [ 22 | "Github", 23 | "text markup", 24 | "screen play" 25 | ], 26 | "maintainer": "https://orcid.org/0000-0003-0900-6903", 27 | "programmingLanguage": [ 28 | "Go" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /release-notes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: scripttool releases 3 | --- 4 | 5 | Releases 6 | ======== 7 | 8 | v0.0.7, 2022-08-07, project refresh 9 | ----------------------------------- 10 | 11 | This release is mostly a code re-organization due to changes in how Go 1.18 supports modules. The packages osf, fountain, and fdx are now part of the scripttool. The modules are largely stable. It's been years since I've changed them. The scripttool itself has bee restructure. A major change is the command line syntax. I am now using a `scripttool [-help|-version|-license] VERB [OPTIONS] [ADDITIONAL_PARAMETERS]`. Each "verb" can have its own set of options and they come after the "verb" before it expected additional parameters. 12 | 13 | The build process for source code and website have been significantly updated. I'm using Pandoc and pdtk to build the website. The old Makefile and Python scripts have been replace by a two new Makefile (i.e. Makefile, website.mak). 14 | 15 | In the `scripttool` command the "characters" verb will list the characters found in a fountain formatted screenplay. By default it is order of appearance but there is now an option `-alpha` for alphabetical sorts. 16 | 17 | -------------------------------------------------------------------------------- /testdata/sample-08.fountain: -------------------------------------------------------------------------------- 1 | Title: SAMPLE 08 2 | Author: Jane Doe 3 | Draft date: 2022-08-07 4 | Copyright: Copyright (c) 2022 5 | Contact: 6 | ACME Examples Production 7 | 1234 5th Avenue 8 | Anytown, Planet Earth, 012345-1234 9 | 10 | 11 | INT. SPACESHIP - NIGHT 12 | 13 | The ROBOT sits at the controls. 14 | 15 | ROBOT 16 | (frustrated) 17 | There must be organic life in the universe or my paper to the symposia will be withdrawn. I'll search the one last galaxy. Such a remote corner of the galactic dice throw. 18 | 19 | INT. STUDIO APARTMENT - NIGHT 20 | 21 | The AUTHOR sits at a desk. 22 | 23 | AUTHOR 24 | (anguished) 25 | Writers block again! 26 | 27 | DISSOLVES TO: 28 | 29 | EXT. PARK - DAY 30 | 31 | Author is jogging. DOG runs up to her and speaks in a human voice. 32 | 33 | DOG 34 | Bark! Bark! Roof! Your not blocked. You're trying to write the story from the wrong character's viewpoint. 35 | 36 | AUTHOR 37 | (disbelief) 38 | But you spoke? 39 | 40 | DOG 41 | That goes without saying, better run along before you loose your cardio moment. 42 | === 43 | 44 | INT. STUDIO APARTMENT - NEXT DAY 45 | 46 | The author is sprawled on the couch. 47 | 48 | AUTHOR 49 | (refreshed) 50 | Shall we try? 51 | 52 | > FADE TO BLACK. 53 | 54 | !>THE END.< 55 | 56 | -------------------------------------------------------------------------------- /about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: scripttool 3 | abstract: "A library and command line program for working with fdx (Final Draft XML), osf, Fade In and Fountain formatted Screen Play files." 4 | authors: 5 | - family_name: Doiel 6 | given_name: Robert 7 | id: https://orcid.org/0000-0003-0900-6903 8 | 9 | 10 | maintainer: 11 | - name: https://orcid.org/0000-0003-0900-6903 12 | 13 | repository_code: https://github.com/rsdoiel/scripttool 14 | version: 0.0.10 15 | license_url: https://spdx.org/licenses/AGPL-3.0-or-later 16 | 17 | programming_language: 18 | - Go 19 | 20 | keywords: 21 | - Github 22 | - text markup 23 | - screen play 24 | 25 | 26 | --- 27 | 28 | About this software 29 | =================== 30 | 31 | ## scripttool 0.0.10 32 | 33 | updated license 34 | 35 | ### Authors 36 | 37 | - Robert Doiel, 38 | 39 | 40 | 41 | 42 | ### Maintainers 43 | 44 | - https://orcid.org/0000-0003-0900-6903 45 | 46 | 47 | A library and command line program for working with fdx (Final Draft XML), osf, Fade In and Fountain formatted Screen Play files. 48 | 49 | - License: 50 | - GitHub: 51 | - Issues: 52 | 53 | ### Programming languages 54 | 55 | - Go 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # generated with CMTools 0.0.10 b59480b 3 | 4 | # 5 | # Release script for scripttool on GitHub using gh cli. 6 | # 7 | # shellcheck disable=SC2046 8 | REPO_ID="$(basename $(pwd))" 9 | # shellcheck disable=SC2046 10 | GROUP_ID="$(basename $(dirname $(pwd)))" 11 | REPO_URL="https://github.com/${GROUP_ID}/${REPO_ID}" 12 | echo "REPO_URL -> ${REPO_URL}" 13 | 14 | # 15 | # Generate a new draft release jq and gh 16 | # 17 | RELEASE_TAG="v$(jq -r .version codemeta.json)" 18 | RELEASE_NOTES="$(jq -r .releaseNotes codemeta.json | tr '\`' "'" | tr '\n' ' ')" 19 | echo "tag: ${RELEASE_TAG}, notes:" 20 | jq -r .releaseNotes codemeta.json >release_notes.tmp 21 | cat release_notes.tmp 22 | 23 | # Now we're ready to push things. 24 | # shellcheck disable=SC2162 25 | read -r -p "Push release to GitHub with gh? (y/N) " YES_NO 26 | if [ "$YES_NO" = "y" ]; then 27 | make save msg="prep for ${RELEASE_TAG}, ${RELEASE_NOTES}" 28 | # Now generate a draft release 29 | echo "Pushing release ${RELEASE_TAG} to GitHub" 30 | gh release create "${RELEASE_TAG}" \ 31 | --draft \ 32 | -F release_notes.tmp \ 33 | --generate-notes 34 | echo "Uploading distribution files" 35 | gh release upload "${RELEASE_TAG}" dist/*.zip 36 | 37 | cat < 7 | 8 | $workingBranch = git branch | Select-String -Pattern "\* " | ForEach-Object { $_ -replace '\* ', '' } 9 | if ($workingBranch -eq "gh-pages") { 10 | git commit -am "publishing to gh-pages branch" 11 | git push origin gh-pages 12 | } else { 13 | Write-Output "You're in $workingBranch branch" 14 | Write-Output "You need to pull in changes to the gh-pages branch to publish" 15 | $yesNo = Read-Host "Process Y/n" 16 | if ($yesNo -eq "Y" -or $yesNo -eq "y") { 17 | Write-Output "Committing and pushing to $workingBranch" 18 | git commit -am "committing to $workingBranch" 19 | git push origin $workingBranch 20 | Write-Output "Changing branches from $workingBranch to gh-pages" 21 | git checkout gh-pages 22 | Write-Output "Merging changes from origin gh-pages" 23 | git pull origin gh-pages 24 | git commit -am "merging origin gh-pages" 25 | Write-Output "Pulling changes from $workingBranch into gh-pages" 26 | git pull origin $workingBranch 27 | Write-Output "Merging changes from $workingBranch" 28 | git commit -am "merging $workingBranch with gh-pages" 29 | Write-Output "Pushing changes up and publishing" 30 | git push origin gh-pages 31 | Write-Output "Changing back to your working branch $workingBranch" 32 | git checkout $workingBranch 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

scripttool

22 | 23 | 24 | 27 | 50 |
51 | 52 | -------------------------------------------------------------------------------- /release.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | generated with CMTools 0.0.10 b59480b 3 | 4 | .SYNOPSIS 5 | Release script for scripttool on GitHub using gh CLI. 6 | #> 7 | 8 | # Determine repository and group IDs 9 | $repoId = Split-Path -Leaf -Path (Get-Location) 10 | $groupId = Split-Path -Leaf -Path (Split-Path -Parent -Path (Get-Location)) 11 | $repoUrl = "https://github.com/$groupId/$repoId" 12 | Write-Output "REPO_URL -> $repoUrl" 13 | 14 | # Generate a new draft release using jq and gh 15 | $releaseTag = "v$(jq -r .version codemeta.json)" 16 | $releaseNotes = jq -r .releaseNotes codemeta.json | ForEach-Object { $_ -replace "`n", " " -replace "`'", "'" } 17 | Write-Output "tag: $releaseTag, notes:" 18 | jq -r .releaseNotes codemeta.json | Out-File -FilePath release_notes.tmp -Encoding utf8 19 | Get-Content release_notes.tmp 20 | 21 | # Prompt user to push release to GitHub 22 | $yesNo = Read-Host -Prompt "Push release to GitHub with gh? (y/N)" 23 | if ($yesNo -eq "y") { 24 | # Assuming 'make save' is a placeholder for a command you have 25 | # Replace 'make save' with the appropriate PowerShell command or function 26 | Write-Output "Preparing for $releaseTag, $releaseNotes" 27 | # Create a draft release 28 | Write-Output "Pushing release $releaseTag to GitHub" 29 | gh release create "$releaseTag" ` 30 | --draft ` 31 | --notes-file release_notes.tmp ` 32 | --generate-notes 33 | Write-Output "Uploading distribution files" 34 | gh release upload "$releaseTag" dist/*.zip 35 | 36 | @" 37 | Now go to repo release and finalize draft. 38 | 39 | $repoUrl/releases 40 | 41 | "@ 42 | 43 | Remove-Item release_notes.tmp 44 | } 45 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | Installation for development of **scripttool** 2 | =========================================== 3 | 4 | **scripttool** A library and command line program for working with fdx (Final Draft XML), osf, Fade In and Fountain formatted Screen Play files. 5 | 6 | Quick install with curl or irm 7 | ------------------------------ 8 | 9 | There is an experimental installer.sh script that can be run with the following command to install latest table release. This may work for macOS, Linux and if you’re using Windows with the Unix subsystem. This would be run from your shell (e.g. Terminal on macOS). 10 | 11 | ~~~shell 12 | curl https://rsdoiel.github.io/scripttool/installer.sh | sh 13 | ~~~ 14 | 15 | This will install the programs included in scripttool in your `$HOME/bin` directory. 16 | 17 | If you are running Windows 10 or 11 use the Powershell command below. 18 | 19 | ~~~ps1 20 | irm https://rsdoiel.github.io/scripttool/installer.ps1 | iex 21 | ~~~ 22 | 23 | ### If your are running macOS or Windows 24 | 25 | You may get security warnings if you are using macOS or Windows. See the notes for the specific operating system you're using to fix issues. 26 | 27 | - [INSTALL_NOTES_macOS.md](INSTALL_NOTES_macOS.md) 28 | - [INSTALL_NOTES_Windows.md](INSTALL_NOTES_Windows.md) 29 | 30 | Installing from source 31 | ---------------------- 32 | 33 | ### Required software 34 | 35 | 36 | ### Steps 37 | 38 | 1. git clone https://github.com/rsdoiel/scripttool 39 | 2. Change directory into the `scripttool` directory 40 | 3. Make to build, test and install 41 | 42 | ~~~shell 43 | git clone https://github.com/rsdoiel/scripttool 44 | cd scripttool 45 | make 46 | make test 47 | make install 48 | ~~~ 49 | 50 | -------------------------------------------------------------------------------- /testdata.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: scripttool, a program for converting screen play formats 3 | --- 4 | 5 | About the test data 6 | =================== 7 | 8 | The testing data for scripttool and its sub-packages fountain, fdx and 9 | osf are held in common in this repository's _testdata_ directory. 10 | 11 | The [fountain](https://fountain.io) website has some good files 12 | for reviewing formatting difference between fountain, fdx and 13 | PDF. Some are referenced in the test programs but they are 14 | optional. It is not clear to me the licensing arrangements for 15 | the text so I have not included them in this repository. You can 16 | use the *bash* script `get-optional-testdata.bash` to retrieve 17 | them from the fountain.io website. 18 | 19 | If you want to include them in the test sequence go to the 20 | fountain website and download them and place them in the _testdata_ 21 | directory. When you run `go test` they will be found and included 22 | in the basic test process. 23 | 24 | Optional test FDX files 25 | ----------------------- 26 | 27 | + [Big Fish](https://fountain.io/_downloads/Big%20Fish.fountain) 28 | + [fdx](https://fountain.io/_downloads/Big%20Fish.fdx) 29 | + [pdf](https://fountain.io/_downloads/Big%20Fish.pdf) 30 | + [Brick & Steel](https://fountain.io/_downloads/Brick%20&%20Steel.fountain) 31 | + [fdx](https://fountain.io/_downloads/Brick%20&%20Steel.fdx) 32 | + [pdf](https://fountain.io/_downloads/Brick%20&%20Steel.pdf) 33 | + [Birthday Card](https://fountain.io/_downloads/The%20Last%20Birthday%20Card.fountain) 34 | + [fdx](https://fountain.io/_downloads/The%20Last%20Birthday%20Card.fdx) 35 | + [pdf](https://fountain.io/_downloads/The%20Last%20Birthday%20Card.pdf) 36 | 37 | -------------------------------------------------------------------------------- /cli_test.go: -------------------------------------------------------------------------------- 1 | package scripttool 2 | 3 | import ( 4 | "io/fs" 5 | "os" 6 | "path" 7 | "strings" 8 | "testing" 9 | ) 10 | 11 | var ( 12 | testdataBase = "testdata" 13 | testoutBase = "testout" 14 | ) 15 | 16 | func TestRunScripttool(t *testing.T) { 17 | var verb string 18 | appName := os.Args[0] 19 | // Run the JSON command 20 | if _, err := os.Stat(testoutBase); err == nil { 21 | os.RemoveAll(testoutBase) 22 | } 23 | os.MkdirAll(testoutBase, 0775) 24 | fSys := os.DirFS(testdataBase) 25 | fs.WalkDir(fSys, ".", func(p string, info fs.DirEntry, err error) error { 26 | if !info.IsDir() { 27 | inName := info.Name() 28 | inExt := path.Ext(inName) 29 | outName := strings.TrimSuffix(inName, inExt) + ".json" 30 | 31 | //fmt.Printf("DEBUG pth: %q fName: %q, ext: %q\n", p, inName, inExt) 32 | switch inExt { 33 | case ".txt": 34 | verb = "fountain2json" 35 | case ".fountain": 36 | verb = "fountain2json" 37 | case ".fdx": 38 | verb = "fdx2json" 39 | case ".fadein": 40 | verb = "fadein2json" 41 | case ".osf": 42 | verb = "osf2json" 43 | default: 44 | // We're only doing 45 | //fmt.Printf("Skipping %q, unsupported to file extension %q\n", inName, inExt) 46 | return nil 47 | } 48 | // We'll just rely on our standard VERB INPUT_NAME OUTPUT_NAME 49 | in := os.Stdin 50 | out := os.Stdout 51 | eout := os.Stderr 52 | inputFName := path.Join(testdataBase, inName) 53 | outputFName := path.Join(testoutBase, outName) 54 | args := []string{appName, verb, inputFName, outputFName} 55 | if err := RunScripttool(in, out, eout, args); err != nil { 56 | t.Errorf("unexpected error RunScripttool(in, out, eout, %+v) -> %s", args, err) 57 | } 58 | } 59 | return nil 60 | }) 61 | } 62 | -------------------------------------------------------------------------------- /about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

About this software

22 |

scripttool 0.0.10

23 |

updated license

24 |

Authors

25 | 29 |

Maintainers

30 |
    31 |
  • https://orcid.org/0000-0003-0900-6903
  • 32 |
33 |

A library and command line program for working with fdx (Final Draft 34 | XML), osf, Fade In and Fountain formatted Screen Play files.

35 | 43 |

Programming languages

44 |
    45 |
  • Go
  • 46 |
47 |
48 | 49 | -------------------------------------------------------------------------------- /release-notes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

Releases

22 |

v0.0.7, 2022-08-07, project 23 | refresh

24 |

This release is mostly a code re-organization due to changes in how 25 | Go 1.18 supports modules. The packages osf, fountain, and fdx are now 26 | part of the scripttool. The modules are largely stable. It’s been years 27 | since I’ve changed them. The scripttool itself has bee restructure. A 28 | major change is the command line syntax. I am now using a 29 | scripttool [-help|-version|-license] VERB [OPTIONS] [ADDITIONAL_PARAMETERS]. 30 | Each “verb” can have its own set of options and they come after the 31 | “verb” before it expected additional parameters.

32 |

The build process for source code and website have been significantly 33 | updated. I’m using Pandoc and pdtk to build the website. The old 34 | Makefile and Python scripts have been replace by a two new Makefile 35 | (i.e. Makefile, website.mak).

36 |

In the scripttool command the “characters” verb will 37 | list the characters found in a fountain formatted screenplay. By default 38 | it is order of appearance but there is now an option -alpha 39 | for alphabetical sorts.

40 |
41 | 42 | -------------------------------------------------------------------------------- /codemeta-about.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | cff-version: 1.2.0 3 | message: "If you use this software, please cite it as below." 4 | type: software 5 | ${if(name)}title: "${name}"${endif} 6 | ${if(description)}abstract: "${description}"${endif} 7 | ${if(author)}authors: 8 | ${for(author)} 9 | - family-names: ${it.familyName} 10 | given-names: ${it.givenName} 11 | orcid: "${it.at__id}" 12 | ${endfor}${endif} 13 | ${if(codeRepository)}repository-code: "${codeRepository}"${endif} 14 | ${if(version)}version: ${version}${endif} 15 | ${if(license)}license-url: "${license}"${endif} 16 | ${if(keywords)}keywords: [ ${for(keywords)}"${it}"${sep}, ${endfor} ]${endif} 17 | ${if(datePublished)}date-released: ${datePublished}${endif} 18 | --- 19 | 20 | About this software 21 | =================== 22 | 23 | ## ${name} ${version} 24 | 25 | ${if(author)} 26 | ### Authors 27 | 28 | ${for(author)} 29 | - ${it.givenName} ${it.familyName} 30 | ${endfor} 31 | ${endif} 32 | 33 | ${if(contributor)} 34 | ### Contributors 35 | 36 | ${for(contributor)} 37 | - ${it.givenName} ${it.familyName} 38 | ${endfor} 39 | ${endif} 40 | 41 | ${if(maintainer)} 42 | ### Maintainers 43 | 44 | ${for(maintainer)} 45 | - ${it.givenName} ${it.familyName} 46 | ${endfor} 47 | ${endif} 48 | 49 | ${if(description)} 50 | ${description} 51 | ${endif} 52 | 53 | ${if(license)}- License: <${license}>${endif} 54 | ${if(codeRepository)}- GitHub: <${codeRepository}>${endif} 55 | ${if(issueTracker)}- Issues: <${issueTracker}>${endif} 56 | 57 | 58 | ${if(programmingLanguage)} 59 | ### Programming languages 60 | 61 | ${for(programmingLanguage)} 62 | - ${programmingLanguage} 63 | ${endfor} 64 | ${endif} 65 | 66 | ${if(operatingSystem)} 67 | ### Operating Systems 68 | 69 | ${for(operatingSystem)} 70 | - ${operatingSystem} 71 | ${endfor} 72 | ${endif} 73 | 74 | ${if(softwareRequirements)} 75 | ### Software Requiremets 76 | 77 | ${for(softwareRequirements)} 78 | - ${softwareRequirements} 79 | ${endfor} 80 | $endif$ 81 | 82 | -------------------------------------------------------------------------------- /testdata/testplay-01b.fdx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FADE IN: 6 | 7 | 8 | A low slung industrial building in an industrial center. 9 | The last car leaves the lot. Parking lot lights switch off. 10 | 11 | 12 | CROSSFADE TO: 13 | 14 | 15 | INT. OFFICE - NIGHT 16 | 17 | 18 | A PROGRAMMER stares at the screen. 19 | 20 | 21 | PROGRAMMER 22 | 23 | 24 | (drowsy) 25 | 26 | 27 | What algorithm is this? 28 | 29 | 30 | CUT TO: 31 | 32 | 33 | EXT. COURTYARD - DAY 34 | 35 | 36 | A programmer lounges by a fountain. 37 | 38 | 39 | PROGRAMMER 40 | 41 | 42 | (drowsy) 43 | 44 | 45 | This is what I remember. 46 | 47 | 48 | FADE TO BLACK. 49 | 50 | 51 | THE END 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 3 | 4 | [![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-white.svg)](https://snapcraft.io/scripttool) 5 | 6 | scripttool 7 | ========== 8 | 9 | A tool for working with screenplay file formats (e.g. fdx, fountain, osf, FadeIn). 10 | 11 | Converting to fountain format 12 | ----------------------------- 13 | 14 | Convert from *screenplay.fdx* to *screenplay.fountain* 15 | 16 | ~~~shell 17 | scripttool fdx2fountain screenplay.fdx screenplay.fountain 18 | ~~~ 19 | 20 | Convert from *screenplay.fadein* to *screenplay.fountain* 21 | 22 | ~~~shell 23 | scripttool fadein2fountain screenplay.fadein screenplay.fountain 24 | ~~~ 25 | 26 | Convert from *screenplay.osf* to *screenplay.fountain* 27 | 28 | ~~~shell 29 | scripttool osf2fountain screenplay.osf screenplay.fountain 30 | ~~~ 31 | 32 | 33 | Working with fountain files 34 | --------------------------- 35 | 36 | Pretty print fountain files 37 | 38 | ~~~shell 39 | scripttool fountainfmt screenplay.fountain 40 | ~~~ 41 | 42 | Render a fountain file as JSON 43 | 44 | ~~~shell 45 | scripttool fountain2json screenplay.fountain 46 | ~~~ 47 | 48 | 49 | Convert from fountain format 50 | ---------------------------- 51 | 52 | Convert from *screenplay.fountain* to *screenplay.fdx* 53 | 54 | ~~~shell 55 | scripttool fountain2fdx screenplay.fountain screenplay.fdx 56 | ~~~ 57 | 58 | Convert from *screenplay.fountain* to *screenplay.fadein* 59 | 60 | ~~~shell 61 | scripttool fountain2fadein screenplay.fountain screenplay.fadein 62 | ~~~ 63 | 64 | Convert from *screenplay.fountain* to *screenplay.osf* 65 | 66 | ~~~shell 67 | scripttool fountain2osf screenplay.fountain screenplay.osf 68 | ~~~ 69 | 70 | 71 | 72 | Script Reports 73 | -------------- 74 | 75 | NOTE: Currently only fountain documents are supported for reporting. Currently the character list report is implemented as a proof of concept. 76 | 77 | List the characters in *screenplay.fountain* 78 | 79 | ~~~shell 80 | scripttool characters screenplay.fountain 81 | ~~~ 82 | 83 | -------------------------------------------------------------------------------- /codemeta-ps1-installer.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | # Generated with codemeta-ps1-installer.tmpl, see https://github.com/caltechlibrary/codemeta-pandoc-examples 3 | 4 | # 5 | # Set the package name and version to install 6 | # 7 | param( 8 | [Parameter()] 9 | [String]$$VERSION = "$version$" 10 | ) 11 | [String]$$PKG_VERSION = [Environment]::GetEnvironmentVariable("PKG_VERSION") 12 | if ($$PKG_VERSION) { 13 | $$VERSION = "$${PKG_VERSION}" 14 | Write-Output "Using '$${PKG_VERSION}' for version value '$${VERSION}'" 15 | } 16 | 17 | $$PACKAGE = "$name$" 18 | $$GIT_GROUP = "$git_org_or_person$" 19 | $$RELEASE = "https://github.com/$${GIT_GROUP}/$${PACKAGE}/releases/tag/v$${VERSION}" 20 | $$SYSTEM_TYPE = Get-ComputerInfo -Property CsSystemType 21 | if ($$SYSTEM_TYPE.CsSystemType.Contains("ARM64")) { 22 | $$MACHINE = "arm64" 23 | } else { 24 | $$MACHINE = "x86_64" 25 | } 26 | 27 | 28 | # FIGURE OUT Install directory 29 | $$BIN_DIR = "$${Home}\bin" 30 | Write-Output "$${PACKAGE} v$${VERSION} will be installed in $${BIN_DIR}" 31 | 32 | # 33 | # Figure out what the zip file is named 34 | # 35 | $$ZIPFILE = "$${PACKAGE}-v$${VERSION}-Windows-$${MACHINE}.zip" 36 | Write-Output "Fetching Zipfile $${ZIPFILE}" 37 | 38 | # 39 | # Check to see if this zip file has been downloaded. 40 | # 41 | $$DOWNLOAD_URL = "https://github.com/$${GIT_GROUP}/$${PACKAGE}/releases/download/v$${VERSION}/$${ZIPFILE}" 42 | Write-Output "Download URL $${DOWNLOAD_URL}" 43 | 44 | if (!(Test-Path $$BIN_DIR)) { 45 | New-Item $$BIN_DIR -ItemType Directory | Out-Null 46 | } 47 | curl.exe -Lo "$${ZIPFILE}" "$${DOWNLOAD_URL}" 48 | #if ([System.IO.File]::Exists($$ZIPFILE)) { 49 | if (!(Test-Path $$ZIPFILE)) { 50 | Write-Output "Failed to download $${ZIPFILE} from $${DOWNLOAD_URL}" 51 | } else { 52 | tar.exe xf "$${ZIPFILE}" -C "$${Home}" 53 | #Remove-Item $$ZIPFILE 54 | 55 | $$User = [System.EnvironmentVariableTarget]::User 56 | $$Path = [System.Environment]::GetEnvironmentVariable('Path', $$User) 57 | if (!(";$${Path};".ToLower() -like "*;$${BIN_DIR};*".ToLower())) { 58 | [System.Environment]::SetEnvironmentVariable('Path', "$${Path};$${BIN_DIR}", $$User) 59 | $$Env:Path += ";$${BIN_DIR}" 60 | } 61 | Write-Output "$${PACKAGE} was installed successfully to $${BIN_DIR}" 62 | } 63 | -------------------------------------------------------------------------------- /convertions.go: -------------------------------------------------------------------------------- 1 | // scripttool is a package focused on converting to/from different 2 | // file formats used in working with scripts,screenplays and other 3 | // creative writing. 4 | // 5 | // @author R. S. Doiel, 6 | // 7 | // # BSD 2-Clause License 8 | // 9 | // Copyright (c) 2021, R. S. Doiel 10 | // All rights reserved. 11 | // 12 | // Redistribution and use in source and binary forms, with or without 13 | // modification, are permitted provided that the following conditions are met: 14 | // 15 | // - Redistributions of source code must retain the above copyright notice, this 16 | // list of conditions and the following disclaimer. 17 | // 18 | // - Redistributions in binary form must reproduce the above copyright notice, 19 | // this list of conditions and the following disclaimer in the documentation 20 | // and/or other materials provided with the distribution. 21 | // 22 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | package scripttool 33 | 34 | import ( 35 | 36 | // My packages 37 | "github.com/rsdoiel/fdx" 38 | "github.com/rsdoiel/fountain" 39 | "github.com/rsdoiel/osf" 40 | ) 41 | 42 | // 43 | // Below are conversions to other formats (e.g. .osf/.fadein, and .fdx) 44 | // 45 | 46 | // fountainToOSF takes a Fountain struct and returns a osf.OpenScreenplay struct 47 | func fountainToOSF(document *fountain.Fountain) *osf.OpenScreenplay { 48 | screenplay := new(osf.OpenScreenplay) 49 | screenplay.Version = "2.0" 50 | screenplay.FromFountain(document) 51 | return screenplay 52 | } 53 | 54 | // fountainToFdx takes a Fountain struct and returns a fdx.FinalDraft struct 55 | func fountainToFdx(document *fountain.Fountain) *fdx.FinalDraft { 56 | screenplay := new(fdx.FinalDraft) 57 | screenplay.FromFountain(document) 58 | return screenplay 59 | } 60 | -------------------------------------------------------------------------------- /testdata.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

About the test data

22 |

The testing data for scripttool and its sub-packages fountain, fdx 23 | and osf are held in common in this repository’s testdata 24 | directory.

25 |

The fountain website has some good 26 | files for reviewing formatting difference between fountain, fdx and PDF. 27 | Some are referenced in the test programs but they are optional. It is 28 | not clear to me the licensing arrangements for the text so I have not 29 | included them in this repository. You can use the bash script 30 | get-optional-testdata.bash to retrieve them from the 31 | fountain.io website.

32 |

If you want to include them in the test sequence go to the fountain 33 | website and download them and place them in the testdata 34 | directory. When you run go test they will be found and 35 | included in the basic test process.

36 |

Optional test FDX files

37 | 63 |
64 | 65 | -------------------------------------------------------------------------------- /cmd/scripttool/main.go: -------------------------------------------------------------------------------- 1 | // scripttool is a tool for working with screenplay file formats. 2 | // 3 | // # BSD 2-Clause License 4 | // 5 | // Copyright (c) 2021, R. S. Doiel 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without 9 | // modification, are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, this 12 | // list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | package main 29 | 30 | import ( 31 | "flag" 32 | "fmt" 33 | "os" 34 | "path" 35 | 36 | // My packages 37 | "github.com/rsdoiel/scripttool" 38 | ) 39 | 40 | var ( 41 | // Standard Options 42 | showHelp bool 43 | showLicense bool 44 | showVersion bool 45 | ) 46 | 47 | func main() { 48 | appName := path.Base(os.Args[0]) 49 | if len(os.Args) == 1 { 50 | fmt.Fprintln(os.Stderr, scripttool.FmtCliText(scripttool.HelpText, appName, "", scripttool.Version)) 51 | os.Exit(1) 52 | } 53 | flag.BoolVar(&showHelp, "help", false, "display help") 54 | flag.BoolVar(&showVersion, "version", false, "display version") 55 | flag.BoolVar(&showLicense, "license", false, "display license") 56 | flag.Parse() 57 | if showHelp { 58 | fmt.Println(scripttool.FmtCliText(scripttool.HelpText, appName, "", scripttool.Version)) 59 | os.Exit(0) 60 | } 61 | if showLicense { 62 | fmt.Println(scripttool.FmtCliText(scripttool.LicenseText, appName, "", scripttool.Version)) 63 | os.Exit(0) 64 | } 65 | if showVersion { 66 | fmt.Printf("%s %s\n", appName, scripttool.Version) 67 | os.Exit(0) 68 | } 69 | 70 | if err := scripttool.RunScripttool(os.Stdin, os.Stdout, os.Stderr, os.Args); err != nil { 71 | fmt.Fprintf(os.Stderr, "%s\n", err) 72 | os.Exit(1) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /installer.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | # generated with CMTools 0.0.10 b59480b 3 | 4 | # 5 | # Set the package name and version to install 6 | # 7 | param( 8 | [Parameter()] 9 | [String]$VERSION = "0.0.10" 10 | ) 11 | [String]$PKG_VERSION = [Environment]::GetEnvironmentVariable("PKG_VERSION") 12 | if ($PKG_VERSION) { 13 | $VERSION = "${PKG_VERSION}" 14 | Write-Output "Using '${PKG_VERSION}' for version value '${VERSION}'" 15 | } 16 | 17 | $PACKAGE = "scripttool" 18 | $GIT_GROUP = "rsdoiel" 19 | $RELEASE = "https://github.com/${GIT_GROUP}/${PACKAGE}/releases/tag/v${VERSION}" 20 | $SYSTEM_TYPE = Get-ComputerInfo -Property CsSystemType 21 | if ($SYSTEM_TYPE.CsSystemType.Contains("ARM64")) { 22 | $MACHINE = "arm64" 23 | } else { 24 | $MACHINE = "x86_64" 25 | } 26 | 27 | Write-Output "Using release ${RELEASE}" 28 | 29 | # FIGURE OUT Install directory 30 | $BIN_DIR = "${Home}\bin" 31 | Write-Output "${PACKAGE} v${VERSION} will be installed in ${BIN_DIR}" 32 | 33 | # 34 | # Figure out what the zip file is named 35 | # 36 | $ZIPFILE = "${PACKAGE}-v${VERSION}-Windows-${MACHINE}.zip" 37 | Write-Output "Fetching Zipfile ${ZIPFILE}" 38 | 39 | # 40 | # Check to see if this zip file has been downloaded. 41 | # 42 | $DOWNLOAD_URL = "https://github.com/${GIT_GROUP}/${PACKAGE}/releases/download/v${VERSION}/${ZIPFILE}" 43 | Write-Output "Download URL ${DOWNLOAD_URL}" 44 | 45 | if (!(Test-Path $BIN_DIR)) { 46 | New-Item $BIN_DIR -ItemType Directory | Out-Null 47 | } 48 | curl.exe -Lo "${ZIPFILE}" "${DOWNLOAD_URL}" 49 | #if ([System.IO.File]::Exists($ZIPFILE)) { 50 | if (!(Test-Path $ZIPFILE)) { 51 | Write-Output "Failed to download ${ZIPFILE} from ${DOWNLOAD_URL}" 52 | } else { 53 | # Do we have a zip file or tar.gz file? 54 | $fileInfo = Get-Item "${ZIPFILE}" 55 | 56 | # Handle zip or tar.gz files 57 | switch ($fileInfo.Extension) { 58 | ".zip" { 59 | Expand-Archive -Force -Path "${ZIPFILE}" "${Home}" 60 | break 61 | } 62 | ".gz" { 63 | tar.exe xf "${ZIPFILE}" -C "${Home}" 64 | break 65 | } 66 | ".tgz" { 67 | tar.exe xf "${ZIPFILE}" -C "${Home}" 68 | break 69 | } 70 | default { 71 | Write-Output "The ${ZIPFILE} from ${DOWNLOAD_URL} is neither a ZIP file nor a gzipped tar file." 72 | exit 1 73 | } 74 | } 75 | 76 | #Remove-Item $ZIPFILE 77 | 78 | $User = [System.EnvironmentVariableTarget]::User 79 | $Path = [System.Environment]::GetEnvironmentVariable('Path', $User) 80 | if (!(";${Path};".ToLower() -like "*;${BIN_DIR};*".ToLower())) { 81 | [System.Environment]::SetEnvironmentVariable('Path', "${Path};${BIN_DIR}", $User) 82 | $Env:Path += ";${BIN_DIR}" 83 | } 84 | Write-Output "${PACKAGE} was installed successfully to ${BIN_DIR}" 85 | Write-Output "If you get a security warning on Windows or macOS please see INSTALL_NOTES_Windows.md or INSTALL_NOTES_macOS.md" 86 | } 87 | -------------------------------------------------------------------------------- /INSTALL.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

Installation for 22 | development of scripttool

23 |

scripttool A library and command line program for 24 | working with fdx (Final Draft XML), osf, Fade In and Fountain formatted 25 | Screen Play files.

26 |

Quick install with curl or 27 | irm

28 |

There is an experimental installer.sh script that can be run with the 29 | following command to install latest table release. This may work for 30 | macOS, Linux and if you’re using Windows with the Unix subsystem. This 31 | would be run from your shell (e.g. Terminal on macOS).

32 |
curl https://rsdoiel.github.io/scripttool/installer.sh | sh
33 |

This will install the programs included in scripttool in your 34 | $HOME/bin directory.

35 |

If you are running Windows 10 or 11 use the Powershell command 36 | below.

37 |
irm https://rsdoiel.github.io/scripttool/installer.ps1 | iex
39 |

If your are running macOS 40 | or Windows

41 |

You may get security warnings if you are using macOS or Windows. See 42 | the notes for the specific operating system you’re using to fix 43 | issues.

44 | 49 |

Installing from source

50 |

Required software

51 |

Steps

52 |
    53 |
  1. git clone https://github.com/rsdoiel/scripttool
  2. 54 |
  3. Change directory into the scripttool directory
  4. 55 |
  5. Make to build, test and install
  6. 56 |
57 |
git clone https://github.com/rsdoiel/scripttool
58 | cd scripttool
59 | make
60 | make test
61 | make install
62 |
63 | 64 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | { 2 | "scripttool": "A program for converting screen play formats" 3 | } 4 | 5 | Action Items 6 | ============ 7 | 8 | Bugs 9 | ---- 10 | 11 | - [ ] fountain parser is miss-identifying some elements as character when they are things like scene headings. This should up in JSON output and characters report, see testdata/sample-07.fountain for example of bug 12 | - `scripttool fountain2json testdata/sample-07.fountain` 13 | - `scripttool characters testdata/sample-07.fountain` 14 | 15 | 16 | Next 17 | ---- 18 | 19 | + [x] fountain2html 20 | + [x] fountain2json 21 | + [x] fountain2fdx (Fountain to Final Draft XML) 22 | + [x] fountain2osf (Fountain to Open Screenplay Format 1.2,2.0) 23 | + [x] fdx2fountain (build on fdx2txt in [fdx](https://github.com/rsdoiel/fdx), handle TitlePage better) 24 | + [x] fdx2osf (Final Draft XML to Open Screenplay Format 1.2,2.0 XML) 25 | + [x] osf2fdx (Open Screenplay Format 1.2,2.0 XML to Final Draft XML) 26 | + [x] osf2fountain (Open Screenplay Format 1.2,2.0 XML to Fountain) 27 | + [x] fountain2fadein, fadein2fountain 28 | + [ ] edit (simple line oriented editor with colorization for Fountain/Markdown) 29 | + auto-convert to/fountain on open 30 | + auto-convert from fountain to origin version on save 31 | + timed-autosave 32 | + backup original files 33 | + [ ] headings - report the headings as a outline 34 | + [ ] scenes - report the number of scenes, order and estimate time 35 | + [ ] lines - report line count 36 | + [ ] words - report word count 37 | + [ ] character - report character count 38 | + [ ] outline (OPML) to scenes/chapters 39 | + [ ] notes, sections and synopsis 40 | + [ ] eprints like metadata for the script 41 | + [ ] Story timeline (using stn) for temporal story outlines 42 | + [ ] Scene beat report, summaries per scene happenings (who speaks, description, estimated running time) 43 | + [ ] Search/indexing for script and related assets 44 | 45 | 46 | Someday, Maybe 47 | -------------- 48 | 49 | + [ ] GUI for managing a screenplay project (like Scrivener but GTK based so as can running under Linux) 50 | + [ ] PDF generation from various formats (possibly via Pandoc) 51 | + [ ] write and fountain2html, fdx2html, osf2html, fadein2html using [scrippets](https://fountain.io/scrippets) approach 52 | + [ ] Create a fountain text to speech script reader 53 | + [ ] Should support configuration for assigning voices to different characters 54 | + [ ] fountain2trelby 55 | + [ ] osf2trelby 56 | + [ ] fdx2trelby 57 | + [ ] trelby2fdx 58 | + [ ] trelby2fountain 59 | + [ ] trelby2osf 60 | 61 | Reference Links 62 | --------------- 63 | 64 | + [gofpdf](https://github.com/jung-kurt/gofpdf) - Kurt Jung's Go implementation of fpdf 65 | + [Fountain](https://fountain.io) 66 | + [Open Screenplay Format 2.0](https://sourceforge.net/projects/openscrfmt/) 67 | + [Open Screenplay Format 2.1](https://github.com/severdia/Open-Screenplay-Format) 68 | + [Screenbox HTML and CSS](https://johnaugust.com/2004/screenbox) is some CSS for marking up HTML classes hand presenting a script section in an HTML page 69 | + [scrippets Wordpress Plugin](https://wordpress.org/plugins/wp-scrippets/), scrippets.org website appears gone. 70 | 71 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scripttools 5 | 6 | 7 | 8 | 20 |
21 |

Project Status: Active – The project has reached a stable, usable state and is being actively developed.

24 |

Get it from the Snap Store

27 |

scripttool

28 |

A tool for working with screenplay file formats (e.g. fdx, fountain, 29 | osf, FadeIn).

30 |

Converting to fountain 31 | format

32 |

Convert from screenplay.fdx to 33 | screenplay.fountain

34 |
    scripttool fdx2fountain screenplay.fdx screenplay.fountain
35 |

Convert from screenplay.fadein to 36 | screenplay.fountain

37 |
    scripttool fadein2fountain screenplay.fadein screenplay.fountain
38 |

Convert from screenplay.osf to 39 | screenplay.fountain

40 |
    scripttool osf2fountain screenplay.osf screenplay.fountain
41 |

Working with fountain files

42 |

Pretty print fountain files

43 |
    scripttool fountainfmt screenplay.fountain
44 |

Render a fountain file as JSON

45 |
    scripttool fountain2json screenplay.fountain
46 |

Convert from fountain format

47 |

Convert from screenplay.fountain to 48 | screenplay.fdx

49 |
    scripttool fountain2fdx screenplay.fountain screenplay.fdx
50 |

Convert from screenplay.fountain to 51 | screenplay.fadein

52 |
    scripttool fountain2fadein screenplay.fountain screenplay.fadein
53 |

Convert from screenplay.fountain to 54 | screenplay.osf

55 |
    scripttool fountain2osf screenplay.fountain screenplay.osf
56 |

Script Reports

57 |

NOTE: Currently only fountain documents are supported for reporting. 58 | Currently the character list report is implemented as a proof of 59 | concept.

60 |

List the characters in screenplay.fountain

61 |
    scripttool characters screenplay.fountain
62 |
63 | 64 | -------------------------------------------------------------------------------- /scripttool_test.go: -------------------------------------------------------------------------------- 1 | // scripttool is a package focused on converting to/from different 2 | // file formats used in working with scripts, screenplays and other 3 | // creative writing. 4 | // 5 | // @author R. S. Doiel, 6 | // 7 | // # BSD 2-Clause License 8 | // 9 | // Copyright (c) 2021, R. S. Doiel 10 | // All rights reserved. 11 | // 12 | // Redistribution and use in source and binary forms, with or without 13 | // modification, are permitted provided that the following conditions are met: 14 | // 15 | // - Redistributions of source code must retain the above copyright notice, this 16 | // list of conditions and the following disclaimer. 17 | // 18 | // - Redistributions in binary form must reproduce the above copyright notice, 19 | // this list of conditions and the following disclaimer in the documentation 20 | // and/or other materials provided with the distribution. 21 | // 22 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | package scripttool 33 | 34 | import ( 35 | "encoding/xml" 36 | "fmt" 37 | "io/ioutil" 38 | "os" 39 | "path" 40 | "testing" 41 | 42 | // My Packages 43 | "github.com/rsdoiel/fdx" 44 | ) 45 | 46 | var ( 47 | expectedDocs map[string][]byte 48 | ) 49 | 50 | func screenplayFile(t *testing.T, dir, fname string) { 51 | dName := "testout" 52 | if _, err := os.Stat(dName); os.IsNotExist(err) { 53 | os.MkdirAll(dName, 0775) 54 | } 55 | src, err := ioutil.ReadFile(path.Join(dir, fname)) 56 | if err != nil { 57 | if fname == "Big-Fish.fdx" { 58 | fmt.Fprintf(os.Stderr, "Skipping %s\n", fname) 59 | } else { 60 | fmt.Fprintf(os.Stderr, "Skipping %s, %s\n", fname, err) 61 | } 62 | return 63 | } 64 | screenplay := new(fdx.FinalDraft) 65 | if err := xml.Unmarshal(src, &screenplay); err != nil { 66 | t.Errorf("%s", err) 67 | t.FailNow() 68 | } else { 69 | os.RemoveAll(path.Join("testout", path.Base(fname))) 70 | if src2, err := xml.MarshalIndent(screenplay, " ", " "); err != nil { 71 | t.Errorf("%s", err) 72 | } else { 73 | if err := ioutil.WriteFile(path.Join("testout", path.Base(fname)), src2, 0666); err != nil { 74 | t.Errorf("%s", err) 75 | } 76 | } 77 | } 78 | } 79 | 80 | func TestConversion(t *testing.T) { 81 | screenplayFile(t, "testdata", "testplay-01a.fdx") 82 | screenplayFile(t, "testdata", "testplay-01b.fdx") 83 | screenplayFile(t, "testdata", "Big-Fish.fdx") 84 | } 85 | 86 | func TestMain(m *testing.M) { 87 | // Setup everything, process flags, etc. 88 | os.Exit(m.Run()) 89 | } 90 | -------------------------------------------------------------------------------- /codemeta-bash-installer.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Set the package name and version to install 5 | # 6 | PACKAGE="$name$" 7 | VERSION="$version$" 8 | GIT_GROUP="$git_org_or_person$" 9 | RELEASE="https://github.com/$$GIT_GROUP/$$PACKAGE/releases/tag/v$$VERSION" 10 | if [ "$$PKG_VERSION" != "" ]; then 11 | VERSION="$${PKG_VERSION}" 12 | echo "$${PKG_VERSION} used for version v$${VERSION}" 13 | fi 14 | 15 | # 16 | # Get the name of this script. 17 | # 18 | INSTALLER="$$(basename "$$0")" 19 | 20 | # 21 | # Figure out what the zip file is named 22 | # 23 | OS_NAME="$$(uname)" 24 | MACHINE="$$(uname -m)" 25 | case "$$OS_NAME" in 26 | Darwin) 27 | OS_NAME="macOS" 28 | ;; 29 | GNU/Linux) 30 | OS_NAME="Linux" 31 | ;; 32 | esac 33 | 34 | if [ "$$1" != "" ]; then 35 | VERSION="$$1" 36 | echo "Version set to v$${VERSION}" 37 | fi 38 | 39 | ZIPFILE="$$PACKAGE-v$$VERSION-$$OS_NAME-$$MACHINE.zip" 40 | 41 | # 42 | # Check to see if this zip file has been downloaded. 43 | # 44 | DOWNLOAD_URL="https://github.com/$$GIT_GROUP/$$PACKAGE/releases/download/v$$VERSION/$$ZIPFILE" 45 | if ! curl -L -o "$$HOME/Downloads/$$ZIPFILE" "$$DOWNLOAD_URL"; then 46 | echo "Curl failed to get $$DOWNLOAD_URL" 47 | fi 48 | cat<.binfiles.tmp 87 | while read -r APP; do 88 | V=$$("./$$APP" --version) 89 | if [ "$$V" = "" ]; then 90 | EXPLAIN_OS_POLICY="yes" 91 | fi 92 | mv "$$APP" "$$HOME/bin/" 93 | done <.binfiles.tmp 94 | rm .binfiles.tmp 95 | 96 | # 97 | # Make sure $$HOME/bin is in the path 98 | # 99 | case :$$PATH: in 100 | *:$$HOME/bin:*) 101 | ;; 102 | *) 103 | # shellcheck disable=SC2016 104 | echo 'export PATH="$$HOME/bin:$$PATH"' >>"$$HOME/.bashrc" 105 | # shellcheck disable=SC2016 106 | echo 'export PATH="$$HOME/bin:$$PATH"' >>"$$HOME/.zshrc" 107 | ;; 108 | esac 109 | 110 | # shellcheck disable=SC2031 111 | if [ "$$EXPLAIN_OS_POLICY" = "no" ]; then 112 | cat <.binfiles.tmp 88 | while read -r APP; do 89 | V=$("./$APP" --version) 90 | if [ "$V" = "" ]; then 91 | EXPLAIN_OS_POLICY="yes" 92 | fi 93 | mv "$APP" "$HOME/bin/" 94 | done <.binfiles.tmp 95 | rm .binfiles.tmp 96 | 97 | # 98 | # Make sure $HOME/bin is in the path 99 | # 100 | case :$PATH: in 101 | *:$HOME/bin:*) 102 | ;; 103 | *) 104 | # shellcheck disable=SC2016 105 | echo 'export PATH="$HOME/bin:$PATH"' >>"$HOME/.bashrc" 106 | # shellcheck disable=SC2016 107 | echo 'export PATH="$HOME/bin:$PATH"' >>"$HOME/.zshrc" 108 | ;; 109 | esac 110 | 111 | # shellcheck disable=SC2031 112 | if [ "$EXPLAIN_OS_POLICY" = "no" ]; then 113 | cat < 2 | 3 | 4 | 5 |