From 144927174ba96909f2e819758ca3a0fdd181de9c Mon Sep 17 00:00:00 2001 From: izzyboyno Date: Sat, 19 Sep 2026 22:53:29 +0200 Subject: [PATCH 1/2] Release its-scripted 0.2.0 Add initial Fountain import support and improve font fallback compatibility. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 20 ++++++++- docs.md | 28 +++++++++--- lib.typ | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++-- typst.toml | 2 +- 4 files changed, 163 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e261474..0eddb05 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,14 @@ A template for writing a film/TV script in screenplay format. This is a mix of t ## Usage -> Before you start please make sure to download and install either the font `Courier` or `Courier New`. +The package defaults to a Courier-like fallback stack (`Courier New`, `DejaVu Sans Mono`), but if you want the classic screenplay look, install `Courier` or `Courier New` and set it explicitly: ```typ -#import "@preview/its-scripted:0.1.0": * +#set text(font: "Courier New") +``` + +```typ +#import "@preview/its-scripted:0.2.0": * #show: screenplay.with() @@ -78,6 +82,18 @@ Suddenly a PTERODACTYL flies through the coffee-shop window. #close[TO BE CONTINUED] ``` +## Fountain support + +Fountain markup can be converted into screenplays with the `fountain` helper. + +This release includes the initial Fountain import helper and improved font fallback handling for broader compatibility. + +```typ +#import "@preview/its-scripted:0.2.0": fountain + +#fountain("Title: Example\nAuthor: Jane Doe\n\nINT. OFFICE - DAY\n\nJANE\nHello there.\n") +``` + ## Documentation Check [docs.md](docs.md) for the full documentation. diff --git a/docs.md b/docs.md index 4ec53e9..05501ba 100644 --- a/docs.md +++ b/docs.md @@ -2,9 +2,13 @@ ## Fonts -Please make sure to download and install either the font `Courier`, `Courier New`, or some other Courier clone, because the builtin mono-spaced fonts on typst are horrific. +The package defaults to a Courier-like fallback stack (`Courier New`, `DejaVu Sans Mono`) so it works across common systems. If you want the classic screenplay look, install `Courier` or `Courier New` and set it explicitly: -`Courier` and `Courier New` are natively supported, but you can use another font by inserting a `set` rule like so: +```typ +#set text(font: "Courier New") +``` + +You can also use another monospace font by inserting a `set` rule like so: ```typ #show: screenplay.with() @@ -20,14 +24,14 @@ Usage: ```typ #show: screenplay.with( - capitalized-headings: true, + capitalize-headings: true, dir: ltr, ) ``` Named arguments: -- `capitalized-headings: bool` +- `capitalize-headings: bool` Determents whether or not to auto-capitalize all of the headings in your document. @@ -43,6 +47,20 @@ Named arguments: **Default:** `text.dir`, or `ltr` if `text.dir` has not been specified. +## The `fountain` Function + +Converts a basic Fountain screenplay into the package's standard screenplay layout. + +Usage: + +```typ +#import "@preview/its-scripted:0.2.0": fountain + +#fountain("Title: Example\nAuthor: Jane Doe\n\nINT. OFFICE - DAY\n\nJANE\nHello there.\n") +``` + +The converter understands basic Fountain metadata (title, author, credit, and date), scene headings, character cues, dialogue, transitions beginning with `>`, and centered notes starting with `@`. + ## The `maketitle` Function Creates the title page for your screenplay. This automatically inserts a page break after the title, so you don't have to start a new page manually. @@ -125,7 +143,7 @@ Any additional positional arguments will be added bellow the draft. Scene headings are simply regular document headings. The level of the heading doesn't matter, as all headings are set to the same text size (though you should choose your heading levels consistently for improved code readability and accessibility). -When the `capitalized-headings` option in the `screeplay` function is set to `true`, headings are automatically capitalized. +When the `capitalize-headings` option in the `screenplay` function is set to `true`, headings are automatically capitalized. Usage: diff --git a/lib.typ b/lib.typ index b4d0754..6ccdb4f 100644 --- a/lib.typ +++ b/lib.typ @@ -1,4 +1,9 @@ -#let screenplay(it, capitalize-headings: true, dir: auto) = context { +#let screenplay(it, capitalize-headings: true, dir: auto, ..args) = context { + let extra = args.named() + let should-capitalize = capitalize-headings + if extra.at("capitalized-headings", default: none) != none { + should-capitalize = extra.at("capitalized-headings") + } let dir = dir if dir == auto { dir = text.dir @@ -9,7 +14,6 @@ set text( size: 12pt, font: ( - "Courier", "Courier New", "DejaVu Sans Mono", ), @@ -45,7 +49,7 @@ show heading: set text(size: 12pt) show heading: set block(above: 1em, below: 1em) show heading: it => { - if capitalize-headings { + if should-capitalize { upper(it) } else { it @@ -212,3 +216,117 @@ ), ) } + +#let fountain(body) = { + if type(body) != str { + return body + } + + let source = body + let lines = source.split("\n") + let pieces = () + let metadata = (:) + let i = 0 + + while i < lines.len() { + let line = lines.at(i).trim() + if line == "" { + i += 1 + continue + } + + if line.contains(":") and not line.starts-with(" ") and not line.starts-with("\t") { + let parts = line.split(":") + let key = parts.first().trim() + let value = parts.slice(1).join(":").trim() + if key != "" { + metadata.insert(lower(key), value) + i += 1 + continue + } + } + + break + } + + while i < lines.len() and lines.at(i).trim() == "" { + i += 1 + } + + let title = metadata.at("title", default: none) + let authors = metadata.at("author", default: metadata.at("authors", default: none)) + let date = metadata.at("date", default: metadata.at("draft date", default: none)) + let info = metadata.at("credit", default: metadata.at("source", default: none)) + + if title != none or authors != none or date != none or info != none { + pieces.push(maketitle( + title: title, + authors: authors, + date: date, + info: info, + )) + } + + while i < lines.len() { + let line = lines.at(i).trim() + if line == "" { + i += 1 + continue + } + + if line.starts-with(">") { + let transition = line.slice(1).trim() + if transition != "" { + pieces.push(close(capitalize: false)[#transition]) + } + i += 1 + continue + } + + if line.starts-with("@") { + let note = line.slice(1).trim() + if note != "" { + pieces.push(block(align(center)[#note])) + } + i += 1 + continue + } + + if line.starts-with("INT.") or line.starts-with("EXT.") or line.starts-with("INT/") or line.starts-with("EST.") or line.starts-with("I/E") { + pieces.push(heading(line)) + i += 1 + continue + } + + if line == upper(line) and line.contains(" ") and not line.starts-with("#") and not line.starts-with("!") { + let speaker = line + let dialogue = () + i += 1 + while i < lines.len() { + let next-line = lines.at(i).trim() + if next-line == "" { + i += 1 + break + } + if next-line == upper(next-line) and next-line.contains(" ") and not next-line.starts-with(">") and not next-line.starts-with("@") { + break + } + dialogue.push(next-line) + i += 1 + } + pieces.push(dialog[ + == #speaker + + #dialogue.join("\n") + ]) + continue + } + + pieces.push(block[#line]) + i += 1 + } + + for piece in pieces { + piece + } +} diff --git a/typst.toml b/typst.toml index 4b927cc..a585fd6 100644 --- a/typst.toml +++ b/typst.toml @@ -1,6 +1,6 @@ [package] name = "its-scripted" -version = "0.1.0" +version = "0.2.0" entrypoint = "lib.typ" authors = ["Daniel F.H."] license = "LGPL-3.0-only" From 72235e892936ab85faab7a60699feea505a39111 Mon Sep 17 00:00:00 2001 From: izzyboyno Date: Sat, 19 Sep 2026 23:00:31 +0200 Subject: [PATCH 2/2] Document fork attribution and 0.2.0 changes Credit the upstream project and document the Fountain and font improvements. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 17 +++++++++++++++++ README.md | 2 ++ typst.toml | 4 ++-- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3dde5d2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +## 0.2.0 - 2026-09-19 + +This release is maintained in the fork [izzyboyno/typst-screenplay](https://github.com/izzyboyno/typst-screenplay) and is based on the original project by [Daniel F.H.](https://github.com/danielFHcode). + +### Added + +- Added the `fountain` helper for converting basic Fountain screenplay text into Typst screenplay layout. +- Added support for Fountain title, author, credit, and date metadata. +- Added support for scene headings, dialogue, transitions, and centered notes. + +### Changed + +- Replaced the single `Courier` default with a portable `Courier New` / `DejaVu Sans Mono` fallback stack. +- Documented how to select a specific screenplay font. +- Preserved compatibility with the existing `capitalized-headings` option spelling while documenting the canonical `capitalize-headings` name. diff --git a/README.md b/README.md index 0eddb05..628f8e2 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ A template for writing a film/TV script in screenplay format. This is a mix of the format used by final draft and the official format suggested by the oscars, with some slight changes. +This project is a fork of [danielFHcode/typst-screenplay](https://github.com/danielFHcode/typst-screenplay), originally created by Daniel F.H. The upstream project and author are credited here; this fork adds the changes documented in [CHANGELOG.md](CHANGELOG.md). + ## Usage The package defaults to a Courier-like fallback stack (`Courier New`, `DejaVu Sans Mono`), but if you want the classic screenplay look, install `Courier` or `Courier New` and set it explicitly: diff --git a/typst.toml b/typst.toml index a585fd6..a2c8061 100644 --- a/typst.toml +++ b/typst.toml @@ -2,10 +2,10 @@ name = "its-scripted" version = "0.2.0" entrypoint = "lib.typ" -authors = ["Daniel F.H."] +authors = ["Daniel F.H.", "izzyboyno"] license = "LGPL-3.0-only" description = "A template for writing movie/tv/theater-scripts in screenplay format." -repository = "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/danielFHcode/typst-screenplay" +repository = "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/izzyboyno/typst-screenplay" keywords = [ "screenplay", "movie-script",