feat: aregister: implement HTML output formatter (#1996)

The HTML formatter outputs a HTML snippet containing a table with a
header row and one data row per report item. The header row names
match those for the CSV output formatter. Multiple commodities in
a report item are listed together in the same cell separated by
commas, again matching the CSV formatter.

A future extension could be to explore using multiple rows for
multiple commodities, with HTML row spanning.

Fixes #1996.

Signed-off-by: Jonathan Dowland <jon@dow.land>
This commit is contained in:
Jonathan Dowland 2023-02-08 16:57:52 +00:00 committed by Simon Michael
parent 9106c9013f
commit 15eadd58ce

View File

@ -25,6 +25,7 @@ import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TB
import Lucid as L hiding (value_)
import System.Console.CmdArgs.Explicit (flagNone, flagReq)
import Hledger
@ -57,7 +58,7 @@ aregistermode = hledgerCommandMode
++ " or $COLUMNS). -wN,M sets description width as well."
)
,flagNone ["align-all"] (setboolopt "align-all") "guarantee alignment across all lines (slower)"
,outputFormatFlag ["txt","csv","json"]
,outputFormatFlag ["txt","html","csv","json"]
,outputFileFlag
])
[generalflagsgroup1]
@ -102,6 +103,7 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
reverse items
-- select renderer
render | fmt=="txt" = accountTransactionsReportAsText opts (_rsQuery rspec') thisacctq
| fmt=="html" = accountTransactionsReportAsHTML opts (_rsQuery rspec') thisacctq
| fmt=="csv" = printCSV . accountTransactionsReportAsCsv wd (_rsQuery rspec') thisacctq
| fmt=="json" = toJsonText
| otherwise = error' $ unsupportedOutputFormatError fmt -- PARTIAL:
@ -126,6 +128,27 @@ accountTransactionsReportItemAsCsvRecord
amt = wbToText $ showMixedAmountB csvDisplay change
bal = wbToText $ showMixedAmountB csvDisplay balance
-- | Render a register report as a HTML snippet.
accountTransactionsReportAsHTML :: CliOpts -> Query -> Query -> AccountTransactionsReport -> TL.Text
accountTransactionsReportAsHTML copts reportq thisacctq items =
L.renderText $ L.table_ (do L.thead_ (L.tr_ (do L.th_ "date"
L.th_ "description"
L.th_ "otheraccounts"
L.th_ "change"
L.th_ "balance"))
L.tbody_ (mconcat (map (htmlRow copts reportq thisacctq) items)))
-- | Render one account register report line item as a HTML table row snippet.
htmlRow :: CliOpts -> Query -> Query -> AccountTransactionsReportItem -> L.Html ()
htmlRow CliOpts{reportspec_=ReportSpec{_rsReportOpts=ropts}} reportq thisacctq
(t@Transaction{tdescription}, _, _issplit, otheracctsstr, amt, bal) =
L.tr_ (do (L.td_ . toHtml . show . transactionRegisterDate (whichDate ropts) reportq thisacctq) t
(L.td_ . toHtml) tdescription
(L.td_ . toHtml) otheracctsstr
-- piggy back on the oneLine display style for now.
(L.td_ . toHtml . wbUnpack . showMixedAmountB oneLine) amt
(L.td_ . toHtml . wbUnpack . showMixedAmountB oneLine) bal)
-- | Render a register report as plain text suitable for console output.
accountTransactionsReportAsText :: CliOpts -> Query -> Query -> AccountTransactionsReport -> TL.Text
accountTransactionsReportAsText copts reportq thisacctq items = TB.toLazyText $