journal: parse account directives
We now parse account directives, like Ledger's. We don't do anything with them yet. The default parent account feature must now be spelled "apply account"/"end apply account".
This commit is contained in:
parent
25cd65442a
commit
31a754544a
@ -137,7 +137,7 @@ nulljournal = Journal { jmodifiertxns = []
|
|||||||
}
|
}
|
||||||
|
|
||||||
nullctx :: JournalContext
|
nullctx :: JournalContext
|
||||||
nullctx = Ctx{ctxYear=Nothing, ctxDefaultCommodityAndStyle=Nothing, ctxAccount=[], ctxAliases=[], ctxTransactionIndex=0}
|
nullctx = Ctx{ctxYear=Nothing, ctxDefaultCommodityAndStyle=Nothing, ctxAccounts=[], ctxParentAccount=[], ctxAliases=[], ctxTransactionIndex=0}
|
||||||
|
|
||||||
journalFilePath :: Journal -> FilePath
|
journalFilePath :: Journal -> FilePath
|
||||||
journalFilePath = fst . mainfile
|
journalFilePath = fst . mainfile
|
||||||
|
|||||||
@ -230,11 +230,12 @@ type Year = Integer
|
|||||||
data JournalContext = Ctx {
|
data JournalContext = Ctx {
|
||||||
ctxYear :: !(Maybe Year) -- ^ the default year most recently specified with Y
|
ctxYear :: !(Maybe Year) -- ^ the default year most recently specified with Y
|
||||||
, ctxDefaultCommodityAndStyle :: !(Maybe (Commodity,AmountStyle)) -- ^ the default commodity and amount style most recently specified with D
|
, ctxDefaultCommodityAndStyle :: !(Maybe (Commodity,AmountStyle)) -- ^ the default commodity and amount style most recently specified with D
|
||||||
, ctxAccount :: ![AccountName] -- ^ the current stack of parent accounts/account name components
|
, ctxAccounts :: ![AccountName] -- ^ the accounts that have been defined with account directives so far
|
||||||
-- specified with "account" directive(s). Concatenated, these
|
, ctxParentAccount :: ![AccountName] -- ^ the current stack of parent accounts/account name components
|
||||||
-- are the account prefix prepended to parsed account names.
|
-- specified with "apply account" directive(s). Concatenated, these
|
||||||
, ctxAliases :: ![AccountAlias] -- ^ the current list of account name aliases in effect
|
-- are the account prefix prepended to parsed account names.
|
||||||
, ctxTransactionIndex :: !Integer -- ^ the number of transactions read so far
|
, ctxAliases :: ![AccountAlias] -- ^ the current list of account name aliases in effect
|
||||||
|
, ctxTransactionIndex :: !Integer -- ^ the number of transactions read so far
|
||||||
} deriving (Read, Show, Eq, Data, Typeable, Generic)
|
} deriving (Read, Show, Eq, Data, Typeable, Generic)
|
||||||
|
|
||||||
instance NFData JournalContext
|
instance NFData JournalContext
|
||||||
|
|||||||
@ -190,18 +190,22 @@ setDefaultCommodityAndStyle cs = modifyState (\ctx -> ctx{ctxDefaultCommodityAnd
|
|||||||
getDefaultCommodityAndStyle :: Stream [Char] m Char => ParsecT [Char] JournalContext m (Maybe (Commodity,AmountStyle))
|
getDefaultCommodityAndStyle :: Stream [Char] m Char => ParsecT [Char] JournalContext m (Maybe (Commodity,AmountStyle))
|
||||||
getDefaultCommodityAndStyle = ctxDefaultCommodityAndStyle `fmap` getState
|
getDefaultCommodityAndStyle = ctxDefaultCommodityAndStyle `fmap` getState
|
||||||
|
|
||||||
|
pushAccount :: Stream [Char] m Char => String -> ParsecT [Char] JournalContext m ()
|
||||||
|
pushAccount acct = modifyState addAccount
|
||||||
|
where addAccount ctx0 = ctx0 { ctxAccounts = acct : ctxAccounts ctx0 }
|
||||||
|
|
||||||
pushParentAccount :: Stream [Char] m Char => String -> ParsecT [Char] JournalContext m ()
|
pushParentAccount :: Stream [Char] m Char => String -> ParsecT [Char] JournalContext m ()
|
||||||
pushParentAccount parent = modifyState addParentAccount
|
pushParentAccount parent = modifyState addParentAccount
|
||||||
where addParentAccount ctx0 = ctx0 { ctxAccount = parent : ctxAccount ctx0 }
|
where addParentAccount ctx0 = ctx0 { ctxParentAccount = parent : ctxParentAccount ctx0 }
|
||||||
|
|
||||||
popParentAccount :: Stream [Char] m Char => ParsecT [Char] JournalContext m ()
|
popParentAccount :: Stream [Char] m Char => ParsecT [Char] JournalContext m ()
|
||||||
popParentAccount = do ctx0 <- getState
|
popParentAccount = do ctx0 <- getState
|
||||||
case ctxAccount ctx0 of
|
case ctxParentAccount ctx0 of
|
||||||
[] -> unexpected "End of account block with no beginning"
|
[] -> unexpected "End of apply account block with no beginning"
|
||||||
(_:rest) -> setState $ ctx0 { ctxAccount = rest }
|
(_:rest) -> setState $ ctx0 { ctxParentAccount = rest }
|
||||||
|
|
||||||
getParentAccount :: Stream [Char] m Char => ParsecT [Char] JournalContext m String
|
getParentAccount :: Stream [Char] m Char => ParsecT [Char] JournalContext m String
|
||||||
getParentAccount = liftM (concatAccountNames . reverse . ctxAccount) getState
|
getParentAccount = liftM (concatAccountNames . reverse . ctxParentAccount) getState
|
||||||
|
|
||||||
addAccountAlias :: Stream [Char] m Char => AccountAlias -> ParsecT [Char] JournalContext m ()
|
addAccountAlias :: Stream [Char] m Char => AccountAlias -> ParsecT [Char] JournalContext m ()
|
||||||
addAccountAlias a = modifyState (\(ctx@Ctx{..}) -> ctx{ctxAliases=a:ctxAliases})
|
addAccountAlias a = modifyState (\(ctx@Ctx{..}) -> ctx{ctxAliases=a:ctxAliases})
|
||||||
@ -251,7 +255,8 @@ directivep = do
|
|||||||
,aliasdirectivep
|
,aliasdirectivep
|
||||||
,endaliasesdirectivep
|
,endaliasesdirectivep
|
||||||
,accountdirectivep
|
,accountdirectivep
|
||||||
,enddirectivep
|
,applyaccountdirectivep
|
||||||
|
,endapplyaccountdirectivep
|
||||||
,tagdirectivep
|
,tagdirectivep
|
||||||
,endtagdirectivep
|
,endtagdirectivep
|
||||||
,defaultyeardirectivep
|
,defaultyeardirectivep
|
||||||
@ -296,18 +301,27 @@ journalAddFile f j@Journal{files=fs} = j{files=fs++[f]}
|
|||||||
|
|
||||||
accountdirectivep :: ParsecT [Char] JournalContext (ExceptT String IO) JournalUpdate
|
accountdirectivep :: ParsecT [Char] JournalContext (ExceptT String IO) JournalUpdate
|
||||||
accountdirectivep = do
|
accountdirectivep = do
|
||||||
(try $ string "apply" >> many1 spacenonewline >> string "account")
|
string "account"
|
||||||
<|> string "account"
|
many1 spacenonewline
|
||||||
|
acct <- accountnamep
|
||||||
|
newline
|
||||||
|
let indentedline = many1 spacenonewline >> restofline
|
||||||
|
many indentedline
|
||||||
|
pushAccount acct
|
||||||
|
return $ ExceptT $ return $ Right id
|
||||||
|
|
||||||
|
applyaccountdirectivep :: ParsecT [Char] JournalContext (ExceptT String IO) JournalUpdate
|
||||||
|
applyaccountdirectivep = do
|
||||||
|
string "apply" >> many1 spacenonewline >> string "account"
|
||||||
many1 spacenonewline
|
many1 spacenonewline
|
||||||
parent <- accountnamep
|
parent <- accountnamep
|
||||||
newline
|
newline
|
||||||
pushParentAccount parent
|
pushParentAccount parent
|
||||||
return $ ExceptT $ return $ Right id
|
return $ ExceptT $ return $ Right id
|
||||||
|
|
||||||
enddirectivep :: ParsecT [Char] JournalContext (ExceptT String IO) JournalUpdate
|
endapplyaccountdirectivep :: ParsecT [Char] JournalContext (ExceptT String IO) JournalUpdate
|
||||||
enddirectivep = do
|
endapplyaccountdirectivep = do
|
||||||
string "end"
|
string "end" >> many1 spacenonewline >> string "apply" >> many1 spacenonewline >> string "account"
|
||||||
optional $ many1 spacenonewline >> string "apply" >> many1 spacenonewline >> string "account"
|
|
||||||
popParentAccount
|
popParentAccount
|
||||||
return $ ExceptT $ return $ Right id
|
return $ ExceptT $ return $ Right id
|
||||||
|
|
||||||
|
|||||||
@ -561,6 +561,59 @@ You can clear (forget) all currently defined aliases with the `end aliases` dire
|
|||||||
end aliases
|
end aliases
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## account directive
|
||||||
|
|
||||||
|
The `account` directive predefines account names, as in Ledger and Beancount.
|
||||||
|
This may be useful for your own documentation; hledger doesn't make use of it yet.
|
||||||
|
|
||||||
|
``` {.journal}
|
||||||
|
; account ACCT
|
||||||
|
; OPTIONAL COMMENTS/TAGS...
|
||||||
|
|
||||||
|
account assets:bank:checking
|
||||||
|
a comment
|
||||||
|
acct-no:12345
|
||||||
|
|
||||||
|
account expenses:food
|
||||||
|
|
||||||
|
; etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
## apply account directive
|
||||||
|
|
||||||
|
You can specify a parent account which will be prepended to all accounts
|
||||||
|
within a section of the journal. Use the `apply account` and `end apply account`
|
||||||
|
directives like so:
|
||||||
|
|
||||||
|
``` {.journal}
|
||||||
|
apply account home
|
||||||
|
|
||||||
|
2010/1/1
|
||||||
|
food $10
|
||||||
|
cash
|
||||||
|
|
||||||
|
end apply account
|
||||||
|
```
|
||||||
|
which is equivalent to:
|
||||||
|
``` {.journal}
|
||||||
|
2010/01/01
|
||||||
|
home:food $10
|
||||||
|
home:cash $-10
|
||||||
|
```
|
||||||
|
|
||||||
|
If `end apply account` is omitted, the effect lasts to the end of the file.
|
||||||
|
Included files are also affected, eg:
|
||||||
|
|
||||||
|
``` {.journal}
|
||||||
|
apply account business
|
||||||
|
include biz.journal
|
||||||
|
end apply account
|
||||||
|
apply account personal
|
||||||
|
include personal.journal
|
||||||
|
```
|
||||||
|
|
||||||
|
Prior to hledger 0.28, legacy `account` and `end` spellings were also supported.
|
||||||
|
|
||||||
## Multi-line comments
|
## Multi-line comments
|
||||||
|
|
||||||
A line containing just `comment` starts a multi-line comment, and a
|
A line containing just `comment` starts a multi-line comment, and a
|
||||||
@ -600,43 +653,6 @@ $ hledger print
|
|||||||
d £-1,000.00
|
d £-1,000.00
|
||||||
```
|
```
|
||||||
|
|
||||||
## Default parent account
|
|
||||||
|
|
||||||
You can specify a parent account which will be prepended to all accounts
|
|
||||||
within a section of the journal. Use the `apply account` directive like so:
|
|
||||||
|
|
||||||
``` {.journal}
|
|
||||||
apply account home
|
|
||||||
|
|
||||||
2010/1/1
|
|
||||||
food $10
|
|
||||||
cash
|
|
||||||
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
(`!account`, `account`, and `end apply account` are also supported).
|
|
||||||
|
|
||||||
If `end` is omitted, the effect lasts to the end of the file.
|
|
||||||
The above is equivalent to:
|
|
||||||
|
|
||||||
``` {.journal}
|
|
||||||
2010/01/01
|
|
||||||
home:food $10
|
|
||||||
home:cash $-10
|
|
||||||
```
|
|
||||||
|
|
||||||
Included files are also affected, eg:
|
|
||||||
|
|
||||||
``` {.journal}
|
|
||||||
account business
|
|
||||||
include biz.journal
|
|
||||||
end
|
|
||||||
account personal
|
|
||||||
include personal.journal
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
## Default year
|
## Default year
|
||||||
|
|
||||||
You can set a default year to be used for subsequent dates which don't
|
You can set a default year to be used for subsequent dates which don't
|
||||||
|
|||||||
@ -62,31 +62,19 @@ tests_Hledger_Cli = TestList
|
|||||||
-- ,tests_Hledger_Cli_Stats
|
-- ,tests_Hledger_Cli_Stats
|
||||||
|
|
||||||
|
|
||||||
,"account directive" ~:
|
,"apply account directive" ~:
|
||||||
let ignoresourcepos j = j{jtxns=map (\t -> t{tsourcepos=nullsourcepos}) (jtxns j)} in
|
let ignoresourcepos j = j{jtxns=map (\t -> t{tsourcepos=nullsourcepos}) (jtxns j)} in
|
||||||
let sameParse str1 str2 = do j1 <- readJournal Nothing Nothing True Nothing str1 >>= either error' (return . ignoresourcepos)
|
let sameParse str1 str2 = do j1 <- readJournal Nothing Nothing True Nothing str1 >>= either error' (return . ignoresourcepos)
|
||||||
j2 <- readJournal Nothing Nothing True Nothing str2 >>= either error' (return . ignoresourcepos)
|
j2 <- readJournal Nothing Nothing True Nothing str2 >>= either error' (return . ignoresourcepos)
|
||||||
j1 `is` j2{filereadtime=filereadtime j1, files=files j1, jContext=jContext j1}
|
j1 `is` j2{filereadtime=filereadtime j1, files=files j1, jContext=jContext j1}
|
||||||
in TestList
|
in TestList
|
||||||
[
|
[
|
||||||
"account directive 1" ~: sameParse
|
"apply account directive 1" ~: sameParse
|
||||||
"2008/12/07 One\n test:from $-1\n test:to $1\n"
|
|
||||||
"!account test\n2008/12/07 One\n from $-1\n to $1\n"
|
|
||||||
|
|
||||||
,"account directive 2" ~: sameParse
|
|
||||||
"2008/12/07 One\n test:foo:from $-1\n test:foo:to $1\n"
|
|
||||||
"!account test\n!account foo\n2008/12/07 One\n from $-1\n to $1\n"
|
|
||||||
|
|
||||||
,"account directive 3" ~: sameParse
|
|
||||||
"2008/12/07 One\n test:from $-1\n test:to $1\n"
|
|
||||||
"!account test\n!account foo\n!end\n2008/12/07 One\n from $-1\n to $1\n"
|
|
||||||
|
|
||||||
,"account directive 4" ~: sameParse
|
|
||||||
("2008/12/07 One\n alpha $-1\n beta $1\n" ++
|
("2008/12/07 One\n alpha $-1\n beta $1\n" ++
|
||||||
"!account outer\n2008/12/07 Two\n aigh $-2\n bee $2\n" ++
|
"apply account outer\n2008/12/07 Two\n aigh $-2\n bee $2\n" ++
|
||||||
"!account inner\n2008/12/07 Three\n gamma $-3\n delta $3\n" ++
|
"apply account inner\n2008/12/07 Three\n gamma $-3\n delta $3\n" ++
|
||||||
"!end\n2008/12/07 Four\n why $-4\n zed $4\n" ++
|
"end apply account\n2008/12/07 Four\n why $-4\n zed $4\n" ++
|
||||||
"!end\n2008/12/07 Five\n foo $-5\n bar $5\n"
|
"end apply account\n2008/12/07 Five\n foo $-5\n bar $5\n"
|
||||||
)
|
)
|
||||||
("2008/12/07 One\n alpha $-1\n beta $1\n" ++
|
("2008/12/07 One\n alpha $-1\n beta $1\n" ++
|
||||||
"2008/12/07 Two\n outer:aigh $-2\n outer:bee $2\n" ++
|
"2008/12/07 Two\n outer:aigh $-2\n outer:bee $2\n" ++
|
||||||
@ -95,8 +83,8 @@ tests_Hledger_Cli = TestList
|
|||||||
"2008/12/07 Five\n foo $-5\n bar $5\n"
|
"2008/12/07 Five\n foo $-5\n bar $5\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
,"account directive should preserve \"virtual\" posting type" ~: do
|
,"apply account directive should preserve \"virtual\" posting type" ~: do
|
||||||
j <- readJournal Nothing Nothing True Nothing "!account test\n2008/12/07 One\n (from) $-1\n (to) $1\n" >>= either error' return
|
j <- readJournal Nothing Nothing True Nothing "apply account test\n2008/12/07 One\n (from) $-1\n (to) $1\n" >>= either error' return
|
||||||
let p = head $ tpostings $ head $ jtxns j
|
let p = head $ tpostings $ head $ jtxns j
|
||||||
assertBool "" $ paccount p == "test:from"
|
assertBool "" $ paccount p == "test:from"
|
||||||
assertBool "" $ ptype p == VirtualPosting
|
assertBool "" $ ptype p == VirtualPosting
|
||||||
|
|||||||
@ -671,6 +671,59 @@ You can clear (forget) all currently defined aliases with the `end aliases` dire
|
|||||||
end aliases
|
end aliases
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### account directive
|
||||||
|
|
||||||
|
The `account` directive predefines account names, as in Ledger and Beancount.
|
||||||
|
This may be useful for your own documentation; hledger doesn't make use of it yet.
|
||||||
|
|
||||||
|
``` {.journal}
|
||||||
|
; account ACCT
|
||||||
|
; OPTIONAL COMMENTS/TAGS...
|
||||||
|
|
||||||
|
account assets:bank:checking
|
||||||
|
a comment
|
||||||
|
acct-no:12345
|
||||||
|
|
||||||
|
account expenses:food
|
||||||
|
|
||||||
|
; etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
##### apply account directive
|
||||||
|
|
||||||
|
You can specify a parent account which will be prepended to all accounts
|
||||||
|
within a section of the journal. Use the `apply account` and `end apply account`
|
||||||
|
directives like so:
|
||||||
|
|
||||||
|
``` {.journal}
|
||||||
|
apply account home
|
||||||
|
|
||||||
|
2010/1/1
|
||||||
|
food $10
|
||||||
|
cash
|
||||||
|
|
||||||
|
end apply account
|
||||||
|
```
|
||||||
|
which is equivalent to:
|
||||||
|
``` {.journal}
|
||||||
|
2010/01/01
|
||||||
|
home:food $10
|
||||||
|
home:cash $-10
|
||||||
|
```
|
||||||
|
|
||||||
|
If `end apply account` is omitted, the effect lasts to the end of the file.
|
||||||
|
Included files are also affected, eg:
|
||||||
|
|
||||||
|
``` {.journal}
|
||||||
|
apply account business
|
||||||
|
include biz.journal
|
||||||
|
end apply account
|
||||||
|
apply account personal
|
||||||
|
include personal.journal
|
||||||
|
```
|
||||||
|
|
||||||
|
Prior to hledger 0.28, legacy `account` and `end` spellings were also supported.
|
||||||
|
|
||||||
##### Multi-line comments
|
##### Multi-line comments
|
||||||
|
|
||||||
A line containing just `comment` starts a multi-line comment, and a
|
A line containing just `comment` starts a multi-line comment, and a
|
||||||
@ -710,43 +763,6 @@ $ hledger print
|
|||||||
d £-1,000.00
|
d £-1,000.00
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Default parent account
|
|
||||||
|
|
||||||
You can specify a parent account which will be prepended to all accounts
|
|
||||||
within a section of the journal. Use the `apply account` directive like so:
|
|
||||||
|
|
||||||
``` {.journal}
|
|
||||||
apply account home
|
|
||||||
|
|
||||||
2010/1/1
|
|
||||||
food $10
|
|
||||||
cash
|
|
||||||
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
(`!account`, `account`, and `end apply account` are also supported).
|
|
||||||
|
|
||||||
If `end` is omitted, the effect lasts to the end of the file.
|
|
||||||
The above is equivalent to:
|
|
||||||
|
|
||||||
``` {.journal}
|
|
||||||
2010/01/01
|
|
||||||
home:food $10
|
|
||||||
home:cash $-10
|
|
||||||
```
|
|
||||||
|
|
||||||
Included files are also affected, eg:
|
|
||||||
|
|
||||||
``` {.journal}
|
|
||||||
account business
|
|
||||||
include biz.journal
|
|
||||||
end
|
|
||||||
account personal
|
|
||||||
include personal.journal
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Default year
|
##### Default year
|
||||||
|
|
||||||
You can set a default year to be used for subsequent dates which don't
|
You can set a default year to be used for subsequent dates which don't
|
||||||
|
|||||||
@ -1,40 +1,10 @@
|
|||||||
# Accept three forms of the account directive
|
# . apply account, end apply account
|
||||||
# . !account, !end (ledger 2, hledger)
|
|
||||||
hledger -f - accounts
|
|
||||||
<<<
|
|
||||||
!account a
|
|
||||||
2016/1/1
|
|
||||||
(b) 1
|
|
||||||
!end
|
|
||||||
2016/1/2
|
|
||||||
(c) 1
|
|
||||||
>>>
|
|
||||||
a:b
|
|
||||||
c
|
|
||||||
>>>=0
|
|
||||||
|
|
||||||
# . account, end (ledger 3 pre ?, hledger)
|
|
||||||
hledger -f - accounts
|
|
||||||
<<<
|
|
||||||
account a
|
|
||||||
2016/1/1
|
|
||||||
(b) 1
|
|
||||||
end
|
|
||||||
2016/1/2
|
|
||||||
(c) 1
|
|
||||||
>>>
|
|
||||||
a:b
|
|
||||||
c
|
|
||||||
>>>=0
|
|
||||||
|
|
||||||
# . apply account, end [apply account] (ledger 3, hledger)
|
|
||||||
# . now: apply account
|
|
||||||
hledger -f - accounts
|
hledger -f - accounts
|
||||||
<<<
|
<<<
|
||||||
apply account a
|
apply account a
|
||||||
2016/1/1
|
2016/1/1
|
||||||
(b) 1
|
(b) 1
|
||||||
end
|
end apply account
|
||||||
apply account aa
|
apply account aa
|
||||||
2016/1/1
|
2016/1/1
|
||||||
(b) 1
|
(b) 1
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user