{- |
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) :
"" :
[]