From d25fe218344fd5da732b4ecd257570bc59002816 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Wed, 29 Oct 2014 08:20:27 -0700 Subject: [PATCH] apply all matching account aliases, not just one directive and one option --- hledger-lib/Hledger/Data/Posting.hs | 11 ++++++++++- hledger-lib/Hledger/Utils/Regex.hs | 7 ++++--- tests/misc/aliases.test | 24 ++++++++++++------------ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/hledger-lib/Hledger/Data/Posting.hs b/hledger-lib/Hledger/Data/Posting.hs index 83fb841ce..ca1c20883 100644 --- a/hledger-lib/Hledger/Data/Posting.hs +++ b/hledger-lib/Hledger/Data/Posting.hs @@ -37,6 +37,7 @@ module Hledger.Data.Posting ( joinAccountNames, concatAccountNames, accountNameApplyAliases, + accountNameApplyOneAlias, -- * arithmetic sumPostings, -- * rendering @@ -218,9 +219,17 @@ concatAccountNames :: [AccountName] -> AccountName concatAccountNames as = accountNameWithPostingType t $ intercalate ":" $ map accountNameWithoutPostingType as where t = headDef RegularPosting $ filter (/= RegularPosting) $ map accountNamePostingType as --- | Rewrite an account name using the first applicable alias from the given list, if any. +-- | Rewrite an account name using all applicable aliases from the given list, in sequence. accountNameApplyAliases :: [AccountAlias] -> AccountName -> AccountName accountNameApplyAliases aliases a = accountNameWithPostingType atype aname' + where + (aname,atype) = (accountNameWithoutPostingType a, accountNamePostingType a) + matchingaliases = filter (\(re,_) -> regexMatchesCI re aname) aliases + aname' = foldl (flip (uncurry regexReplaceCI)) aname matchingaliases + +-- | Rewrite an account name using the first applicable alias from the given list, if any. +accountNameApplyOneAlias :: [AccountAlias] -> AccountName -> AccountName +accountNameApplyOneAlias aliases a = accountNameWithPostingType atype aname' where (aname,atype) = (accountNameWithoutPostingType a, accountNamePostingType a) firstmatchingalias = headDef Nothing $ map Just $ filter (\(re,_) -> regexMatchesCI re aname) aliases diff --git a/hledger-lib/Hledger/Utils/Regex.hs b/hledger-lib/Hledger/Utils/Regex.hs index 5426252a9..f92d2cabe 100644 --- a/hledger-lib/Hledger/Utils/Regex.hs +++ b/hledger-lib/Hledger/Utils/Regex.hs @@ -58,7 +58,7 @@ import Hledger.Utils.UTF8IOCompat (error') -- | Regular expression. Extended regular expression-ish syntax ? But does not support eg (?i) syntax. type Regexp = String --- | A replacement pattern. May include backreferences (\N). +-- | A replacement pattern. May include numeric backreferences (\N). type Replacement = String -- | Convert our string-based regexps to real ones. Can fail if the @@ -91,8 +91,9 @@ regexReplaceBy r = replaceAllBy (toRegex r) regexReplaceByCI :: Regexp -> (String -> String) -> String -> String regexReplaceByCI r = replaceAllBy (toRegexCI r) --- | Replace all occurrences of the regexp with the replacement pattern. --- The replacement pattern supports \N backreferences but no other RE syntax. +-- | Replace all occurrences of the regexp with the replacement +-- pattern. The replacement pattern supports numeric backreferences +-- (\N) but no other RE syntax. regexReplace :: Regexp -> Replacement -> String -> String regexReplace re = replaceRegex (toRegex re) diff --git a/tests/misc/aliases.test b/tests/misc/aliases.test index 50d7db5c1..eb5e01e72 100644 --- a/tests/misc/aliases.test +++ b/tests/misc/aliases.test @@ -1,10 +1,11 @@ # alias-related tests # 1. alias directive. The pattern is a case-insensitive regular -# expression matching anywhere in the account name. Only the most -# recently declared matching alias is applied to an account name. The -# replacement can replace multiple matches within the account name. -# The replacement pattern does not yet support match references. +# expression matching anywhere in the account name. All matching +# aliases will be applied to an account name in turn, most recently +# declared first. The replacement can replace multiple matches within +# the account name. The replacement pattern supports numeric +# backreferences. # hledgerdev -f- print <<< @@ -29,14 +30,14 @@ alias A (.)=\1 c -3 2011/01/01 - a 1 - a 2 + b 1 + b 2 c -3 >>>=0 -# 2. command-line --alias option. Only the first matching alias is -# applied per account name. Spaces are allowed if quoted. +# 2. command-line --alias option. These are applied in the order +# written. Spaces are allowed if quoted. # hledgerdev -f- print --alias 'A (.)=a' --alias a=b <<< @@ -47,14 +48,13 @@ hledgerdev -f- print --alias 'A (.)=a' --alias a=b >>> 2011/01/01 - a 1 - a 2 + b 1 + b 2 c -3 >>>=0 -# 3. Alias options run after alias directives. At most one of each is -# applied. +# 3. Alias options run after alias directives. # hledgerdev -f- print --alias a=A --alias B=C --alias B=D --alias C=D <<<