-- | Defines output formats for the different documents we can generate.
module Drasil.Generator.Formats (
  -- * Types (Printing Options)
  DocSpec(..), Filename, Format(..),
  -- * Rules
  buildMakefile
) where

import Build.Drasil ((+:+), Command, makeS, mkCheckedCommand, mkCommand, mkFreeVar,
  mkFile, mkRule, mkMakefile, Makefile)
import Drasil.Metadata (watermark)

-- | When choosing your document, you must specify the filename for
-- the generated output (specified /without/ a file extension).
type Filename = String

-- | Possible formats for printer output.
data Format = TeX | HTML | Jupyter | MDBook

instance Show Format where
  show :: Format -> String
show Format
TeX     = String
"PDF"
  show Format
HTML    = String
"HTML"
  show Format
Jupyter = String
"Jupyter"
  show Format
MDBook  = String
"mdBook"

-- | Document specifications. Holds the type of document ('DocType') and its name ('Filename').
data DocSpec = DocSpec Format Filename

-- | Create a 'Makefile' necessary for building a 'DocSpec' when rendered as a
-- concrete artifact. Only relevant to 'TeX' and 'MDBook'.
buildMakefile :: DocSpec -> Maybe Makefile
buildMakefile :: DocSpec -> Maybe Makefile
buildMakefile (DocSpec Format
TeX String
fn) = Makefile -> Maybe Makefile
forall a. a -> Maybe a
Just (Makefile -> Maybe Makefile) -> Makefile -> Maybe Makefile
forall a b. (a -> b) -> a -> b
$ [Rule] -> Makefile
mkMakefile [
  Annotation -> Target -> Dependencies -> [Command] -> Rule
mkRule [String
watermark] (String -> Target
makeS String
"srs") [Target
pdfName] [],
  Annotation -> Target -> Dependencies -> [Command] -> Rule
mkFile [] Target
pdfName [String -> Target
makeS (String -> Target) -> String -> Target
forall a b. (a -> b) -> a -> b
$ String
fn String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".tex"] ([Command] -> Rule) -> [Command] -> Rule
forall a b. (a -> b) -> a -> b
$
    ((String -> Command) -> Command)
-> [String -> Command] -> [Command]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> Command) -> String -> Command
forall a b. (a -> b) -> a -> b
$ String
fn) [String -> Command
lualatex, String -> Command
bibtex, String -> Command
lualatex, String -> Command
lualatex]] where
      lualatex, bibtex :: String -> Command
      lualatex :: String -> Command
lualatex = Target -> Command
mkCheckedCommand (Target -> Command) -> (String -> Target) -> String -> Command
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Target -> Target -> Target
(+:+) (String -> Target
makeS String
"lualatex" Target -> Target -> Target
+:+ String -> Target
mkFreeVar String
"TEXFLAGS") (Target -> Target) -> (String -> Target) -> String -> Target
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Target
makeS
      bibtex :: String -> Command
bibtex = Target -> Command
mkCommand (Target -> Command) -> (String -> Target) -> String -> Command
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Target -> Target -> Target
(+:+) (String -> Target
makeS String
"bibtex" Target -> Target -> Target
+:+ String -> Target
mkFreeVar String
"BIBTEXFLAGS") (Target -> Target) -> (String -> Target) -> String -> Target
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Target
makeS
      pdfName :: Target
pdfName = String -> Target
makeS (String -> Target) -> String -> Target
forall a b. (a -> b) -> a -> b
$ String
fn String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".pdf"
buildMakefile (DocSpec Format
MDBook String
_) = Makefile -> Maybe Makefile
forall a. a -> Maybe a
Just (Makefile -> Maybe Makefile) -> Makefile -> Maybe Makefile
forall a b. (a -> b) -> a -> b
$ [Rule] -> Makefile
mkMakefile [
  Annotation -> Target -> Dependencies -> [Command] -> Rule
mkRule [String
watermark] (String -> Target
makeS String
"build")  [] [Command
build],
  Annotation -> Target -> Dependencies -> [Command] -> Rule
mkRule [] (String -> Target
makeS String
"server") [] [Command
server]]
  where
    build :: Command
build = Target -> Command
mkCheckedCommand (Target -> Command) -> Target -> Command
forall a b. (a -> b) -> a -> b
$ String -> Target
makeS String
"mdbook build"
    server :: Command
server = Target -> Command
mkCheckedCommand (Target -> Command) -> Target -> Command
forall a b. (a -> b) -> a -> b
$ String -> Target
makeS String
"mdbook serve --open"
buildMakefile DocSpec
_ = Maybe Makefile
forall a. Maybe a
Nothing