% % This is file `screenwriter.cls', version 1.0.2 (2026-05-10) % % Author: J. A. Corbal (jacorbal [at] gmail [dot] net) % Copyright 2013--2026 J. A. Corbal % Based on J. Pate's `screenplay.cls' % % This work may be distributed and/or modified under the conditions of % the LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of the license is in . % \NeedsTeXFormat{LaTeX2e} \ProvidesClass{screenwriter}[2026/05/10 v1.0.2 Screenwriter class] % --- internal language state (default: english) \newcommand*{\screenwriter@lang}{english} \newif\ifscreenwriter@lang@explicit \screenwriter@lang@explicitfalse % --- default geometry-related parameters (US Letter screenplay-style) \newcommand*{\mybaselinestretch}{0.9} \newcommand*{\myparindent}{0.0in} \newcommand*{\myevensidemargin}{0.5in} \newcommand*{\myoddsidemargin}{0.5in} \newcommand*{\mytopmargin}{-0.5in} \newcommand*{\myheadsep}{0.5in} \newcommand*{\mytopskip}{0.0in} \newcommand*{\mytextwidth}{6.0in} \newcommand*{\mytextheight}{9in} \newcommand*{\mywidthgutter}{0.1in} \newcommand*{\mydialgutter}{0.2in} \newcommand*{\mydialwidth}{3.0in} \newcommand*{\myparenwidth}{1.5in} \newcommand*{\myparentab}{0.7in} \newcommand*{\mytitskip}{3.75in plus 0in minus 1.5in} \newcommand*{\mytitheadskip}{2.25in} \newcommand*{\mybaselineskip}{12pt plus 0pt minus 0pt} \newcommand*{\myaddrwidth}{2in} \newcommand*{\myaddrseplen}{2.0in plus 0in minus 0.5in} % --- default texts (English) \newcommand*{\myaddresstext}{Contact via Agency} \newcommand*{\myadlibtext}{ad~lib.} \newcommand*{\mybytext}{by} \newcommand*{\mycontdtext}{(CONT'D)} \newcommand*{\myexttext}{EXT} \newcommand*{\myfadeintext}{FADE IN} \newcommand*{\myfadeouttext}{FADE OUT} \newcommand*{\myflashbacktext}{FLASHBACK TO} \newcommand*{\myintercuttext}{INTERCUT WITH} \newcommand*{\myinttext}{INT} \newcommand*{\mymoretext}{(MORE)} \newcommand*{\myoffscreentext}{(O.S.)} \newcommand*{\myplacesep}{.~} \newcommand*{\mypovtext}{P.O.V.} \newcommand*{\mypunctcharA}{:} \newcommand*{\mypunctcharB}{:} \newcommand*{\myreverttext}{REVERSE \pov} \newcommand*{\mysepintext}{./} \newcommand*{\myslugspace}{ -- } \newcommand*{\mythirtytext}{THE END} \newcommand*{\mytitleovertext}{TITLE OVER} \newcommand*{\myvoiceovertext}{(V.O.)} % --- options \newcommand*{\slug}{} % will be redefined by literary/technical % language internal state \newif\ifscreenwriter@lang@explicit \screenwriter@lang@explicitfalse % specific language via options \DeclareOption{english}{% \def\screenwriter@lang{english}% \screenwriter@lang@explicittrue } \DeclareOption{spanish}{% \def\screenwriter@lang{spanish}% \screenwriter@lang@explicittrue } \DeclareOption{french}{% \def\screenwriter@lang{french}% \screenwriter@lang@explicittrue } \DeclareOption{german}{% \def\screenwriter@lang{german}% \screenwriter@lang@explicittrue } \DeclareOption{italian}{% \def\screenwriter@lang{italian}% \screenwriter@lang@explicittrue } \DeclareOption{portuguese}{% \def\screenwriter@lang{portuguese}% \screenwriter@lang@explicittrue } \DeclareOption{galician}{% \def\screenwriter@lang{galician}% \screenwriter@lang@explicittrue } \DeclareOption{catalan}{% \def\screenwriter@lang{catalan}% \screenwriter@lang@explicittrue } \DeclareOption{esperanto}{% \def\screenwriter@lang{esperanto}% \screenwriter@lang@explicittrue } % paper size \DeclareOption{a4paper}{% \PassOptionsToClass{a4paper}{article}% \PassOptionsToPackage{a4paper}{geometry}% \renewcommand{\mytextwidth}{15cm}% \renewcommand{\mytextheight}{24.45cm}% \renewcommand{\myparenwidth}{3.8cm}% \renewcommand{\myparentab}{1.8cm}% \renewcommand{\myaddrwidth}{6.2cm}% \renewcommand{\myaddrseplen}{3cm plus 0cm minus 1.5cm}% } \DeclareOption{letterpaper}{% \PassOptionsToClass{letterpaper}{article}% \PassOptionsToPackage{letterpaper}{geometry}% } % screenplay type \DeclareOption{literary}{% \renewcommand{\slug}[3][]{% \MakeUppercase{#2\placesep#3}% \ifthenelse{\not\equal{#1}{}}% {\slugspace\MakeUppercase{#1}\hspace{\fill}}% {}% \nopagebreak }% } \DeclareOption{technical}{% \newcounter{scene}% \renewcommand{\slug}[3][]{% \stepcounter{scene}% \MakeUppercase{#2\placesep#3}\marginpar{\arabic{scene}}% \ifthenelse{\not\equal{#1}{}}% {\slugspace\MakeUppercase{#1}\hspace{\fill}}% {}% \hfill\reversemarginpar{\arabic{scene}}% \nopagebreak }% } % default options \ExecuteOptions{letterpaper,literary} \ProcessOptions\relax % --- base class and packages \RequirePackage{ifthen} \LoadClass[12pt,onecolumn,oneside]{article} \RequirePackage{geometry} \RequirePackage{courier} % --- basic behaviour \renewcommand*{\familydefault}{\ttdefault} \raggedright \pagenumbering{arabic} \pagestyle{myheadings} % --- babel language integration \AtBeginDocument{% \@ifpackageloaded{babel}{% \ifscreenwriter@lang@explicit % the user has selected language in document class \else \@ifundefined{languagename}{}{% \edef\screenwriter@lang{\languagename}% }% \fi }{}% \InputIfFileExists{lang/screenwriter-lang-\screenwriter@lang.ldf}{}{% \def\screenwriter@lang{english}% \InputIfFileExists{lang/screenwriter-lang-english.ldf}{}{}% }% } % Margins. \setlength{\baselineskip}{12pt plus 0pt minus 0pt} \renewcommand*{\baselinestretch}{\mybaselinestretch} \newcommand*{\dialfix}{\vspace{2pt}} \setlength{\parskip}{\baselineskip} \setlength{\parindent}{\myparindent} \newcommand*{\slugspace}{\myslugspace} \setlength{\evensidemargin}{\myevensidemargin} \setlength{\oddsidemargin}{\myoddsidemargin} \setlength{\topmargin}{\mytopmargin} \setlength{\headsep}{\myheadsep} \setlength{\topskip}{\mytopskip} \setlength{\textheight}{\mytextheight} \setlength{\textwidth}{\mytextwidth} \newlength{\widthgutter} \setlength{\widthgutter}{\mywidthgutter} \addtolength{\textwidth}{\widthgutter} \newlength{\dialwidth} \setlength{\dialwidth}{\mydialwidth} \newlength{\dialgutter} \setlength{\dialgutter}{\mydialgutter} \addtolength{\dialwidth}{\dialgutter} \newcommand*{\dialtab}{\hspace*{1.5in}} \newcommand*{\dialnametab}{\hspace*{1.2in}} \newlength{\parenwidth} \setlength{\parenwidth}{\myparenwidth} \addtolength{\parenwidth}{\dialgutter} \newcommand*{\parentab}{\hspace{\myparentab}} \renewcommand*{\textfraction}{1} \renewcommand*{\topfraction}{0} \renewcommand*{\bottomfraction}{0} % Title and address related. \title{Prima Opus Magnum} \author{Alan Smithee} \newcommand{\@realauthor}{\@author} \newcommand{\realauthor}[1]{\renewcommand{\@realauthor}{#1}} \newcommand{\@address}{\myaddresstext} \newcommand{\address}[1]{\renewcommand{\@address}{#1}} \newcommand{\@agent}{~} \newcommand{\agent}[1]{\renewcommand{\@agent}{#1}} \newlength{\titskip} \setlength{\titskip}{3.75in plus 0in minus 1.5in} \newlength{\addrwidth} \setlength{\addrwidth}{2.0in} \newlength{\addrseplen} \setlength{\addrseplen}{2.0in plus 0in minus 0.5in} \newcommand*{\bytext}{\mybytext} \newcommand*{\byskip}{\baselineskip} % Cover related. \newlength{\titheadskip} \setlength{\titheadskip}{2.25in} \newcommand{\nicholl}{% \thispagestyle{empty}% \vspace*{\titheadskip}% \begin{center}\MakeUppercase{\@title}\end{center}% \newpage\setcounter{page}{1}% } \newcommand{\coverpage}{% \thispagestyle{empty}% \vspace*{\titheadskip}% \begin{center}{\MakeUppercase{\@title}}\\ \vspace{\byskip}% \bytext\\ \vspace{\byskip}% \@author \end{center}% \vspace{\titskip}% \parbox[t]{\addrwidth}{\@agent}\hspace{\addrseplen}% \parbox[t]{\addrwidth}{\@realauthor\\\@address}% \newpage\setcounter{page}{1}% } % Text strings. \newcommand*{\more}{\mymoretext} \newcommand*{\contd}{\mycontdtext} \newcommand*{\voiceover}{\myvoiceovertext} \newcommand*{\offscreen}{\myoffscreentext} \newcommand*{\adlib}{\myadlibtext} \newcommand*{\pov}{\mypovtext} \newcommand*{\revert}{\myreverttext} \newcommand*{\thirty}{\mythirtytext} \newcommand{\theend}{\sccenter{\thirty}} % Dialog related. \newcommand{\paren}[1]{% \par\parentab\parbox[t]{\parenwidth}{\raggedright(#1)\dialfix}\\% } \newenvironment{dialogue}[2][]{% \dialtab\dialnametab\hbox{\MakeUppercase{#2}}\\*% \dialtab\begin{minipage}[b]{\dialwidth}% \dialfix \raggedright \ifthenelse{\not\equal{#1}{}}% {\paren{#1}}% {}% }{\end{minipage}} \newcommand{\dialbreak}[2][]{% \nopagebreak \dialnametab\hbox{\more}% \end{dialogue} \newpage \ifthenelse{\not\equal{#1}{}}% {\begin{dialogue}[#1]{\MakeUppercase{#2} \contd}}% {\begin{dialogue}{\MakeUppercase{#2} \contd}}% } % Slugs. \newcommand*{\placesep}{\myplacesep} \newcommand*{\inttext}{\myinttext} \newcommand{\intslug}[2][]{\slug[#1]{\inttext}{#2}} \newcommand*{\exttext}{\myexttext} \newcommand{\extslug}[2][]{\slug[#1]{\exttext}{#2}} \newcommand*{\sepintext}{\mysepintext} \newcommand{\intextslug}[2][]{\slug[#1]{\inttext\sepintext\exttext}{#2}} \newcommand{\extintslug}[2][]{\slug[#1]{\exttext\sepintext\inttext}{#2}} \newcommand*{\sccenter}[1]{\hspace*{\fill}{#1}\hspace{\fill}\hspace{\widthgutter}} \newcommand*{\sccentre}[1]{\sccenter{#1}} \newcommand*{\scflushright}[1]{\hspace*{\fill}{#1}\hspace{\widthgutter}} % Title over, fades, intercuts and more labels. \newcommand*{\punctcharA}{\mypunctcharA} \newcommand*{\punctcharB}{\mypunctcharB} \newcommand*{\titleovertext}{\mytitleovertext} \newenvironment{titleover}[1][]{% \ifthenelse{\not\equal{#1}{}}% {\titleovertext #1\punctcharA}% {\titleovertext\punctcharA}% \\*[\baselineskip]% \dialtab\begin{minipage}[b]{\dialwidth}% \raggedright }{\end{minipage}} \newcommand{\titbreak}{% \nopagebreak \dialnametab\hbox{\more}% \end{titleover} \newpage \begin{titleover}[\contd]% } \newcommand{\centertitle}[1]{% \titleovertext\punctcharA\\*[\baselineskip]% \sccentre{#1}\\ \bigskip } \newcommand{\centretitle}[1]{\centertitle{#1}} \newcommand*{\fadeintext}{\myfadeintext} \newcommand{\fadein}{% \fadeintext\punctcharA\\ \bigskip } \newcommand{\RIGHT}[2]{% \scflushright{#1#2}\\ \bigskip } \newcommand*{\intercuttext}{\myintercuttext} \newcommand*{\flashbacktext}{\myflashbacktext} \newcommand*{\fadeouttext}{\myfadeouttext} \newcommand{\intercut}{\RIGHT{\intercuttext}{\punctcharA}} \newcommand{\flashback}{\RIGHT{\flashbacktext}{\punctcharA}} \newcommand{\fadeout}{\RIGHT{\fadeouttext}{\punctcharB}}