    {-# 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)

    -- | Render TeXMath expressions as StarMath syntax.
    -- Falls back to TeX output for expressions that are not yet supported.
    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
      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] -> [(Exp, Text)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Exp]
    exps [Text]
    rendered
      let merged = [(Exp, Text)] -> Text
    mergePieces [(Exp, Text)]
    pieces
      let 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
      pure $ if endsWithInfixNeedingRhs exps
                then T.stripEnd withLhs <> " {}"
                else 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
          num' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    AlignDefault Exp
    num
          den' <- renderExpIn dt AlignDefault den
          let num'' = AlignContext -> Text -> Text
    maybeCenterFractionArg AlignContext
    ctx Text
    num'
          let den'' = AlignContext -> Text -> Text
    maybeCenterFractionArg AlignContext
    ctx Text
    den'
          pure $ case 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
          idx' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    idx
          rad' <- renderExpIn dt ctx rad
          pure $ "nroot {" <> idx' <> "} {" <> rad' <> "}"

        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
          body <- DisplayType -> AlignContext -> [InEDelimited] -> Maybe Text
    renderDelimitedBody DisplayType
    dt AlignContext
    ctx [InEDelimited]
    xs
          let op' = DelimSide -> Text -> Text
    delimToken DelimSide
    DelimLeft Text
    op
          let cl' = DelimSide -> Text -> Text
    delimToken DelimSide
    DelimRight Text
    cl
          pure $ "left " <> op' <> " " <> body <> " right " <> cl'

        ESub Exp
    base Exp
    sub -> do
          base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
          sub'  <- renderScriptArg dt ctx sub
          pure $ renderScriptBase base base' <> "_" <> sub'

        ESuper Exp
    base Exp
    sup -> do
          baseRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
          case renderPrimeSuffix 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
              supRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    sup
              pure $ renderScriptBase base baseRendered <> "^" <> supRendered

        ESubsup Exp
    base Exp
    sub Exp
    sup -> do
          baseRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
          subRendered <- renderScriptArg dt ctx sub
          case renderPrimeSuffix 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
              supRendered <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    sup
              pure $ renderScriptBase base baseRendered <> "_" <> subRendered <> "^" <> 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
                   over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    over
                   pure $ arrow <> " csup " <> centerScriptArg over'
          | Just Text
    op <- Exp -> Maybe Text
    centeredScriptOpName Exp
    base -> do
              over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    over
              pure $ "{" <> op <> "} csup " <> centerScriptArg over'
          | Just Text
    brace <- Exp -> Maybe Text
    braceAnnotationName Exp
    over -> do
              base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
              pure $ renderScriptBase base base' <> " " <> brace
          | Exp -> Bool
    isBraceAnnotatedExp Exp
    base -> do
              base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
              over' <- renderBraceLabel dt ctx over
              pure $ base' <> " " <> over'
          | Just Text
    accent <- Exp -> Maybe Text
    accentName Exp
    over -> do
              base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
              pure $ accent <> " " <> renderAccentArg base base'
          | Just Text
    op <- Exp -> Maybe Text
    limitOpName Exp
    base -> do
              over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderLimitArg DisplayType
    dt AlignContext
    ctx Exp
    over
              pure $ op <> " to " <> over' <> " "
          | 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
                   under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    under
                   pure $ arrow <> " csub " <> centerScriptArg under'
            Maybe Text
    Nothing ->
              case Exp -> Maybe Text
    underlineMarkerName Exp
    under of
                Just Text
    marker -> do
                  base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
                  pure $ marker <> " " <> renderAccentArg base base'
                Maybe Text
    Nothing ->
                  case Exp -> Maybe Text
    braceAnnotationName Exp
    under of
                    Just Text
    brace -> do
                      base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
                      pure $ renderScriptBase base base' <> " " <> brace
                    Maybe Text
    Nothing ->
                      if Exp -> Bool
    isBraceAnnotatedExp Exp
    base
                         then do
                           base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
                           under' <- renderBraceLabel dt ctx under
                           pure $ base' <> " " <> under'
                         else
                           case Exp -> Maybe Text
    centeredScriptOpName Exp
    base of
                             Just Text
    op -> do
                               under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    under
                               pure $ "{" <> op <> "} csub " <> centerScriptArg under'
                             Maybe Text
    Nothing ->
                               case Exp -> Maybe Text
    limitOpName Exp
    base of
                                 Just Text
    op -> do
                                   under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderLimitArg DisplayType
    dt AlignContext
    ctx Exp
    under
                                   pure $ op <> " from " <> under' <> " "
                                 Maybe Text
    Nothing -> do
                                   base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
                                   under' <- renderScriptArg dt ctx under
                                   pure $ renderScriptBase base base' <> "_" <> 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
                  under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    under
                  pure $ arrow <> " csub " <> centerScriptArg under'
                (Bool
    True, Bool
    False) -> do
                  over' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    over
                  pure $ arrow <> " csup " <> centerScriptArg over'
                (Bool
    False, Bool
    False) -> do
                  under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    under
                  over' <- renderScriptArg dt ctx over
                  pure $ arrow <> " csub " <> centerScriptArg under'
                      <> " csup " <> centerScriptArg over'
            Maybe Text
    Nothing ->
              case Exp -> Maybe Text
    centeredScriptOpName Exp
    base of
                Just Text
    op -> do
                  under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderScriptArg DisplayType
    dt AlignContext
    ctx Exp
    under
                  over' <- renderScriptArg dt ctx over
                  pure $ "{" <> op <> "} csub " <> centerScriptArg under'
                      <> " csup " <> centerScriptArg over'
                Maybe Text
    Nothing ->
                  case Exp -> Maybe Text
    limitOpName Exp
    base of
                    Just Text
    op -> do
                      under' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderLimitArg DisplayType
    dt AlignContext
    ctx Exp
    under
                      over'  <- renderLimitArg dt ctx over
                      pure $ op <> " from " <> under' <> " to " <> over' <> " "
                    Maybe Text
    Nothing -> do
                      base' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    base
                      under' <- renderScriptArg dt ctx under
                      over' <- renderScriptArg dt ctx over
                      pure $ renderScriptBase base base' <> "_" <> under' <> "^" <> over'
        EArray [Alignment]
    aligns [ArrayLine]
    rows -> DisplayType -> [Alignment] -> [ArrayLine] -> Maybe Text
    renderMatrix DisplayType
    dt [Alignment]
    aligns [ArrayLine]
    rows
        EPhantom Exp
    x         -> do
          x' <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    x
          pure $ "phantom " <> renderPhantomArg x 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
      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
      pure $ T.strip (mergeDelimitedChunks 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
      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
      pure $ "matrix { " <> T.intercalate " ## " rows' <> " }"

    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 [])
      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
        ]
      pure $ T.intercalate " # " 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
      rendered <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
    renderExpsIn DisplayType
    dt AlignContext
    ctx [Exp]
    xs
      let stripped = Text -> Text
    T.strip Text
    rendered
      pure $ if T.null stripped then "{}" else 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
      cell <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
    renderMatrixCell DisplayType
    dt (Alignment -> AlignContext
    alignmentContext Alignment
    align) [Exp]
    xs
      pure $ case 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
      body <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
    renderExpsIn DisplayType
    dt AlignContext
    ctx [Exp]
    xs
      pure $ case 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
          base' <- Exp -> Maybe Text
    styledTextExp Exp
    base
          sub'  <- styledTextNonNumericExp sub
          pure $ base' <> "_" <> sub'
        ESuper Exp
    base Exp
    sup   -> do
          base' <- Exp -> Maybe Text
    styledTextExp Exp
    base
          sup'  <- styledTextNonNumericExp sup
          pure $ base' <> "^" <> sup'
        ESubsup Exp
    base Exp
    sub Exp
    sup -> do
          base' <- Exp -> Maybe Text
    styledTextExp Exp
    base
          sub'  <- styledTextNonNumericExp sub
          sup'  <- styledTextNonNumericExp sup
          pure $ base' <> "_" <> sub' <> "^" <> 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
      txt <- Exp -> Maybe Text
    styledTextExp Exp
    e
      if T.any isAsciiDigit txt
         then Nothing
         else Just 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
      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'
      pure $ mergePieces (zip xs' 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
          body <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
    renderExpsIn DisplayType
    dt AlignContext
    AlignDefault [Exp]
    xs
          pure $ "bold nitalic " <> styleArg 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
          base' <- DisplayType -> Exp -> Maybe Text
    renderTextNormalExp DisplayType
    dt Exp
    base
          sub'  <- renderTextNormalExp dt sub
          pure $ base' <> "_" <> sub'
        ESuper Exp
    base Exp
    sup -> do
          base' <- DisplayType -> Exp -> Maybe Text
    renderTextNormalExp DisplayType
    dt Exp
    base
          sup'  <- renderTextNormalExp dt sup
          pure $ base' <> "^" <> sup'
        ESubsup Exp
    base Exp
    sub Exp
    sup -> do
          base' <- DisplayType -> Exp -> Maybe Text
    renderTextNormalExp DisplayType
    dt Exp
    base
          sub'  <- renderTextNormalExp dt sub
          sup'  <- renderTextNormalExp dt sup
          pure $ base' <> "_" <> sub' <> "^" <> 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
      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 -> Text
    T.strip Text
    rendered0
      pure $ if (isAtomic e && not (needsNeutralScriptOperands e)) || isQuotedText rendered
                then rendered
                else "{" <> rendered <> "}"

    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
          rendered <- DisplayType -> AlignContext -> [Exp] -> Maybe Text
    renderExpsIn DisplayType
    dt AlignContext
    ctx [Exp]
    xs
          let stripped = Text -> Text
    T.strip Text
    rendered
          pure $
            if T.null stripped
               then "{}"
               else if containsRelationLike xs
                       then stripped
               else if isQuotedText stripped || isWrapped stripped || T.length stripped == 1
                       then stripped
                       else "{" <> stripped <> "}"
        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
      rendered0 <- DisplayType -> AlignContext -> Exp -> Maybe Text
    renderExpIn DisplayType
    dt AlignContext
    ctx Exp
    e
      let rendered = Text -> Text
    T.strip Text
    rendered0
      pure $ if isQuotedText rendered || isAtomic e
                then rendered
                else "{" <> rendered <> "}"

    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