From ddefec412fe8cd66e16dd7ee26d22d4880267c9e Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sun, 8 May 2016 20:56:34 -0700 Subject: [PATCH] journal: also allow one-line commodity directives --- hledger-lib/Hledger/Read/JournalReader.hs | 33 ++++++++++++++++++++--- tests/journal/commodity-styles.test | 15 +++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/hledger-lib/Hledger/Read/JournalReader.hs b/hledger-lib/Hledger/Read/JournalReader.hs index a18641d28..efc7ffb67 100644 --- a/hledger-lib/Hledger/Read/JournalReader.hs +++ b/hledger-lib/Hledger/Read/JournalReader.hs @@ -377,13 +377,38 @@ parserErrorAt :: SourcePos -> String -> ErroringJournalParser a parserErrorAt pos s = do 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 = 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" many1 spacenonewline sym <- commoditysymbolp - _ <- followingcommentp + _ <- followingcommentp <|> (eolof >> return "") mformat <- lastMay <$> many (indented $ formatdirectivep sym) let comm = Commodity{csymbol=sym, cformat=mformat} return $ ExceptT $ return $ Right $ \j -> j{jcommodities=M.insert sym comm $ jcommodities j} @@ -398,7 +423,7 @@ formatdirectivep expectedsym = do many1 spacenonewline pos <- getPosition Amount{acommodity,astyle} <- amountp - _ <- followingcommentp + _ <- followingcommentp <|> (eolof >> return "") if acommodity==expectedsym then return astyle else parserErrorAt pos $ diff --git a/tests/journal/commodity-styles.test b/tests/journal/commodity-styles.test index 2a4f3427e..c39ad35e3 100644 --- a/tests/journal/commodity-styles.test +++ b/tests/journal/commodity-styles.test @@ -6,6 +6,21 @@ hledger -f- bal -V -N <<< ; use a commodity directive to ensure B is displayed with two decimal ; 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 format 1.00 B