journal: also allow one-line commodity directives

This commit is contained in:
Simon Michael 2016-05-08 20:56:34 -07:00
parent b583cb327d
commit ddefec412f
2 changed files with 44 additions and 4 deletions

View File

@ -377,13 +377,38 @@ parserErrorAt :: SourcePos -> String -> ErroringJournalParser a
parserErrorAt pos s = do parserErrorAt pos s = do
throwError $ show pos ++ ":\n" ++ s throwError $ show pos ++ ":\n" ++ s
-- | Parse a commodity directive, containing 0 or more format subdirectives. -- | Parse a one-line or multi-line commodity directive.
--
-- >>> Right _ <- rejp commoditydirectivep "commodity $1.00"
-- >>> Right _ <- rejp commoditydirectivep "commodity $\n format $1.00"
-- >>> Right _ <- rejp commoditydirectivep "commodity $\n\n" -- a commodity with no format
-- >>> Right _ <- rejp commoditydirectivep "commodity $1.00\n format $1.00" -- both, what happens ?
commoditydirectivep :: ErroringJournalParser JournalUpdate commoditydirectivep :: ErroringJournalParser JournalUpdate
commoditydirectivep = do commoditydirectivep = try commoditydirectiveonelinep <|> commoditydirectivemultilinep
-- | Parse a one-line commodity directive.
--
-- >>> Right _ <- rejp commoditydirectiveonelinep "commodity $1.00"
-- >>> Right _ <- rejp commoditydirectiveonelinep "commodity $1.00 ; blah\n"
commoditydirectiveonelinep :: ErroringJournalParser JournalUpdate
commoditydirectiveonelinep = do
string "commodity"
many1 spacenonewline
Amount{acommodity,astyle} <- amountp
many spacenonewline
_ <- followingcommentp <|> (eolof >> return "")
let comm = Commodity{csymbol=acommodity, cformat=Just astyle}
return $ ExceptT $ return $ Right $ \j -> j{jcommodities=M.insert acommodity comm $ jcommodities j}
-- | Parse a multi-line commodity directive, containing 0 or more format subdirectives.
--
-- >>> Right _ <- rejp commoditydirectivemultilinep "commodity $ ; blah \n format $1.00 ; blah"
commoditydirectivemultilinep :: ErroringJournalParser JournalUpdate
commoditydirectivemultilinep = do
string "commodity" string "commodity"
many1 spacenonewline many1 spacenonewline
sym <- commoditysymbolp sym <- commoditysymbolp
_ <- followingcommentp _ <- followingcommentp <|> (eolof >> return "")
mformat <- lastMay <$> many (indented $ formatdirectivep sym) mformat <- lastMay <$> many (indented $ formatdirectivep sym)
let comm = Commodity{csymbol=sym, cformat=mformat} let comm = Commodity{csymbol=sym, cformat=mformat}
return $ ExceptT $ return $ Right $ \j -> j{jcommodities=M.insert sym comm $ jcommodities j} return $ ExceptT $ return $ Right $ \j -> j{jcommodities=M.insert sym comm $ jcommodities j}
@ -398,7 +423,7 @@ formatdirectivep expectedsym = do
many1 spacenonewline many1 spacenonewline
pos <- getPosition pos <- getPosition
Amount{acommodity,astyle} <- amountp Amount{acommodity,astyle} <- amountp
_ <- followingcommentp _ <- followingcommentp <|> (eolof >> return "")
if acommodity==expectedsym if acommodity==expectedsym
then return astyle then return astyle
else parserErrorAt pos $ else parserErrorAt pos $

View File

@ -6,6 +6,21 @@ hledger -f- bal -V -N
<<< <<<
; use a commodity directive to ensure B is displayed with two decimal ; use a commodity directive to ensure B is displayed with two decimal
; places, or the price directive plus -V would make it four ; places, or the price directive plus -V would make it four
commodity 1.00 B
P 2015/1/1 A 1.0001 B
2015/1/1
(a) 1.00 A
(b) 1.00 B
>>>
1.00 B a
1.00 B b
>>>=0
# 2. A multi-line commodity directive also works.
hledger -f- bal -V -N
<<<
commodity B commodity B
format 1.00 B format 1.00 B