{- |
Module      : Language.Egison.PrettyMath.Latex
Licence     : MIT
-}

module Language.Egison.PrettyMath.Latex
  ( showMathExpr
  ) where

import           Data.List                      (intercalate)

import           Language.Egison.PrettyMath.AST

showMathExpr :: MathExpr -> String
showMathExpr :: MathExpr -> String
showMathExpr (Atom String
a []) = String
a
showMathExpr (Atom String
a [MathIndex]
xs) = String
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathIndex] -> String
showMathExprScript [MathIndex]
xs
showMathExpr (Partial MathExpr
f [MathExpr]
xs) = String
"\\frac{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (MathExpr, Int) -> String
convertToPartial (MathExpr
f, [MathExpr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [MathExpr]
xs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showPartial [MathExpr]
xs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
 where
  showPartial :: [MathExpr] -> String
  showPartial :: [MathExpr] -> String
showPartial [MathExpr]
xs = let lx :: [(MathExpr, Int)]
lx = [MathExpr] -> [(MathExpr, Int)]
forall a. Eq a => [a] -> [(a, Int)]
elemCount [MathExpr]
xs in (MathExpr, Int) -> String
convertToPartial2 ([(MathExpr, Int)] -> (MathExpr, Int)
forall a. [a] -> a
head [(MathExpr, Int)]
lx) String -> String -> String
forall a. [a] -> [a] -> [a]
++ ((MathExpr, Int) -> String -> String)
-> String -> [(MathExpr, Int)] -> String
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(MathExpr, Int)
x String
acc -> String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (MathExpr, Int) -> String
convertToPartial2 (MathExpr, Int)
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
acc) String
"" ([(MathExpr, Int)] -> [(MathExpr, Int)]
forall a. [a] -> [a]
tail [(MathExpr, Int)]
lx)

  convertToPartial :: (MathExpr, Int) -> String
  convertToPartial :: (MathExpr, Int) -> String
convertToPartial (MathExpr
x, Int
1) = String
"\\partial " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x
  convertToPartial (MathExpr
x, Int
n) = String
"\\partial^" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x

  convertToPartial2 :: (MathExpr, Int) -> String
  convertToPartial2 :: (MathExpr, Int) -> String
convertToPartial2 (MathExpr
x, Int
1) = String
"\\partial " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x
  convertToPartial2 (MathExpr
x, Int
n) = String
"\\partial " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"^"  String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
showMathExpr (NegativeAtom String
a) = String
"-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
a
showMathExpr (Plus []) = String
""
showMathExpr (Plus (MathExpr
x:[MathExpr]
xs)) = MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showMathExprForPlus [MathExpr]
xs
 where
  showMathExprForPlus :: [MathExpr] -> String
  showMathExprForPlus :: [MathExpr] -> String
showMathExprForPlus []                                  = String
""
  showMathExprForPlus (NegativeAtom String
a:[MathExpr]
xs)                 = String
" - " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showMathExprForPlus [MathExpr]
xs
  showMathExprForPlus (Multiply (NegativeAtom String
"1":[MathExpr]
ys):[MathExpr]
xs) = String
" - " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr ([MathExpr] -> MathExpr
Multiply [MathExpr]
ys) String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showMathExprForPlus [MathExpr]
xs
  showMathExprForPlus (Multiply (NegativeAtom String
a:[MathExpr]
ys):[MathExpr]
xs)   = String
" - " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr ([MathExpr] -> MathExpr
Multiply (String -> [MathIndex] -> MathExpr
Atom String
a []MathExpr -> [MathExpr] -> [MathExpr]
forall a. a -> [a] -> [a]
:[MathExpr]
ys)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showMathExprForPlus [MathExpr]
xs
  showMathExprForPlus (MathExpr
x:[MathExpr]
xs)                              = String
" + " String -> String -> String
forall a. [a] -> [a] -> [a]
++  MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showMathExprForPlus [MathExpr]
xs
showMathExpr (Multiply []) = String
""
showMathExpr (Multiply [MathExpr
x]) = MathExpr -> String
showMathExpr MathExpr
x
showMathExpr (Multiply (Atom String
"1" []:[MathExpr]
xs)) = MathExpr -> String
showMathExpr ([MathExpr] -> MathExpr
Multiply [MathExpr]
xs)
showMathExpr (Multiply (NegativeAtom String
"1":[MathExpr]
xs)) = String
"-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr ([MathExpr] -> MathExpr
Multiply [MathExpr]
xs)
showMathExpr (Multiply (MathExpr
x:[MathExpr]
xs)) = MathExpr -> String
showMathExpr' MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr ([MathExpr] -> MathExpr
Multiply [MathExpr]
xs)
showMathExpr (Div MathExpr
x MathExpr
y) = String
"\\frac{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
y String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
showMathExpr (Power MathExpr
lv1 MathExpr
lv2) = MathExpr -> String
showMathExpr MathExpr
lv1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"^" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
lv2
showMathExpr (Func (Atom String
"sqrt" []) [MathExpr
x]) = String
"\\sqrt{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
showMathExpr (Func (Atom String
"rt" []) [MathExpr
x, MathExpr
y]) = String
"\\sqrt[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
y String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
showMathExpr (Func (Atom String
"exp" []) [MathExpr
x]) = String
"e^{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
showMathExpr (Func MathExpr
f [MathExpr]
xs) = MathExpr -> String
showMathExpr MathExpr
f String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String -> String
showMathExprArg [MathExpr]
xs String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
showMathExpr (Tensor [MathExpr]
xs [MathIndex]
mis) = String
"\\begin{pmatrix} " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showMathExprVectors [MathExpr]
xs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\\end{pmatrix}" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathIndex] -> String
showMathExprScript [MathIndex]
mis
showMathExpr (Tuple [MathExpr]
xs) = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String -> String
showMathExprArg [MathExpr]
xs String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
showMathExpr (Collection [MathExpr]
xs) = String
"\\{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String -> String
showMathExprArg [MathExpr]
xs String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\\}"
showMathExpr (Quote MathExpr
x) = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr MathExpr
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"

showMathExpr' :: MathExpr -> String
showMathExpr' :: MathExpr -> String
showMathExpr' (Plus [MathExpr]
xs) = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ MathExpr -> String
showMathExpr ([MathExpr] -> MathExpr
Plus [MathExpr]
xs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
showMathExpr' MathExpr
x         = MathExpr -> String
showMathExpr MathExpr
x

showMathExprArg :: [MathExpr] -> String -> String
showMathExprArg :: [MathExpr] -> String -> String
showMathExprArg [MathExpr]
exprs String
sep = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
sep ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (MathExpr -> String) -> [MathExpr] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map MathExpr -> String
showMathExpr [MathExpr]
exprs

showMathExprSuper :: MathIndex -> String
showMathExprSuper :: MathIndex -> String
showMathExprSuper (Super (Atom String
"#" [])) = String
"\\#"
showMathExprSuper (Super MathExpr
x)             = MathExpr -> String
showMathExpr MathExpr
x
showMathExprSuper (Sub MathExpr
_)               = String
"\\;"

showMathExprSub :: MathIndex -> String
showMathExprSub :: MathIndex -> String
showMathExprSub (Sub (Atom String
"#" [])) = String
"\\#"
showMathExprSub (Sub MathExpr
x)             = MathExpr -> String
showMathExpr MathExpr
x
showMathExprSub (Super MathExpr
_)           = String
"\\;"

showMathExprScript :: [MathIndex] -> String
showMathExprScript :: [MathIndex] -> String
showMathExprScript [] = String
""
showMathExprScript [MathIndex]
is = String
"_{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (MathIndex -> String) -> [MathIndex] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap MathIndex -> String
showMathExprSub [MathIndex]
is String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}^{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (MathIndex -> String) -> [MathIndex] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap MathIndex -> String
showMathExprSuper [MathIndex]
is String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"

showMathExprVectors :: [MathExpr] -> String
showMathExprVectors :: [MathExpr] -> String
showMathExprVectors []                = String
""
showMathExprVectors (Tensor [MathExpr]
lvs []:[MathExpr]
r) = [MathExpr] -> String -> String
showMathExprArg [MathExpr]
lvs String
" & " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" \\\\ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [MathExpr] -> String
showMathExprVectors [MathExpr]
r
showMathExprVectors [MathExpr]
lvs               = [MathExpr] -> String -> String
showMathExprArg [MathExpr]
lvs String
" \\\\ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\\\\ "

elemCount :: Eq a => [a] -> [(a, Int)]
elemCount :: [a] -> [(a, Int)]
elemCount []     = []
elemCount (a
x:[a]
xs) = (a
x, [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
x) [a]
xs) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (a, Int) -> [(a, Int)] -> [(a, Int)]
forall a. a -> [a] -> [a]
: [a] -> [(a, Int)]
forall a. Eq a => [a] -> [(a, Int)]
elemCount ((a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
x) [a]
xs)