diff --git a/hledger-lib/Hledger/Write/Ods.hs b/hledger-lib/Hledger/Write/Ods.hs
index 0b93e4d13..31d95ad6c 100644
--- a/hledger-lib/Hledger/Write/Ods.hs
+++ b/hledger-lib/Hledger/Write/Ods.hs
@@ -21,8 +21,30 @@ 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), [[Text]]) -> TL.Text
+ IO.TextEncoding -> Map Text ((Maybe Int, Maybe Int), [[Cell]]) -> TL.Text
printFods encoding tables =
let fileOpen =
map (map (\c -> case c of '\'' -> '"'; _ -> c)) $
@@ -45,6 +67,22 @@ printFods encoding tables =
" xmlns:of='urn:oasis:names:tc:opendocument:xmlns:of:1.2'" :
" xmlns:field='urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0'" :
" xmlns:form='urn:oasis:names:tc:opendocument:xmlns:form:1.0'>" :
+ "" :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ " " :
+ "" :
[]
fileClose =
@@ -98,12 +136,24 @@ printFods encoding tables =
tableOpen name ++
(table >>= \row ->
"" :
- (row >>= \cell ->
- "" :
- printf "%s" cell :
- "" :
- []) ++
+ (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) :
+ "" :
+ []
diff --git a/hledger/Hledger/Cli/Commands/Balance.hs b/hledger/Hledger/Cli/Commands/Balance.hs
index 745be9a91..a78bdbb9c 100644
--- a/hledger/Hledger/Cli/Commands/Balance.hs
+++ b/hledger/Hledger/Cli/Commands/Balance.hs
@@ -248,6 +248,7 @@ module Hledger.Cli.Commands.Balance (
-- ** balance output rendering
,balanceReportAsText
,balanceReportAsCsv
+ ,balanceReportAsFods
,balanceReportItemAsText
,multiBalanceRowAsCsvText
,multiBalanceRowAsText
@@ -304,6 +305,7 @@ import Hledger.Cli.CliOptions
import Hledger.Cli.Utils
import Hledger.Write.Csv (CSV, printCSV, printTSV)
import Hledger.Write.Ods (printFods)
+import qualified Hledger.Write.Ods as Ods
-- | Command line options for this command.
@@ -402,7 +404,7 @@ balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of
"tsv" -> \ropts1 -> printTSV . balanceReportAsCsv ropts1
-- "html" -> \ropts -> (<>"\n") . L.renderText . multiBalanceReportAsHtml ropts . balanceReportAsMultiBalanceReport ropts
"json" -> const $ (<>"\n") . toJsonText
- "fods" -> \ropts1 -> printFods IO.localeEncoding . Map.singleton "Hledger" . (,) (Just 1, Nothing) . balanceReportAsCsv ropts1
+ "fods" -> \ropts1 -> printFods IO.localeEncoding . Map.singleton "Hledger" . (,) (Just 1, Nothing) . balanceReportAsFods ropts1
_ -> error' $ unsupportedOutputFormatError fmt -- PARTIAL:
writeOutputLazyText opts $ render ropts report
where
@@ -557,6 +559,42 @@ renderComponent topaligned oneline opts (acctname, dep, total) (FormatField ljus
,displayColour = color_ opts
}
+-- | Render a single-column balance report as FODS.
+balanceReportAsFods :: ReportOpts -> BalanceReport -> [[Ods.Cell]]
+balanceReportAsFods opts (items, total) =
+ headers :
+ concatMap (\(a, _, _, b) -> rows a b) items ++
+ if no_total_ opts then []
+ else map (map (\c -> c {Ods.cellStyle = Ods.Foot})) $
+ rows totalRowHeadingCsv total
+ where
+ cell content = Ods.defaultCell { Ods.cellContent = content }
+ headers =
+ map (\content -> (cell content) {Ods.cellStyle = Ods.Head}) $
+ "account" : case layout_ opts of
+ LayoutBare -> ["commodity", "balance"]
+ _ -> ["balance"]
+ rows :: AccountName -> MixedAmount -> [[Ods.Cell]]
+ rows name ma = case layout_ opts of
+ LayoutBare ->
+ map (\a ->
+ [showName name,
+ cell $ acommodity a,
+ renderAmount $ mixedAmount a])
+ . amounts $ mixedAmountStripCosts ma
+ _ -> [[showName name, renderAmount ma]]
+
+ showName = cell . accountNameDrop (drop_ opts)
+ renderAmount amt =
+ (cell $ wbToText $ showMixedAmountB bopts amt) {
+ Ods.cellType = Ods.TypeAmount
+ }
+ where
+ bopts = machineFmt{displayCommodity=showcomm, displayCommodityOrder = commorder}
+ (showcomm, commorder)
+ | layout_ opts == LayoutBare = (False, Just $ S.toList $ maCommodities amt)
+ | otherwise = (True, Nothing)
+
-- Multi-column balance reports
-- | Render a multi-column balance report as CSV.