{-# LANGUAGE CPP, OverloadedStrings, TypeFamilies #-}
#if __GLASGOW_HASKELL__ >= 801
{-# OPTIONS_GHC -Wno-orphans #-}
#else
{-# OPTIONS_GHC -fno-warn-orphans #-}
#endif

-- | <https://ctan.org/pkg/amsmath?lang=en amsmath> is a de-facto standard
--  package for maths in LaTeX. It is used in most scientific documents
--  and also available by default in MathJax.
-- 
-- Note that many of the maths commands this module exports are actually defined
--  in LaTeX itself, and do not really require the @amsmath@ package.
--  See the "Text.LaTeX.Base.Math" module for this minimal command-set.
module Text.LaTeX.Packages.AMSMath
 ( -- * AMSMath package
   amsmath
   -- * Math Environments
 , math, mathDisplay
 , equation , equation_
 , align , align_
 , cases
   -- ** Referencing
 , eqref , nonumber
   -- * Symbols and utilities
   
   -- ** Brackets / delimiters
 , autoParens
 , autoSquareBrackets, autoBraces, autoAngleBrackets
 , autoBrackets
 
 , langle , rangle
 , lfloor , rfloor
 , lceil , rceil 
 , dblPipe
   -- ** Superscript and subscript
 , (^:) , (!:), (!^)
   -- ** Function symbols
   -- | Some symbols are preceded with /t/ to be distinguished from
   --   predefined Haskell entities (like 'sin' and 'cos').
 , tsin , arcsin
 , tcos , arccos
 , ttan , arctan
 , cot , arccot
 , tsinh , tcosh , ttanh , coth
 , sec , csc
 , texp
 , tlog , ln
 , tsqrt
   -- ** Custom function symbols
 , operatorname
   -- ** Summation \/ integration \/ differentiation \/ relations
 , tsum , sumFromTo
 , prod , prodFromTo
 , coprod, coprodFromTo
 , integral , integralFromTo
 , partial, totald, partialOf, totaldOf
 , bigcup, bigcupFromTo
 , bigcap, bigcapFromTo 
   -- ** Operator symbols
   -- *** Arithmetic
 , (+-), (-+)
 , cdot , times , div_
 , frac, tfrac
 , (*:) , star
 , circ , bullet
   -- *** Comparison
 , (=:) , (/=:)
 , (<:) , (<=:)
 , (>:) , (>=:)
 , ll , gg
 , equiv
 , propto
 , parallel
 , perp
 , approx
 , sim
 , simeq
 , cong
   -- *** Sets
 , in_ , ni , notin
 , subset , supset
 , subseteq , supseteq
 , cap , cup
 , setminus
   -- *** Misc operators
 , vee , wedge
 , oplus , ominus , otimes
 , oslash , odot
   -- *** Accents
 , hat, tilde, bar, vec, widehat, widetilde
 , dot, ddot, dddot
 , overline
 
   -- ** Greek alphabet
   -- | Functions of greek alphabet symbols.
   --
   --   Uppercase versions are suffixed with @u@.
   --   Variants are prefixed with @var@.
   --   The function 'pi_' is ended by an underscore symbol to
   --   distinguish it from the 'pi' Prelude function.
 , alpha    , beta       , gamma
 , gammau   , delta      , deltau
 , epsilon  , varepsilon , zeta
 , eta      , theta      , vartheta , thetau
 , iota     , kappa      , lambda
 , lambdau  , mu         , nu
 , xi       , xiu        , pi_
 , varpi    , piu        , rho
 , varrho   , sigma      , varsigma
 , sigmau   , tau        , upsilon
 , upsilonu , phi        , varphi
 , phiu     , chi        , psi
 , psiu     , omega      , omegau
   -- ** Other symbols
 , pm , mp
 , to , mapsto, implies
 , forall , exists
 , dagger, ddagger
 , infty
 , imath, jmath
 , bot
   -- * Fonts
 , mathdefault
 , mathbf
 , mathrm
 , text
 , mathcal
 , mathsf
 , mathtt
 , mathit
   -- * Matrices
 , pmatrix  , bmatrix
 , b2matrix , vmatrix
 , v2matrix
   -- * Math spacing
 , quad, qquad
 , thinspace, medspace, thickspace, negspace, space
   ) where

import Text.LaTeX.Base
import Text.LaTeX.Base.Syntax
import Text.LaTeX.Base.Class

-- External imports
import Data.List
import Data.Ratio
import Data.Matrix

-- | AMSMath package.
-- Example:
--
-- > usepackage [] amsmath
amsmath :: PackageName
amsmath :: PackageName
amsmath = PackageName
"amsmath"


-- | A reference to a numbered equation. Use with a 'label' defined in the
-- scope of the equation refered to.
eqref :: LaTeXC l => l -> l
eqref :: forall l. LaTeXC l => l -> l
eqref = forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL forall a b. (a -> b) -> a -> b
$ \LaTeX
l -> PackageName -> [TeXArg] -> LaTeX
TeXComm PackageName
"eqref" [LaTeX -> TeXArg
FixArg forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> LaTeX
TeXRaw forall a b. (a -> b) -> a -> b
$ forall a. Render a => a -> Text
render LaTeX
l]

-- | An array of aligned equations. Use '&' to specify the points that should
-- horizontally match. Each equation is numbered, unless prevented by 'nonumber'.
align :: LaTeXC l => [l] -> l
align :: forall l. LaTeXC l => [l] -> l
align = forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL(PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv PackageName
"align" []) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse forall l. LaTeXC l => l
lnbk 

-- | The unnumbered variant of 'align'.
align_ :: LaTeXC l => [l] -> l
align_ :: forall l. LaTeXC l => [l] -> l
align_ = forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL(PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv PackageName
"align*" []) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse forall l. LaTeXC l => l
lnbk 

-- | The cases environment allows the writing of piecewise functions
cases :: LaTeXC l => l -> l
cases :: forall l. LaTeXC l => l -> l
cases = forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL forall a b. (a -> b) -> a -> b
$ PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv PackageName
"cases" []

-------------------------------------
------- Symbols and utilities -------


-- | Like 'frac' but smaller (uses subscript size for the numerator and denominator.
tfrac :: LaTeXC l => l -> l -> l
tfrac :: forall l. LaTeXC l => l -> l -> l
tfrac = forall l. LaTeXC l => (LaTeX -> LaTeX -> LaTeX) -> l -> l -> l
liftL2 forall a b. (a -> b) -> a -> b
$ \LaTeX
p LaTeX
q -> PackageName -> [TeXArg] -> LaTeX
TeXComm PackageName
"tfrac" [LaTeX -> TeXArg
FixArg LaTeX
p, LaTeX -> TeXArg
FixArg LaTeX
q]


-- | Add a dot accent above a symbol, as used to denote a second derivative,
--   like \(\ddot{y}\)
ddot :: LaTeXC l => l -> l
ddot :: forall l. LaTeXC l => l -> l
ddot = forall l. LaTeXC l => PackageName -> l -> l
comm1 PackageName
"ddot"

-- | Add a triple dot accent above a symbol, as used to denote a third derivative,
--   like \(\dddot{z}\)
dddot :: LaTeXC l => l -> l
dddot :: forall l. LaTeXC l => l -> l
dddot = forall l. LaTeXC l => PackageName -> l -> l
comm1 PackageName
"dddot"




-- | Escape from math mode, into a normal-text box.
--   Unlike 'mathrm', this won't squash spaces, i.e. you can write actual sentences.
--   You can embed 'math' again within such a box.
text :: LaTeXC l => l -> l
text :: forall l. LaTeXC l => l -> l
text = forall l. LaTeXC l => PackageName -> l -> l
comm1 PackageName
"text"

-------------------------------------
------------- Matrices --------------

matrix2tex :: (Texy a, LaTeXC l) => Matrix a -> l
matrix2tex :: forall a l. (Texy a, LaTeXC l) => Matrix a -> l
matrix2tex Matrix a
m = forall a. Monoid a => [a] -> a
mconcat
 [ forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 forall l. LaTeXC l => l -> l -> l
(&) [ forall t l. (Texy t, LaTeXC l) => t -> l
texy forall a b. (a -> b) -> a -> b
$ Matrix a
m forall a. Matrix a -> (Int, Int) -> a
! (Int
i,Int
j)
     | Int
j <- [Int
1 .. forall a. Matrix a -> Int
ncols Matrix a
m]
     ] forall a. Semigroup a => a -> a -> a
<> forall l. LaTeXC l => l
lnbk
     | Int
i <- [Int
1 .. forall a. Matrix a -> Int
nrows Matrix a
m]
   ]

toMatrix :: (Texy a, LaTeXC l) => String -> Maybe HPos -> Matrix a -> l
toMatrix :: forall a l.
(Texy a, LaTeXC l) =>
PackageName -> Maybe HPos -> Matrix a -> l
toMatrix PackageName
str Maybe HPos
Nothing  = forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL (PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv PackageName
str []) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a l. (Texy a, LaTeXC l) => Matrix a -> l
matrix2tex
toMatrix PackageName
str (Just HPos
p) = forall l. LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL (PackageName -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv (PackageName
str forall a. [a] -> [a] -> [a]
++ PackageName
"*") [LaTeX -> TeXArg
OptArg forall a b. (a -> b) -> a -> b
$ forall a l. (Render a, LaTeXC l) => a -> l
rendertex HPos
p]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a l. (Texy a, LaTeXC l) => Matrix a -> l
matrix2tex

-- | LaTeX rendering of a matrix using @pmatrix@ and a custom function to render cells.
--   Optional argument sets the alignment of the cells. Default (providing 'Nothing') 
--   is centered.
--
-- \[ \begin{pmatrix} 0 & 1 \\ 2 & 3 \end{pmatrix} \]
--
pmatrix :: (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
pmatrix :: forall a l. (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
pmatrix = forall a l.
(Texy a, LaTeXC l) =>
PackageName -> Maybe HPos -> Matrix a -> l
toMatrix PackageName
"pmatrix"

-- | LaTeX rendering of a matrix using @bmatrix@ and a custom function to render cells.
--   Optional argument sets the alignment of the cells. Default (providing 'Nothing') 
--   is centered.
--
-- \[ \begin{bmatrix} 0 & 1 \\ 2 & 3 \end{bmatrix} \]
--
bmatrix :: (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
bmatrix :: forall a l. (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
bmatrix = forall a l.
(Texy a, LaTeXC l) =>
PackageName -> Maybe HPos -> Matrix a -> l
toMatrix PackageName
"bmatrix"

-- | LaTeX rendering of a matrix using @Bmatrix@ and a custom function to render cells.
--   Optional argument sets the alignment of the cells. Default (providing 'Nothing') 
--   is centered.
--
-- \[ \begin{Bmatrix} 0 & 1 \\ 2 & 3 \end{Bmatrix} \]
--
b2matrix :: (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
b2matrix :: forall a l. (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
b2matrix = forall a l.
(Texy a, LaTeXC l) =>
PackageName -> Maybe HPos -> Matrix a -> l
toMatrix PackageName
"Bmatrix"

-- | LaTeX rendering of a matrix using @vmatrix@ and a custom function to render cells.
--   Optional argument sets the alignment of the cells. Default (providing 'Nothing') 
--   is centered.
--
-- \[ \begin{vmatrix} 0 & 1 \\ 2 & 3 \end{vmatrix} \]
--
vmatrix :: (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
vmatrix :: forall a l. (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
vmatrix = forall a l.
(Texy a, LaTeXC l) =>
PackageName -> Maybe HPos -> Matrix a -> l
toMatrix PackageName
"vmatrix"

-- | LaTeX rendering of a matrix using @Vmatrix@ and a custom function to render cells.
--   Optional argument sets the alignment of the cells. Default (providing 'Nothing') 
--   is centered.
--
-- \[ \begin{Vmatrix} 0 & 1 \\ 2 & 3 \end{Vmatrix} \]
--
v2matrix :: (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
v2matrix :: forall a l. (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
v2matrix = forall a l.
(Texy a, LaTeXC l) =>
PackageName -> Maybe HPos -> Matrix a -> l
toMatrix PackageName
"Vmatrix"

-------------------------------------
---------- Texy instances -----------

-- | Instance defined in "Text.LaTeX.Packages.AMSMath".
#if MIN_VERSION_base(4,9,0)
instance Texy a => Texy (Ratio a) where
#else
instance (Integral a, Texy a) => Texy (Ratio a) where
#endif
 texy :: forall l. LaTeXC l => Ratio a -> l
texy Ratio a
x = forall l. LaTeXC l => l -> l -> l
frac (forall t l. (Texy t, LaTeXC l) => t -> l
texy forall a b. (a -> b) -> a -> b
$ forall a. Ratio a -> a
numerator Ratio a
x) (forall t l. (Texy t, LaTeXC l) => t -> l
texy forall a b. (a -> b) -> a -> b
$ forall a. Ratio a -> a
denominator Ratio a
x)

-- | Instance defined in "Text.LaTeX.Packages.AMSMath".
instance (Texy a, Texy b) => Texy (a,b) where
 texy :: forall l. LaTeXC l => (a, b) -> l
texy (a
x,b
y) = forall l. LaTeXC l => l -> l
autoParens forall a b. (a -> b) -> a -> b
$ forall t l. (Texy t, LaTeXC l) => t -> l
texy a
x forall a. Semigroup a => a -> a -> a
<> l
"," forall a. Semigroup a => a -> a -> a
<> forall t l. (Texy t, LaTeXC l) => t -> l
texy b
y
 
-- | Instance defined in "Text.LaTeX.Packages.AMSMath".
instance (Texy a, Texy b, Texy c) => Texy (a,b,c) where
 texy :: forall l. LaTeXC l => (a, b, c) -> l
texy (a
x,b
y,c
z) = forall l. LaTeXC l => l -> l
autoParens forall a b. (a -> b) -> a -> b
$ forall t l. (Texy t, LaTeXC l) => t -> l
texy a
x forall a. Semigroup a => a -> a -> a
<> l
"," forall a. Semigroup a => a -> a -> a
<> forall t l. (Texy t, LaTeXC l) => t -> l
texy b
y forall a. Semigroup a => a -> a -> a
<> l
"," forall a. Semigroup a => a -> a -> a
<> forall t l. (Texy t, LaTeXC l) => t -> l
texy c
z

-- | Instance defined in "Text.LaTeX.Packages.AMSMath".
instance (Texy a, Texy b, Texy c, Texy d) => Texy (a,b,c,d) where
 texy :: forall l. LaTeXC l => (a, b, c, d) -> l
texy (a
a,b
b,c
c,d
d) = forall l. LaTeXC l => l -> l
autoParens forall a b. (a -> b) -> a -> b
$ forall t l. (Texy t, LaTeXC l) => t -> l
texy a
a forall a. Semigroup a => a -> a -> a
<> l
"," forall a. Semigroup a => a -> a -> a
<> forall t l. (Texy t, LaTeXC l) => t -> l
texy b
b forall a. Semigroup a => a -> a -> a
<> l
"," forall a. Semigroup a => a -> a -> a
<> forall t l. (Texy t, LaTeXC l) => t -> l
texy c
c forall a. Semigroup a => a -> a -> a
<> l
"," forall a. Semigroup a => a -> a -> a
<> forall t l. (Texy t, LaTeXC l) => t -> l
texy d
d

-- | Instance defined in "Text.LaTeX.Packages.AMSMath".
instance Texy a => Texy (Matrix a) where
 texy :: forall l. LaTeXC l => Matrix a -> l
texy = forall a l. (Texy a, LaTeXC l) => Maybe HPos -> Matrix a -> l
pmatrix forall a. Maybe a
Nothing

-- | Instance defined in "Text.LaTeX.Packages.AMSMath".
instance Texy a => Texy [a] where
 texy :: forall l. LaTeXC l => [a] -> l
texy = forall l. LaTeXC l => l -> l
autoSquareBrackets forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
.  forall a. a -> [a] -> [a]
intersperse l
"," forall b c a. (b -> c) -> (a -> b) -> a -> c
.  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall t l. (Texy t, LaTeXC l) => t -> l
texy

-------------------------------------
----------- Math Spacing-------------

-- | @\,@ space equal to 3/18 of \quad (= 3 mu). \(a\,b\)
thinspace :: LaTeXC l => l
thinspace :: forall l. LaTeXC l => l
thinspace = forall l. LaTeXC l => PackageName -> l
comm0 PackageName
","

-- | @\:@ space equal to 4/18 of \quad (= 4 mu). \(a\:b\)
medspace :: LaTeXC l => l
medspace :: forall l. LaTeXC l => l
medspace = forall l. LaTeXC l => PackageName -> l
comm0 PackageName
":"

-- | @\:@ space equal to 5/18 of \quad (= 5 mu). \(a\;b\)
thickspace :: LaTeXC l => l
thickspace :: forall l. LaTeXC l => l
thickspace = forall l. LaTeXC l => PackageName -> l
comm0 PackageName
";"

-- | @\!@ space equal to -3/18 of \quad (= -3 mu). \(a\!b\)
negspace :: LaTeXC l => l
negspace :: forall l. LaTeXC l => l
negspace = forall l. LaTeXC l => PackageName -> l
comm0 PackageName
"!"

-- | @\ @ (space after backslash) equivalent of space in normal text. \(a\ b\)
space :: LaTeXC l => l
space :: forall l. LaTeXC l => l
space = forall l. LaTeXC l => PackageName -> l
comm0 PackageName
" "