journal: Fully unbracket AccountNames in account directives

Currently an account name like "a:(aa)" will not have (aa) unbracketed.
However, this seems reasonable since the full name is unbracketed and
thus will not be confused with virtual or virtual-balanced posting.
This commit is contained in:
Chris Lemaire 2023-01-22 12:26:45 +01:00 committed by Simon Michael
parent eff29ac10d
commit 4ada2a3fbc
6 changed files with 91 additions and 7 deletions

View File

@ -376,5 +376,21 @@ tests_AccountName = testGroup "AccountName" [
accountNameInferType "revenues" @?= Just Revenue
accountNameInferType "revenue" @?= Just Revenue
accountNameInferType "income" @?= Just Revenue
,testCase "joinAccountNames" $ do
joinAccountNames "assets" "cash" @?= "assets:cash"
joinAccountNames "assets:cash" "a" @?= "assets:cash:a"
joinAccountNames "assets" "(cash)" @?= "(assets:cash)"
joinAccountNames "assets" "[cash]" @?= "[assets:cash]"
joinAccountNames "(assets)" "cash" @?= "(assets:cash)"
joinAccountNames "" "assets" @?= "assets"
joinAccountNames "assets" "" @?= "assets"
,testCase "concatAccountNames" $ do
concatAccountNames ["assets", "cash"] @?= "assets:cash"
concatAccountNames ["assets:cash", "a"] @?= "assets:cash:a"
concatAccountNames ["assets", "(cash)"] @?= "(assets:cash)"
concatAccountNames ["assets", "[cash]"] @?= "[assets:cash]"
concatAccountNames ["(assets)", "cash"] @?= "(assets:cash)"
concatAccountNames ["", "assets"] @?= ":assets"
concatAccountNames ["assets", ""] @?= "assets:"
]

View File

@ -433,7 +433,7 @@ addAccountDeclaration (a,cmt,tags,pos) = do
modify' (\j ->
let
decls = jdeclaredaccounts j
d = (a, nullaccountdeclarationinfo{
d = (textUnbracket a, nullaccountdeclarationinfo{
adicomment = cmt
,aditags = tags
,adideclarationorder = length decls + 1 -- gets renumbered when Journals are finalised or merged

View File

@ -53,6 +53,7 @@ where
import Data.Char (digitToInt)
import Data.Default (def)
import Data.Maybe (catMaybes)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
@ -175,12 +176,17 @@ isDoubleQuoted :: Text -> Bool
isDoubleQuoted s =
T.length s >= 2 && T.head s == '"' && T.last s == '"'
-- | Remove all matching pairs of square brackets and parentheses from the text.
textUnbracket :: Text -> Text
textUnbracket s
| T.null s = s
| T.head s == '[' && T.last s == ']' = T.init $ T.tail s
| T.head s == '(' && T.last s == ')' = T.init $ T.tail s
| otherwise = s
textUnbracket s = T.drop stripN $ T.dropEnd stripN s
where
matchBracket :: Char -> Maybe Char
matchBracket '(' = Just ')'
matchBracket '[' = Just ']'
matchBracket _ = Nothing
expectedClosingBrackets = catMaybes $ takeWhile (/= Nothing) $ matchBracket <$> T.unpack s
stripN = length $ takeWhile (uncurry (==)) $ zip expectedClosingBrackets $ reverse $ T.unpack s
-- | Join several multi-line strings as side-by-side rectangular strings of the same height, top-padded.
-- Treats wide characters as double width.
@ -271,5 +277,18 @@ tests_Text = testGroup "Text" [
quoteIfSpaced "mimi's cafe" @?= "\"mimi's cafe\""
quoteIfSpaced "\"alex\" cafe" @?= "\"\\\"alex\\\" cafe\""
quoteIfSpaced "le'shan's cafe" @?= "\"le'shan's cafe\""
quoteIfSpaced "\"be'any's\" cafe" @?= "\"\\\"be'any's\\\" cafe\""
quoteIfSpaced "\"be'any's\" cafe" @?= "\"\\\"be'any's\\\" cafe\"",
testCase "textUnbracket" $ do
textUnbracket "()" @?= ""
textUnbracket "(a)" @?= "a"
textUnbracket "(ab)" @?= "ab"
textUnbracket "[ab]" @?= "ab"
textUnbracket "([ab])" @?= "ab"
textUnbracket "(()b)" @?= "()b"
textUnbracket "[[]b]" @?= "[]b"
textUnbracket "[()b]" @?= "()b"
textUnbracket "[([]())]" @?= "[]()"
textUnbracket "[([[[()]]])]" @?= ""
textUnbracket "[([[[(]]])]" @?= "("
textUnbracket "[([[[)]]])]" @?= ")"
]

View File

@ -1769,6 +1769,12 @@ They are written as the word `account` followed by a hledger-style [account name
account assets:bank:checking
```
Note, however, that account names declared in the account directive are stripped of surrounding brackets and parentheses.
The above directive is thus equivalent to this:
```journal
account (assets:bank:checking)
```
### Account comments
Text following **two or more spaces** and `;` at the end of an account directive line,

View File

@ -68,6 +68,29 @@ account Expenses:Food
$ hledger -f- accounts
Expenses:Food
# 5. It unbrackets account names.
<
account (a)
account (a:aa)
account (a:(aaa))
account [b]
account [b:bb]
account [b:[bbb]]
account [([c])]
account [([c:cc])]
account [([c:[ccc]])]
$ hledger -f- accounts
a
a:aa
a:(aaa)
b
b:bb
b:[bbb]
c
c:cc
c:[ccc]
# TODO
# a trailing : should give a clear error
# 2009/1/1

View File

@ -1,9 +1,13 @@
# Tests for parentheses and brackets in account names
# 1. Parentheses in the middle of an account name are ignored.
hledger -f - print
<<<
2009-01-01 x
a 2
b (b) b -1
c
>>>
2009-01-01 x
a 2
@ -11,3 +15,19 @@ hledger -f - print
c
>>>=0
# 2. Nested parentheses are removed and the outer brackets are used as the type.
hledger -f- print
<<<
2023-01-01
[([(a)])] 1
[(b:bb)] 1
[b:[bbb]]
>>>
2023-01-01
[a] 1
[b:bb] 1
[b:[bbb]]
>>>=0