    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE ViewPatterns #-}
    {-
    Copyright (C) 2012 John MacFarlane <jgm@berkeley.edu>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    -}

    {- | Functions for writing a parsed formula as OMML.
    -}

    module Text.TeXMath.Writers.OMML (writeOMML)
    where

    import Text.XML.Light
    import Text.TeXMath.Types
    import Text.TeXMath.Shared (isUppercaseGreek, isRLSequence)
    import Data.Generics (everywhere, mkT)
    import Data.Char (isSymbol, isPunctuation)
    import Data.Either (lefts, isLeft, rights)
    import qualified Data.Text as T
    import Data.List.Split  (splitWhen)
    import Data.List (intercalate)

    -- | Transforms an expression tree to an OMML XML Tree
    writeOMML :: DisplayType -> [Exp] -> Element
    writeOMML :: DisplayType -> [Exp] -> Element
    writeOMML DisplayType
    dt = [Element] -> Element
    container ([Element] -> Element) -> ([Exp] -> [Element]) -> [Exp] -> Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Exp -> [Element]) -> [Exp] -> [Element]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([Element] -> Exp -> [Element]
    showExp [])
                ([Exp] -> [Element]) -> ([Exp] -> [Exp]) -> [Exp] -> [Element]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (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]
    handleDownup DisplayType
    dt)
                ([Exp] -> [Exp]) -> ([Exp] -> [Exp]) -> [Exp] -> [Exp]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (forall a. Data a => a -> a) -> forall a. Data a => a -> a
    everywhere (([InEDelimited] -> [InEDelimited]) -> a -> a
    forall a b. (Typeable a, Typeable b) => (b -> b) -> a -> a
    mkT (([InEDelimited] -> [InEDelimited]) -> a -> a)
    -> ([InEDelimited] -> [InEDelimited]) -> a -> a
    forall a b. (a -> b) -> a -> b
    $ DisplayType -> [InEDelimited] -> [InEDelimited]
    handleDownup' DisplayType
    dt)
                ([Exp] -> [Exp]) -> ([Exp] -> [Exp]) -> [Exp] -> [Exp]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (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
    $ [Exp] -> [Exp]
    handleScaledDelims)
        where container :: [Element] -> Element
    container = case DisplayType
    dt of
                      DisplayType
    DisplayBlock  -> \[Element]
    x -> String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "oMathPara"
                                        [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "oMathParaPr"
                                          (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "jc" String
    "center" ()
                                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "oMath" [Element]
    x ]
                      DisplayType
    DisplayInline -> String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "oMath"

    -- Kept as String for Text.XML.Light
    mnode :: Node t => String -> t -> Element
    mnode :: forall t. Node t => String -> t -> Element
    mnode String
    s = QName -> t -> Element
    forall t. Node t => QName -> t -> Element
    node (String -> Maybe String -> Maybe String -> QName
    QName String
    s Maybe String
    forall a. Maybe a
    Nothing (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    "m"))

    -- Kept as String for Text.XML.Light
    mnodeA :: Node t => String -> String -> t -> Element
    mnodeA :: forall t. Node t => String -> String -> t -> Element
    mnodeA String
    s String
    v = Attr -> Element -> Element
    add_attr (QName -> String -> Attr
    Attr (String -> Maybe String -> Maybe String -> QName
    QName String
    "val" Maybe String
    forall a. Maybe a
    Nothing (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    "m")) String
    v) (Element -> Element) -> (t -> Element) -> t -> Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> t -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    s

    str :: [Element] -> T.Text -> Element
    str :: [Element] -> Text -> Element
    str []    Text
    s = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "r" [ String -> String -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "t" (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    T.unpack Text
    s ]
    str [Element]
    props Text
    s = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "r" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "rPr" [Element]
    props
                            , String -> String -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "t" (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    T.unpack Text
    s ]

    showFraction :: [Element] -> FractionType -> Exp -> Exp -> Element
    showFraction :: [Element] -> FractionType -> Exp -> Exp -> Element
    showFraction [Element]
    props FractionType
    ft Exp
    x Exp
    y =
      case FractionType
    ft of
           FractionType
    NormalFrac -> String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "f" [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "fPr" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
                                    String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "type" String
    "bar" ()
                                 , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "num" [Element]
    x'
                                 , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "den" [Element]
    y']
           FractionType
    DisplayFrac -> [Element] -> FractionType -> Exp -> Exp -> Element
    showFraction [Element]
    props FractionType
    NormalFrac Exp
    x Exp
    y
           FractionType
    InlineFrac -> String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "f" [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "fPr" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
                                     String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "type" String
    "lin" ()
                                  , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "num" [Element]
    x'
                                  , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "den" [Element]
    y']
           FractionType
    NoLineFrac -> String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "f" [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "fPr" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
                                                  String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "type" String
    "noBar" ()
                                                 , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "num" [Element]
    x'
                                                 , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "den" [Element]
    y'
                                                 ]
        where x' :: [Element]
    x' = [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x
              y' :: [Element]
    y' = [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    y

    maximum' :: [Int] -> Int
    maximum' :: [Int] -> Int
    maximum' [] = Int
    0
    maximum' [Int]
    xs = [Int] -> Int
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [Int]
    xs

    makeArray :: [Element] -> [Alignment] -> [ArrayLine] -> Element
    makeArray :: [Element] -> [Alignment] -> [ArrayLine] -> Element
    makeArray [Element]
    props [Alignment]
    as [ArrayLine]
    rs
      | [Alignment] -> Bool
    isRLSequence [Alignment]
    as = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "eqArr" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ (ArrayLine -> Element) -> [ArrayLine] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map ArrayLine -> Element
    forall {t :: * -> *}. Foldable t => [t Exp] -> Element
    toE [ArrayLine]
    rs
      where toE :: [t Exp] -> Element
    toE [t Exp]
    r = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> [[Element]] -> [Element]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Element]
    ampersand
                                ((t Exp -> [Element]) -> [t Exp] -> [[Element]]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Exp -> [Element]) -> t Exp -> [Element]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([Element] -> Exp -> [Element]
    showExp [Element]
    props)) [t Exp]
    r))
            ampersand :: [Element]
    ampersand = [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "r" [ String -> String -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "t" (String
    "&" :: String) ]]
    makeArray [Element]
    props [Alignment]
    as [ArrayLine]
    rs = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "m" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ Element
    mProps Element -> [Element] -> [Element]
    forall a. a -> [a] -> [a]
    : (ArrayLine -> Element) -> [ArrayLine] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map ArrayLine -> Element
    forall {t :: * -> *}. Foldable t => [t Exp] -> Element
    toMr [ArrayLine]
    rs
      where mProps :: Element
    mProps = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "mPr"
                      [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "baseJc" String
    "center" ()
                      , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "plcHide" String
    "on" ()
                      , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "mcs" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ (Alignment -> Element) -> [Alignment] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map Alignment -> Element
    toMc [Alignment]
    as' ]
            as' :: [Alignment]
    as'    = Int -> [Alignment] -> [Alignment]
    forall a. Int -> [a] -> [a]
    take ([Int] -> Int
    maximum' ([Int] -> Int) -> [Int] -> Int
    forall a b. (a -> b) -> a -> b
    $ (ArrayLine -> Int) -> [ArrayLine] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map ArrayLine -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [ArrayLine]
    rs) ([Alignment] -> [Alignment]) -> [Alignment] -> [Alignment]
    forall a b. (a -> b) -> a -> b
    $ [Alignment]
    as [Alignment] -> [Alignment] -> [Alignment]
    forall a. [a] -> [a] -> [a]
    ++ Alignment -> [Alignment]
    forall a. a -> [a]
    repeat Alignment
    AlignCenter
            toMr :: [t Exp] -> Element
    toMr [t Exp]
    r = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "mr" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ (t Exp -> Element) -> [t Exp] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> (t Exp -> [Element]) -> t Exp -> Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Exp -> [Element]) -> t Exp -> [Element]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([Element] -> Exp -> [Element]
    showExp [Element]
    props)) [t Exp]
    r
            toMc :: Alignment -> Element
    toMc Alignment
    a = String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "mc" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "mcPr"
                                [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "mcJc" (Alignment -> String
    forall {a}. IsString a => Alignment -> a
    toAlign Alignment
    a) ()
                                , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "count" String
    "1" ()
                                ]
            toAlign :: Alignment -> a
    toAlign Alignment
    AlignLeft    = a
    "left"
            toAlign Alignment
    AlignRight   = a
    "right"
            toAlign Alignment
    AlignCenter  = a
    "center"

    makeText :: TextType -> T.Text -> Element
    makeText :: TextType -> Text -> Element
    makeText TextType
    a Text
    s = [Element] -> Text -> Element
    str (String -> () -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "nor" () Element -> [Element] -> [Element]
    forall a. a -> [a] -> [a]
    : TextType -> [Element]
    setProps TextType
    a) Text
    s

    defaultTo :: TextType -> [Element] -> [Element]
    defaultTo :: TextType -> [Element] -> [Element]
    defaultTo TextType
    tt [] = TextType -> [Element]
    setProps TextType
    tt
    defaultTo TextType
    _  [Element]
    ps = [Element]
    ps

    setProps :: TextType -> [Element]
    setProps :: TextType -> [Element]
    setProps TextType
    tt =
      case TextType
    tt of
           TextType
    TextNormal       -> [String -> Element
    sty String
    "p"]
           TextType
    TextBold         -> [String -> Element
    sty String
    "b"]
           TextType
    TextItalic       -> [String -> Element
    sty String
    "i"]
           TextType
    TextMonospace    -> [String -> Element
    scr String
    "monospace", String -> Element
    sty String
    "p"]
           TextType
    TextSansSerif    -> [String -> Element
    scr String
    "sans-serif", String -> Element
    sty String
    "p"]
           TextType
    TextDoubleStruck -> [String -> Element
    scr String
    "double-struck", String -> Element
    sty String
    "p"]
           TextType
    TextScript       -> [String -> Element
    scr String
    "script", String -> Element
    sty String
    "p"]
           TextType
    TextFraktur      -> [String -> Element
    scr String
    "fraktur", String -> Element
    sty String
    "p"]
           TextType
    TextBoldItalic    -> [String -> Element
    sty String
    "bi"]
           TextType
    TextSansSerifBold -> [String -> Element
    scr String
    "sans-serif", String -> Element
    sty String
    "b"]
           TextType
    TextBoldScript    -> [String -> Element
    scr String
    "script", String -> Element
    sty String
    "b"]
           TextType
    TextBoldFraktur   -> [String -> Element
    scr String
    "fraktur", String -> Element
    sty String
    "b"]
           TextType
    TextSansSerifItalic -> [String -> Element
    scr String
    "sans-serif", String -> Element
    sty String
    "i"]
           TextType
    TextSansSerifBoldItalic -> [String -> Element
    scr String
    "sans-serif", String -> Element
    sty String
    "bi"]
       where sty :: String -> Element
    sty String
    x = String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "sty" String
    x ()
             scr :: String -> Element
    scr String
    x = String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "scr" String
    x ()

    handleScaledDelims :: [Exp] -> [Exp]
    handleScaledDelims :: [Exp] -> [Exp]
    handleScaledDelims (x :: Exp
    x@(EScaled Rational
    scale (ESymbol TeXSymbolType
    Open Text
    op)) : [Exp]
    xs) =
      case (Exp -> Bool) -> [Exp] -> ([Exp], [Exp])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Exp -> Bool
    isCloser [Exp]
    xs of
        ([Exp]
    ys, EScaled Rational
    scale' (ESymbol TeXSymbolType
    Close Text
    cl) : [Exp]
    zs) | Rational
    scale' Rational -> Rational -> Bool
    forall a. Eq a => a -> a -> Bool
    == Rational
    scale ->
          Text -> Text -> [InEDelimited] -> Exp
    EDelimited Text
    op Text
    cl ((Exp -> InEDelimited) -> [Exp] -> [InEDelimited]
    forall a b. (a -> b) -> [a] -> [b]
    map Exp -> InEDelimited
    forall a b. b -> Either a b
    Right [Exp]
    ys) Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    zs
        ([Exp], [Exp])
    _ -> Exp
    xExp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    :[Exp]
    xs
     where
      isCloser :: Exp -> Bool
    isCloser (EScaled Rational
    _ (ESymbol TeXSymbolType
    Close Text
    _)) = Bool
    True
      isCloser Exp
    _ = Bool
    False
    handleScaledDelims [Exp]
    xs = [Exp]
    xs

    handleDownup :: DisplayType -> [Exp] -> [Exp]
    handleDownup :: DisplayType -> [Exp] -> [Exp]
    handleDownup DisplayType
    dt (Exp
    exp' : [Exp]
    xs) =
      case Exp
    exp' of
           EOver Bool
    convertible Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  ->
                 [Exp] -> Exp
    EGrouped [Bool -> Exp -> Exp -> Exp -> Exp
    EUnderover Bool
    convertible Exp
    x Exp
    emptyGroup Exp
    y, Exp
    next] Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    rest
             | Bool
    convertible Bool -> Bool -> Bool
    && DisplayType
    dt DisplayType -> DisplayType -> Bool
    forall a. Eq a => a -> a -> Bool
    == DisplayType
    DisplayInline -> Exp -> Exp -> Exp
    ESuper Exp
    x Exp
    y Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    xs
           EUnder Bool
    convertible Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  ->
                 [Exp] -> Exp
    EGrouped [Bool -> Exp -> Exp -> Exp -> Exp
    EUnderover Bool
    convertible Exp
    x Exp
    y Exp
    emptyGroup, Exp
    next] Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    rest
             | Bool
    convertible Bool -> Bool -> Bool
    && DisplayType
    dt DisplayType -> DisplayType -> Bool
    forall a. Eq a => a -> a -> Bool
    == DisplayType
    DisplayInline -> Exp -> Exp -> Exp
    ESub Exp
    x Exp
    y Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    xs
           EUnderover Bool
    convertible Exp
    x Exp
    y Exp
    z
             | Exp -> Bool
    isNary Exp
    x  ->
                 [Exp] -> Exp
    EGrouped [Bool -> Exp -> Exp -> Exp -> Exp
    EUnderover Bool
    convertible Exp
    x Exp
    y Exp
    z, Exp
    next] Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    rest
             | Bool
    convertible Bool -> Bool -> Bool
    && DisplayType
    dt DisplayType -> DisplayType -> Bool
    forall a. Eq a => a -> a -> Bool
    == DisplayType
    DisplayInline -> Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    y Exp
    z Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    xs
           ESub Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  -> [Exp] -> Exp
    EGrouped [Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    y Exp
    emptyGroup, Exp
    next] Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    rest
           ESuper Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  -> [Exp] -> Exp
    EGrouped [Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    emptyGroup Exp
    y, Exp
    next] Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    rest
           ESubsup Exp
    x Exp
    y Exp
    z
             | Exp -> Bool
    isNary Exp
    x  -> [Exp] -> Exp
    EGrouped [Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    y Exp
    z, Exp
    next] Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    rest
           Exp
    _             -> Exp
    exp' Exp -> [Exp] -> [Exp]
    forall a. a -> [a] -> [a]
    : [Exp]
    xs
        where (Exp
    next, [Exp]
    rest) = case [Exp]
    xs of
                                  (Exp
    t:[Exp]
    ts) -> (Exp
    t,[Exp]
    ts)
                                  []     -> (Exp
    emptyGroup, [])
              emptyGroup :: Exp
    emptyGroup = [Exp] -> Exp
    EGrouped []
    handleDownup DisplayType
    _ []            = []

    -- TODO This duplication is ugly and inefficient.  See #92.
    handleDownup' :: DisplayType -> [InEDelimited] -> [InEDelimited]
    handleDownup' :: DisplayType -> [InEDelimited] -> [InEDelimited]
    handleDownup' DisplayType
    dt ((Right Exp
    exp') : [InEDelimited]
    xs) =
      case Exp
    exp' of
           EOver Bool
    convertible Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  ->
                 Exp -> InEDelimited
    forall a b. b -> Either a b
    Right ([Exp] -> Exp
    EGrouped [Bool -> Exp -> Exp -> Exp -> Exp
    EUnderover Bool
    convertible Exp
    x Exp
    emptyGroup Exp
    y, Exp
    next]) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    :
                 [InEDelimited]
    rest
             | Bool
    convertible Bool -> Bool -> Bool
    && DisplayType
    dt DisplayType -> DisplayType -> Bool
    forall a. Eq a => a -> a -> Bool
    == DisplayType
    DisplayInline -> Exp -> InEDelimited
    forall a b. b -> Either a b
    Right (Exp -> Exp -> Exp
    ESuper Exp
    x Exp
    y) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    xs
           EUnder Bool
    convertible Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  ->
                 Exp -> InEDelimited
    forall a b. b -> Either a b
    Right ([Exp] -> Exp
    EGrouped [Bool -> Exp -> Exp -> Exp -> Exp
    EUnderover Bool
    convertible Exp
    x Exp
    y Exp
    emptyGroup, Exp
    next]) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    :
                 [InEDelimited]
    rest
             | Bool
    convertible Bool -> Bool -> Bool
    && DisplayType
    dt DisplayType -> DisplayType -> Bool
    forall a. Eq a => a -> a -> Bool
    == DisplayType
    DisplayInline -> Exp -> InEDelimited
    forall a b. b -> Either a b
    Right (Exp -> Exp -> Exp
    ESub Exp
    x Exp
    y) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    xs
           EUnderover Bool
    convertible Exp
    x Exp
    y Exp
    z
             | Exp -> Bool
    isNary Exp
    x  ->
                 Exp -> InEDelimited
    forall a b. b -> Either a b
    Right ([Exp] -> Exp
    EGrouped [Bool -> Exp -> Exp -> Exp -> Exp
    EUnderover Bool
    convertible Exp
    x Exp
    y Exp
    z, Exp
    next]) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    rest
             | Bool
    convertible Bool -> Bool -> Bool
    && DisplayType
    dt DisplayType -> DisplayType -> Bool
    forall a. Eq a => a -> a -> Bool
    == DisplayType
    DisplayInline -> Exp -> InEDelimited
    forall a b. b -> Either a b
    Right (Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    y Exp
    z) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    xs
           ESub Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  -> Exp -> InEDelimited
    forall a b. b -> Either a b
    Right ([Exp] -> Exp
    EGrouped [Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    y Exp
    emptyGroup, Exp
    next]) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    rest
           ESuper Exp
    x Exp
    y
             | Exp -> Bool
    isNary Exp
    x  -> Exp -> InEDelimited
    forall a b. b -> Either a b
    Right ([Exp] -> Exp
    EGrouped [Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    emptyGroup Exp
    y, Exp
    next]) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    rest
           ESubsup Exp
    x Exp
    y Exp
    z
             | Exp -> Bool
    isNary Exp
    x  -> Exp -> InEDelimited
    forall a b. b -> Either a b
    Right ([Exp] -> Exp
    EGrouped [Exp -> Exp -> Exp -> Exp
    ESubsup Exp
    x Exp
    y Exp
    z, Exp
    next]) InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    rest
           Exp
    _             -> Exp -> InEDelimited
    forall a b. b -> Either a b
    Right Exp
    exp' InEDelimited -> [InEDelimited] -> [InEDelimited]
    forall a. a -> [a] -> [a]
    : [InEDelimited]
    xs
        where (Exp
    next, [InEDelimited]
    rest) = case [InEDelimited]
    xs of
                                  (Right Exp
    t:[InEDelimited]
    ts) -> (Exp
    t,[InEDelimited]
    ts)
                                  [InEDelimited]
    _            -> (Exp
    emptyGroup, [InEDelimited]
    xs)
              emptyGroup :: Exp
    emptyGroup = [Exp] -> Exp
    EGrouped []
    handleDownup' DisplayType
    _ [InEDelimited]
    xs = [InEDelimited]
    xs

    showExp :: [Element] -> Exp -> [Element]
    showExp :: [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    e =
     case Exp
    e of
       ENumber Text
    x        -> [[Element] -> Text -> Element
    str [Element]
    props Text
    x]
       EGrouped [EUnderover Bool
    _ (ESymbol TeXSymbolType
    Op Text
    s) Exp
    y Exp
    z, Exp
    w] ->
         [[Element] -> String -> Text -> Exp -> Exp -> Exp -> Element
    makeNary [Element]
    props String
    "undOvr" Text
    s Exp
    y Exp
    z Exp
    w]
       EGrouped [ESubsup (ESymbol TeXSymbolType
    Op Text
    s) Exp
    y Exp
    z, Exp
    w] ->
         [[Element] -> String -> Text -> Exp -> Exp -> Exp -> Element
    makeNary [Element]
    props String
    "subSup" Text
    s Exp
    y Exp
    z Exp
    w]
       EGrouped []      -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x200B"] -- avoid dashed box, see #118
       EGrouped [Exp]
    xs      -> (Exp -> [Element]) -> [Exp] -> [Element]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([Element] -> Exp -> [Element]
    showExp [Element]
    props) [Exp]
    xs
       EDelimited Text
    start Text
    end [InEDelimited]
    xs ->
                      [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "d" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "dPr"
                                   [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "begChr" (Text -> String
    T.unpack Text
    start) ()
                                   , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "sepChr" (Text -> String
    T.unpack Text
    sepchr) ()
                                   , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "endChr" (Text -> String
    T.unpack Text
    end) ()
                                   , String -> () -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "grow" () ]
                                  Element -> [Element] -> [Element]
    forall a. a -> [a] -> [a]
    : ([Exp] -> Element) -> ArrayLine -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> ([Exp] -> [Element]) -> [Exp] -> Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Exp -> [Element]) -> [Exp] -> [Element]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([Element] -> Exp -> [Element]
    showExp [Element]
    props)) ArrayLine
    es
                      ]
          where
           seps :: [Text]
    seps = [InEDelimited] -> [Text]
    forall a b. [Either a b] -> [a]
    lefts [InEDelimited]
    xs
           sepchr :: Text
    sepchr = case [Text]
    seps of
                      []    -> Text
    ""
                      (Text
    s:[Text]
    _) -> Text
    s
           es :: ArrayLine
    es   = ([InEDelimited] -> [Exp]) -> [[InEDelimited]] -> ArrayLine
    forall a b. (a -> b) -> [a] -> [b]
    map [InEDelimited] -> [Exp]
    forall a b. [Either a b] -> [b]
    rights ([[InEDelimited]] -> ArrayLine) -> [[InEDelimited]] -> ArrayLine
    forall a b. (a -> b) -> a -> b
    $ (InEDelimited -> Bool) -> [InEDelimited] -> [[InEDelimited]]
    forall a. (a -> Bool) -> [a] -> [[a]]
    splitWhen InEDelimited -> Bool
    forall a b. Either a b -> Bool
    isLeft [InEDelimited]
    xs

       EIdentifier Text
    ""   -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x200B"]  -- 0-width space
                           -- to avoid the dashed box we get otherwise; see #118
       EIdentifier Text
    x
         | Text -> Bool
    isUppercaseGreek Text
    x
         , [Element] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Element]
    props -> [[Element] -> Text -> Element
    str [String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "sty" String
    "p" ()] Text
    x]
         | Bool -> Bool
    not (Text -> Bool
    isUppercaseGreek Text
    x)
         , [Element{ elName :: Element -> QName
    elName = QName String
    "sty" Maybe String
    _ Maybe String
    _
                  , elAttribs :: Element -> [Attr]
    elAttribs = [Attr (QName String
    "val" Maybe String
    Nothing (Just String
    "m")) String
    "b"] }] <- [Element]
    props
          -> [[Element] -> Text -> Element
    str [String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "sty" String
    "bi" ()] Text
    x] -- #280
         | Bool
    otherwise  -> [[Element] -> Text -> Element
    str [Element]
    props Text
    x]
       EMathOperator Text
    x  -> [[Element] -> Text -> Element
    str (String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "sty" String
    "p" () Element -> [Element] -> [Element]
    forall a. a -> [a] -> [a]
    : [Element]
    props) Text
    x]
       ESymbol TeXSymbolType
    ty Text
    xs
        | Just (Char
    c, Text
    xs') <- Text -> Maybe (Char, Text)
    T.uncons Text
    xs
        , Text -> Bool
    T.null Text
    xs'
        , Char -> Bool
    isSymbol Char
    c Bool -> Bool -> Bool
    || Char -> Bool
    isPunctuation Char
    c
                        -> [[Element] -> Text -> Element
    str (TextType -> [Element] -> [Element]
    defaultTo TextType
    TextNormal [Element]
    props) Text
    xs]
        | TeXSymbolType
    ty TeXSymbolType -> [TeXSymbolType] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [TeXSymbolType
    Op, TeXSymbolType
    Bin, TeXSymbolType
    Rel]
                        -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "box"
                            [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "boxPr"
                              [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "opEmu" String
    "on" () ]
                            , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e"
                              [[Element] -> Text -> Element
    str (TextType -> [Element] -> [Element]
    defaultTo TextType
    TextNormal [Element]
    props) Text
    xs]
                            ]]
        | Bool
    otherwise     -> [[Element] -> Text -> Element
    str (TextType -> [Element] -> [Element]
    defaultTo TextType
    TextNormal [Element]
    props) Text
    xs]
       ESpace Rational
    n
         | Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    0 Bool -> Bool -> Bool
    && Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Rational
    0.17    -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x2009"]
         | Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    0.17 Bool -> Bool -> Bool
    && Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Rational
    0.23 -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x2005"]
         | Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    0.23 Bool -> Bool -> Bool
    && Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Rational
    0.28 -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x2004"]
         | Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    0.28 Bool -> Bool -> Bool
    && Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Rational
    0.5  -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x2004"]
         | Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    0.5 Bool -> Bool -> Bool
    && Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Rational
    1.8   -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x2001"]
         | Rational
    n Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    1.8               -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x2001\x2001"]
         | Bool
    otherwise             -> [[Element] -> Text -> Element
    str [Element]
    props Text
    "\x200B"]
           -- this is how the xslt sheet handles all spaces
       EUnder Bool
    _ Exp
    x (ESymbol TeXSymbolType
    TUnder Text
    t) | (Char -> Bool) -> Text -> Bool
    T.all Char -> Bool
    isBarChar Text
    t ->
                           [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "bar" [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "barPr" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
                                            String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "pos" String
    "bot" ()
                                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x ]]
       EOver Bool
    _ Exp
    x (ESymbol TeXSymbolType
    TOver Text
    t) | (Char -> Bool) -> Text -> Bool
    T.all Char -> Bool
    isBarChar Text
    t ->
                           [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "bar" [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "barPr" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
                                            String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "pos" String
    "top" ()
                                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x ]]
       EOver Bool
    _ Exp
    x (ESymbol TeXSymbolType
    st (Text -> String
    T.unpack -> String
    y))
        | TeXSymbolType
    st TeXSymbolType -> TeXSymbolType -> Bool
    forall a. Eq a => a -> a -> Bool
    == TeXSymbolType
    Accent  -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "acc" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "accPr" [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "chr" String
    y () ]
                                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x ]]
        | TeXSymbolType
    st TeXSymbolType -> TeXSymbolType -> Bool
    forall a. Eq a => a -> a -> Bool
    == TeXSymbolType
    TUnder  -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "groupChr" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "groupChrPr"
                                               [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "chr" String
    y ()
                                               , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "pos" String
    "bot" ()
                                               , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "vertJc" String
    "top" () ]
                                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x ]]
        | TeXSymbolType
    st TeXSymbolType -> TeXSymbolType -> Bool
    forall a. Eq a => a -> a -> Bool
    == TeXSymbolType
    TOver   -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "groupChr" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "groupChrPr"
                                               [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "chr" String
    y ()
                                               , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "pos" String
    "top" ()
                                               , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "vertJc" String
    "bot" () ]
                                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x ]]
       ESub Exp
    x Exp
    y         -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sSub" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x
                                         , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sub" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    y]]
       ESuper Exp
    x Exp
    y       -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sSup" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x
                                         , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sup" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    y]]
       ESubsup Exp
    x Exp
    y Exp
    z    -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sSubSup" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x
                                            , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sub" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    y
                                            , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sup" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    z]]
       EUnder Bool
    _ Exp
    x Exp
    y  -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "limLow" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x
                                           , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "lim" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    y]]
       EOver Bool
    _ Exp
    x Exp
    y   -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "limUpp" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x
                                           , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "lim" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    y]]
       EUnderover Bool
    c Exp
    x Exp
    y Exp
    z -> [Element] -> Exp -> [Element]
    showExp [Element]
    props (Bool -> Exp -> Exp -> Exp
    EUnder Bool
    c (Bool -> Exp -> Exp -> Exp
    EOver Bool
    c Exp
    x Exp
    z) Exp
    y)
       ESqrt Exp
    x       -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "rad" [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "radPr" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "degHide" String
    "on" ()
                                          , String -> () -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "deg" ()
                                          , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x]]
       ERoot Exp
    i Exp
    x     -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "rad" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "deg" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    i
                                     , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x]]
       EFraction FractionType
    ft Exp
    x Exp
    y -> [[Element] -> FractionType -> Exp -> Exp -> Element
    showFraction [Element]
    props FractionType
    ft Exp
    x Exp
    y]
       EPhantom Exp
    x       -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "phant" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "phantPr"
                                                [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "show" String
    "off" () ]
                                              , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x]]
       EBoxed   Exp
    x       -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "borderBox" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x]]
       ECancel StrokeType
    st Exp
    x     -> [[Element] -> StrokeType -> Exp -> Element
    makeCancel [Element]
    props StrokeType
    st Exp
    x]
       EScaled Rational
    _ Exp
    x      -> [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x -- no support for scaler?
       EArray [Alignment]
    as [ArrayLine]
    ls     -> [[Element] -> [Alignment] -> [ArrayLine] -> Element
    makeArray [Element]
    props [Alignment]
    as [ArrayLine]
    ls]
       EText TextType
    a Text
    s        -> [TextType -> Text -> Element
    makeText TextType
    a Text
    s]
       EStyled TextType
    a [Exp]
    es     -> (Exp -> [Element]) -> [Exp] -> [Element]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([Element] -> Exp -> [Element]
    showExp (TextType -> [Element]
    setProps TextType
    a)) [Exp]
    es

    isBarChar :: Char -> Bool
    isBarChar :: Char -> Bool
    isBarChar Char
    c = Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\x203E' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\x00AF' Bool -> Bool -> Bool
    ||
                  Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\x0304' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\x0333' Bool -> Bool -> Bool
    ||
                  Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '_'

    -- | Checks whether an expression marks the start of an nary operator
    -- expression. These are different integrals, sums, products, and
    -- coproducts.
    isNary :: Exp -> Bool
    isNary :: Exp -> Bool
    isNary (ESymbol TeXSymbolType
    Op Text
    s) = case Text
    s of
      Text
    "\x222b" -> Bool
    True  -- integral
      Text
    "\x222c" -> Bool
    True  -- double integral
      Text
    "\x222d" -> Bool
    True  -- triple integral
      Text
    "\x222e" -> Bool
    True  -- line integral
      Text
    "\x222f" -> Bool
    True  -- double line integral
      Text
    "\x2230" -> Bool
    True  -- triple line integral
      Text
    "\x220f" -> Bool
    True  -- product
      Text
    "\x2210" -> Bool
    True  -- coproduct
      Text
    "\x2211" -> Bool
    True  -- sum
      Text
    _        -> Bool
    False
    isNary Exp
    _ = Bool
    False

    -- Kept as String for Text.XML.Light
    makeNary :: [Element] -> String -> T.Text -> Exp -> Exp -> Exp -> Element
    makeNary :: [Element] -> String -> Text -> Exp -> Exp -> Exp -> Element
    makeNary [Element]
    props String
    t Text
    s Exp
    y Exp
    z Exp
    w =
      String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "nary" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "naryPr"
                     [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "chr" (Text -> String
    T.unpack Text
    s) ()
                     , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "limLoc" String
    t ()
                     , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "subHide"
                        (if Exp
    y Exp -> Exp -> Bool
    forall a. Eq a => a -> a -> Bool
    == [Exp] -> Exp
    EGrouped [] then String
    "on" else String
    "off") ()
                     , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "supHide"
                        (if Exp
    z Exp -> Exp -> Bool
    forall a. Eq a => a -> a -> Bool
    == [Exp] -> Exp
    EGrouped [] then String
    "on" else String
    "off") ()
                     ]
                   , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sub" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    y
                   , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "sup" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    z
                   , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    w ]

    makeCancel :: [Element] -> StrokeType -> Exp -> Element
    makeCancel :: [Element] -> StrokeType -> Exp -> Element
    makeCancel [Element]
    props StrokeType
    st Exp
    x = do
      let sn :: [Element]
    sn = case StrokeType
    st of
                 StrokeType
    ForwardSlash -> [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "strikeBLTR" String
    "1" () ]
                 StrokeType
    BackSlash    -> [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "strikeTLBR" String
    "1" () ]
                 StrokeType
    XSlash       -> [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "strikeBLTR" String
    "1" ()
                                 , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "strikeTLBR" String
    "1" () ]
      String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "borderBox" [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "borderBoxPr" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                          [ String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "hideTop" String
    "1" ()
                          , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "hideBot" String
    "1" ()
                          , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "hideLeft" String
    "1" ()
                          , String -> String -> () -> Element
    forall t. Node t => String -> String -> t -> Element
    mnodeA String
    "hideRight" String
    "1" () ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    sn
                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    mnode String
    "e" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element] -> Exp -> [Element]
    showExp [Element]
    props Exp
    x ]