{-# LANGUAGE OverloadedStrings #-}
module Text.TeXMath.Writers.StarMath
( writeStarMath
) where
import Data.Char (isLetter)
import Data.Generics (everywhere, mkT)
import qualified Data.List as List
import qualified Data.Text as T
import qualified Text.TeXMath.Shared as S
import Text.TeXMath.Unicode.ToUnicode (toUnicodeChar)
import Text.TeXMath.Types
( Alignment(..)
, DisplayType(..)
, Exp(..)
, FractionType(..)
, TeXSymbolType(..)
, TextType(..)
)
import Text.TeXMath.Writers.TeX (writeTeX)
writeStarMath :: DisplayType -> [Exp] -> T.Text
writeStarMath :: DisplayType -> [Exp] -> Text
writeStarMath DisplayType
dt [Exp]
exps =
case DisplayType -> [Exp] -> Maybe Text
renderExps DisplayType
dt ([Exp] -> [Exp]
normalizeExps ((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]
exps)) of
Just Text
rendered -> Text -> Text
T.strip Text
rendered
Maybe Text
Nothing -> [Exp] -> Text
writeTeX [Exp]
exps
data AlignContext = AlignDefault | AlignLeftCtx | AlignRightCtx
deriving (AlignContext -> AlignContext -> Bool
(AlignContext -> AlignContext -> Bool)
-> (AlignContext -> AlignContext -> Bool) -> Eq AlignContext
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AlignContext -> AlignContext -> Bool
== :: AlignContext -> AlignContext -> Bool
$c/= :: AlignContext -> AlignContext -> Bool
/= :: AlignContext -> AlignContext -> Bool
Eq)
renderExps :: DisplayType -> [Exp] -> Maybe T.Text
renderExps :: DisplayType -> [Exp] -> Maybe Text
renderExps DisplayType
dt = DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
AlignDefault
normalizeExps :: [Exp] -> [Exp]
normalizeExps :: [Exp] -> [Exp]
normalizeExps =
[Exp] -> [Exp]
normalizeBareBars
([Exp] -> [Exp]) -> ([Exp] -> [Exp]) -> [Exp] -> [Exp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Exp] -> [Exp]
normalizeEvaluationBars
([Exp] -> [Exp]) -> ([Exp] -> [Exp]) -> [Exp] -> [Exp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Exp] -> [Exp]
mergeAdjacentUnicodeSerifStyled
([Exp] -> [Exp]) -> ([Exp] -> [Exp]) -> [Exp] -> [Exp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Exp] -> [Exp]
normalizeBareBraces
([Exp] -> [Exp]) -> ([Exp] -> [Exp]) -> [Exp] -> [Exp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp -> Exp) -> [Exp] -> [Exp]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> Exp
normalizeExp
normalizeExp :: Exp -> Exp
normalizeExp :: Exp -> Exp
normalizeExp Exp
e =
case Exp
e of
EGrouped [Exp]
xs -> [Exp] -> Exp
EGrouped ([Exp] -> [Exp]
normalizeExps [Exp]
xs)
EStyled TextType
sty [Exp]
xs -> TextType -> [Exp] -> Exp
EStyled TextType
sty ([Exp] -> [Exp]
normalizeExps [Exp]
xs)
EFraction FractionType
ft Exp
num Exp
den -> FractionType -> Exp -> Exp -> Exp
EFraction FractionType
ft (Exp -> Exp
normalizeExp Exp
num) (Exp -> Exp
normalizeExp Exp
den)
ESqrt Exp
x -> Exp -> Exp
ESqrt (Exp -> Exp
normalizeExp Exp
x)
ERoot Exp
idx Exp
rad -> Exp -> Exp -> Exp
ERoot (Exp -> Exp
normalizeExp Exp
idx) (Exp -> Exp
normalizeExp Exp
rad)
EDelimited Text
op Text
cl [InEDelimited]
xs -> Text -> Text -> [InEDelimited] -> Exp
EDelimited Text
op Text
cl ((InEDelimited -> InEDelimited) -> [InEDelimited] -> [InEDelimited]
forall a b. (a -> b) -> [a] -> [b]
map InEDelimited -> InEDelimited
normalizeDelimitedPiece [InEDelimited]
xs)
ESub Exp
base Exp
sub -> Exp -> Exp -> Exp
ESub (Exp -> Exp
normalizeExp Exp
base) (Exp -> Exp
normalizeExp Exp
sub)
ESuper Exp
base Exp
sup -> Exp -> Exp -> Exp
ESuper (Exp -> Exp
normalizeExp Exp
base) (Exp -> Exp
normalizeExp Exp
sup)
ESubsup Exp
base Exp
sub Exp
sup -> Exp -> Exp -> Exp -> Exp
ESubsup (Exp -> Exp
normalizeExp Exp
base) (Exp -> Exp
normalizeExp Exp
sub) (Exp -> Exp
normalizeExp Exp
sup)
EOver Bool
b Exp
base Exp
over -> Bool -> Exp -> Exp -> Exp
EOver Bool
b (Exp -> Exp
normalizeExp Exp
base) (Exp -> Exp
normalizeExp Exp
over)
EUnder Bool
b Exp
base Exp
under -> Bool -> Exp -> Exp -> Exp
EUnder Bool
b (Exp -> Exp
normalizeExp Exp
base) (Exp -> Exp
normalizeExp Exp
under)
EUnderover Bool
b Exp
base Exp
u Exp
o -> Bool -> Exp -> Exp -> Exp -> Exp
EUnderover Bool
b (Exp -> Exp
normalizeExp Exp
base) (Exp -> Exp
normalizeExp Exp
u) (Exp -> Exp
normalizeExp Exp
o)
EArray [Alignment]
aligns [ArrayLine]
rows -> [Alignment] -> [ArrayLine] -> Exp
EArray [Alignment]
aligns ((ArrayLine -> ArrayLine) -> [ArrayLine] -> [ArrayLine]
forall a b. (a -> b) -> [a] -> [b]
map (([Exp] -> [Exp]) -> ArrayLine -> ArrayLine
forall a b. (a -> b) -> [a] -> [b]
map [Exp] -> [Exp]
normalizeExps) [ArrayLine]
rows)
EPhantom Exp
x -> Exp -> Exp
EPhantom (Exp -> Exp
normalizeExp Exp
x)
Exp
_ -> Exp
e
normalizeDelimitedPiece :: Either T.Text Exp -> Either T.Text Exp
normalizeDelimitedPiece :: InEDelimited -> InEDelimited
normalizeDelimitedPiece InEDelimited
p =
case InEDelimited
p of
Left Text
t -> Text -> InEDelimited
forall a b. a -> Either a b
Left Text
t
Right Exp
e -> Exp -> InEDelimited
forall a b. b -> Either a b
Right (Exp -> Exp
normalizeExp Exp
e)
normalizeBareBars :: [Exp] -> [Exp]
normalizeBareBars :: [Exp] -> [Exp]
normalizeBareBars [] = []
normalizeBareBars (Exp
x : [Exp]
xs)
| Just Text
sym <- Exp -> Maybe Text
bareBarSymbol Exp
x =
case Text -> [Exp] -> [Exp] -> Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
collectBareDelimited Text
sym [] [Exp]
xs of
Just ([Exp]
mid, Maybe (Exp -> Exp)
trailingScript, [Exp]
rest) ->
let delimited :: Exp
delimited = Text -> Text -> [InEDelimited] -> Exp
EDelimited Text
sym Text
sym ((Exp -> InEDelimited) -> [Exp] -> [InEDelimited]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> InEDelimited
forall a b. b -> Either a b
Right [Exp]
mid)
scripted :: Exp
scripted = Exp -> ((Exp -> Exp) -> Exp) -> Maybe (Exp -> Exp) -> Exp
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Exp
delimited ((Exp -> Exp) -> Exp -> Exp
forall a b. (a -> b) -> a -> b
$ Exp
delimited) Maybe (Exp -> Exp)
trailingScript
in Exp
scripted Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
normalizeBareBars [Exp]
rest
Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
_ ->
Exp
x Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
normalizeBareBars [Exp]
xs
normalizeBareBars (Exp
x:[Exp]
xs) = Exp
x Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
normalizeBareBars [Exp]
xs
normalizeBareBraces :: [Exp] -> [Exp]
normalizeBareBraces :: [Exp] -> [Exp]
normalizeBareBraces [] = []
normalizeBareBraces (ESymbol TeXSymbolType
Open Text
"{" : [Exp]
xs) =
case [Exp] -> [Exp] -> Maybe ([Exp], [Exp])
collectBareBraces [] [Exp]
xs of
Just ([Exp]
mid, [Exp]
rest) -> Text -> Text -> [InEDelimited] -> Exp
EDelimited Text
"{" Text
"}" ((Exp -> InEDelimited) -> [Exp] -> [InEDelimited]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> InEDelimited
forall a b. b -> Either a b
Right [Exp]
mid) Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
normalizeBareBraces [Exp]
rest
Maybe ([Exp], [Exp])
Nothing -> TeXSymbolType -> Text -> Exp
ESymbol TeXSymbolType
Open Text
"{" Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
normalizeBareBraces [Exp]
xs
normalizeBareBraces (Exp
x:[Exp]
xs) = Exp
x Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
normalizeBareBraces [Exp]
xs
mergeAdjacentUnicodeSerifStyled :: [Exp] -> [Exp]
mergeAdjacentUnicodeSerifStyled :: [Exp] -> [Exp]
mergeAdjacentUnicodeSerifStyled [] = []
mergeAdjacentUnicodeSerifStyled (EStyled TextType
sty [Exp]
xs : EStyled TextType
sty' [Exp]
ys : [Exp]
rest)
| TextType
sty TextType -> TextType -> Bool
forall a. Eq a => a -> a -> Bool
== TextType
sty' Bool -> Bool -> Bool
&& TextType -> Bool
isUnicodeSerifStyle TextType
sty =
[Exp] -> [Exp]
mergeAdjacentUnicodeSerifStyled (TextType -> [Exp] -> Exp
EStyled TextType
sty ([Exp]
xs [Exp] -> [Exp] -> [Exp]
forall a. Semigroup a => a -> a -> a
<> [Rational -> Exp
ESpace Rational
1] [Exp] -> [Exp] -> [Exp]
forall a. Semigroup a => a -> a -> a
<> [Exp]
ys) Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp]
rest)
mergeAdjacentUnicodeSerifStyled (Exp
x:[Exp]
xs) = Exp
x Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
mergeAdjacentUnicodeSerifStyled [Exp]
xs
isUnicodeSerifStyle :: TextType -> Bool
isUnicodeSerifStyle :: TextType -> Bool
isUnicodeSerifStyle TextType
sty =
TextType
sty TextType -> [TextType] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
[ TextType
TextScript
, TextType
TextFraktur
, TextType
TextDoubleStruck
, TextType
TextBoldScript
, TextType
TextBoldFraktur
]
normalizeEvaluationBars :: [Exp] -> [Exp]
normalizeEvaluationBars :: [Exp] -> [Exp]
normalizeEvaluationBars = [Exp] -> [Exp]
forall a. [a] -> [a]
reverse ([Exp] -> [Exp]) -> ([Exp] -> [Exp]) -> [Exp] -> [Exp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Exp] -> [Exp] -> [Exp]
go []
where
go :: [Exp] -> [Exp] -> [Exp]
go [Exp]
acc [] = [Exp]
acc
go [Exp]
acc (Exp
cur : [Exp]
xs)
| Just Exp -> Exp
script <- Exp -> Maybe (Exp -> Exp)
evaluationBarScript Exp
cur
, Just ([Exp]
rest, Exp
target) <- [Exp] -> Maybe ([Exp], Exp)
takeEvaluationTarget [Exp]
acc =
[Exp] -> [Exp] -> [Exp]
go (Exp -> Exp
script Exp
target Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp]
rest) [Exp]
xs
| Bool
otherwise =
[Exp] -> [Exp] -> [Exp]
go (Exp
cur Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp]
acc) [Exp]
xs
evaluationBarScript :: Exp -> Maybe (Exp -> Exp)
evaluationBarScript :: Exp -> Maybe (Exp -> Exp)
evaluationBarScript Exp
cur =
case Exp
cur of
ESub Exp
base Exp
sub
| Exp -> Bool
isEvaluationBarBase Exp
base ->
(Exp -> Exp) -> Maybe (Exp -> Exp)
forall a. a -> Maybe a
Just (\Exp
target -> Exp -> Exp -> Exp
ESub (Text -> Text -> [InEDelimited] -> Exp
EDelimited Text
"." Text
"|" [Exp -> InEDelimited
forall a b. b -> Either a b
Right Exp
target]) Exp
sub)
ESuper Exp
base Exp
sup
| Exp -> Bool
isEvaluationBarBase Exp
base ->
(Exp -> Exp) -> Maybe (Exp -> Exp)
forall a. a -> Maybe a
Just (\Exp
target -> Exp -> Exp -> Exp
ESuper (Text -> Text -> [InEDelimited] -> Exp
EDelimited Text
"." Text
"|" [Exp -> InEDelimited
forall a b. b -> Either a b
Right Exp
target]) Exp
sup)
ESubsup Exp
base Exp
sub Exp
sup
| Exp -> Bool
isEvaluationBarBase Exp
base ->
(Exp -> Exp) -> Maybe (Exp -> Exp)
forall a. a -> Maybe a
Just (\Exp
target -> Exp -> Exp -> Exp -> Exp
ESubsup (Text -> Text -> [InEDelimited] -> Exp
EDelimited Text
"." Text
"|" [Exp -> InEDelimited
forall a b. b -> Either a b
Right Exp
target]) Exp
sub Exp
sup)
Exp
_ -> Maybe (Exp -> Exp)
forall a. Maybe a
Nothing
takeEvaluationTarget :: [Exp] -> Maybe ([Exp], Exp)
takeEvaluationTarget :: [Exp] -> Maybe ([Exp], Exp)
takeEvaluationTarget [] = Maybe ([Exp], Exp)
forall a. Maybe a
Nothing
takeEvaluationTarget (Exp
e : [Exp]
rest) =
case Exp
e of
EDelimited{} -> ([Exp], Exp) -> Maybe ([Exp], Exp)
forall a. a -> Maybe a
Just ([Exp]
rest, Exp
e)
ESymbol TeXSymbolType
Close Text
c
| Just ([Exp]
rest', Exp
target) <- Text -> [Exp] -> Maybe ([Exp], Exp)
takeDelimitedTarget Text
c [Exp]
rest ->
([Exp], Exp) -> Maybe ([Exp], Exp)
forall a. a -> Maybe a
Just ([Exp]
rest', Exp
target)
Exp
_ -> ([Exp], Exp) -> Maybe ([Exp], Exp)
forall a. a -> Maybe a
Just ([Exp]
rest, Exp
e)
takeDelimitedTarget :: T.Text -> [Exp] -> Maybe ([Exp], Exp)
takeDelimitedTarget :: Text -> [Exp] -> Maybe ([Exp], Exp)
takeDelimitedTarget Text
closeTxt = Integer -> [Exp] -> [Exp] -> Maybe ([Exp], Exp)
forall {a}.
(Num a, Eq a) =>
a -> [Exp] -> [Exp] -> Maybe ([Exp], Exp)
go Integer
0 []
where
openTxt :: Maybe Text
openTxt =
case Text
closeTxt of
Text
")" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"("
Text
"]" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"["
Text
"}" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"{"
Text
_ -> Maybe Text
forall a. Maybe a
Nothing
go :: a -> [Exp] -> [Exp] -> Maybe ([Exp], Exp)
go a
_ [Exp]
_ [] = Maybe ([Exp], Exp)
forall a. Maybe a
Nothing
go a
depth [Exp]
inner (Exp
e : [Exp]
rest) =
case (Maybe Text
openTxt, Exp
e) of
(Just Text
open, ESymbol TeXSymbolType
Close Text
c)
| Text
c Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
closeTxt ->
a -> [Exp] -> [Exp] -> Maybe ([Exp], Exp)
go (a
depth a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) (Exp
e Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp]
inner) [Exp]
rest
(Just Text
open, ESymbol TeXSymbolType
Open Text
o)
| Text
o Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
open ->
if a
depth a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0
then ([Exp], Exp) -> Maybe ([Exp], Exp)
forall a. a -> Maybe a
Just ([Exp]
rest, Text -> Text -> [InEDelimited] -> Exp
EDelimited Text
open Text
closeTxt ((Exp -> InEDelimited) -> [Exp] -> [InEDelimited]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> InEDelimited
forall a b. b -> Either a b
Right [Exp]
inner))
else a -> [Exp] -> [Exp] -> Maybe ([Exp], Exp)
go (a
depth a -> a -> a
forall a. Num a => a -> a -> a
- a
1) (Exp
e Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp]
inner) [Exp]
rest
(Maybe Text, Exp)
_ ->
a -> [Exp] -> [Exp] -> Maybe ([Exp], Exp)
go a
depth (Exp
e Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp]
inner) [Exp]
rest
isEvaluationBarBase :: Exp -> Bool
isEvaluationBarBase :: Exp -> Bool
isEvaluationBarBase Exp
e =
case Exp
e of
EScaled Rational
_ (ESymbol TeXSymbolType
Open Text
"|") -> Bool
True
EScaled Rational
_ (ESymbol TeXSymbolType
Close Text
"|") -> Bool
True
Exp
_ -> Bool
False
collectBareBraces :: [Exp] -> [Exp] -> Maybe ([Exp], [Exp])
collectBareBraces :: [Exp] -> [Exp] -> Maybe ([Exp], [Exp])
collectBareBraces [Exp]
_ [] = Maybe ([Exp], [Exp])
forall a. Maybe a
Nothing
collectBareBraces [Exp]
acc (ESymbol TeXSymbolType
Close Text
"}" : [Exp]
xs) = ([Exp], [Exp]) -> Maybe ([Exp], [Exp])
forall a. a -> Maybe a
Just ([Exp] -> [Exp]
forall a. [a] -> [a]
reverse [Exp]
acc, [Exp]
xs)
collectBareBraces [Exp]
acc (Exp
x:[Exp]
xs) = [Exp] -> [Exp] -> Maybe ([Exp], [Exp])
collectBareBraces (Exp
xExp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
:[Exp]
acc) [Exp]
xs
collectBareDelimited :: T.Text -> [Exp] -> [Exp]
-> Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
collectBareDelimited :: Text -> [Exp] -> [Exp] -> Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
collectBareDelimited Text
_ [Exp]
acc [] = Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
forall a. Maybe a
Nothing
collectBareDelimited Text
sym [Exp]
acc (Exp
y:[Exp]
ys)
| Text -> Exp -> Bool
matchesBareBar Text
sym Exp
y = ([Exp], Maybe (Exp -> Exp), [Exp])
-> Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
forall a. a -> Maybe a
Just ([Exp] -> [Exp]
forall a. [a] -> [a]
reverse [Exp]
acc, Maybe (Exp -> Exp)
forall a. Maybe a
Nothing, [Exp]
ys)
| Just Exp -> Exp
apply <- Text -> Exp -> Maybe (Exp -> Exp)
scriptedBareBar Text
sym Exp
y = ([Exp], Maybe (Exp -> Exp), [Exp])
-> Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
forall a. a -> Maybe a
Just ([Exp] -> [Exp]
forall a. [a] -> [a]
reverse [Exp]
acc, (Exp -> Exp) -> Maybe (Exp -> Exp)
forall a. a -> Maybe a
Just Exp -> Exp
apply, [Exp]
ys)
| Bool
otherwise = Text -> [Exp] -> [Exp] -> Maybe ([Exp], Maybe (Exp -> Exp), [Exp])
collectBareDelimited Text
sym (Exp
yExp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
:[Exp]
acc) [Exp]
ys
bareBarSymbol :: Exp -> Maybe T.Text
bareBarSymbol :: Exp -> Maybe Text
bareBarSymbol Exp
e =
case Exp
e of
ESymbol TeXSymbolType
_ Text
"|" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"|"
ESymbol TeXSymbolType
_ Text
"∣" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"|"
ESymbol TeXSymbolType
_ Text
"∥" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"∥"
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
matchesBareBar :: T.Text -> Exp -> Bool
matchesBareBar :: Text -> Exp -> Bool
matchesBareBar Text
sym Exp
e =
case Exp -> Maybe Text
bareBarSymbol Exp
e of
Just Text
sym' -> Text
sym Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
sym'
Maybe Text
Nothing -> Bool
False
scriptedBareBar :: T.Text -> Exp -> Maybe (Exp -> Exp)
scriptedBareBar :: Text -> Exp -> Maybe (Exp -> Exp)
scriptedBareBar Text
sym Exp
e =
case Exp
e of
ESub Exp
base Exp
sub
| Text -> Exp -> Bool
matchesBareBar Text
sym Exp
base -> (Exp -> Exp) -> Maybe (Exp -> Exp)
forall a. a -> Maybe a
Just (\Exp
del -> Exp -> Exp -> Exp
ESub Exp
del Exp
sub)
ESuper Exp
base Exp
sup
| Text -> Exp -> Bool
matchesBareBar Text
sym Exp
base -> (Exp -> Exp) -> Maybe (Exp -> Exp)
forall a. a -> Maybe a
Just (\Exp
del -> Exp -> Exp -> Exp
ESuper Exp
del Exp
sup)
ESubsup Exp
base Exp
sub Exp
sup
| Text -> Exp -> Bool
matchesBareBar Text
sym Exp
base -> (Exp -> Exp) -> Maybe (Exp -> Exp)
forall a. a -> Maybe a
Just (\Exp
del -> Exp -> Exp -> Exp -> Exp
ESubsup Exp
del Exp
sub Exp
sup)
Exp
_ -> Maybe (Exp -> Exp)
forall a. Maybe a
Nothing
renderExpsIn :: DisplayType -> AlignContext -> [Exp] -> Maybe T.Text
renderExpsIn :: DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
ctx [Exp]
exps = do
[Text]
rendered <- (Exp -> Maybe Text) -> [Exp] -> Maybe [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx) [Exp]
exps
let pieces :: [(Exp, Text)]
pieces = [Exp] -> [Text] -> [(Exp, Text)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Exp]
exps [Text]
rendered
let merged :: Text
merged = [(Exp, Text)] -> Text
mergePieces [(Exp, Text)]
pieces
let withLhs :: Text
withLhs =
if [Exp] -> Bool
startsWithInfixNeedingLhs [Exp]
exps
then Text
"{} " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
T.stripStart Text
merged
else Text
merged
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ if [Exp] -> Bool
endsWithInfixNeedingRhs [Exp]
exps
then Text -> Text
T.stripEnd Text
withLhs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" {}"
else Text
withLhs
mergePieces :: [(Exp, T.Text)] -> T.Text
mergePieces :: [(Exp, Text)] -> Text
mergePieces [] = Text
""
mergePieces ((Exp
e0, Text
t0) : [(Exp, Text)]
rest) = (Exp, Text) -> Text
forall a b. (a, b) -> b
snd ((Exp, Text) -> Text) -> (Exp, Text) -> Text
forall a b. (a -> b) -> a -> b
$ ((Exp, Text) -> (Exp, Text) -> (Exp, Text))
-> (Exp, Text) -> [(Exp, Text)] -> (Exp, Text)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (Exp, Text) -> (Exp, Text) -> (Exp, Text)
step (Exp
e0, Text
t0) [(Exp, Text)]
rest
where
step :: (Exp, Text) -> (Exp, Text) -> (Exp, Text)
step (Exp
prevE, Text
acc) (Exp
curE, Text
curT) =
if Text -> Bool
T.null Text
curT
then (Exp
prevE, Text
acc)
else
(Exp
curE, Bool -> Text -> Text -> Text
appendRendered (Exp -> Exp -> Bool
needsSeparator Exp
prevE Exp
curE) Text
acc Text
curT)
appendRendered :: Bool -> T.Text -> T.Text -> T.Text
appendRendered :: Bool -> Text -> Text -> Text
appendRendered Bool
needSep Text
left Text
right
| Text -> Bool
T.null Text
left = Text -> Text
T.stripStart Text
right
| Text -> Bool
T.null Text
right = Text -> Text
T.stripEnd Text
left
| Bool
otherwise =
let leftHadWs :: Bool
leftHadWs = Text -> Bool
endsWithAsciiSpace Text
left
rightHadWs :: Bool
rightHadWs = Text -> Bool
startsWithAsciiSpace Text
right
left' :: Text
left' = (Char -> Bool) -> Text -> Text
T.dropWhileEnd Char -> Bool
isAsciiSpaceChar Text
left
right' :: Text
right' = (Char -> Bool) -> Text -> Text
T.dropWhile Char -> Bool
isAsciiSpaceChar Text
right
sep :: Text
sep = if Bool
leftHadWs Bool -> Bool -> Bool
|| Bool
rightHadWs Bool -> Bool -> Bool
|| Bool
needSep then Text
" " else Text
""
in Text
left' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sep Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
right'
startsWithAsciiSpace :: T.Text -> Bool
startsWithAsciiSpace :: Text -> Bool
startsWithAsciiSpace Text
t =
case Text -> Maybe (Char, Text)
T.uncons Text
t of
Just (Char
c, Text
_) -> Char -> Bool
isAsciiSpaceChar Char
c
Maybe (Char, Text)
Nothing -> Bool
False
endsWithAsciiSpace :: T.Text -> Bool
endsWithAsciiSpace :: Text -> Bool
endsWithAsciiSpace Text
t =
case Text -> Maybe (Text, Char)
T.unsnoc Text
t of
Just (Text
_, Char
c) -> Char -> Bool
isAsciiSpaceChar Char
c
Maybe (Text, Char)
Nothing -> Bool
False
isAsciiSpaceChar :: Char -> Bool
isAsciiSpaceChar :: Char -> Bool
isAsciiSpaceChar Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n'
needsSeparator :: Exp -> Exp -> Bool
needsSeparator :: Exp -> Exp -> Bool
needsSeparator Exp
prevE Exp
curE
| Exp -> Bool
isGreekIdentifierExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isGreekIdentifierExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isRootLike Exp
curE = Bool
True
| Exp -> Bool
isGreekIdentifierExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isTerminatingPunctuation Exp
curE = Bool
True
| Exp -> Bool
isWordSymbolLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isWordSymbolLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isOpenLike Exp
curE = Bool
True
| Exp -> Bool
isWordStyledExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isAccentCommandExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isAccentCommandExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isOpenLike Exp
curE = Bool
True
| Exp -> Bool
isAccentCommandExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isRootLike Exp
curE = Bool
True
| Exp -> Bool
isMathOperatorExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isUnaryMinusSymbol Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isMathOperatorExp Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isRootLike Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isArrowScriptedExp Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isScriptedMathOperatorExp Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isWordSymbolLike Exp
curE = Bool
True
| Exp -> Bool
isLargeOpScriptedExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isLargeOpScriptedExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isFractionLike Exp
curE = Bool
True
| Exp -> Bool
isLargeOpScriptedExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isAccentCommandExp Exp
curE = Bool
True
| Exp -> Bool
isScripted Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isArrowScriptedExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isScriptedMathOperatorExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isDelimited Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isDelimited Exp
curE = Bool
True
| Exp -> Bool
isCloseLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isIdentifierLike Exp
curE = Bool
True
| Exp -> Bool
isCloseLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isWordSymbolLike Exp
curE = Bool
True
| Exp -> Bool
isCloseLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isAccentCommandExp Exp
curE = Bool
True
| Exp -> Bool
isCloseLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isArrayLike Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isWordStyledExp Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isUprightMathTextExp Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isAccentCommandExp Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isWideSpace Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isDelimited Exp
curE = Bool
True
| Exp -> Bool
isIdentifierLike Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isNonNormalTextExp Exp
curE = Bool
True
| Exp -> Bool
isQuotedTextExp Exp
prevE Bool -> Bool -> Bool
&& Exp -> Bool
isItalicTextExp Exp
curE = Bool
True
| Bool
otherwise = Bool
False
isGreekIdentifierExp :: Exp -> Bool
isGreekIdentifierExp :: Exp -> Bool
isGreekIdentifierExp Exp
e =
case Exp
e of
EIdentifier Text
t -> Text -> Maybe Text
greekName Text
t Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
Exp
_ -> Bool
False
isIdentifierLike :: Exp -> Bool
isIdentifierLike :: Exp -> Bool
isIdentifierLike Exp
e =
case Exp
e of
EIdentifier{} -> Bool
True
ENumber{} -> Bool
True
EMathOperator{} -> Bool
True
ESub{} -> Bool
True
ESuper{} -> Bool
True
ESubsup{} -> Bool
True
EStyled{} -> Bool
True
Exp
_ -> Bool
False
isMathOperatorExp :: Exp -> Bool
isMathOperatorExp :: Exp -> Bool
isMathOperatorExp Exp
e =
case Exp
e of
EMathOperator{} -> Bool
True
Exp
_ -> Bool
False
isDelimited :: Exp -> Bool
isDelimited :: Exp -> Bool
isDelimited Exp
e =
case Exp
e of
EDelimited{} -> Bool
True
Exp
_ -> Bool
False
isArrayLike :: Exp -> Bool
isArrayLike :: Exp -> Bool
isArrayLike Exp
e =
case Exp
e of
EArray{} -> Bool
True
Exp
_ -> Bool
False
isFractionLike :: Exp -> Bool
isFractionLike :: Exp -> Bool
isFractionLike Exp
e =
case Exp
e of
EFraction{} -> Bool
True
Exp
_ -> Bool
False
isWideSpace :: Exp -> Bool
isWideSpace :: Exp -> Bool
isWideSpace Exp
e =
case Exp
e of
ESpace Rational
w -> Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= Rational
1
Exp
_ -> Bool
False
isWordSymbolLike :: Exp -> Bool
isWordSymbolLike :: Exp -> Bool
isWordSymbolLike Exp
e =
case Exp
e of
ESymbol TeXSymbolType
_ Text
"∀" -> Bool
True
ESymbol TeXSymbolType
_ Text
"∃" -> Bool
True
ESymbol TeXSymbolType
_ Text
"∇" -> Bool
True
ESymbol TeXSymbolType
_ Text
"∂" -> Bool
True
ESymbol TeXSymbolType
_ Text
"¬" -> Bool
True
ESymbol TeXSymbolType
_ Text
"∧" -> Bool
True
ESymbol TeXSymbolType
_ Text
"∨" -> Bool
True
ESymbol TeXSymbolType
_ Text
"and" -> Bool
True
ESymbol TeXSymbolType
_ Text
"or" -> Bool
True
Exp
_ -> Bool
False
isOpenLike :: Exp -> Bool
isOpenLike :: Exp -> Bool
isOpenLike Exp
e =
case Exp
e of
ESymbol TeXSymbolType
Open Text
_ -> Bool
True
Exp
_ -> Bool
False
isRootLike :: Exp -> Bool
isRootLike :: Exp -> Bool
isRootLike Exp
e =
case Exp
e of
ESqrt{} -> Bool
True
ERoot{} -> Bool
True
Exp
_ -> Bool
False
isWordStyledExp :: Exp -> Bool
isWordStyledExp :: Exp -> Bool
isWordStyledExp Exp
e =
case Exp
e of
EStyled TextType
TextNormal [Exp
x] -> Exp -> Bool
isWordStyledExp Exp
x
EStyled TextType
TextItalic [Exp]
_ -> Bool
True
EStyled TextType
TextBold [Exp]
_ -> Bool
True
EStyled TextType
TextScript [Exp]
_ -> Bool
True
EStyled TextType
TextFraktur [Exp]
_ -> Bool
True
EStyled TextType
TextDoubleStruck [Exp]
_ -> Bool
True
Exp
_ -> Bool
False
isUprightMathTextExp :: Exp -> Bool
isUprightMathTextExp :: Exp -> Bool
isUprightMathTextExp Exp
e =
case Exp
e of
EStyled TextType
TextNormal [EIdentifier Text
_] -> Bool
True
Exp
_ -> Bool
False
isItalicTextExp :: Exp -> Bool
isItalicTextExp :: Exp -> Bool
isItalicTextExp Exp
e =
case Exp
e of
EText TextType
TextItalic Text
_ -> Bool
True
Exp
_ -> Bool
False
isQuotedTextExp :: Exp -> Bool
isQuotedTextExp :: Exp -> Bool
isQuotedTextExp Exp
e =
case Exp
e of
EText TextType
TextNormal Text
_ -> Bool
True
Exp
_ -> Bool
False
isNonNormalTextExp :: Exp -> Bool
isNonNormalTextExp :: Exp -> Bool
isNonNormalTextExp Exp
e =
case Exp
e of
EText TextType
sty Text
_ -> TextType
sty TextType -> TextType -> Bool
forall a. Eq a => a -> a -> Bool
/= TextType
TextNormal
Exp
_ -> Bool
False
isAccentCommandExp :: Exp -> Bool
isAccentCommandExp :: Exp -> Bool
isAccentCommandExp Exp
e =
case Exp
e of
EOver Bool
_ Exp
_ Exp
over -> Exp -> Maybe Text
accentName Exp
over Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
Exp
_ -> Bool
False
isTerminatingPunctuation :: Exp -> Bool
isTerminatingPunctuation :: Exp -> Bool
isTerminatingPunctuation Exp
e =
case Exp
e of
ESymbol TeXSymbolType
_ Text
"." -> Bool
True
ESymbol TeXSymbolType
_ Text
"," -> Bool
True
ESymbol TeXSymbolType
_ Text
";" -> Bool
True
ESymbol TeXSymbolType
_ Text
":" -> Bool
True
Exp
_ -> Bool
False
isCloseLike :: Exp -> Bool
isCloseLike :: Exp -> Bool
isCloseLike Exp
e =
case Exp
e of
ESymbol TeXSymbolType
Close Text
_ -> Bool
True
EDelimited{} -> Bool
True
Exp
_ -> Bool
False
isScripted :: Exp -> Bool
isScripted :: Exp -> Bool
isScripted Exp
e =
case Exp
e of
ESub{} -> Bool
True
ESuper{} -> Bool
True
ESubsup{} -> Bool
True
Exp
_ -> Bool
False
isArrowScriptedExp :: Exp -> Bool
isArrowScriptedExp :: Exp -> Bool
isArrowScriptedExp Exp
e =
case Exp
e of
EUnder Bool
_ Exp
base Exp
_ -> Exp -> Bool
isArrowBase Exp
base
EOver Bool
_ Exp
base Exp
_ -> Exp -> Bool
isArrowBase Exp
base
EUnderover Bool
_ Exp
base Exp
_ Exp
_ -> Exp -> Bool
isArrowBase Exp
base
ESub Exp
base Exp
_ -> Exp -> Bool
isArrowBase Exp
base
ESuper Exp
base Exp
_ -> Exp -> Bool
isArrowBase Exp
base
ESubsup Exp
base Exp
_ Exp
_ -> Exp -> Bool
isArrowBase Exp
base
Exp
_ -> Bool
False
isScriptedMathOperatorExp :: Exp -> Bool
isScriptedMathOperatorExp :: Exp -> Bool
isScriptedMathOperatorExp Exp
e =
case Exp
e of
ESub Exp
base Exp
_ -> Exp -> Bool
isMathOperatorExp Exp
base
ESuper Exp
base Exp
_ -> Exp -> Bool
isMathOperatorExp Exp
base
ESubsup Exp
base Exp
_ Exp
_ -> Exp -> Bool
isMathOperatorExp Exp
base
EUnder Bool
_ Exp
base Exp
_ -> Exp -> Bool
isMathOperatorExp Exp
base
EOver Bool
_ Exp
base Exp
_ -> Exp -> Bool
isMathOperatorExp Exp
base
EUnderover Bool
_ Exp
base Exp
_ Exp
_ -> Exp -> Bool
isMathOperatorExp Exp
base
Exp
_ -> Bool
False
isArrowBase :: Exp -> Bool
isArrowBase :: Exp -> Bool
isArrowBase Exp
e =
case Exp
e of
ESymbol TeXSymbolType
_ Text
"←" -> Bool
True
ESymbol TeXSymbolType
_ Text
"→" -> Bool
True
ESymbol TeXSymbolType
_ Text
"↔" -> Bool
True
ESymbol TeXSymbolType
_ Text
"⇐" -> Bool
True
ESymbol TeXSymbolType
_ Text
"⇒" -> Bool
True
ESymbol TeXSymbolType
_ Text
"⇔" -> Bool
True
ESymbol TeXSymbolType
_ Text
"↦" -> Bool
True
Exp
_ -> Bool
False
isUnaryMinusSymbol :: Exp -> Bool
isUnaryMinusSymbol :: Exp -> Bool
isUnaryMinusSymbol Exp
e =
case Exp
e of
ESymbol TeXSymbolType
t Text
"-" -> TeXSymbolType
t TeXSymbolType -> TeXSymbolType -> Bool
forall a. Eq a => a -> a -> Bool
/= TeXSymbolType
Bin
ESymbol TeXSymbolType
t Text
"−" -> TeXSymbolType
t TeXSymbolType -> TeXSymbolType -> Bool
forall a. Eq a => a -> a -> Bool
/= TeXSymbolType
Bin
Exp
_ -> Bool
False
isLargeOpScriptedExp :: Exp -> Bool
isLargeOpScriptedExp :: Exp -> Bool
isLargeOpScriptedExp Exp
e =
case Exp
e of
EUnder Bool
_ Exp
base Exp
_ -> Exp -> Maybe Text
largeOpName Exp
base Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
EOver Bool
_ Exp
base Exp
_ -> Exp -> Maybe Text
largeOpName Exp
base Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
EUnderover Bool
_ Exp
base Exp
_ Exp
_ -> Exp -> Maybe Text
largeOpName Exp
base Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
ESub Exp
base Exp
_ -> Exp -> Maybe Text
largeOpName Exp
base Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
ESuper Exp
base Exp
_ -> Exp -> Maybe Text
largeOpName Exp
base Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
ESubsup Exp
base Exp
_ Exp
_ -> Exp -> Maybe Text
largeOpName Exp
base Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
Exp
_ -> Bool
False
startsWithInfixNeedingLhs :: [Exp] -> Bool
startsWithInfixNeedingLhs :: [Exp] -> Bool
startsWithInfixNeedingLhs [Exp]
exps =
case [Exp]
exps of
(Exp
e : [Exp]
_) -> Exp -> Bool
needsNeutralLhs Exp
e
[Exp]
_ -> Bool
False
endsWithInfixNeedingRhs :: [Exp] -> Bool
endsWithInfixNeedingRhs :: [Exp] -> Bool
endsWithInfixNeedingRhs [Exp]
exps =
case [Exp] -> [Exp]
forall a. [a] -> [a]
reverse [Exp]
exps of
(Exp
e : [Exp]
_) -> Exp -> Bool
needsNeutralRhs Exp
e
[Exp]
_ -> Bool
False
needsNeutralLhs :: Exp -> Bool
needsNeutralLhs :: Exp -> Bool
needsNeutralLhs = Exp -> Bool
isInfixLikeExp
needsNeutralRhs :: Exp -> Bool
needsNeutralRhs :: Exp -> Bool
needsNeutralRhs = Exp -> Bool
isInfixLikeExp
needsNeutralScriptOperands :: Exp -> Bool
needsNeutralScriptOperands :: Exp -> Bool
needsNeutralScriptOperands Exp
e =
Exp -> Bool
isInfixLikeExp Exp
e Bool -> Bool -> Bool
&& Bool -> Bool
not (Exp -> Bool
isAtomicScriptOperator Exp
e)
isAtomicScriptOperator :: Exp -> Bool
isAtomicScriptOperator :: Exp -> Bool
isAtomicScriptOperator Exp
e =
case Exp
e of
ESymbol TeXSymbolType
_ Text
"∘" -> Bool
True
Exp
_ -> Bool
False
isInfixLikeExp :: Exp -> Bool
isInfixLikeExp :: Exp -> Bool
isInfixLikeExp Exp
e =
case Exp
e of
ESymbol TeXSymbolType
t Text
s
| TeXSymbolType
t TeXSymbolType -> TeXSymbolType -> Bool
forall a. Eq a => a -> a -> Bool
== TeXSymbolType
Bin -> Bool
True
| TeXSymbolType
t TeXSymbolType -> TeXSymbolType -> Bool
forall a. Eq a => a -> a -> Bool
== TeXSymbolType
Rel -> Bool
True
| Bool
otherwise -> 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
"×", Text
"⋅", Text
"·", Text
"∘"
, Text
"∈", Text
"∉", Text
"∋"
, Text
"∩", Text
"∪"
, Text
"⊂", Text
"⊆", Text
"⊃", Text
"⊇"
, Text
"≤", Text
"≥", Text
"≠", Text
"≈", Text
"≡", Text
"∝"
, Text
"∥", Text
"⊥"
, Text
"±", Text
"∓"
, Text
"/", Text
"←", Text
"→", Text
"↔", Text
"⇐", Text
"⇒", Text
"⇔", Text
"↦"
]
Exp
_ -> Bool
False
renderExpIn :: DisplayType -> AlignContext -> Exp -> Maybe T.Text
renderExpIn :: DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
e =
case Exp
e of
ENumber Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
EIdentifier Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Text
renderIdentifier Text
t)
EMathOperator Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Text
renderMathOperator Text
t)
ESymbol TeXSymbolType
t Text
s -> Text -> Maybe Text
forall a. a -> Maybe a
Just (TeXSymbolType -> Text -> Text
renderSymbol TeXSymbolType
t Text
s)
EText TextType
sty Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just (TextType -> Text -> Text
renderTextAtom TextType
sty Text
t)
ESpace Rational
w -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Rational -> Text
renderSpace Rational
w)
EGrouped [Exp]
xs -> (Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}") (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
ctx [Exp]
xs
EStyled TextType
sty [Exp]
xs -> DisplayType -> AlignContext -> TextType -> [Exp] -> Maybe Text
renderStyled DisplayType
dt AlignContext
ctx TextType
sty [Exp]
xs
EFraction FractionType
frac Exp
num Exp
den -> do
Text
num' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
AlignDefault Exp
num
Text
den' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
AlignDefault Exp
den
let num'' :: Text
num'' = AlignContext -> Text -> Text
maybeCenterFractionArg AlignContext
ctx Text
num'
let den'' :: Text
den'' = AlignContext -> Text -> Text
maybeCenterFractionArg AlignContext
ctx Text
den'
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ case FractionType
frac of
FractionType
NoLineFrac -> Text
"binom" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
asDelimitedArg Text
num'' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
asDelimitedArg Text
den''
FractionType
InlineFrac -> Text -> Text -> Text
renderInlineFraction Text
num'' Text
den''
FractionType
NormalFrac
| DisplayType
dt DisplayType -> DisplayType -> Bool
forall a. Eq a => a -> a -> Bool
== DisplayType
DisplayInline -> Text -> Text -> Text
renderInlineFraction Text
num'' Text
den''
FractionType
_ -> Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
num'' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" over " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
den'' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
ESqrt Exp
x -> (Text
"sqrt {" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}") (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
x
ERoot Exp
idx Exp
rad -> do
Text
idx' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
idx
Text
rad' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
rad
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"nroot {" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
idx' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"} {" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rad' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
EScaled Rational
_ (ESymbol TeXSymbolType
Open Text
"|") ->
Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"mline"
EScaled Rational
_ (ESymbol TeXSymbolType
Close Text
"|") ->
Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"mline"
EScaled Rational
_ Exp
x ->
DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
x
EDelimited Text
op Text
cl [InEDelimited]
xs -> do
Text
body <- DisplayType -> AlignContext -> [InEDelimited] -> Maybe Text
renderDelimitedBody DisplayType
dt AlignContext
ctx [InEDelimited]
xs
let op' :: Text
op' = DelimSide -> Text -> Text
delimToken DelimSide
DelimLeft Text
op
let cl' :: Text
cl' = DelimSide -> Text -> Text
delimToken DelimSide
DelimRight Text
cl
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"left " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
op' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
body Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" right " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cl'
ESub Exp
base Exp
sub -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text
sub' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
sub
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sub'
ESuper Exp
base Exp
sup -> do
Text
baseRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
case Exp -> Maybe Text
renderPrimeSuffix Exp
sup of
Just Text
primes ->
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
baseRendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
primes
Maybe Text
Nothing -> do
Text
supRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
sup
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
baseRendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
supRendered
ESubsup Exp
base Exp
sub Exp
sup -> do
Text
baseRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text
subRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
sub
case Exp -> Maybe Text
renderPrimeSuffix Exp
sup of
Just Text
primes ->
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
baseRendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
subRendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
primes
Maybe Text
Nothing -> do
Text
supRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
sup
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
baseRendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
subRendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
supRendered
EOver Bool
_ Exp
base Exp
over
| Just Text
arrow <- Exp -> Maybe Text
arrowScriptOpName Exp
base -> do
if Exp -> Bool
isEmptyScriptArg Exp
over
then Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
arrow
else do
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
arrow Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" csup " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
over'
| Just Text
op <- Exp -> Maybe Text
centeredScriptOpName Exp
base -> do
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
op Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"} csup " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
over'
| Just Text
brace <- Exp -> Maybe Text
braceAnnotationName Exp
over -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
brace
| Exp -> Bool
isBraceAnnotatedExp Exp
base -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderBraceLabel DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
over'
| Just Text
accent <- Exp -> Maybe Text
accentName Exp
over -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
accent Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text -> Text
renderAccentArg Exp
base Text
base'
| Just Text
op <- Exp -> Maybe Text
limitOpName Exp
base -> do
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderLimitArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
op Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
over' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
| Bool
otherwise -> Maybe Text
forall a. Maybe a
Nothing
EUnder Bool
_ Exp
base Exp
under ->
case Exp -> Maybe Text
arrowScriptOpName Exp
base of
Just Text
arrow ->
if Exp -> Bool
isEmptyScriptArg Exp
under
then Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
arrow
else do
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
under
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
arrow Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" csub " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
under'
Maybe Text
Nothing ->
case Exp -> Maybe Text
underlineMarkerName Exp
under of
Just Text
marker -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
marker Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text -> Text
renderAccentArg Exp
base Text
base'
Maybe Text
Nothing ->
case Exp -> Maybe Text
braceAnnotationName Exp
under of
Just Text
brace -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
brace
Maybe Text
Nothing ->
if Exp -> Bool
isBraceAnnotatedExp Exp
base
then do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderBraceLabel DisplayType
dt AlignContext
ctx Exp
under
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
under'
else
case Exp -> Maybe Text
centeredScriptOpName Exp
base of
Just Text
op -> do
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
under
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
op Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"} csub " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
under'
Maybe Text
Nothing ->
case Exp -> Maybe Text
limitOpName Exp
base of
Just Text
op -> do
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderLimitArg DisplayType
dt AlignContext
ctx Exp
under
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
op Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" from " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
under' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
Maybe Text
Nothing -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
under
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
under'
EUnderover Bool
_ Exp
base Exp
under Exp
over ->
case Exp -> Maybe Text
arrowScriptOpName Exp
base of
Just Text
arrow ->
case (Exp -> Bool
isEmptyScriptArg Exp
under, Exp -> Bool
isEmptyScriptArg Exp
over) of
(Bool
True, Bool
True) -> Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
arrow
(Bool
False, Bool
True) -> do
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
under
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
arrow Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" csub " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
under'
(Bool
True, Bool
False) -> do
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
arrow Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" csup " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
over'
(Bool
False, Bool
False) -> do
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
under
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
arrow Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" csub " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
under'
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" csup " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
over'
Maybe Text
Nothing ->
case Exp -> Maybe Text
centeredScriptOpName Exp
base of
Just Text
op -> do
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
under
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
op Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"} csub " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
under'
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" csup " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
centerScriptArg Text
over'
Maybe Text
Nothing ->
case Exp -> Maybe Text
limitOpName Exp
base of
Just Text
op -> do
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderLimitArg DisplayType
dt AlignContext
ctx Exp
under
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderLimitArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
op Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" from " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
under' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
over' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
Maybe Text
Nothing -> do
Text
base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
base
Text
under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
under
Text
over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
over
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Exp -> Text -> Text
renderScriptBase Exp
base Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
under' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
over'
EArray [Alignment]
aligns [ArrayLine]
rows -> DisplayType -> [Alignment] -> [ArrayLine] -> Maybe Text
renderMatrix DisplayType
dt [Alignment]
aligns [ArrayLine]
rows
EPhantom Exp
x -> do
Text
x' <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
x
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"phantom " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Exp -> Text -> Text
renderPhantomArg Exp
x Text
x'
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
renderDelimitedBody :: DisplayType -> AlignContext -> [Either T.Text Exp] -> Maybe T.Text
renderDelimitedBody :: DisplayType -> AlignContext -> [InEDelimited] -> Maybe Text
renderDelimitedBody DisplayType
dt AlignContext
ctx [InEDelimited]
xs = do
[DelimitedChunk]
chunks <- (InEDelimited -> Maybe DelimitedChunk)
-> [InEDelimited] -> Maybe [DelimitedChunk]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (DisplayType -> AlignContext -> InEDelimited -> Maybe DelimitedChunk
renderDelimitedChunk DisplayType
dt AlignContext
ctx) [InEDelimited]
xs
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
T.strip ([DelimitedChunk] -> Text
mergeDelimitedChunks [DelimitedChunk]
chunks)
data DelimitedChunk = DelimRaw T.Text | DelimExp Exp T.Text
renderDelimitedChunk :: DisplayType -> AlignContext -> Either T.Text Exp -> Maybe DelimitedChunk
renderDelimitedChunk :: DisplayType -> AlignContext -> InEDelimited -> Maybe DelimitedChunk
renderDelimitedChunk DisplayType
dt AlignContext
ctx InEDelimited
p =
case InEDelimited
p of
Left Text
t -> DelimitedChunk -> Maybe DelimitedChunk
forall a. a -> Maybe a
Just (DelimitedChunk -> Maybe DelimitedChunk)
-> DelimitedChunk -> Maybe DelimitedChunk
forall a b. (a -> b) -> a -> b
$ Text -> DelimitedChunk
DelimRaw (Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> DelimSide -> Text -> Text
delimToken DelimSide
DelimMiddle Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ")
Right Exp
x -> Exp -> Text -> DelimitedChunk
DelimExp Exp
x (Text -> DelimitedChunk) -> Maybe Text -> Maybe DelimitedChunk
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
x
mergeDelimitedChunks :: [DelimitedChunk] -> T.Text
mergeDelimitedChunks :: [DelimitedChunk] -> Text
mergeDelimitedChunks [] = Text
""
mergeDelimitedChunks (DelimitedChunk
c0:[DelimitedChunk]
cs) = (Maybe Exp, Text) -> Text
forall a b. (a, b) -> b
snd ((Maybe Exp, Text) -> Text) -> (Maybe Exp, Text) -> Text
forall a b. (a -> b) -> a -> b
$ ((Maybe Exp, Text) -> DelimitedChunk -> (Maybe Exp, Text))
-> (Maybe Exp, Text) -> [DelimitedChunk] -> (Maybe Exp, Text)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (Maybe Exp, Text) -> DelimitedChunk -> (Maybe Exp, Text)
step (DelimitedChunk -> Maybe Exp
chunkExp DelimitedChunk
c0, DelimitedChunk -> Text
chunkText DelimitedChunk
c0) [DelimitedChunk]
cs
where
step :: (Maybe Exp, Text) -> DelimitedChunk -> (Maybe Exp, Text)
step (Maybe Exp
prevExp, Text
acc) DelimitedChunk
cur
| Text -> Bool
T.null Text
curText = (Maybe Exp
prevExp, Text
acc)
| Bool
otherwise =
case DelimitedChunk
cur of
DelimRaw Text
_ -> (Maybe Exp
forall a. Maybe a
Nothing, Bool -> Text -> Text -> Text
appendRendered Bool
False Text
acc Text
curText)
DelimExp Exp
curExp Text
_ ->
let needSep :: Bool
needSep = case Maybe Exp
prevExp of
Just Exp
pe -> Exp -> Exp -> Bool
needsSeparator Exp
pe Exp
curExp
Maybe Exp
Nothing -> Bool
False
in (Exp -> Maybe Exp
forall a. a -> Maybe a
Just Exp
curExp, Bool -> Text -> Text -> Text
appendRendered Bool
needSep Text
acc Text
curText)
where
curText :: Text
curText = DelimitedChunk -> Text
chunkText DelimitedChunk
cur
chunkText :: DelimitedChunk -> Text
chunkText DelimitedChunk
c =
case DelimitedChunk
c of
DelimRaw Text
t -> Text
t
DelimExp Exp
_ Text
t -> Text
t
chunkExp :: DelimitedChunk -> Maybe Exp
chunkExp DelimitedChunk
c =
case DelimitedChunk
c of
DelimRaw Text
_ -> Maybe Exp
forall a. Maybe a
Nothing
DelimExp Exp
e Text
_ -> Exp -> Maybe Exp
forall a. a -> Maybe a
Just Exp
e
renderMatrix :: DisplayType -> [Alignment] -> [[[Exp]]] -> Maybe T.Text
renderMatrix :: DisplayType -> [Alignment] -> [ArrayLine] -> Maybe Text
renderMatrix DisplayType
dt [Alignment]
aligns [ArrayLine]
rows = do
[Text]
rows' <- (ArrayLine -> Maybe Text) -> [ArrayLine] -> Maybe [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (DisplayType -> [Alignment] -> ArrayLine -> Maybe Text
renderMatrixRow DisplayType
dt [Alignment]
aligns) [ArrayLine]
rows
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"matrix { " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate Text
" ## " [Text]
rows' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" }"
renderMatrixRow :: DisplayType -> [Alignment] -> [[Exp]] -> Maybe T.Text
renderMatrixRow :: DisplayType -> [Alignment] -> ArrayLine -> Maybe Text
renderMatrixRow DisplayType
dt [Alignment]
aligns ArrayLine
cells = do
let explicitCenter :: Bool
explicitCenter = (Alignment -> Bool) -> [Alignment] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Alignment -> Alignment -> Bool
forall a. Eq a => a -> a -> Bool
/= Alignment
AlignCenter) [Alignment]
aligns
let columnCount :: Int
columnCount = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max ([Alignment] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Alignment]
aligns) (ArrayLine -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ArrayLine
cells)
let paddedCells :: ArrayLine
paddedCells = Int -> ArrayLine -> ArrayLine
forall a. Int -> [a] -> [a]
take Int
columnCount (ArrayLine
cells ArrayLine -> ArrayLine -> ArrayLine
forall a. [a] -> [a] -> [a]
++ [Exp] -> ArrayLine
forall a. a -> [a]
repeat [])
[Text]
cells' <- [Maybe Text] -> Maybe [Text]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence
[ DisplayType -> Bool -> Alignment -> [Exp] -> Maybe Text
renderMatrixCellWithAlign DisplayType
dt Bool
explicitCenter ([Alignment] -> Int -> Alignment
columnAlign [Alignment]
aligns Int
i) [Exp]
c
| (Int
i, [Exp]
c) <- [Int] -> ArrayLine -> [(Int, [Exp])]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Int
0 :: Int) ..] ArrayLine
paddedCells
]
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
T.intercalate Text
" # " [Text]
cells'
renderMatrixCell :: DisplayType -> AlignContext -> [Exp] -> Maybe T.Text
renderMatrixCell :: DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderMatrixCell DisplayType
_ AlignContext
_ [] = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"{}"
renderMatrixCell DisplayType
dt AlignContext
ctx [Exp]
xs = do
Text
rendered <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
ctx [Exp]
xs
let stripped :: Text
stripped = Text -> Text
T.strip Text
rendered
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ if Text -> Bool
T.null Text
stripped then Text
"{}" else Text
stripped
renderMatrixCellWithAlign :: DisplayType -> Bool -> Alignment -> [Exp] -> Maybe T.Text
renderMatrixCellWithAlign :: DisplayType -> Bool -> Alignment -> [Exp] -> Maybe Text
renderMatrixCellWithAlign DisplayType
dt Bool
explicitCenter Alignment
align [Exp]
xs = do
Text
cell <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderMatrixCell DisplayType
dt (Alignment -> AlignContext
alignmentContext Alignment
align) [Exp]
xs
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ case Alignment
align of
Alignment
AlignLeft -> Text
"alignl " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cell
Alignment
AlignRight -> Text
"alignr " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cell
Alignment
AlignCenter | Bool
explicitCenter -> Text
"alignc " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cell
Alignment
_ -> Text
cell
columnAlign :: [Alignment] -> Int -> Alignment
columnAlign :: [Alignment] -> Int -> Alignment
columnAlign [Alignment]
aligns Int
i =
case Int -> [Alignment] -> [Alignment]
forall a. Int -> [a] -> [a]
drop Int
i [Alignment]
aligns of
(Alignment
a : [Alignment]
_) -> Alignment
a
[] -> Alignment
AlignCenter
renderStyled :: DisplayType -> AlignContext -> TextType -> [Exp] -> Maybe T.Text
renderStyled :: DisplayType -> AlignContext -> TextType -> [Exp] -> Maybe Text
renderStyled DisplayType
dt AlignContext
ctx TextType
sty [Exp]
xs = do
Text
body <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
ctx [Exp]
xs
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ case TextType
sty of
TextType
_
| Just Text
unicodeBody <- TextType -> [Exp] -> Maybe Text
renderUnicodeSerifStyled TextType
sty [Exp]
xs ->
Text
"nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
unicodeBody
TextType
TextNormal
| Just Text
ident <- [Exp] -> Maybe Text
singleUprightIdentifier [Exp]
xs ->
Text
"nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
renderTextNormalIdentifier Text
ident
| Bool -> Bool
not ([Exp] -> Bool
hasStructuralScript [Exp]
xs)
, Just Text
txt <- [Exp] -> Maybe Text
styledText [Exp]
xs -> Text -> Text
quoteText Text
txt
| Just Text
txt <- DisplayType -> [Exp] -> Maybe Text
renderTextNormalStyled DisplayType
dt [Exp]
xs
, [Exp] -> Bool
shouldForceUprightTextNormal [Exp]
xs -> Text
"nitalic{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
txt Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
| Just Text
txt <- DisplayType -> [Exp] -> Maybe Text
renderTextNormalStyled DisplayType
dt [Exp]
xs -> Text
txt
TextType
TextItalic -> Text
"ital " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
TextBold
| [Exp] -> Bool
shouldForceUprightBold [Exp]
xs -> Text
"bold nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
| Bool
otherwise -> Text
"bold " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
TextBoldItalic -> Text
"bold " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg (Text
"ital " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body)
TextType
TextMonospace -> Text
"font fixed nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
TextSansSerif -> Text
"font sans nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
TextSansSerifBold -> Text
"bold " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg (Text
"font sans nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body)
TextType
TextSansSerifBoldItalic -> Text
"bold " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg (Text
"font sans ital " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body)
TextType
TextSansSerifItalic -> Text
"font sans ital " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
TextScript -> Text
"ital " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
TextFraktur -> Text
"bold " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
TextDoubleStruck -> Text
"bold nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
TextType
_ -> Text
body
where
styleArg :: Text -> Text
styleArg Text
t
| Text -> Bool
T.null Text
t = Text
"{}"
| Text -> Int
T.length Text
t Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = 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
"}"
renderUnicodeSerifStyled :: TextType -> [Exp] -> Maybe T.Text
renderUnicodeSerifStyled :: TextType -> [Exp] -> Maybe Text
renderUnicodeSerifStyled TextType
sty [Exp]
xs =
case TextType
sty of
TextType
TextScript -> TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty [Exp]
xs
TextType
TextFraktur -> TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty [Exp]
xs
TextType
TextDoubleStruck -> TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty [Exp]
xs
TextType
TextBoldScript -> TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty [Exp]
xs
TextType
TextBoldFraktur -> TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty [Exp]
xs
TextType
_ -> Maybe Text
forall a. Maybe a
Nothing
styledUnicodeText :: TextType -> [Exp] -> Maybe T.Text
styledUnicodeText :: TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty = ([Text] -> Text) -> Maybe [Text] -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Text] -> Text
T.concat (Maybe [Text] -> Maybe Text)
-> ([Exp] -> Maybe [Text]) -> [Exp] -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp -> Maybe Text) -> [Exp] -> Maybe [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (TextType -> Exp -> Maybe Text
styledUnicodeExp TextType
sty)
styledUnicodeExp :: TextType -> Exp -> Maybe T.Text
styledUnicodeExp :: TextType -> Exp -> Maybe Text
styledUnicodeExp TextType
sty Exp
e =
case Exp
e of
EIdentifier Text
t -> TextType -> Text -> Maybe Text
mapStyledUnicode TextType
sty Text
t
ENumber Text
t -> TextType -> Text -> Maybe Text
mapStyledUnicode TextType
sty Text
t
EGrouped [Exp]
xs -> TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty [Exp]
xs
EStyled TextType
TextNormal [Exp]
xs -> TextType -> [Exp] -> Maybe Text
styledUnicodeText TextType
sty [Exp]
xs
ESpace Rational
w
| Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= Rational
0 -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
""
| Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= Rational
2 -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
" "
| Bool
otherwise -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
" "
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
mapStyledUnicode :: TextType -> T.Text -> Maybe T.Text
mapStyledUnicode :: TextType -> Text -> Maybe Text
mapStyledUnicode TextType
sty Text
t = String -> Text
T.pack (String -> Text) -> Maybe String -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Maybe Char) -> String -> Maybe String
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\Char
c -> (TextType, Char) -> Maybe Char
toUnicodeChar (TextType
sty, Char
c)) (Text -> String
T.unpack Text
t)
hasStructuralScript :: [Exp] -> Bool
hasStructuralScript :: [Exp] -> Bool
hasStructuralScript = (Exp -> Bool) -> [Exp] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Exp -> Bool
go
where
go :: Exp -> Bool
go Exp
e =
case Exp
e of
ESub{} -> Bool
True
ESuper{} -> Bool
True
ESubsup{} -> Bool
True
EGrouped [Exp]
xs -> [Exp] -> Bool
hasStructuralScript [Exp]
xs
EStyled TextType
TextNormal [Exp]
xs -> [Exp] -> Bool
hasStructuralScript [Exp]
xs
Exp
_ -> Bool
False
styledText :: [Exp] -> Maybe T.Text
styledText :: [Exp] -> Maybe Text
styledText = ([Text] -> Text) -> Maybe [Text] -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Text] -> Text
T.concat (Maybe [Text] -> Maybe Text)
-> ([Exp] -> Maybe [Text]) -> [Exp] -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp -> Maybe Text) -> [Exp] -> Maybe [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Exp -> Maybe Text
styledTextExp
styledTextExp :: Exp -> Maybe T.Text
styledTextExp :: Exp -> Maybe Text
styledTextExp Exp
e =
case Exp
e of
ENumber Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
EIdentifier Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
EText TextType
_ Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
ESpace Rational
w
| Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= Rational
0 -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
""
| Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= Rational
2 -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
" "
| Bool
otherwise -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
" "
EGrouped [Exp]
xs -> [Exp] -> Maybe Text
styledText [Exp]
xs
EStyled TextType
TextNormal [Exp]
xs -> [Exp] -> Maybe Text
styledText [Exp]
xs
ESub Exp
base Exp
sub -> do
Text
base' <- Exp -> Maybe Text
styledTextExp Exp
base
Text
sub' <- Exp -> Maybe Text
styledTextNonNumericExp Exp
sub
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sub'
ESuper Exp
base Exp
sup -> do
Text
base' <- Exp -> Maybe Text
styledTextExp Exp
base
Text
sup' <- Exp -> Maybe Text
styledTextNonNumericExp Exp
sup
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sup'
ESubsup Exp
base Exp
sub Exp
sup -> do
Text
base' <- Exp -> Maybe Text
styledTextExp Exp
base
Text
sub' <- Exp -> Maybe Text
styledTextNonNumericExp Exp
sub
Text
sup' <- Exp -> Maybe Text
styledTextNonNumericExp Exp
sup
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sub' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sup'
ESymbol TeXSymbolType
_ Text
s
| Text -> Bool
isPlainTextSymbol Text
s -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
s
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
styledTextNonNumericExp :: Exp -> Maybe T.Text
styledTextNonNumericExp :: Exp -> Maybe Text
styledTextNonNumericExp Exp
e = do
Text
txt <- Exp -> Maybe Text
styledTextExp Exp
e
if (Char -> Bool) -> Text -> Bool
T.any Char -> Bool
isAsciiDigit Text
txt
then Maybe Text
forall a. Maybe a
Nothing
else Text -> Maybe Text
forall a. a -> Maybe a
Just Text
txt
isAsciiDigit :: Char -> Bool
isAsciiDigit :: Char -> Bool
isAsciiDigit Char
c = Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9'
isPlainTextSymbol :: T.Text -> Bool
isPlainTextSymbol :: Text -> Bool
isPlainTextSymbol 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
"_", Text
",", Text
".", Text
":", Text
";", Text
"-", Text
"−", Text
"/", Text
"(", Text
")", Text
"[", Text
"]"
, Text
"+", Text
"=", Text
"'", Text
"′"
]
renderTextNormalStyled :: DisplayType -> [Exp] -> Maybe T.Text
renderTextNormalStyled :: DisplayType -> [Exp] -> Maybe Text
renderTextNormalStyled DisplayType
dt [Exp]
xs = do
let xs' :: [Exp]
xs' = [Exp] -> [Exp]
quoteStarMathKeywordRuns [Exp]
xs
[Text]
rendered <- (Exp -> Maybe Text) -> [Exp] -> Maybe [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt) [Exp]
xs'
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ [(Exp, Text)] -> Text
mergePieces ([Exp] -> [Text] -> [(Exp, Text)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Exp]
xs' [Text]
rendered)
quoteStarMathKeywordRuns :: [Exp] -> [Exp]
quoteStarMathKeywordRuns :: [Exp] -> [Exp]
quoteStarMathKeywordRuns [] = []
quoteStarMathKeywordRuns xs :: [Exp]
xs@(Exp
x : [Exp]
rest)
| Just Text
_ <- Exp -> Maybe Text
asciiIdentifierWord Exp
x =
let (Text
word, [Exp]
wordExps, [Exp]
rest') = [Exp] -> (Text, [Exp], [Exp])
takeIdentifierWordRun [Exp]
xs
in if Text -> Bool
isStarMathReservedWord Text
word
then TextType -> Text -> Exp
EText TextType
TextNormal Text
word Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
quoteStarMathKeywordRuns [Exp]
rest'
else [Exp]
wordExps [Exp] -> [Exp] -> [Exp]
forall a. Semigroup a => a -> a -> a
<> [Exp] -> [Exp]
quoteStarMathKeywordRuns [Exp]
rest'
| Bool
otherwise = Exp
x Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp] -> [Exp]
quoteStarMathKeywordRuns [Exp]
rest
takeIdentifierWordRun :: [Exp] -> (T.Text, [Exp], [Exp])
takeIdentifierWordRun :: [Exp] -> (Text, [Exp], [Exp])
takeIdentifierWordRun = [Text] -> [Exp] -> [Exp] -> (Text, [Exp], [Exp])
go [] []
where
go :: [Text] -> [Exp] -> [Exp] -> (Text, [Exp], [Exp])
go [Text]
pieces [Exp]
exps (Exp
e : [Exp]
rest)
| Just Text
piece <- Exp -> Maybe Text
asciiIdentifierWord Exp
e = [Text] -> [Exp] -> [Exp] -> (Text, [Exp], [Exp])
go (Text
piece Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
pieces) (Exp
e Exp -> [Exp] -> [Exp]
forall a. a -> [a] -> [a]
: [Exp]
exps) [Exp]
rest
go [Text]
pieces [Exp]
exps [Exp]
rest = ([Text] -> Text
T.concat ([Text] -> [Text]
forall a. [a] -> [a]
reverse [Text]
pieces), [Exp] -> [Exp]
forall a. [a] -> [a]
reverse [Exp]
exps, [Exp]
rest)
asciiIdentifierWord :: Exp -> Maybe T.Text
asciiIdentifierWord :: Exp -> Maybe Text
asciiIdentifierWord Exp
e =
case Exp
e of
EIdentifier Text
t
| Bool -> Bool
not (Text -> Bool
T.null Text
t) Bool -> Bool -> Bool
&& (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isAsciiAlpha Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
renderTextNormalExp :: DisplayType -> Exp -> Maybe T.Text
renderTextNormalExp :: DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
e =
case Exp
e of
ENumber Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
EIdentifier Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Text
renderIdentifier Text
t)
EText TextType
sty Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just (TextType -> Text -> Text
renderTextAtom TextType
sty Text
t)
ESpace Rational
w -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Rational -> Text
renderSpace Rational
w)
EGrouped [Exp]
xs -> DisplayType -> [Exp] -> Maybe Text
renderTextNormalStyled DisplayType
dt [Exp]
xs
EStyled TextType
TextNormal [Exp]
xs -> DisplayType -> [Exp] -> Maybe Text
renderTextNormalStyled DisplayType
dt [Exp]
xs
EStyled TextType
TextBold [Exp]
xs -> do
Text
body <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
AlignDefault [Exp]
xs
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"bold nitalic " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
body
EStyled TextType
sty [Exp]
xs -> DisplayType -> AlignContext -> TextType -> [Exp] -> Maybe Text
renderStyled DisplayType
dt AlignContext
AlignDefault TextType
sty [Exp]
xs
ESub Exp
base Exp
sub -> do
Text
base' <- DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
base
Text
sub' <- DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
sub
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sub'
ESuper Exp
base Exp
sup -> do
Text
base' <- DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
base
Text
sup' <- DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
sup
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sup'
ESubsup Exp
base Exp
sub Exp
sup -> do
Text
base' <- DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
base
Text
sub' <- DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
sub
Text
sup' <- DisplayType -> Exp -> Maybe Text
renderTextNormalExp DisplayType
dt Exp
sup
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
base' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sub' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sup'
ESymbol TeXSymbolType
t Text
s -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Text
T.strip (TeXSymbolType -> Text -> Text
renderSymbol TeXSymbolType
t Text
s))
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
shouldForceUprightTextNormal :: [Exp] -> Bool
shouldForceUprightTextNormal :: [Exp] -> Bool
shouldForceUprightTextNormal = (Exp -> Bool) -> [Exp] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Exp -> Bool
isUprightTextNormalExp
shouldForceUprightBold :: [Exp] -> Bool
shouldForceUprightBold :: [Exp] -> Bool
shouldForceUprightBold = (Exp -> Bool) -> [Exp] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Exp -> Bool
isUprightBoldExp
isUprightBoldExp :: Exp -> Bool
isUprightBoldExp :: Exp -> Bool
isUprightBoldExp Exp
e =
case Exp
e of
ENumber{} -> Bool
True
EIdentifier Text
t -> (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isAsciiAlphaNum Text
t
EText{} -> Bool
True
ESpace{} -> Bool
True
ESymbol TeXSymbolType
_ Text
s -> Text -> Bool
isPlainTextSymbol Text
s
EGrouped [Exp]
xs -> [Exp] -> Bool
shouldForceUprightBold [Exp]
xs
EStyled TextType
TextNormal [Exp]
xs -> [Exp] -> Bool
shouldForceUprightBold [Exp]
xs
ESub Exp
base Exp
sub -> Exp -> Bool
isUprightBoldExp Exp
base Bool -> Bool -> Bool
&& Exp -> Bool
isUprightBoldExp Exp
sub
ESuper Exp
base Exp
sup -> Exp -> Bool
isUprightBoldExp Exp
base Bool -> Bool -> Bool
&& Exp -> Bool
isUprightBoldExp Exp
sup
ESubsup Exp
base Exp
sub Exp
sup -> Exp -> Bool
isUprightBoldExp Exp
base
Bool -> Bool -> Bool
&& Exp -> Bool
isUprightBoldExp Exp
sub
Bool -> Bool -> Bool
&& Exp -> Bool
isUprightBoldExp Exp
sup
Exp
_ -> Bool
False
isUprightTextNormalExp :: Exp -> Bool
isUprightTextNormalExp :: Exp -> Bool
isUprightTextNormalExp Exp
e =
case Exp
e of
ENumber{} -> Bool
True
EIdentifier{} -> Bool
True
EText{} -> Bool
True
ESpace{} -> Bool
True
ESymbol TeXSymbolType
_ Text
s -> Text -> Bool
isPlainTextSymbol Text
s
EGrouped [Exp]
xs -> [Exp] -> Bool
shouldForceUprightTextNormal [Exp]
xs
EStyled TextType
TextNormal [Exp]
xs -> [Exp] -> Bool
shouldForceUprightTextNormal [Exp]
xs
ESub Exp
base Exp
sub -> Exp -> Bool
isUprightTextNormalExp Exp
base Bool -> Bool -> Bool
&& Exp -> Bool
isUprightTextNormalExp Exp
sub
ESuper Exp
base Exp
sup -> Exp -> Bool
isUprightTextNormalExp Exp
base Bool -> Bool -> Bool
&& Exp -> Bool
isUprightTextNormalExp Exp
sup
ESubsup Exp
base Exp
sub Exp
sup -> Exp -> Bool
isUprightTextNormalExp Exp
base
Bool -> Bool -> Bool
&& Exp -> Bool
isUprightTextNormalExp Exp
sub
Bool -> Bool -> Bool
&& Exp -> Bool
isUprightTextNormalExp Exp
sup
Exp
_ -> Bool
False
isAsciiAlpha :: Char -> Bool
isAsciiAlpha :: Char -> Bool
isAsciiAlpha Char
c =
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'A' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'Z') Bool -> Bool -> Bool
||
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'a' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'z')
isAsciiAlphaNum :: Char -> Bool
isAsciiAlphaNum :: Char -> Bool
isAsciiAlphaNum Char
c =
Char -> Bool
isAsciiAlpha Char
c Bool -> Bool -> Bool
||
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9')
styleArg :: T.Text -> T.Text
styleArg :: Text -> Text
styleArg Text
t
| Text -> Bool
T.null Text
t = Text
"{}"
| Text -> Int
T.length Text
t Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = 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
"}"
singleUprightIdentifier :: [Exp] -> Maybe T.Text
singleUprightIdentifier :: [Exp] -> Maybe Text
singleUprightIdentifier [Exp]
xs =
case [Exp]
xs of
[EIdentifier Text
t] -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
[Exp]
_ -> Maybe Text
forall a. Maybe a
Nothing
alignmentContext :: Alignment -> AlignContext
alignmentContext :: Alignment -> AlignContext
alignmentContext Alignment
a =
case Alignment
a of
Alignment
AlignLeft -> AlignContext
AlignLeftCtx
Alignment
AlignRight -> AlignContext
AlignRightCtx
Alignment
_ -> AlignContext
AlignDefault
maybeCenterFractionArg :: AlignContext -> T.Text -> T.Text
maybeCenterFractionArg :: AlignContext -> Text -> Text
maybeCenterFractionArg AlignContext
ctx Text
t
| AlignContext
ctx AlignContext -> AlignContext -> Bool
forall a. Eq a => a -> a -> Bool
== AlignContext
AlignLeftCtx Bool -> Bool -> Bool
|| AlignContext
ctx AlignContext -> AlignContext -> Bool
forall a. Eq a => a -> a -> Bool
== AlignContext
AlignRightCtx = Text
"{alignc " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
asArg Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
| Bool
otherwise = Text
t
where
asArg :: Text -> Text
asArg Text
x =
let s :: Text
s = Text -> Text
T.strip Text
x
in if Text -> Bool
T.null Text
s
then Text
"{}"
else if Text -> Int
T.length Text
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
then Text
s
else if HasCallStack => Text -> Char
Text -> Char
T.head Text
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'{' Bool -> Bool -> Bool
&& HasCallStack => Text -> Char
Text -> Char
T.last Text
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'}'
then Text
s
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
asDelimitedArg :: T.Text -> T.Text
asDelimitedArg :: Text -> Text
asDelimitedArg Text
t =
let s :: Text
s = Text -> Text
T.strip Text
t
in if Text -> Bool
T.null Text
s
then Text
"{}"
else if HasCallStack => Text -> Char
Text -> Char
T.head Text
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'{' Bool -> Bool -> Bool
&& HasCallStack => Text -> Char
Text -> Char
T.last Text
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'}'
then Text
s
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
renderInlineFraction :: T.Text -> T.Text -> T.Text
renderInlineFraction :: Text -> Text -> Text
renderInlineFraction Text
num Text
den =
Text
"size*0.7 {" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
num Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" over " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
den Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
renderSpace :: Rational -> T.Text
renderSpace :: Rational -> Text
renderSpace Rational
w
| Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= Rational
0 = Text
""
| Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= Rational
2 = Text
"~~ "
| Rational
w Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= Rational
1 = Text
"~ "
| Bool
otherwise = Text
" "
renderIdentifier :: T.Text -> T.Text
renderIdentifier :: Text -> Text
renderIdentifier Text
ident =
case Text -> Maybe Text
greekName Text
ident of
Just Text
name
| Text -> Bool
shouldItalicizeGreek Text
ident -> Text
"%i" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name
| Bool
otherwise -> Text
"%" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name
Maybe Text
Nothing -> Text
ident
renderTextNormalIdentifier :: T.Text -> T.Text
renderTextNormalIdentifier :: Text -> Text
renderTextNormalIdentifier Text
ident =
case Text -> Maybe Text
greekName Text
ident of
Just{} -> Text -> Text
renderIdentifier Text
ident
Maybe Text
Nothing
| Text -> Bool
isStarMathReservedWord Text
ident -> Text -> Text
quoteText Text
ident
| Bool
otherwise -> Text
ident
isStarMathReservedWord :: T.Text -> Bool
isStarMathReservedWord :: Text -> Bool
isStarMathReservedWord Text
t =
Text
t Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
[ Text
"alignc", Text
"alignl", Text
"alignr"
, Text
"and", Text
"approx"
, Text
"bar", Text
"binom", Text
"bold", Text
"breve"
, Text
"cdot", Text
"check", Text
"circ", Text
"cos", Text
"cosh", Text
"cot", Text
"csub", Text
"csup"
, Text
"dlarrow", Text
"dlrarrow", Text
"dot", Text
"dotsaxis", Text
"dotsdown", Text
"dotslow"
, Text
"dotsup", Text
"dotsvert", Text
"downarrow", Text
"drarrow"
, Text
"emptyset", Text
"equiv", Text
"exists", Text
"exp"
, Text
"fixed", Text
"font", Text
"forall", Text
"from", Text
"func"
, Text
"gg"
, Text
"hat"
, Text
"in", Text
"infinity", Text
"int", Text
"intersection", Text
"ital", Text
"iiint"
, Text
"langle", Text
"lbrace", Text
"lceil", Text
"ldbracket", Text
"ldline", Text
"left"
, Text
"leftarrow", Text
"leftrightarrow", Text
"lfloor", Text
"lim", Text
"liminf"
, Text
"limsup", Text
"ll", Text
"lline", Text
"ln", Text
"log"
, Text
"mapsto", Text
"matrix", Text
"max", Text
"min", Text
"minusplus", Text
"mline"
, Text
"nabla", Text
"neg", Text
"none", Text
"notin", Text
"nitalic", Text
"nroot"
, Text
"or", Text
"ortho", Text
"over", Text
"overbrace", Text
"overline", Text
"owns"
, Text
"parallel", Text
"phantom", Text
"plusminus", Text
"partial", Text
"prod", Text
"prop"
, Text
"rangle", Text
"rbrace", Text
"rceil", Text
"rdbracket", Text
"rdline", Text
"rfloor"
, Text
"right", Text
"rline"
, Text
"sans", Text
"sin", Text
"sinh", Text
"sqrt", Text
"subset", Text
"subseteq", Text
"sum"
, Text
"supset", Text
"supseteq"
, Text
"tilde", Text
"times", Text
"to", Text
"toward"
, Text
"underbrace", Text
"underline", Text
"union", Text
"uparrow"
, Text
"vec"
]
renderMathOperator :: T.Text -> T.Text
renderMathOperator :: Text -> Text
renderMathOperator Text
t
| Text
t Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"min" = Text
"func min"
| Text
t Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"max" = Text
"func max"
| Text -> Bool
isBareMathOperator Text
t = Text
t
| Text -> Bool
shouldQuoteMathOperator Text
t = Text
"func " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteText Text
t
| Bool
otherwise = Text
"func " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t
isBareMathOperator :: T.Text -> Bool
isBareMathOperator :: Text -> Bool
isBareMathOperator Text
t =
Text
t Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
[ Text
"min", Text
"max", Text
"log", Text
"sin", Text
"cos", Text
"cosh", Text
"sinh"
, Text
"cot", Text
"ln", Text
"exp"
]
shouldQuoteMathOperator :: T.Text -> Bool
shouldQuoteMathOperator :: Text -> Bool
shouldQuoteMathOperator = Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isLetter
shouldItalicizeGreek :: T.Text -> Bool
shouldItalicizeGreek :: Text -> Bool
shouldItalicizeGreek Text
ident =
case Text
ident of
Text
"α" -> Bool
True
Text
"β" -> Bool
True
Text
"γ" -> Bool
True
Text
"δ" -> Bool
True
Text
"ϵ" -> Bool
True
Text
"ε" -> Bool
True
Text
"ζ" -> Bool
True
Text
"η" -> Bool
True
Text
"θ" -> Bool
True
Text
"ϑ" -> Bool
True
Text
"ι" -> Bool
True
Text
"κ" -> Bool
True
Text
"λ" -> Bool
True
Text
"μ" -> Bool
True
Text
"ν" -> Bool
True
Text
"ξ" -> Bool
True
Text
"ο" -> Bool
True
Text
"π" -> Bool
True
Text
"ϖ" -> Bool
True
Text
"ρ" -> Bool
True
Text
"ϱ" -> Bool
True
Text
"𝜚" -> Bool
True
Text
"σ" -> Bool
True
Text
"ς" -> Bool
True
Text
"𝜍" -> Bool
True
Text
"τ" -> Bool
True
Text
"υ" -> Bool
True
Text
"ϕ" -> Bool
True
Text
"φ" -> Bool
True
Text
"χ" -> Bool
True
Text
"ψ" -> Bool
True
Text
"ω" -> Bool
True
Text
_ -> Bool
False
greekName :: T.Text -> Maybe T.Text
greekName :: Text -> Maybe Text
greekName Text
ident =
case Text
ident of
Text
"α" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"alpha"
Text
"β" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"beta"
Text
"γ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"gamma"
Text
"δ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"delta"
Text
"ϵ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"epsilon"
Text
"ε" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"varepsilon"
Text
"ζ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"zeta"
Text
"η" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"eta"
Text
"θ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"theta"
Text
"ϑ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"vartheta"
Text
"ι" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"iota"
Text
"κ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"kappa"
Text
"λ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"lambda"
Text
"μ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"mu"
Text
"ν" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"nu"
Text
"ξ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"xi"
Text
"ο" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"omicron"
Text
"π" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"pi"
Text
"ϖ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"varpi"
Text
"ρ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"rho"
Text
"ϱ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"varrho"
Text
"𝜚" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"varrho"
Text
"σ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"sigma"
Text
"ς" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"varsigma"
Text
"𝜍" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"varsigma"
Text
"τ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"tau"
Text
"υ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"upsilon"
Text
"ϕ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"phi"
Text
"φ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"varphi"
Text
"χ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"chi"
Text
"ψ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"psi"
Text
"ω" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"omega"
Text
"Γ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"GAMMA"
Text
"Δ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"DELTA"
Text
"Θ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"THETA"
Text
"Λ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"LAMBDA"
Text
"Ξ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"XI"
Text
"Π" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"PI"
Text
"Σ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"SIGMA"
Text
"Υ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"UPSILON"
Text
"Φ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"PHI"
Text
"Ψ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"PSI"
Text
"Ω" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"OMEGA"
Text
_ -> Maybe Text
forall a. Maybe a
Nothing
renderScriptBase :: Exp -> T.Text -> T.Text
renderScriptBase :: Exp -> Text -> Text
renderScriptBase Exp
e Text
rendered0 =
let rendered :: Text
rendered = Text -> Text
T.strip Text
rendered0
in if Exp -> Bool
isEmptyScriptBase Exp
e Bool -> Bool -> Bool
|| Text -> Bool
T.null Text
rendered
then Text
"{}"
else if Text -> Bool
isWrapped Text
rendered
then Text
rendered
else if Exp -> Bool
isAtomic Exp
e
then Text
rendered
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
renderScriptArg :: DisplayType -> AlignContext -> Exp -> Maybe T.Text
renderScriptArg :: DisplayType -> AlignContext -> Exp -> Maybe Text
renderScriptArg DisplayType
dt AlignContext
ctx Exp
e = do
Text
rendered0 <-
if Exp -> Bool
needsNeutralScriptOperands Exp
e
then DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
ctx [Exp
e]
else DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
e
let rendered :: Text
rendered = Text -> Text
T.strip Text
rendered0
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ if (Exp -> Bool
isAtomic Exp
e Bool -> Bool -> Bool
&& Bool -> Bool
not (Exp -> Bool
needsNeutralScriptOperands Exp
e)) Bool -> Bool -> Bool
|| Text -> Bool
isQuotedText Text
rendered
then Text
rendered
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
renderPrimeSuffix :: Exp -> Maybe T.Text
renderPrimeSuffix :: Exp -> Maybe Text
renderPrimeSuffix Exp
e =
case Exp
e of
ESymbol TeXSymbolType
Pun Text
"'" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"'"
ESymbol TeXSymbolType
Pun Text
"′" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"'"
ESymbol TeXSymbolType
Pun Text
"″" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"''"
ESymbol TeXSymbolType
Pun Text
"‴" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"'''"
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
renderLimitArg :: DisplayType -> AlignContext -> Exp -> Maybe T.Text
renderLimitArg :: DisplayType -> AlignContext -> Exp -> Maybe Text
renderLimitArg DisplayType
dt AlignContext
ctx Exp
e =
case Exp
e of
EGrouped [Exp]
xs -> do
Text
rendered <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
renderExpsIn DisplayType
dt AlignContext
ctx [Exp]
xs
let stripped :: Text
stripped = Text -> Text
T.strip Text
rendered
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$
if Text -> Bool
T.null Text
stripped
then Text
"{}"
else if [Exp] -> Bool
containsRelationLike [Exp]
xs
then Text
stripped
else if Text -> Bool
isQuotedText Text
stripped Bool -> Bool -> Bool
|| Text -> Bool
isWrapped Text
stripped Bool -> Bool -> Bool
|| Text -> Int
T.length Text
stripped Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
then Text
stripped
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
stripped Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
Exp
_ -> Text -> Text
T.strip (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
e
containsRelationLike :: [Exp] -> Bool
containsRelationLike :: [Exp] -> Bool
containsRelationLike = (Exp -> Bool) -> [Exp] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Exp -> Bool
isRelationLike
where
isRelationLike :: Exp -> Bool
isRelationLike Exp
expn =
case Exp
expn of
ESymbol TeXSymbolType
Rel Text
_ -> Bool
True
ESymbol TeXSymbolType
Bin Text
_ -> Bool
True
EGrouped [Exp]
ys -> [Exp] -> Bool
containsRelationLike [Exp]
ys
Exp
_ -> Bool
False
renderAccentArg :: Exp -> T.Text -> T.Text
renderAccentArg :: Exp -> Text -> Text
renderAccentArg Exp
e Text
rendered0 =
let rendered :: Text
rendered = Text -> Text
T.strip Text
rendered0
in if Exp -> Bool
isAtomic Exp
e
then Text
rendered
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
renderPhantomArg :: Exp -> T.Text -> T.Text
renderPhantomArg :: Exp -> Text -> Text
renderPhantomArg Exp
e Text
rendered0 =
let rendered :: Text
rendered = Text -> Text
T.strip Text
rendered0
in if Exp -> Bool
isAtomic Exp
e
then Text
rendered
else if Text -> Bool
isWrapped Text
rendered
then Text
rendered
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
centerScriptArg :: T.Text -> T.Text
centerScriptArg :: Text -> Text
centerScriptArg Text
rendered
| Text -> Bool
isWrapped Text
rendered = Text
rendered
| Bool
otherwise = Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
isWrapped :: T.Text -> Bool
isWrapped :: Text -> Bool
isWrapped Text
t = Text -> Int
T.length Text
t Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 Bool -> Bool -> Bool
&& HasCallStack => Text -> Char
Text -> Char
T.head Text
t Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'{' Bool -> Bool -> Bool
&& HasCallStack => Text -> Char
Text -> Char
T.last Text
t Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'}'
isAtomic :: Exp -> Bool
isAtomic :: Exp -> Bool
isAtomic Exp
e =
case Exp
e of
ENumber{} -> Bool
True
EIdentifier{} -> Bool
True
EMathOperator{} -> Bool
True
EText{} -> Bool
True
ESymbol{} -> Bool
True
Exp
_ -> Bool
False
isEmptyScriptBase :: Exp -> Bool
isEmptyScriptBase :: Exp -> Bool
isEmptyScriptBase Exp
e =
case Exp
e of
EIdentifier Text
t -> Text -> Bool
T.null Text
t
Exp
_ -> Bool
False
isEmptyScriptArg :: Exp -> Bool
isEmptyScriptArg :: Exp -> Bool
isEmptyScriptArg Exp
e =
case Exp
e of
EGrouped [] -> Bool
True
EIdentifier Text
t -> Text -> Bool
T.null Text
t
Exp
_ -> Bool
False
isBraceAnnotatedExp :: Exp -> Bool
isBraceAnnotatedExp :: Exp -> Bool
isBraceAnnotatedExp Exp
e =
case Exp
e of
EOver Bool
_ Exp
_ Exp
over -> Exp -> Maybe Text
braceAnnotationName Exp
over Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
EUnder Bool
_ Exp
_ Exp
under -> Exp -> Maybe Text
braceAnnotationName Exp
under Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe Text
forall a. Maybe a
Nothing
Exp
_ -> Bool
False
braceAnnotationName :: Exp -> Maybe T.Text
braceAnnotationName :: Exp -> Maybe Text
braceAnnotationName Exp
e =
case Exp
e of
ESymbol TeXSymbolType
TOver Text
"\9182" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"overbrace"
ESymbol TeXSymbolType
TOver Text
"\9140" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"overbrace"
ESymbol TeXSymbolType
TUnder Text
"\9183" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"underbrace"
ESymbol TeXSymbolType
TUnder Text
"\9141" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"underbrace"
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
underlineMarkerName :: Exp -> Maybe T.Text
underlineMarkerName :: Exp -> Maybe Text
underlineMarkerName Exp
e =
case Exp
e of
ESymbol TeXSymbolType
TUnder Text
"_" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"underline"
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
renderBraceLabel :: DisplayType -> AlignContext -> Exp -> Maybe T.Text
renderBraceLabel :: DisplayType -> AlignContext -> Exp -> Maybe Text
renderBraceLabel DisplayType
dt AlignContext
ctx Exp
e = do
Text
rendered0 <- DisplayType -> AlignContext -> Exp -> Maybe Text
renderExpIn DisplayType
dt AlignContext
ctx Exp
e
let rendered :: Text
rendered = Text -> Text
T.strip Text
rendered0
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ if Text -> Bool
isQuotedText Text
rendered Bool -> Bool -> Bool
|| Exp -> Bool
isAtomic Exp
e
then Text
rendered
else Text
"{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rendered Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"}"
arrowScriptOpName :: Exp -> Maybe T.Text
arrowScriptOpName :: Exp -> Maybe Text
arrowScriptOpName Exp
e =
case Exp
e of
ESymbol TeXSymbolType
_ Text
"←" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"leftarrow"
ESymbol TeXSymbolType
_ Text
"→" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"toward"
ESymbol TeXSymbolType
_ Text
"↔" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"leftrightarrow"
ESymbol TeXSymbolType
_ Text
"⇐" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"dlarrow"
ESymbol TeXSymbolType
_ Text
"⇒" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"drarrow"
ESymbol TeXSymbolType
_ Text
"⇔" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"dlrarrow"
ESymbol TeXSymbolType
_ Text
"↦" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"mapsto"
ESymbol TeXSymbolType
_ Text
"↑" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"uparrow"
ESymbol TeXSymbolType
_ Text
"↓" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"downarrow"
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
accentName :: Exp -> Maybe T.Text
accentName :: Exp -> Maybe Text
accentName Exp
e =
case Exp
e of
ESymbol TeXSymbolType
Accent Text
s -> Text -> Maybe Text
accentFromChar Text
s
ESymbol TeXSymbolType
TOver Text
s -> Text -> Maybe Text
overAccentFromChar Text
s
ESymbol TeXSymbolType
_ Text
s -> Text -> Maybe Text
accentFromChar Text
s
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
overAccentFromChar :: T.Text -> Maybe T.Text
overAccentFromChar :: Text -> Maybe Text
overAccentFromChar Text
s =
case Text
s of
Text
"\772" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"overline"
Text
"\8254" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"overline"
Text
"¯" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"overline"
Text
_ -> Text -> Maybe Text
accentFromChar Text
s
accentFromChar :: T.Text -> Maybe T.Text
accentFromChar :: Text -> Maybe Text
accentFromChar Text
s =
case Text
s of
Text
"\775" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"dot"
Text
"˙" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"dot"
Text
"\776" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"ddot"
Text
"¨" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"ddot"
Text
"\770" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"hat"
Text
"ˆ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"hat"
Text
"\780" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"check"
Text
"ˇ" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"check"
Text
"\771" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"tilde"
Text
"˜" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"tilde"
Text
"\772" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"bar"
Text
"\8254" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"bar"
Text
"¯" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"bar"
Text
"\8407" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"vec"
Text
"→" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"vec"
Text
"\774" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"breve"
Text
"˘" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"breve"
Text
_ -> Maybe Text
forall a. Maybe a
Nothing
data DelimSide = DelimLeft | DelimRight | DelimMiddle
delimToken :: DelimSide -> T.Text -> T.Text
delimToken :: DelimSide -> Text -> Text
delimToken DelimSide
side Text
raw =
case Text
raw of
Text
"" -> Text
"none"
Text
"." -> Text
"none"
Text
"(" -> Text
"("
Text
")" -> Text
")"
Text
"[" -> Text
"["
Text
"]" -> Text
"]"
Text
"{" -> case DelimSide
side of
DelimSide
DelimLeft -> Text
"lbrace"
DelimSide
DelimRight -> Text
"rbrace"
DelimSide
DelimMiddle -> Text
"{"
Text
"}" -> case DelimSide
side of
DelimSide
DelimLeft -> Text
"lbrace"
DelimSide
DelimRight -> Text
"rbrace"
DelimSide
DelimMiddle -> Text
"}"
Text
"|" -> case DelimSide
side of
DelimSide
DelimLeft -> Text
"lline"
DelimSide
DelimRight -> Text
"rline"
DelimSide
DelimMiddle -> Text
"mline"
Text
"∣" -> case DelimSide
side of
DelimSide
DelimLeft -> Text
"lline"
DelimSide
DelimRight -> Text
"rline"
DelimSide
DelimMiddle -> Text
"mline"
Text
"∥" -> case DelimSide
side of
DelimSide
DelimLeft -> Text
"ldline"
DelimSide
DelimRight -> Text
"rdline"
DelimSide
DelimMiddle -> Text
"mline"
Text
"⟨" -> Text
"langle"
Text
"⟩" -> Text
"rangle"
Text
"⌊" -> Text
"lfloor"
Text
"⌋" -> Text
"rfloor"
Text
"⌈" -> Text
"lceil"
Text
"⌉" -> Text
"rceil"
Text
"⟦" -> Text
"ldbracket"
Text
"⟧" -> Text
"rdbracket"
Text
_ -> Text
raw
renderSymbol :: TeXSymbolType -> T.Text -> T.Text
renderSymbol :: TeXSymbolType -> Text -> Text
renderSymbol TeXSymbolType
t Text
s =
case Text
s of
Text
"∫" -> Text
"int "
Text
"∑" -> Text
"sum "
Text
"←" -> Text
" leftarrow "
Text
"→" -> Text
" toward "
Text
"↔" -> Text
" leftrightarrow "
Text
"⇐" -> Text
" dlarrow "
Text
"⇒" -> Text
" drarrow "
Text
"⇔" -> Text
" dlrarrow "
Text
"↑" -> Text
" uparrow "
Text
"↓" -> Text
" downarrow "
Text
"↦" -> Text
" mapsto "
Text
"\8230 " -> Text
" dotslow "
Text
"… " -> Text
" dotslow "
Text
"\8230" -> Text
" dotslow "
Text
"…" -> Text
" dotslow "
Text
"\8943" -> Text
" dotsaxis "
Text
"⋯" -> Text
" dotsaxis "
Text
"⋮" -> Text
" dotsvert "
Text
"⋱" -> Text
" dotsdown "
Text
"⋰" -> Text
" dotsup "
Text
"∈" -> Text
" in "
Text
"∉" -> Text
" notin "
Text
"∋" -> Text
" owns "
Text
"∩" -> Text
" intersection "
Text
"∪" -> Text
" union "
Text
"⊂" -> Text
" subset "
Text
"⊆" -> Text
" subseteq "
Text
"⊃" -> Text
" supset "
Text
"⊇" -> Text
" supseteq "
Text
"≤" -> Text
" <= "
Text
"≥" -> Text
" >= "
Text
"≠" -> Text
" <> "
Text
"≈" -> Text
" approx "
Text
"≡" -> Text
" equiv "
Text
"\8810" -> Text
" ll "
Text
"≪" -> Text
" ll "
Text
"\8811" -> Text
" gg "
Text
"≫" -> Text
" gg "
Text
"∝" -> Text
" prop "
Text
"∥" -> Text
" parallel "
Text
"⊥" -> Text
" ortho "
Text
"±" -> Text
" plusminus "
Text
"∓" -> Text
" minusplus "
Text
"×" -> Text
" times "
Text
"⋅" -> Text
" cdot "
Text
"·" -> Text
" cdot "
Text
"∘" -> Text
" circ "
Text
"/" -> Text
" / "
Text
"∂" -> Text
"partial"
Text
"∇" -> Text
"nabla"
Text
"∀" -> Text
"forall"
Text
"∃" -> Text
"exists"
Text
"¬" -> Text
"neg"
Text
"∧" -> Text
"and"
Text
"∨" -> Text
"or"
Text
"∞" -> Text
"infinity"
Text
"∅" -> Text
"emptyset"
Text
"+" -> Text
" + "
Text
"-" | TeXSymbolType
t TeXSymbolType -> TeXSymbolType -> Bool
forall a. Eq a => a -> a -> Bool
== TeXSymbolType
Bin -> Text
" - "
Text
"-" -> Text
"-"
Text
"−" | TeXSymbolType
t TeXSymbolType -> TeXSymbolType -> Bool
forall a. Eq a => a -> a -> Bool
== TeXSymbolType
Bin -> Text
" - "
Text
"−" -> Text
"-"
Text
"<" -> Text
" < "
Text
">" -> Text
" > "
Text
"=" -> Text
" = "
Text
"," -> Text
", "
Text
";" -> Text
"; "
Text
":" -> Text
" : "
Text
"!" -> Text
" ! "
Text
"'" -> Text
"'"
Text
"′" -> Text
"'"
Text
"″" -> Text
"''"
Text
"‴" -> Text
"'''"
Text
_ | Text -> Bool
isWordLiteralSymbol Text
s -> Text -> Text
quoteText Text
s
| Bool
otherwise -> Text
s
isWordLiteralSymbol :: T.Text -> Bool
isWordLiteralSymbol :: Text -> Bool
isWordLiteralSymbol Text
s =
Bool -> Bool
not (Text -> Bool
T.null Text
s) Bool -> Bool -> Bool
&& (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isWordLiteralChar Text
s
isWordLiteralChar :: Char -> Bool
isWordLiteralChar :: Char -> Bool
isWordLiteralChar Char
c =
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'A' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'Z') Bool -> Bool -> Bool
||
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'a' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'z') Bool -> Bool -> Bool
||
Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-'
quoteText :: T.Text -> T.Text
quoteText :: Text -> Text
quoteText Text
t = Text
"\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
escapeQuotes Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""
escapeQuotes :: T.Text -> T.Text
escapeQuotes :: Text -> Text
escapeQuotes = HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"\"" Text
"\\\""
isQuotedText :: T.Text -> Bool
isQuotedText :: Text -> Bool
isQuotedText Text
t =
Text -> Int
T.length Text
t Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 Bool -> Bool -> Bool
&& HasCallStack => Text -> Char
Text -> Char
T.head Text
t Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"' Bool -> Bool -> Bool
&& HasCallStack => Text -> Char
Text -> Char
T.last Text
t Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"'
largeOpName :: Exp -> Maybe T.Text
largeOpName :: Exp -> Maybe Text
largeOpName Exp
e =
case Exp
e of
ESymbol TeXSymbolType
Op Text
"\8747" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int"
ESymbol TeXSymbolType
Op Text
"\8751" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"iiint"
ESymbol TeXSymbolType
Op Text
"\8721" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"sum"
ESymbol TeXSymbolType
Op Text
"\8719" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"prod"
ESymbol TeXSymbolType
Op Text
"\8899" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"oper ∪"
ESymbol TeXSymbolType
Op Text
"\8898" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"oper ∩"
ESymbol TeXSymbolType
Op Text
"∫" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int"
ESymbol TeXSymbolType
Op Text
"∭" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"iiint"
ESymbol TeXSymbolType
Op Text
"∑" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"sum"
ESymbol TeXSymbolType
Op Text
"∏" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"prod"
ESymbol TeXSymbolType
Op Text
"⋃" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"oper ∪"
ESymbol TeXSymbolType
Op Text
"⋂" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"oper ∩"
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
limitOpName :: Exp -> Maybe T.Text
limitOpName :: Exp -> Maybe Text
limitOpName Exp
e =
case Exp -> Maybe Text
largeOpName Exp
e of
Just Text
op -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
op
Maybe Text
Nothing ->
case Exp
e of
EMathOperator Text
"lim" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"lim"
EMathOperator Text
"liminf" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"liminf"
EMathOperator Text
"limsup" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"limsup"
EMathOperator Text
"min" -> Maybe Text
forall a. Maybe a
Nothing
EMathOperator Text
"max" -> Maybe Text
forall a. Maybe a
Nothing
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
centeredScriptOpName :: Exp -> Maybe T.Text
centeredScriptOpName :: Exp -> Maybe Text
centeredScriptOpName Exp
e =
case Exp
e of
EMathOperator Text
"min" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"func min"
EMathOperator Text
"max" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"func max"
EMathOperator Text
"det" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"func det"
EMathOperator Text
"Pr" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"func Pr"
EMathOperator Text
"gcd" -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"func gcd"
EMathOperator Text
"lim" -> Maybe Text
forall a. Maybe a
Nothing
EMathOperator Text
"liminf" -> Maybe Text
forall a. Maybe a
Nothing
EMathOperator Text
"limsup" -> Maybe Text
forall a. Maybe a
Nothing
EMathOperator Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Text
renderMathOperator Text
t)
Exp
_ -> Maybe Text
forall a. Maybe a
Nothing
renderTextAtom :: TextType -> T.Text -> T.Text
renderTextAtom :: TextType -> Text -> Text
renderTextAtom TextType
sty Text
t =
case TextType
sty of
TextType
TextItalic -> Text
"ital " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg Text
t
TextType
TextBold -> Text
"bold " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
styleArg (Text -> Text
quoteText Text
t)
TextType
TextMonospace -> Text
"font fixed " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteText Text
t
TextType
TextSansSerif -> Text
"font sans " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteText Text
t
TextType
_ -> Text -> Text
quoteText Text
t