{-# LANGUAGE OverloadedStrings #-}

-- | Package for theorem environments.
module Text.LaTeX.Packages.AMSThm
 ( -- * AMSThm package
   amsthm
   -- * AMSThm functions
 , newtheorem
 , theorem
 , proof
 , qed
 , qedhere
 , TheoremStyle (..)
 , theoremstyle
   ) where

import Text.LaTeX.Base.Syntax
import Text.LaTeX.Base.Class
import Text.LaTeX.Base.Render
import Text.LaTeX.Base.Types

-- | AMSThm package.
-- Example:
--
-- > usepackage [] amsthm
amsthm :: PackageName
amsthm :: PackageName
amsthm = PackageName
"amsthm"

-- | Create a new 'theorem' environment type.
--   Arguments are environment name (this will be the argument
--   when using the 'theorem' function) and the displayed title.
--
--   For example:
--
-- > newtheorem "prop" "Proposition"
--
-- > theorem "prop" "This is it."
newtheorem :: LaTeXC l => String -> l -> l
newtheorem :: PackageName -> l -> l
newtheorem PackageName
str = (LaTeX -> LaTeX) -> l -> l
forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL ((LaTeX -> LaTeX) -> l -> l) -> (LaTeX -> LaTeX) -> l -> l
forall a b. (a -> b) -> a -> b
$ \LaTeX
l -> PackageName -> [TeXArg] -> LaTeX
TeXComm PackageName
"newtheorem" [ LaTeX -> TeXArg
FixArg (LaTeX -> TeXArg) -> LaTeX -> TeXArg
forall a b. (a -> b) -> a -> b
$ PackageName -> LaTeX
forall a. IsString a => PackageName -> a
fromString PackageName
str , LaTeX -> TeXArg
FixArg LaTeX
l ]

-- | Use a environment created by 'newtheorem'.
theorem :: LaTeXC l => String -> l -> l
theorem :: PackageName -> l -> l
theorem PackageName
str = (LaTeX -> LaTeX) -> l -> l
forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL ((LaTeX -> LaTeX) -> l -> l) -> (LaTeX -> LaTeX) -> l -> l
forall a b. (a -> b) -> a -> b
$ PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv PackageName
str []

-- | The 'proof' environment. The first optional argument
--   is used to put a custom title to the proof.
proof :: LaTeXC l => Maybe l -> l -> l
proof :: Maybe l -> l -> l
proof  Maybe l
Nothing = (LaTeX -> LaTeX) -> l -> l
forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL ((LaTeX -> LaTeX) -> l -> l) -> (LaTeX -> LaTeX) -> l -> l
forall a b. (a -> b) -> a -> b
$ PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv PackageName
"proof" []
proof (Just l
n) = (LaTeX -> LaTeX -> LaTeX) -> l -> l -> l
forall l. LaTeXC l => (LaTeX -> LaTeX -> LaTeX) -> l -> l -> l
liftL2 (\LaTeX
m -> PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv PackageName
"proof" [LaTeX -> TeXArg
OptArg LaTeX
m]) l
n

-- | Insert the /QED/ symbol \(\square\), as a concluding right-aligned terminator.
--   Note that within a 'proof' environment, this is automatically done at the end.
qed :: LaTeXC l => l
qed :: l
qed = PackageName -> l
forall l. LaTeXC l => PackageName -> l
comm0 PackageName
"qed"

-- | Insert the /QED/ symbol. This is supposed to be used within a 'proof' environment,
--   to change the default behaviour of putting the \(\square\) at the end.
qedhere :: LaTeXC l => l
qedhere :: l
qedhere = PackageName -> l
forall l. LaTeXC l => PackageName -> l
comm0 PackageName
"qedhere"

-- | Different styles for 'theorem's.
data TheoremStyle =
   Plain
 | Definition
 | Remark
 | CustomThmStyle String
   deriving Int -> TheoremStyle -> ShowS
[TheoremStyle] -> ShowS
TheoremStyle -> PackageName
(Int -> TheoremStyle -> ShowS)
-> (TheoremStyle -> PackageName)
-> ([TheoremStyle] -> ShowS)
-> Show TheoremStyle
forall a.
(Int -> a -> ShowS)
-> (a -> PackageName) -> ([a] -> ShowS) -> Show a
showList :: [TheoremStyle] -> ShowS
$cshowList :: [TheoremStyle] -> ShowS
show :: TheoremStyle -> PackageName
$cshow :: TheoremStyle -> PackageName
showsPrec :: Int -> TheoremStyle -> ShowS
$cshowsPrec :: Int -> TheoremStyle -> ShowS
Show

instance Render TheoremStyle where
 render :: TheoremStyle -> Text
render TheoremStyle
Plain = Text
"plain"
 render TheoremStyle
Definition = Text
"definition"
 render TheoremStyle
Remark = Text
"remark"
 render (CustomThmStyle PackageName
str) = PackageName -> Text
forall a. IsString a => PackageName -> a
fromString PackageName
str

-- | Set the theorem style. Call this function in the preamble.
theoremstyle :: LaTeXC l => TheoremStyle -> l
theoremstyle :: TheoremStyle -> l
theoremstyle TheoremStyle
thmsty = LaTeX -> l
forall l. LaTeXC l => LaTeX -> l
fromLaTeX (LaTeX -> l) -> LaTeX -> l
forall a b. (a -> b) -> a -> b
$ PackageName -> [TeXArg] -> LaTeX
TeXComm PackageName
"theoremstyle" [ LaTeX -> TeXArg
FixArg (LaTeX -> TeXArg) -> LaTeX -> TeXArg
forall a b. (a -> b) -> a -> b
$ Text -> LaTeX
TeXRaw (Text -> LaTeX) -> Text -> LaTeX
forall a b. (a -> b) -> a -> b
$ TheoremStyle -> Text
forall a. Render a => a -> Text
render TheoremStyle
thmsty ]