{-# LANGUAGE GeneralizedNewtypeDeriving, ViewPatterns, GADTs, OverloadedStrings #-}
module Text.TeXMath.Writers.Typst (writeTypst) where
import Data.List (transpose)
import qualified Data.Map as M
import qualified Data.Text as T
import Text.TeXMath.Types
import qualified Text.TeXMath.Shared as S
import Typst.Symbols (typstSymbols)
import Data.Generics (everywhere, mkT)
import Data.Text (Text)
import Data.Char (isDigit, isAlpha, isAscii)
import Data.Maybe (fromMaybe)
writeTypst :: DisplayType -> [Exp] -> Text
writeTypst :: DisplayType -> [Exp] -> Text
writeTypst DisplayType
dt [Exp]
exprs =
[Text] -> Text
T.unwords ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Exp -> Text) -> [Exp] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> Text
writeExp ([Exp] -> [Text]) -> [Exp] -> [Text]
forall a b. (a -> b) -> a -> b
$ (forall a. Data a => a -> a) -> forall a. Data a => a -> a
everywhere ((Exp -> Exp) -> a -> a
forall a b. (Typeable a, Typeable b) => (b -> b) -> a -> a
mkT ((Exp -> Exp) -> a -> a) -> (Exp -> Exp) -> a -> a
forall a b. (a -> b) -> a -> b
$ DisplayType -> Exp -> Exp
S.handleDownup DisplayType
dt) [Exp]
exprs
writeExps :: [Exp] -> Text
writeExps :: [Exp] -> Text
writeExps = Text -> [Text] -> Text
T.intercalate Text
" " ([Text] -> Text) -> ([Exp] -> [Text]) -> [Exp] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp -> Text) -> [Exp] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> Text
writeExp
inParens :: Text -> Text
inParens :: Text -> Text
inParens Text
s = Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
inQuotes :: Text -> Text
inQuotes :: Text -> Text
inQuotes Text
s = Text
"\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
escInQuotes Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""
esc :: Text -> Text
esc :: Text -> Text
esc Text
t =
if (Char -> Bool) -> Text -> Bool
T.any Char -> Bool
needsEscape Text
t
then (Char -> Text) -> Text -> Text
T.concatMap Char -> Text
escapeChar Text
t
else Text
t
where
escapeChar :: Char -> Text
escapeChar Char
c
| Char -> Bool
needsEscape Char
c = Text
"\\" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Char -> Text
T.singleton Char
c
| Bool
otherwise = Char -> Text
T.singleton Char
c
needsEscape :: Char -> Bool
needsEscape Char
'[' = Bool
True
needsEscape Char
']' = Bool
True
needsEscape Char
'|' = Bool
True
needsEscape Char
'#' = Bool
True
needsEscape Char
'$' = Bool
True
needsEscape Char
'(' = Bool
True
needsEscape Char
')' = Bool
True
needsEscape Char
'_' = Bool
True
needsEscape Char
'*' = Bool
True
needsEscape Char
'^' = Bool
True
needsEscape Char
'"' = Bool
True
needsEscape Char
'/' = Bool
True
needsEscape Char
'\\' = Bool
True
needsEscape Char
_ = Bool
False
escInQuotes :: Text -> Text
escInQuotes :: Text -> Text
escInQuotes Text
t =
if (Char -> Bool) -> Text -> Bool
T.any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"') Text
t
then (Char -> Text) -> Text -> Text
T.concatMap Char -> Text
escapeChar Text
t
else Text
t
where
escapeChar :: Char -> Text
escapeChar Char
c
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"' = Text
"\\" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Char -> Text
T.singleton Char
c
| Bool
otherwise = Char -> Text
T.singleton Char
c
writeExpS :: Exp -> Text
writeExpS :: Exp -> Text
writeExpS (EGrouped [Exp]
es) = Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Exp] -> Text
writeExps [Exp]
es Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExpS Exp
e =
case Exp -> Text
writeExp Exp
e of
Text
t | (Char -> Bool) -> Text -> Bool
T.all (\Char
c -> Char -> Bool
isDigit Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') Text
t -> Text
t
| (Char -> Bool) -> Text -> Bool
T.all (\Char
c -> Char -> Bool
isAlpha Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') Text
t -> Text
t
| Bool
otherwise -> Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExpB :: Exp -> Text
writeExpB :: Exp -> Text
writeExpB Exp
e =
case Exp -> Text
writeExp Exp
e of
Text
"" -> Text
"zws"
Text
t -> Text
t
writeExp :: Exp -> Text
writeExp :: Exp -> Text
writeExp (ENumber Text
s) = Text
s
writeExp (ESymbol TeXSymbolType
_t Text
s)
| (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isAscii Text
s = Text -> Text
esc Text
s
| Text
s Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"\x2212" = Text
"-"
| Bool
otherwise = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (Text -> Text
esc Text
s) (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Map Text Text -> Maybe Text
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Text
s Map Text Text
typstSymbolMap
writeExp (EIdentifier Text
s) =
if Text -> Int
T.length Text
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
then Exp -> Text
writeExp (TeXSymbolType -> Text -> Exp
ESymbol TeXSymbolType
Ord Text
s)
else Text -> Text
inQuotes Text
s
writeExp (EMathOperator Text
s)
| Text
s Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"arccos", Text
"arcsin", Text
"arctan", Text
"arg", Text
"cos", Text
"cosh",
Text
"cot", Text
"ctg", Text
"coth", Text
"csc", Text
"deg", Text
"det", Text
"dim", Text
"exp",
Text
"gcd", Text
"hom", Text
"mod", Text
"inf", Text
"ker", Text
"lg", Text
"lim", Text
"ln",
Text
"log", Text
"max", Text
"min", Text
"Pr", Text
"sec", Text
"sin", Text
"sinh", Text
"sup",
Text
"tan", Text
"tg", Text
"tanh", Text
"liminf", Text
"and", Text
"limsup"]
= Text
s
| Bool
otherwise = Text
"\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""
writeExp (EGrouped [Exp]
es) = [Exp] -> Text
writeExps [Exp]
es
writeExp (EFraction FractionType
_fractype Exp
e1 Exp
e2) =
case (Exp
e1, Exp
e2) of
(EGrouped [Exp]
_, Exp
_) -> Text
"frac(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e2 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
(Exp
_, EGrouped [Exp]
_) -> Text
"frac(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e2 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
(Exp, Exp)
_ -> Exp -> Text
writeExp Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" / " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e2
writeExp (ESub Exp
b Exp
e1) = Exp -> Text
writeExpB Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e1
writeExp (ESuper Exp
b Exp
e1) = Exp -> Text
writeExpB Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e1
writeExp (ESubsup Exp
b Exp
e1 Exp
e2) = Exp -> Text
writeExpB Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e2
writeExp (EOver Bool
_ (EOver Bool
_ Exp
b (ESymbol TeXSymbolType
TOver Text
"\9182")) Exp
e1) =
Text
"overbrace(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EOver Bool
_ (EOver Bool
_ Exp
b (ESymbol TeXSymbolType
TOver Text
"\9140")) Exp
e1) =
Text
"overbracket(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EOver Bool
_convertible Exp
b Exp
e1) =
case Exp
e1 of
ESymbol TeXSymbolType
Accent Text
"`" -> Text
"grave" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\768" -> Text
"grave" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\xb4" -> Text
"acute" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"^" -> Text
"hat" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\770" -> Text
"hat" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"~" -> Text
"tilde" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\771" -> Text
"tilde" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\xaf" -> Text
"macron" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\x2d8" -> Text
"breve" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"." -> Text
"dot" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\775" -> Text
"dot" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\xa8" -> Text
"diaer" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\x2218" -> Text
"circle" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\x2dd" -> Text
"acute.double" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\x2c7" -> Text
"caron" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\x2192" -> Text
"->" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\x2190" -> Text
"<-" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
Accent Text
"\8407" -> Text
"arrow" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Exp -> Text
writeExp Exp
b)
ESymbol TeXSymbolType
TOver Text
"\9182" -> Text
"overbrace(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
ESymbol TeXSymbolType
TOver Text
"\9140" -> Text
"overbracket(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
ESymbol TeXSymbolType
TOver Text
"\175" -> Text
"overline(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
Exp
_ -> Exp -> Text
writeExpB Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e1
writeExp (EUnder Bool
_ (EUnder Bool
_ Exp
b (ESymbol TeXSymbolType
TUnder Text
"\9183")) Exp
e1) =
Text
"underbrace(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EUnder Bool
_ (EUnder Bool
_ Exp
b (ESymbol TeXSymbolType
TUnder Text
"\9140")) Exp
e1) =
Text
"underbrace(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EUnder Bool
_convertible Exp
b Exp
e1) =
case Exp
e1 of
ESymbol TeXSymbolType
TUnder Text
"_" -> Text
"underline(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
ESymbol TeXSymbolType
TUnder Text
"\9183" -> Text
"underbrace(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
ESymbol TeXSymbolType
TUnder Text
"\9140" -> Text
"underbracket(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
Exp
_ -> Exp -> Text
writeExpB Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e1
writeExp (EUnderover Bool
convertible Exp
b Exp
e1 Exp
e2) =
case (Exp
e1, Exp
e2) of
(Exp
_, ESymbol TeXSymbolType
Accent Text
_) -> Exp -> Text
writeExp (Bool -> Exp -> Exp -> Exp
EUnder Bool
convertible (Bool -> Exp -> Exp -> Exp
EOver Bool
False Exp
b Exp
e2) Exp
e1)
(Exp
_, ESymbol TeXSymbolType
TOver Text
_) -> Exp -> Text
writeExp (Bool -> Exp -> Exp -> Exp
EUnder Bool
convertible (Bool -> Exp -> Exp -> Exp
EOver Bool
False Exp
b Exp
e2) Exp
e1)
(ESymbol TeXSymbolType
TUnder Text
_, Exp
_) -> Exp -> Text
writeExp (Bool -> Exp -> Exp -> Exp
EOver Bool
convertible (Bool -> Exp -> Exp -> Exp
EUnder Bool
False Exp
b Exp
e1) Exp
e2)
(Exp, Exp)
_ -> Exp -> Text
writeExpB Exp
b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExpS Exp
e2
writeExp (ESqrt Exp
e) = Text
"sqrt(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (ERoot Exp
i Exp
e) = Text
"root(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (ESpace Rational
width) =
case (Rational -> Int
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Rational
width Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
18) :: Int) of
Int
0 -> Text
"zws"
Int
3 -> Text
"thin"
Int
4 -> Text
"med"
Int
6 -> Text
"thick"
Int
18 -> Text
"quad"
Int
n -> Text
"#h(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow (Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
18) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"em)"
writeExp (EText TextType
ttype Text
s) =
case TextType
ttype of
TextType
TextNormal -> Text
"upright" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextItalic -> Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextBold -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextBoldItalic -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s))
TextType
TextMonospace -> Text
"mono" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextSansSerif -> Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextDoubleStruck -> Text
"bb" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextScript -> Text
"cal" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextFraktur -> Text
"frak" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)
TextType
TextSansSerifBold -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s))
TextType
TextSansSerifBoldItalic -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text -> Text
inParens (Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s)))
TextType
TextBoldScript -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"cal" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s))
TextType
TextBoldFraktur -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"frak" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s))
TextType
TextSansSerifItalic -> Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text -> Text
inParens (Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text -> Text
inQuotes Text
s))
writeExp (EStyled TextType
ttype [Exp]
es) =
let contents :: Text
contents = [Exp] -> Text
writeExps [Exp]
es
in case TextType
ttype of
TextType
TextNormal -> Text
"upright" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextItalic -> Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextBold -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextBoldItalic -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents)
TextType
TextMonospace -> Text
"mono" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextSansSerif -> Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextDoubleStruck -> Text
"bb" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextScript -> Text
"cal" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextFraktur -> Text
"frak" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents
TextType
TextSansSerifBold -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents)
TextType
TextSansSerifBoldItalic -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text -> Text
inParens (Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents))
TextType
TextBoldScript -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"cal" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents)
TextType
TextBoldFraktur -> Text
"bold" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"frak" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents)
TextType
TextSansSerifItalic -> Text
"italic" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
"sans" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens Text
contents)
writeExp (EBoxed Exp
e) = Text
"#box(stroke: black, inset: 3pt, [$ " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" $])"
writeExp (EPhantom Exp
e) = Text
"#hide[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]"
writeExp (EScaled Rational
size Exp
e) =
Text
"#scale(x: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow (Rational -> Int
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Rational
100 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
size) :: Int) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text
"%, y: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow (Rational -> Int
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Rational
100 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
size) :: Int) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
Text
"%)[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
e Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]"
writeExp (EDelimited Text
"(" Text
")" [ Right (EFraction FractionType
NoLineFrac Exp
x Exp
y) ]) =
Text
"binom(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text
writeExp Exp
y Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"(" Text
")" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)])
| (ArrayLine -> Bool) -> [ArrayLine] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\ArrayLine
row -> ArrayLine -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ArrayLine
row Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1) [ArrayLine]
rows =
Text
"vec(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray ([ArrayLine] -> [ArrayLine]
forall a. [[a]] -> [[a]]
transpose [ArrayLine]
rows) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"(" Text
")" [Right (EArray [Alignment]
_aligns [[[Exp]
xs],[[Exp]
ys]])]) =
Text
"binom(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Exp] -> Text
writeExps [Exp]
xs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Exp] -> Text
writeExps [Exp]
ys Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"(" Text
")" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)]) =
Text
"mat(delim: \"(\", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray [ArrayLine]
rows Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"[" Text
"]" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)]) =
Text
"mat(delim: \"[\", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray [ArrayLine]
rows Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"{" Text
"}" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)]) =
Text
"mat(delim: \"{\", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray [ArrayLine]
rows Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"|" Text
"|" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)]) =
Text
"mat(delim: \"|\", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray [ArrayLine]
rows Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"||" Text
"||" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)]) =
Text
"mat(delim: \"||\", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray [ArrayLine]
rows Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"\x2223" Text
"\x2223" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)]) =
Text
"mat(delim: \"||\", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray [ArrayLine]
rows Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
"\x2225" Text
"\x2225" [Right (EArray [Alignment]
_aligns [ArrayLine]
rows)]) =
Text
"mat(delim: \"||\", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [ArrayLine] -> Text
mkArray [ArrayLine]
rows Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
writeExp (EDelimited Text
op Text
"" [Right (EArray [Alignment
AlignLeft, Alignment
AlignLeft] [ArrayLine]
rows)]) =
Text
"cases" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens(Text
"delim: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inQuotes Text
op Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat ((ArrayLine -> Text) -> [ArrayLine] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ArrayLine -> Text
toCase [ArrayLine]
rows))
where toCase :: ArrayLine -> Text
toCase = (Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> (ArrayLine -> Text) -> ArrayLine -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate Text
" & " ([Text] -> Text) -> (ArrayLine -> [Text]) -> ArrayLine -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Exp] -> Text) -> ArrayLine -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map [Exp] -> Text
writeExps
writeExp (EDelimited Text
open Text
close [Either Text Exp]
es) =
if Text -> Bool
forall {a}. (Eq a, IsString a) => a -> Bool
isDelim Text
open Bool -> Bool -> Bool
&& Text -> Bool
forall {a}. (Eq a, IsString a) => a -> Bool
isDelim Text
close
then
if Text -> Text -> Bool
forall {a} {a}.
(Eq a, Eq a, IsString a, IsString a) =>
a -> a -> Bool
matchedPair Text
open Text
close Bool -> Bool -> Bool
&&
Bool -> Bool
not ((Either Text Exp -> Bool) -> [Either Text Exp] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\Either Text Exp
x -> Either Text Exp
x Either Text Exp -> Either Text Exp -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Either Text Exp
forall a b. a -> Either a b
Left Text
open Bool -> Bool -> Bool
|| Either Text Exp
x Either Text Exp -> Either Text Exp -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Either Text Exp
forall a b. a -> Either a b
Left Text
close) [Either Text Exp]
es)
then Text
open Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
body Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
close
else Text
"lr" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inParens (Text
open Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
body Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
close)
else Text -> Text
esc Text
open Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
body Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
esc Text
close
where fromDelimited :: Either Text Exp -> Text
fromDelimited (Left Text
e) = Text
e
fromDelimited (Right Exp
e) = Exp -> Text
writeExp Exp
e
isDelim :: a -> Bool
isDelim a
c = a
c a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a
"(",a
")",a
"[",a
"]",a
"{",a
"}",a
"|",a
"||"]
matchedPair :: a -> a -> Bool
matchedPair a
"(" a
")" = Bool
True
matchedPair a
"[" a
"]" = Bool
True
matchedPair a
"{" a
"}" = Bool
True
matchedPair a
_ a
_ = Bool
False
body :: Text
body = [Text] -> Text
T.unwords ((Either Text Exp -> Text) -> [Either Text Exp] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Either Text Exp -> Text
fromDelimited [Either Text Exp]
es)
writeExp (EArray [Alignment]
_aligns [ArrayLine]
rows)
= Text -> [Text] -> Text
T.intercalate Text
"\\\n" ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (ArrayLine -> Text) -> [ArrayLine] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ArrayLine -> Text
mkRow [ArrayLine]
rows
where mkRow :: ArrayLine -> Text
mkRow = Text -> [Text] -> Text
T.intercalate Text
" & " ([Text] -> Text) -> (ArrayLine -> [Text]) -> ArrayLine -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Exp] -> Text) -> ArrayLine -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map [Exp] -> Text
writeExps
mkArray :: [[[Exp]]] -> Text
mkArray :: [ArrayLine] -> Text
mkArray [ArrayLine]
rows =
Text -> [Text] -> Text
T.intercalate Text
"; " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (ArrayLine -> Text) -> [ArrayLine] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ArrayLine -> Text
mkRow [ArrayLine]
rows
where
mkRow :: ArrayLine -> Text
mkRow = Text -> [Text] -> Text
T.intercalate Text
", " ([Text] -> Text) -> (ArrayLine -> [Text]) -> ArrayLine -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> [Text]
forall {a}. (Eq a, IsString a) => [a] -> [a]
mkCells ([Text] -> [Text]) -> (ArrayLine -> [Text]) -> ArrayLine -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Exp] -> Text) -> ArrayLine -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map [Exp] -> Text
mkCell
mkCells :: [a] -> [a]
mkCells [a]
cs =
case [a]
cs of
(a
"":[a]
rest) -> a
"#none" a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
rest
[a]
_ -> [a]
cs
mkCell :: [Exp] -> Text
mkCell = [Exp] -> Text
writeExps
tshow :: Show a => a -> Text
tshow :: forall a. Show a => a -> Text
tshow = String -> Text
T.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
typstSymbolMap :: M.Map Text Text
typstSymbolMap :: Map Text Text
typstSymbolMap = [(Text, Text)] -> Map Text Text
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Text, Text)] -> Map Text Text)
-> [(Text, Text)] -> Map Text Text
forall a b. (a -> b) -> a -> b
$
(Text
"\776", Text
"dot.double")
(Text, Text) -> [(Text, Text)] -> [(Text, Text)]
forall a. a -> [a] -> [a]
: [(Text
s,Text
name) | (Text
name, Bool
_, Text
s) <- [(Text, Bool, Text)]
typstSymbols]