Eq-1.0: EqManips/Renderer/Latex.hs
module EqManips.Renderer.Latex ( latexRender, latexRenderS ) where
import Data.Ratio
import EqManips.Types
import EqManips.Polynome
import EqManips.Algorithm.Utils
import EqManips.Propreties
import EqManips.Renderer.RenderConf
latexRender :: Conf -> Formula TreeForm -> String
latexRender conf f = latexRenderS conf f ""
latexRenderS :: Conf -> Formula TreeForm -> ShowS
latexRenderS conf(Formula f) = str "\\begin{equation*}\n"
. lno conf f
. str "\n\\end{equation*}\n"
str :: String -> ShowS
str = (++)
char :: Char -> ShowS
char = (:)
latexOfEntity :: Entity -> String
latexOfEntity Pi = "\\pi "
latexOfEntity Nabla = "\\nabla "
latexOfEntity Infinite = "\\infty "
latexOfEntity Ellipsis = "\\cdots"
stringOfUnOp :: UnOperator -> String
stringOfUnOp OpSin = "\\sin "
stringOfUnOp OpSinh = "\\sinh "
stringOfUnOp OpASin = "\\arcsin "
stringOfUnOp OpASinh = "\\arcsinh "
stringOfUnOp OpCos = "\\cos "
stringOfUnOp OpCosh = "\\cosh "
stringOfUnOp OpACos = "\\arccos "
stringOfUnOp OpACosh = "\\arccosh "
stringOfUnOp OpTan = "\\tan "
stringOfUnOp OpTanh = "\\tanh "
stringOfUnOp OpATan = "\\arctan "
stringOfUnOp OpATanh = "\\arctanh "
stringOfUnOp OpLn = "\\ln "
stringOfUnOp OpLog = "\\log "
stringOfUnOp op = error $ "stringOfUnop : unknown op " ++ show op
stringOfBinOp :: BinOperator -> String
stringOfBinOp OpAdd = "+"
stringOfBinOp OpSub = "-"
stringOfBinOp OpMul = "\\ast"
stringOfBinOp OpDiv = "\\div"
stringOfBinOp OpAnd = " \\and "
stringOfBinOp OpOr = " \\or "
stringOfBinOp OpEq = " = "
stringOfBinOp OpNe = " \\ne "
stringOfBinOp OpLt = " < "
stringOfBinOp OpGt = " > "
stringOfBinOp OpGe = " \\ge "
stringOfBinOp OpLe = " \\le "
stringOfBinOp OpAttrib = " := "
stringOfBinOp _ = error "stringOfBinOp - unknown op"
lno :: Conf -> FormulaPrim -> ShowS
lno conf = l conf (Nothing, False)
latexargs :: Conf -> [FormulaPrim] -> ShowS
latexargs _ [] = id
latexargs conf (x:xs) = foldr (\e acc -> lno conf e . str ", " . acc)
(lno conf x) xs
l :: Conf -> (Maybe BinOperator, Bool) -> FormulaPrim -> ShowS
l conf op (Poly _ p) = l conf op . unTagFormula . treeIfyFormula $ convertToFormula p
l conf op (Fraction f) = l conf op $ (CInteger $ numerator f) / (CInteger $ denominator f)
l conf op (Complex _ c) = l conf op $ complexTranslate c
l conf _ (List _ lst) = str "\\left[" . latexargs conf lst . str "\\right]"
l conf _ (Indexes _ main lst) = lno conf main . str "_{" . latexargs conf lst . char '}'
l _ _ (Block _ _ _) = str "block"
l _ _ (Variable v) = str v
l _ _ (NumEntity e) = str $ latexOfEntity e
l _ _ (Truth t) = shows t
l _ _ (CInteger i) = shows i
l _ _ (CFloat d) = shows d
l conf op (Meta _ _ f) = l conf op f
l _ _ (Lambda _ _clauses) = id
l conf (Just pop,right) (BinOp _ OpMul [a,b])
| mulAsDot conf = if needParenthesis right pop OpMul
then str "\\left( " . expr . str "\\right) "
else expr
where expr = l conf (Just OpMul, False) a
. str "\\cdot "
. l conf (Just OpMul, True) b
l conf (Nothing,_) (BinOp _ OpMul [a,b])
| mulAsDot conf =
l conf (Just OpMul, False) a . str "\\cdot " . l conf (Just OpMul, True) b
l conf _ (BinOp _ OpDiv [a,b]) = str "\\frac{" . lno conf a . str "}{" . lno conf b . char '}'
l conf _ (BinOp _ OpPow [a,b]) = char '{' . l conf (Just OpPow, False) a
. str "}^{" . l conf (Just OpPow, True) b . char '}'
l conf (Just pop,right) (BinOp _ op [a,b]) =
if needParenthesis right pop op
then str "\\left( " . expr . str "\\right) "
else expr
where expr = l conf (Just op, False) a
. str (stringOfBinOp op)
. l conf (Just op, True) b
l conf (Nothing,_) (BinOp _ op [a,b]) = lno conf a . str (stringOfBinOp op) . lno conf b
l _ _ (BinOp _ _ _) = error "latexification require treeified formula"
-- Unary operators
l conf _ (UnOp _ OpAbs f) = str "\\lvert " . lno conf f . str "\\rvert "
l conf _ (UnOp _ OpFloor f) = str "\\lfloor " . lno conf f . str "\\rfloor"
l conf _ (UnOp _ OpCeil f) = str "\\lceil " . lno conf f . str "\\rceil"
l conf _ (UnOp _ OpFrac f) = str "\\lbrace " . lno conf f . str "\\rbrace"
l conf _ (UnOp _ OpSqrt f) = str "\\sqrt{" . lno conf f . char '}'
l conf _ (UnOp _ OpExp f) = str "\\exp ^ {" . l conf (Just OpPow, True) f . str "} "
l conf _ (UnOp _ OpNegate f)
| f `hasProp` LeafNode = str " -" . lno conf f
| otherwise = str "-\\left( " . lno conf f . str "\\right)"
l conf _ (UnOp _ OpFactorial f)
| f `hasProp` LeafNode = lno conf f . str "!"
| otherwise = str "\\left( " . lno conf f . str "\\right)!"
l conf _ (UnOp _ op f)
| f `hasProp` LeafNode = str (stringOfUnOp op) . lno conf f
| otherwise = str (stringOfUnOp op) . str "\\left(" . lno conf f . str "\\right)"
l conf _ (Sum _ begin end what) =
str "\\sum_{" . lno conf begin . str "}^{" . lno conf end . str "} " . lno conf what
l conf _ (Product _ begin end what) =
str "\\prod_{" . lno conf begin . str "}^{" . lno conf end . str "} " . lno conf what
l conf _ (Integrate _ begin end what var) =
str "\\int_{" . lno conf begin . str "}^{" . lno conf end
. str "} \\! " . lno conf what . str " \\, d" . lno conf var
l conf _ (Derivate _ f var) =
str "\\frac{d " . lno conf f . str "}{ d" . lno conf var . char '}'
l conf _ (App _ func args) =
lno conf func . str "\\left(" . latexargs conf args . str "\\right)"
where
l conf _ (Matrix _ _ _ lsts) = str "\\begin{bmatrix}\n"
. matrixCells
. str "\n\\end{bmatrix}"
where perLine = interspereseS (str " & ") . map (lno conf)
matrixCells = interspereseS (str "\\\\\n") $ map perLine lsts