    {-# LANGUAGE CPP #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE DeriveGeneric #-}
    module Codec.Xlsx.Types.Cell
      ( CellFormula(..)
      , FormulaExpression(..)
      , simpleCellFormula
      , sharedFormulaByIndex
      , SharedFormulaIndex(..)
      , SharedFormulaOptions(..)
      , formulaDataFromCursor
      , applySharedFormulaOpts
      , Cell(..)
      , cellStyle
      , cellValue
      , cellComment
      , cellFormula
      , CellMap
      ) where

    import Control.Arrow (first)
    #ifdef USE_MICROLENS
    import Lens.Micro.TH (makeLenses)
    #else
    import Control.Lens.TH (makeLenses)
    #endif
    import Control.DeepSeq (NFData)
    import Data.Default
    import Data.Map (Map)
    import qualified Data.Map as M
    import Data.Maybe (catMaybes, listToMaybe)
    import Data.Monoid ((<>))
    import Data.Text (Text)
    import GHC.Generics (Generic)
    import Text.XML
    import Text.XML.Cursor

    import Codec.Xlsx.Parser.Internal
    import Codec.Xlsx.Types.Comment
    import Codec.Xlsx.Types.Common
    import Codec.Xlsx.Writer.Internal

    -- | Formula for the cell.
    --
    -- TODO: array, dataTable formula types support
    --
    -- See 18.3.1.40 "f (Formula)" (p. 1636)
    data CellFormula = CellFormula
      { CellFormula -> FormulaExpression
    _cellfExpression :: FormulaExpression
      , CellFormula -> Bool
    _cellfAssignsToName :: Bool
          -- ^ Specifies that this formula assigns a value to a name.
      , CellFormula -> Bool
    _cellfCalculate :: Bool
          -- ^ Indicates that this formula needs to be recalculated
          -- the next time calculation is performed.
          -- [/Example/: This is always set on volatile functions,
          -- like =RAND(), and circular references. /end example/]
      } deriving (CellFormula -> CellFormula -> Bool
    (CellFormula -> CellFormula -> Bool)
    -> (CellFormula -> CellFormula -> Bool) -> Eq CellFormula
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CellFormula -> CellFormula -> Bool
    == :: CellFormula -> CellFormula -> Bool
    $c/= :: CellFormula -> CellFormula -> Bool
    /= :: CellFormula -> CellFormula -> Bool
    Eq, Int -> CellFormula -> ShowS
    [CellFormula] -> ShowS
    CellFormula -> [Char]
    (Int -> CellFormula -> ShowS)
    -> (CellFormula -> [Char])
    -> ([CellFormula] -> ShowS)
    -> Show CellFormula
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CellFormula -> ShowS
    showsPrec :: Int -> CellFormula -> ShowS
    $cshow :: CellFormula -> [Char]
    show :: CellFormula -> [Char]
    $cshowList :: [CellFormula] -> ShowS
    showList :: [CellFormula] -> ShowS
    Show, (forall x. CellFormula -> Rep CellFormula x)
    -> (forall x. Rep CellFormula x -> CellFormula)
    -> Generic CellFormula
    forall x. Rep CellFormula x -> CellFormula
    forall x. CellFormula -> Rep CellFormula x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. CellFormula -> Rep CellFormula x
    from :: forall x. CellFormula -> Rep CellFormula x
    $cto :: forall x. Rep CellFormula x -> CellFormula
    to :: forall x. Rep CellFormula x -> CellFormula
    Generic)
    instance NFData CellFormula

    -- | formula type with type-specific options
    data FormulaExpression
      = NormalFormula Formula
      | SharedFormula SharedFormulaIndex
      deriving (FormulaExpression -> FormulaExpression -> Bool
    (FormulaExpression -> FormulaExpression -> Bool)
    -> (FormulaExpression -> FormulaExpression -> Bool)
    -> Eq FormulaExpression
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FormulaExpression -> FormulaExpression -> Bool
    == :: FormulaExpression -> FormulaExpression -> Bool
    $c/= :: FormulaExpression -> FormulaExpression -> Bool
    /= :: FormulaExpression -> FormulaExpression -> Bool
    Eq, Int -> FormulaExpression -> ShowS
    [FormulaExpression] -> ShowS
    FormulaExpression -> [Char]
    (Int -> FormulaExpression -> ShowS)
    -> (FormulaExpression -> [Char])
    -> ([FormulaExpression] -> ShowS)
    -> Show FormulaExpression
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> FormulaExpression -> ShowS
    showsPrec :: Int -> FormulaExpression -> ShowS
    $cshow :: FormulaExpression -> [Char]
    show :: FormulaExpression -> [Char]
    $cshowList :: [FormulaExpression] -> ShowS
    showList :: [FormulaExpression] -> ShowS
    Show, (forall x. FormulaExpression -> Rep FormulaExpression x)
    -> (forall x. Rep FormulaExpression x -> FormulaExpression)
    -> Generic FormulaExpression
    forall x. Rep FormulaExpression x -> FormulaExpression
    forall x. FormulaExpression -> Rep FormulaExpression x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. FormulaExpression -> Rep FormulaExpression x
    from :: forall x. FormulaExpression -> Rep FormulaExpression x
    $cto :: forall x. Rep FormulaExpression x -> FormulaExpression
    to :: forall x. Rep FormulaExpression x -> FormulaExpression
    Generic)
    instance NFData FormulaExpression

    defaultFormulaType :: Text
    defaultFormulaType :: Text
    defaultFormulaType = Text
    "normal"

    -- | index of shared formula in worksheet's 'wsSharedFormulas'
    -- property
    newtype SharedFormulaIndex = SharedFormulaIndex Int
      deriving (SharedFormulaIndex -> SharedFormulaIndex -> Bool
    (SharedFormulaIndex -> SharedFormulaIndex -> Bool)
    -> (SharedFormulaIndex -> SharedFormulaIndex -> Bool)
    -> Eq SharedFormulaIndex
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    == :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    $c/= :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    /= :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    Eq, Eq SharedFormulaIndex
    Eq SharedFormulaIndex =>
    (SharedFormulaIndex -> SharedFormulaIndex -> Ordering)
    -> (SharedFormulaIndex -> SharedFormulaIndex -> Bool)
    -> (SharedFormulaIndex -> SharedFormulaIndex -> Bool)
    -> (SharedFormulaIndex -> SharedFormulaIndex -> Bool)
    -> (SharedFormulaIndex -> SharedFormulaIndex -> Bool)
    -> (SharedFormulaIndex -> SharedFormulaIndex -> SharedFormulaIndex)
    -> (SharedFormulaIndex -> SharedFormulaIndex -> SharedFormulaIndex)
    -> Ord SharedFormulaIndex
    SharedFormulaIndex -> SharedFormulaIndex -> Bool
    SharedFormulaIndex -> SharedFormulaIndex -> Ordering
    SharedFormulaIndex -> SharedFormulaIndex -> SharedFormulaIndex
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: SharedFormulaIndex -> SharedFormulaIndex -> Ordering
    compare :: SharedFormulaIndex -> SharedFormulaIndex -> Ordering
    $c< :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    < :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    $c<= :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    <= :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    $c> :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    > :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    $c>= :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    >= :: SharedFormulaIndex -> SharedFormulaIndex -> Bool
    $cmax :: SharedFormulaIndex -> SharedFormulaIndex -> SharedFormulaIndex
    max :: SharedFormulaIndex -> SharedFormulaIndex -> SharedFormulaIndex
    $cmin :: SharedFormulaIndex -> SharedFormulaIndex -> SharedFormulaIndex
    min :: SharedFormulaIndex -> SharedFormulaIndex -> SharedFormulaIndex
    Ord, Int -> SharedFormulaIndex -> ShowS
    [SharedFormulaIndex] -> ShowS
    SharedFormulaIndex -> [Char]
    (Int -> SharedFormulaIndex -> ShowS)
    -> (SharedFormulaIndex -> [Char])
    -> ([SharedFormulaIndex] -> ShowS)
    -> Show SharedFormulaIndex
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SharedFormulaIndex -> ShowS
    showsPrec :: Int -> SharedFormulaIndex -> ShowS
    $cshow :: SharedFormulaIndex -> [Char]
    show :: SharedFormulaIndex -> [Char]
    $cshowList :: [SharedFormulaIndex] -> ShowS
    showList :: [SharedFormulaIndex] -> ShowS
    Show, (forall x. SharedFormulaIndex -> Rep SharedFormulaIndex x)
    -> (forall x. Rep SharedFormulaIndex x -> SharedFormulaIndex)
    -> Generic SharedFormulaIndex
    forall x. Rep SharedFormulaIndex x -> SharedFormulaIndex
    forall x. SharedFormulaIndex -> Rep SharedFormulaIndex x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. SharedFormulaIndex -> Rep SharedFormulaIndex x
    from :: forall x. SharedFormulaIndex -> Rep SharedFormulaIndex x
    $cto :: forall x. Rep SharedFormulaIndex x -> SharedFormulaIndex
    to :: forall x. Rep SharedFormulaIndex x -> SharedFormulaIndex
    Generic)
    instance NFData SharedFormulaIndex

    data SharedFormulaOptions = SharedFormulaOptions
      { SharedFormulaOptions -> CellRef
    _sfoRef :: CellRef
      , SharedFormulaOptions -> Formula
    _sfoExpression :: Formula
      }
      deriving (SharedFormulaOptions -> SharedFormulaOptions -> Bool
    (SharedFormulaOptions -> SharedFormulaOptions -> Bool)
    -> (SharedFormulaOptions -> SharedFormulaOptions -> Bool)
    -> Eq SharedFormulaOptions
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SharedFormulaOptions -> SharedFormulaOptions -> Bool
    == :: SharedFormulaOptions -> SharedFormulaOptions -> Bool
    $c/= :: SharedFormulaOptions -> SharedFormulaOptions -> Bool
    /= :: SharedFormulaOptions -> SharedFormulaOptions -> Bool
    Eq, Int -> SharedFormulaOptions -> ShowS
    [SharedFormulaOptions] -> ShowS
    SharedFormulaOptions -> [Char]
    (Int -> SharedFormulaOptions -> ShowS)
    -> (SharedFormulaOptions -> [Char])
    -> ([SharedFormulaOptions] -> ShowS)
    -> Show SharedFormulaOptions
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SharedFormulaOptions -> ShowS
    showsPrec :: Int -> SharedFormulaOptions -> ShowS
    $cshow :: SharedFormulaOptions -> [Char]
    show :: SharedFormulaOptions -> [Char]
    $cshowList :: [SharedFormulaOptions] -> ShowS
    showList :: [SharedFormulaOptions] -> ShowS
    Show, (forall x. SharedFormulaOptions -> Rep SharedFormulaOptions x)
    -> (forall x. Rep SharedFormulaOptions x -> SharedFormulaOptions)
    -> Generic SharedFormulaOptions
    forall x. Rep SharedFormulaOptions x -> SharedFormulaOptions
    forall x. SharedFormulaOptions -> Rep SharedFormulaOptions x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. SharedFormulaOptions -> Rep SharedFormulaOptions x
    from :: forall x. SharedFormulaOptions -> Rep SharedFormulaOptions x
    $cto :: forall x. Rep SharedFormulaOptions x -> SharedFormulaOptions
    to :: forall x. Rep SharedFormulaOptions x -> SharedFormulaOptions
    Generic)
    instance NFData SharedFormulaOptions

    simpleCellFormula :: Text -> CellFormula
    simpleCellFormula :: Text -> CellFormula
    simpleCellFormula Text
    expr = CellFormula
        { _cellfExpression :: FormulaExpression
    _cellfExpression    = Formula -> FormulaExpression
    NormalFormula (Formula -> FormulaExpression) -> Formula -> FormulaExpression
    forall a b. (a -> b) -> a -> b
    $ Text -> Formula
    Formula Text
    expr
        , _cellfAssignsToName :: Bool
    _cellfAssignsToName = Bool
    False
        , _cellfCalculate :: Bool
    _cellfCalculate     = Bool
    False
        }

    sharedFormulaByIndex :: SharedFormulaIndex -> CellFormula
    sharedFormulaByIndex :: SharedFormulaIndex -> CellFormula
    sharedFormulaByIndex SharedFormulaIndex
    si =
      CellFormula
      { _cellfExpression :: FormulaExpression
    _cellfExpression = SharedFormulaIndex -> FormulaExpression
    SharedFormula SharedFormulaIndex
    si
      , _cellfAssignsToName :: Bool
    _cellfAssignsToName = Bool
    False
      , _cellfCalculate :: Bool
    _cellfCalculate = Bool
    False
      }

    -- | Currently cell details include cell values, style ids and cell
    -- formulas (inline strings from @\<is\>@ subelements are ignored)
    data Cell = Cell
        { Cell -> Maybe Int
    _cellStyle   :: Maybe Int
        , Cell -> Maybe CellValue
    _cellValue   :: Maybe CellValue
        , Cell -> Maybe Comment
    _cellComment :: Maybe Comment
        , Cell -> Maybe CellFormula
    _cellFormula :: Maybe CellFormula
        } deriving (Cell -> Cell -> Bool
    (Cell -> Cell -> Bool) -> (Cell -> Cell -> Bool) -> Eq Cell
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Cell -> Cell -> Bool
    == :: Cell -> Cell -> Bool
    $c/= :: Cell -> Cell -> Bool
    /= :: Cell -> Cell -> Bool
    Eq, Int -> Cell -> ShowS
    [Cell] -> ShowS
    Cell -> [Char]
    (Int -> Cell -> ShowS)
    -> (Cell -> [Char]) -> ([Cell] -> ShowS) -> Show Cell
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Cell -> ShowS
    showsPrec :: Int -> Cell -> ShowS
    $cshow :: Cell -> [Char]
    show :: Cell -> [Char]
    $cshowList :: [Cell] -> ShowS
    showList :: [Cell] -> ShowS
    Show, (forall x. Cell -> Rep Cell x)
    -> (forall x. Rep Cell x -> Cell) -> Generic Cell
    forall x. Rep Cell x -> Cell
    forall x. Cell -> Rep Cell x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Cell -> Rep Cell x
    from :: forall x. Cell -> Rep Cell x
    $cto :: forall x. Rep Cell x -> Cell
    to :: forall x. Rep Cell x -> Cell
    Generic)
    instance NFData Cell

    instance Default Cell where
        def :: Cell
    def = Maybe Int
    -> Maybe CellValue -> Maybe Comment -> Maybe CellFormula -> Cell
    Cell Maybe Int
    forall a. Maybe a
    Nothing Maybe CellValue
    forall a. Maybe a
    Nothing Maybe Comment
    forall a. Maybe a
    Nothing Maybe CellFormula
    forall a. Maybe a
    Nothing

    makeLenses ''Cell

    -- | Map containing cell values which are indexed by row and column
    -- if you need to use more traditional (x,y) indexing please you could
    -- use corresponding accessors from ''Codec.Xlsx.Lens''
    type CellMap = Map (RowIndex, ColumnIndex) Cell

    {-------------------------------------------------------------------------------
      Parsing
    -------------------------------------------------------------------------------}

    formulaDataFromCursor ::
         Cursor -> [(CellFormula, Maybe (SharedFormulaIndex, SharedFormulaOptions))]
    formulaDataFromCursor :: Cursor
    -> [(CellFormula,
         Maybe (SharedFormulaIndex, SharedFormulaOptions))]
    formulaDataFromCursor Cursor
    cur = do
      _cellfAssignsToName <- Name -> Bool -> Cursor -> [Bool]
    forall a. FromAttrVal a => Name -> a -> Cursor -> [a]
    fromAttributeDef Name
    "bx" Bool
    False Cursor
    cur
      _cellfCalculate <- fromAttributeDef "ca" False cur
      t <- fromAttributeDef "t" defaultFormulaType cur
      (_cellfExpression, shared) <-
        case t of
          Text
    d| Text
    d Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    defaultFormulaType -> do
            formula <- Cursor -> [Formula]
    forall a. FromCursor a => Cursor -> [a]
    fromCursor Cursor
    cur
            return (NormalFormula formula, Nothing)
          Text
    "shared" -> do
            let expr :: Maybe Formula
    expr = [Formula] -> Maybe Formula
    forall a. [a] -> Maybe a
    listToMaybe ([Formula] -> Maybe Formula) -> [Formula] -> Maybe Formula
    forall a b. (a -> b) -> a -> b
    $ Cursor -> [Formula]
    forall a. FromCursor a => Cursor -> [a]
    fromCursor Cursor
    cur
            ref <- Name -> Cursor -> [Maybe CellRef]
    forall a. FromAttrVal a => Name -> Cursor -> [Maybe a]
    maybeAttribute Name
    "ref" Cursor
    cur
            si <- fromAttribute "si" cur
            return (SharedFormula si, (,) <$> pure si <*>
                     (SharedFormulaOptions <$> ref <*> expr))
          Text
    _ ->
            [Char]
    -> [(FormulaExpression,
         Maybe (SharedFormulaIndex, SharedFormulaOptions))]
    forall a. [Char] -> [a]
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char]
     -> [(FormulaExpression,
          Maybe (SharedFormulaIndex, SharedFormulaOptions))])
    -> [Char]
    -> [(FormulaExpression,
         Maybe (SharedFormulaIndex, SharedFormulaOptions))]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected formula type" [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Text -> [Char]
    forall a. Show a => a -> [Char]
    show Text
    t
      return (CellFormula {..}, shared)

    instance FromAttrVal SharedFormulaIndex where
      fromAttrVal :: Reader SharedFormulaIndex
    fromAttrVal = ((Int, Text) -> (SharedFormulaIndex, Text))
    -> Either [Char] (Int, Text)
    -> Either [Char] (SharedFormulaIndex, Text)
    forall a b. (a -> b) -> Either [Char] a -> Either [Char] b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((Int -> SharedFormulaIndex)
    -> (Int, Text) -> (SharedFormulaIndex, Text)
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first Int -> SharedFormulaIndex
    SharedFormulaIndex) (Either [Char] (Int, Text)
     -> Either [Char] (SharedFormulaIndex, Text))
    -> (Text -> Either [Char] (Int, Text)) -> Reader SharedFormulaIndex
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Either [Char] (Int, Text)
    forall a. FromAttrVal a => Reader a
    fromAttrVal

    instance FromAttrBs SharedFormulaIndex where
      fromAttrBs :: ByteString -> Either Text SharedFormulaIndex
    fromAttrBs = (Int -> SharedFormulaIndex)
    -> Either Text Int -> Either Text SharedFormulaIndex
    forall a b. (a -> b) -> Either Text a -> Either Text b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Int -> SharedFormulaIndex
    SharedFormulaIndex (Either Text Int -> Either Text SharedFormulaIndex)
    -> (ByteString -> Either Text Int)
    -> ByteString
    -> Either Text SharedFormulaIndex
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Either Text Int
    forall a. FromAttrBs a => ByteString -> Either Text a
    fromAttrBs

    {-------------------------------------------------------------------------------
      Rendering
    -------------------------------------------------------------------------------}

    instance ToElement CellFormula where
      toElement :: Name -> CellFormula -> Element
    toElement Name
    nm CellFormula {Bool
    FormulaExpression
    _cellfExpression :: CellFormula -> FormulaExpression
    _cellfAssignsToName :: CellFormula -> Bool
    _cellfCalculate :: CellFormula -> Bool
    _cellfExpression :: FormulaExpression
    _cellfAssignsToName :: Bool
    _cellfCalculate :: Bool
    ..} =
        Element
    formulaEl {elementAttributes = elementAttributes formulaEl <> commonAttrs}
        where
          commonAttrs :: Map Name Text
    commonAttrs =
            [(Name, Text)] -> Map Name Text
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([(Name, Text)] -> Map Name Text)
    -> [(Name, Text)] -> Map Name Text
    forall a b. (a -> b) -> a -> b
    $
            [Maybe (Name, Text)] -> [(Name, Text)]
    forall a. [Maybe a] -> [a]
    catMaybes
              [ Name
    "bx" Name -> Maybe Bool -> Maybe (Name, Text)
    forall a. ToAttrVal a => Name -> Maybe a -> Maybe (Name, Text)
    .=? Bool -> Maybe Bool
    justTrue Bool
    _cellfAssignsToName
              , Name
    "ca" Name -> Maybe Bool -> Maybe (Name, Text)
    forall a. ToAttrVal a => Name -> Maybe a -> Maybe (Name, Text)
    .=? Bool -> Maybe Bool
    justTrue Bool
    _cellfCalculate
              , Name
    "t" Name -> Maybe Text -> Maybe (Name, Text)
    forall a. ToAttrVal a => Name -> Maybe a -> Maybe (Name, Text)
    .=? Text -> Text -> Maybe Text
    forall a. Eq a => a -> a -> Maybe a
    justNonDef Text
    defaultFormulaType Text
    fType
              ]
          (Element
    formulaEl, Text
    fType) =
            case FormulaExpression
    _cellfExpression of
              NormalFormula Formula
    f -> (Name -> Formula -> Element
    forall a. ToElement a => Name -> a -> Element
    toElement Name
    nm Formula
    f, Text
    defaultFormulaType)
              SharedFormula SharedFormulaIndex
    si -> (Name -> [(Name, Text)] -> Element
    leafElement Name
    nm [Name
    "si" Name -> SharedFormulaIndex -> (Name, Text)
    forall a. ToAttrVal a => Name -> a -> (Name, Text)
    .= SharedFormulaIndex
    si], Text
    "shared")

    instance ToAttrVal SharedFormulaIndex where
      toAttrVal :: SharedFormulaIndex -> Text
    toAttrVal (SharedFormulaIndex Int
    si) = Int -> Text
    forall a. ToAttrVal a => a -> Text
    toAttrVal Int
    si

    applySharedFormulaOpts :: SharedFormulaOptions -> Element -> Element
    applySharedFormulaOpts :: SharedFormulaOptions -> Element -> Element
    applySharedFormulaOpts SharedFormulaOptions {Formula
    CellRef
    _sfoRef :: SharedFormulaOptions -> CellRef
    _sfoExpression :: SharedFormulaOptions -> Formula
    _sfoRef :: CellRef
    _sfoExpression :: Formula
    ..} Element
    el =
      Element
    el
      { elementAttributes = elementAttributes el <> M.fromList ["ref" .= _sfoRef]
      , elementNodes = NodeContent (unFormula _sfoExpression) : elementNodes el
      }