From 3b40edba9c6901bcc9ca2c438c722e4b977c32e3 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sat, 10 Oct 2015 11:53:28 -0700 Subject: [PATCH] print: fix wide char support, add tests (#242) The print command wasn't lining up amounts with wide chars in account names, fixed it properly this time. Transaction and Posting's Show instances should also be wide-char-aware now. --- hledger-lib/Hledger/Data/Posting.hs | 5 +- hledger-lib/Hledger/Data/Transaction.hs | 11 ++-- hledger-lib/Hledger/Utils/String.hs | 2 +- tests/nonascii/wide-char-layout.test | 88 +++++++++++++++++-------- 4 files changed, 70 insertions(+), 36 deletions(-) diff --git a/hledger-lib/Hledger/Data/Posting.hs b/hledger-lib/Hledger/Data/Posting.hs index d603e2ac9..7543cc854 100644 --- a/hledger-lib/Hledger/Data/Posting.hs +++ b/hledger-lib/Hledger/Data/Posting.hs @@ -54,7 +54,6 @@ import Data.Ord import Data.Time.Calendar import Safe import Test.HUnit -import Text.Printf import Hledger.Utils import Hledger.Data.Types @@ -90,12 +89,12 @@ showPosting p@Posting{paccount=a,pamount=amt,ptype=t} = where ledger3ishlayout = False acctnamewidth = if ledger3ishlayout then 25 else 22 - showaccountname = printf ("%-"++(show acctnamewidth)++"s") . bracket . elideAccountName width + showaccountname = fitString (Just acctnamewidth) Nothing False False . bracket . elideAccountName width (bracket,width) = case t of BalancedVirtualPosting -> (\s -> "["++s++"]", acctnamewidth-2) VirtualPosting -> (\s -> "("++s++")", acctnamewidth-2) _ -> (id,acctnamewidth) - showamount = padleft 12 . showMixedAmount + showamount = padLeftWide 12 . showMixedAmount showComment :: String -> String diff --git a/hledger-lib/Hledger/Data/Transaction.hs b/hledger-lib/Hledger/Data/Transaction.hs index 6e3ea77a6..06ebfcec3 100644 --- a/hledger-lib/Hledger/Data/Transaction.hs +++ b/hledger-lib/Hledger/Data/Transaction.hs @@ -136,9 +136,7 @@ showTransaction' elide t = ++ [""] where descriptionline = rstrip $ concat [date, status, code, desc, samelinecomment] - date = showdate (tdate t) ++ maybe "" showedate (tdate2 t) - showdate = printf "%-10s" . showDate - showedate = printf "=%s" . showdate + date = showDate (tdate t) ++ maybe "" (("="++) . showDate) (tdate2 t) status | tstatus t == Cleared = " *" | tstatus t == Pending = " !" | otherwise = "" @@ -183,12 +181,13 @@ postingAsLines elideamount ps p = case renderCommentLines (pcomment p) of [] -> ("",[]) c:cs -> (c,cs) showacct p = - indent $ showstatus p ++ printf (printf "%%-%ds" w) (showAccountName Nothing (ptype p) (paccount p)) + indent $ + showstatus p ++ fitString (Just w) Nothing False True (showAccountName Nothing (ptype p) (paccount p)) where showstatus p = if pstatus p == Cleared then "* " else "" - w = maximum $ map (length . paccount) ps + w = maximum $ map (strWidth . paccount) ps showamt = - padleft 12 . showMixedAmount + padLeftWide 12 . showMixedAmount tests_postingAsLines = [ "postingAsLines" ~: do diff --git a/hledger-lib/Hledger/Utils/String.hs b/hledger-lib/Hledger/Utils/String.hs index 3867d5568..567d3de88 100644 --- a/hledger-lib/Hledger/Utils/String.hs +++ b/hledger-lib/Hledger/Utils/String.hs @@ -266,7 +266,7 @@ fitto w h s = intercalate "\n" $ take h $ rows ++ repeat blankline -- Functions below treat wide (eg CJK) characters as double-width. --- | General-purpose single-line string layout function. +-- | General-purpose wide-char-aware single-line string layout function. -- It can left- or right-pad a short string to a minimum width. -- It can left- or right-clip a long string to a maximum width, optionally inserting an ellipsis (the third argument). -- It clips and pads on the right when the fourth argument is true, otherwise on the left. diff --git a/tests/nonascii/wide-char-layout.test b/tests/nonascii/wide-char-layout.test index 8cb259401..8f86da562 100644 --- a/tests/nonascii/wide-char-layout.test +++ b/tests/nonascii/wide-char-layout.test @@ -1,31 +1,67 @@ -# alignment calculations should handle wide characters +# ALl output should preserve alignment etc. when showing wide characters. +# XXX For a better test, the sample journals should have commodity symbols. +# XXX How to test hledger-ui ? -# 1. register, account name -hledger -f - register -<<< -1/1 - 知 1 - b +# 1. +hledger -f chinese.journal print >>> -2015/01/01 知 1 1 - b -1 0 +2014/01/01 transaction 1 + 㐀 1 + 㐀:㐁 -1 + +2014/01/02 transaction 2 + 㐀:㐁:㐂 1 + 㐀:㐁:㐂:㐃 -1 + +2014/01/03 transaction 3 + 㐀:㐁:㐂:㐃:㐄 1 + 㐀 -1 + >>>=0 -# # 2. balance, commodity symbol -# hledger -f - balance -# <<< -# 1/1 -# a 知1 -# b $-1 -# >>> -# 知1 a -# $-1 b -# -------------------- -# $-1 -# 知1 -# >>>=0 +# 2. +hledger -f chinese.journal register --width 80 +>>> +2014/01/01 transaction 1 㐀 1 1 + 㐀:㐁 -1 0 +2014/01/02 transaction 2 㐀:㐁:㐂 1 1 + 㐀:㐁:㐂:㐃 -1 0 +2014/01/03 transaction 3 㐀:㐁:㐂:㐃:㐄 1 1 + 㐀 -1 0 +>>>=0 + +# 3. +hledger -f chinese.journal balance +>>> + 0 㐀:㐁 + 1 㐂 + 0 㐃 + 1 㐄 +-------------------- + 0 +>>>=0 + +# 4. +hledger -f chinese.journal balance -Y +>>> +Balance changes in 2014: + + || 2014 +================++======= + 㐀:㐁 || -1 + 㐀:㐁:㐂 || 1 + 㐀:㐁:㐂:㐃 || -1 + 㐀:㐁:㐂:㐃:㐄 || 1 +----------------++------- + || 0 + +>>>=0 + +# 5. + +# 6. + +# 7. + +# 8. -# import Text.Data.ICU.Char -# case property EastAsianWidth c of -# Wide -> 2 -# _ -> 1