{- | Export table data as OpenDocument Spreadsheet . This format supports character encodings, fixed header rows and columns, number formatting, text styles, merged cells, formulas, hyperlinks. Currently we support Flat ODS, a plain uncompressed XML format. This is derived from -} module Hledger.Write.Ods where import qualified Data.Text.Lazy as TL import qualified Data.Text as T import Data.Text (Text) import qualified Data.Map as Map import Data.Foldable (fold) import Data.Map (Map) import qualified System.IO as IO import Text.Printf (printf) data Type = TypeString | TypeAmount deriving (Eq, Ord, Show) data Style = Ordinary | Head | Foot deriving (Eq, Ord, Show) data Cell = Cell { cellType :: Type, cellStyle :: Style, cellContent :: Text } defaultCell :: Cell defaultCell = Cell { cellType = TypeString, cellStyle = Ordinary, cellContent = T.empty } printFods :: IO.TextEncoding -> Map Text ((Maybe Int, Maybe Int), [[Cell]]) -> TL.Text printFods encoding tables = let fileOpen = map (map (\c -> case c of '\'' -> '"'; _ -> c)) $ printf "" (show encoding) : "" : "" : " " : " " : " " : " " : " " : " " : " " : " " : " " : " " : " " : " " : " " : " " : "" : [] fileClose = "" : [] tableConfig tableNames = " " : " " : " " : " " : " " : (fold $ flip Map.mapWithKey tableNames $ \tableName (mTopRow,mLeftColumn) -> printf " " tableName : (flip foldMap mLeftColumn $ \leftColumn -> " 2" : printf " %d" leftColumn : printf " %d" leftColumn : []) ++ (flip foldMap mTopRow $ \topRow -> " 2" : printf " %d" topRow : printf " %d" topRow : []) ++ " " : []) ++ " " : " " : " " : " " : " " : [] tableOpen name = "" : "" : printf "" name : [] tableClose = "" : "" : "" : [] in TL.unlines $ map (TL.fromStrict . T.pack) $ fileOpen ++ tableConfig (fmap fst tables) ++ (Map.toAscList tables >>= \(name,(_,table)) -> tableOpen name ++ (table >>= \row -> "" : (row >>= formatCell) ++ "" : []) ++ tableClose) ++ fileClose formatCell :: Cell -> [String] formatCell cell = let style :: String style = case (cellStyle cell, cellType cell) of (Ordinary, TypeString) -> "" (Ordinary, TypeAmount) -> " table:style-name='amount'" (Foot, TypeString) -> " table:style-name='foot'" (Foot, TypeAmount) -> " table:style-name='total-amount'" (Head, _) -> " table:style-name='head'" in printf "" style : printf "%s" (cellContent cell) : "" : []