packages feed

hledger-lib 1.3 → 1.3.1

raw patch · 26 files changed

+425/−310 lines, 26 filesdep ~megaparsecdep ~timePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: megaparsec, time

API changes (from Hackage documentation)

- Hledger.Utils.Parse: type JournalStateParser m a = StateT Journal (ParsecT Dec Text m) a
+ Hledger.Utils.Parse: type SimpleStringParser a = Parsec MPErr String a
+ Hledger.Utils.Parse: type SimpleTextParser = Parsec MPErr Text
+ Text.Megaparsec.Compat: mpMkParseError :: FilePath -> String -> ParseError Char String
+ Text.Megaparsec.Compat: mpMkPos :: Int -> Pos
+ Text.Megaparsec.Compat: mpUnPos :: Pos -> Int
+ Text.Megaparsec.Compat: mptext :: MonadParsec e Text m => Tokens Text -> m (Tokens Text)
+ Text.Megaparsec.Compat: type MPErr = Void
- Hledger.Data.Dates: fixSmartDateStrEither :: Day -> Text -> Either (ParseError Char Dec) String
+ Hledger.Data.Dates: fixSmartDateStrEither :: Day -> Text -> Either (ParseError Char MPErr) String
- Hledger.Data.Dates: fixSmartDateStrEither' :: Day -> Text -> Either (ParseError Char Dec) Day
+ Hledger.Data.Dates: fixSmartDateStrEither' :: Day -> Text -> Either (ParseError Char MPErr) Day
- Hledger.Data.Dates: parsePeriodExpr :: Day -> Text -> Either (ParseError Char Dec) (Interval, DateSpan)
+ Hledger.Data.Dates: parsePeriodExpr :: Day -> Text -> Either (ParseError Char MPErr) (Interval, DateSpan)
- Hledger.Data.Dates: smartdate :: Parser SmartDate
+ Hledger.Data.Dates: smartdate :: SimpleTextParser SmartDate
- Hledger.Read.Common: amountp :: Monad m => JournalStateParser m Amount
+ Hledger.Read.Common: amountp :: Monad m => JournalParser m Amount
- Hledger.Read.Common: commentStartingWithp :: [Char] -> JournalStateParser m Text
+ Hledger.Read.Common: commentStartingWithp :: [Char] -> JournalParser m Text
- Hledger.Read.Common: commentp :: JournalStateParser m Text
+ Hledger.Read.Common: commentp :: JournalParser m Text
- Hledger.Read.Common: datep :: JournalStateParser m Day
+ Hledger.Read.Common: datep :: JournalParser m Day
- Hledger.Read.Common: datetimep :: JournalStateParser m LocalTime
+ Hledger.Read.Common: datetimep :: JournalParser m LocalTime
- Hledger.Read.Common: descriptionp :: JournalStateParser m String
+ Hledger.Read.Common: descriptionp :: JournalParser m String
- Hledger.Read.Common: emptyorcommentlinep :: JournalStateParser m ()
+ Hledger.Read.Common: emptyorcommentlinep :: JournalParser m ()
- Hledger.Read.Common: fixedlotpricep :: Monad m => JournalStateParser m (Maybe Amount)
+ Hledger.Read.Common: fixedlotpricep :: Monad m => JournalParser m (Maybe Amount)
- Hledger.Read.Common: followingcommentp :: JournalStateParser m Text
+ Hledger.Read.Common: followingcommentp :: JournalParser m Text
- Hledger.Read.Common: getDefaultCommodityAndStyle :: JournalStateParser m (Maybe (CommoditySymbol, AmountStyle))
+ Hledger.Read.Common: getDefaultCommodityAndStyle :: JournalParser m (Maybe (CommoditySymbol, AmountStyle))
- Hledger.Read.Common: getParentAccount :: JournalStateParser m AccountName
+ Hledger.Read.Common: getParentAccount :: JournalParser m AccountName
- Hledger.Read.Common: getYear :: JournalStateParser m (Maybe Year)
+ Hledger.Read.Common: getYear :: JournalParser m (Maybe Year)
- Hledger.Read.Common: leftsymbolamountp :: Monad m => JournalStateParser m Amount
+ Hledger.Read.Common: leftsymbolamountp :: Monad m => JournalParser m Amount
- Hledger.Read.Common: modifiedaccountnamep :: JournalStateParser m AccountName
+ Hledger.Read.Common: modifiedaccountnamep :: JournalParser m AccountName
- Hledger.Read.Common: multilinecommentp :: JournalStateParser m ()
+ Hledger.Read.Common: multilinecommentp :: JournalParser m ()
- Hledger.Read.Common: nontagp :: Parser String
+ Hledger.Read.Common: nontagp :: SimpleTextParser String
- Hledger.Read.Common: nosymbolamountp :: Monad m => JournalStateParser m Amount
+ Hledger.Read.Common: nosymbolamountp :: Monad m => JournalParser m Amount
- Hledger.Read.Common: parseAndFinaliseJournal' :: JournalParser ParsedJournal -> Bool -> FilePath -> Text -> ExceptT String IO Journal
+ Hledger.Read.Common: parseAndFinaliseJournal' :: JournalParser Identity ParsedJournal -> Bool -> FilePath -> Text -> ExceptT String IO Journal
- Hledger.Read.Common: partialbalanceassertionp :: Monad m => JournalStateParser m (Maybe Amount)
+ Hledger.Read.Common: partialbalanceassertionp :: Monad m => JournalParser m (Maybe Amount)
- Hledger.Read.Common: popParentAccount :: JournalStateParser m ()
+ Hledger.Read.Common: popParentAccount :: JournalParser m ()
- Hledger.Read.Common: priceamountp :: Monad m => JournalStateParser m Price
+ Hledger.Read.Common: priceamountp :: Monad m => JournalParser m Price
- Hledger.Read.Common: pushAccount :: AccountName -> JournalStateParser m ()
+ Hledger.Read.Common: pushAccount :: AccountName -> JournalParser m ()
- Hledger.Read.Common: pushParentAccount :: AccountName -> JournalStateParser m ()
+ Hledger.Read.Common: pushParentAccount :: AccountName -> JournalParser m ()
- Hledger.Read.Common: rightsymbolamountp :: Monad m => JournalStateParser m Amount
+ Hledger.Read.Common: rightsymbolamountp :: Monad m => JournalParser m Amount
- Hledger.Read.Common: rjp :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char Dec) a)
+ Hledger.Read.Common: rjp :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char MPErr) a)
- Hledger.Read.Common: rtp :: TextParser Identity a -> Text -> Either (ParseError Char Dec) a
+ Hledger.Read.Common: rtp :: TextParser Identity a -> Text -> Either (ParseError Char MPErr) a
- Hledger.Read.Common: runJournalParser :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char Dec) a)
+ Hledger.Read.Common: runJournalParser :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char MPErr) a)
- Hledger.Read.Common: runTextParser :: TextParser Identity a -> Text -> Either (ParseError Char Dec) a
+ Hledger.Read.Common: runTextParser :: TextParser Identity a -> Text -> Either (ParseError Char MPErr) a
- Hledger.Read.Common: secondarydatep :: Day -> JournalStateParser m Day
+ Hledger.Read.Common: secondarydatep :: Day -> JournalParser m Day
- Hledger.Read.Common: semicoloncommentp :: JournalStateParser m Text
+ Hledger.Read.Common: semicoloncommentp :: JournalParser m Text
- Hledger.Read.Common: setDefaultCommodityAndStyle :: (CommoditySymbol, AmountStyle) -> JournalStateParser m ()
+ Hledger.Read.Common: setDefaultCommodityAndStyle :: (CommoditySymbol, AmountStyle) -> JournalParser m ()
- Hledger.Read.Common: setYear :: Year -> JournalStateParser m ()
+ Hledger.Read.Common: setYear :: Year -> JournalParser m ()
- Hledger.Read.Common: spaceandamountormissingp :: Monad m => JournalStateParser m MixedAmount
+ Hledger.Read.Common: spaceandamountormissingp :: Monad m => JournalParser m MixedAmount
- Hledger.Read.Common: tagnamep :: Parser Text
+ Hledger.Read.Common: tagnamep :: SimpleTextParser Text
- Hledger.Read.Common: tagp :: Parser Tag
+ Hledger.Read.Common: tagp :: SimpleTextParser Tag
- Hledger.Read.Common: tagsp :: Parser [Tag]
+ Hledger.Read.Common: tagsp :: SimpleTextParser [Tag]
- Hledger.Read.JournalReader: datep :: JournalStateParser m Day
+ Hledger.Read.JournalReader: datep :: JournalParser m Day
- Hledger.Read.JournalReader: datetimep :: JournalStateParser m LocalTime
+ Hledger.Read.JournalReader: datetimep :: JournalParser m LocalTime
- Hledger.Read.JournalReader: defaultyeardirectivep :: JournalStateParser m ()
+ Hledger.Read.JournalReader: defaultyeardirectivep :: JournalParser m ()
- Hledger.Read.JournalReader: emptyorcommentlinep :: JournalStateParser m ()
+ Hledger.Read.JournalReader: emptyorcommentlinep :: JournalParser m ()
- Hledger.Read.JournalReader: followingcommentp :: JournalStateParser m Text
+ Hledger.Read.JournalReader: followingcommentp :: JournalParser m Text
- Hledger.Read.JournalReader: getParentAccount :: JournalStateParser m AccountName
+ Hledger.Read.JournalReader: getParentAccount :: JournalParser m AccountName
- Hledger.Read.JournalReader: marketpricedirectivep :: Monad m => JournalStateParser m MarketPrice
+ Hledger.Read.JournalReader: marketpricedirectivep :: Monad m => JournalParser m MarketPrice
- Hledger.Read.JournalReader: modifiedaccountnamep :: JournalStateParser m AccountName
+ Hledger.Read.JournalReader: modifiedaccountnamep :: JournalParser m AccountName
- Hledger.Read.JournalReader: rjp :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char Dec) a)
+ Hledger.Read.JournalReader: rjp :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char MPErr) a)
- Hledger.Read.JournalReader: runJournalParser :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char Dec) a)
+ Hledger.Read.JournalReader: runJournalParser :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char MPErr) a)
- Hledger.Read.TimedotReader: timedotfilep :: JournalStateParser m ParsedJournal
+ Hledger.Read.TimedotReader: timedotfilep :: JournalParser m ParsedJournal
- Hledger.Utils.Parse: choiceInState :: [StateT s (ParsecT Dec Text m) a] -> StateT s (ParsecT Dec Text m) a
+ Hledger.Utils.Parse: choiceInState :: [StateT s (ParsecT MPErr Text m) a] -> StateT s (ParsecT MPErr Text m) a
- Hledger.Utils.Parse: parseWithState :: Monad m => st -> StateT st (ParsecT Dec Text m) a -> Text -> m (Either (ParseError Char Dec) a)
+ Hledger.Utils.Parse: parseWithState :: Monad m => st -> StateT st (ParsecT MPErr Text m) a -> Text -> m (Either (ParseError Char MPErr) a)
- Hledger.Utils.Parse: parseWithState' :: (Stream s, ErrorComponent e) => st -> StateT st (ParsecT e s Identity) a -> s -> (Either (ParseError (Token s) e) a)
+ Hledger.Utils.Parse: parseWithState' :: (Stream s) => st -> StateT st (ParsecT e s Identity) a -> s -> (Either (ParseError (Token s) e) a)
- Hledger.Utils.Parse: spacenonewline :: (Stream s, Char ~ Token s) => ParsecT Dec s m Char
+ Hledger.Utils.Parse: spacenonewline :: (Stream s, Char ~ Token s) => ParsecT MPErr s m Char
- Hledger.Utils.Parse: type ErroringJournalParser m a = StateT Journal (ParsecT Dec Text (ExceptT String m)) a
+ Hledger.Utils.Parse: type ErroringJournalParser m a = StateT Journal (ParsecT MPErr Text (ExceptT String m)) a
- Hledger.Utils.Parse: type JournalParser a = StateT Journal (ParsecT Dec Text Identity) a
+ Hledger.Utils.Parse: type JournalParser m a = StateT Journal (ParsecT MPErr Text m) a
- Hledger.Utils.Parse: type TextParser m a = ParsecT Dec Text m a
+ Hledger.Utils.Parse: type TextParser m a = ParsecT MPErr Text m a

Files

CHANGES view
@@ -1,23 +1,39 @@ API-ish changes in the hledger-lib package. See also the hledger and project change logs (for user-visible changes). +# 1.3.1 (2017/8/25) -# 1.3 (2017/6/30)+* Fix a bug with -H showing nothing for empty periods (Nicholas Niro)+This patch fixes a bug that happened when using the -H option on+a period without any transaction. Previously, the behavior was no+output at all even though it should have shown the previous ending balances+of past transactions. (This is similar to previously using -H with -E,+but with the extra advantage of not showing empty accounts) -Deps: allow megaparsec 5.3.+* allow megaparsec 6 (#594) -CSV conversion: assigning to the "balance" field name creates balance-assertions (#537, Dmitry Astapov).-Doubled minus signs are handled more robustly (fixes #524, Nicolas Wavrant, Simon Michael)+* allow megaparsec-6.1 (Hans-Peter Deifel) -The "uncleared" transaction/posting status, and associated UI flags+* fix test suite with Cabal 2 (#596)+++# 1.3 (2017/6/30)++journal: The "uncleared" transaction/posting status, and associated UI flags and keys, have been renamed to "unmarked" to remove ambiguity and confusion.  This means that we have dropped the `--uncleared` flag, and our `-U` flag now matches only unmarked things and not pending ones.  See the issue and linked mail list discussion for more background.  (#564) -Multiple status: query terms are now OR'd together. (#564)+csv: assigning to the "balance" field name creates balance+assertions (#537, Dmitry Astapov).++csv: Doubled minus signs are handled more robustly (fixes #524, Nicolas Wavrant, Simon Michael)++Multiple "status:" query terms are now OR'd together. (#564)++deps: allow megaparsec 5.3.   # 1.2 (2017/3/31)
Hledger/Data/Dates.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} {-|  Date parsing and utilities for hledger.@@ -86,8 +87,7 @@ import Data.Time.Clock import Data.Time.LocalTime import Safe (headMay, lastMay, readMay)-import Text.Megaparsec-import Text.Megaparsec.Text+import Text.Megaparsec.Compat import Text.Printf  import Hledger.Data.Types@@ -256,7 +256,7 @@  -- | Parse a period expression to an Interval and overall DateSpan using -- the provided reference date, or return a parse error.-parsePeriodExpr :: Day -> Text -> Either (ParseError Char Dec) (Interval, DateSpan)+parsePeriodExpr :: Day -> Text -> Either (ParseError Char MPErr) (Interval, DateSpan) parsePeriodExpr refdate = parsewith (periodexpr refdate <* eof)  maybePeriod :: Day -> Text -> Maybe (Interval,DateSpan)@@ -316,13 +316,13 @@ fixSmartDateStr d s = either                        (\e->error' $ printf "could not parse date %s %s" (show s) (show e))                        id-                       $ (fixSmartDateStrEither d s :: Either (ParseError Char Dec) String)+                       $ (fixSmartDateStrEither d s :: Either (ParseError Char MPErr) String)  -- | A safe version of fixSmartDateStr.-fixSmartDateStrEither :: Day -> Text -> Either (ParseError Char Dec) String+fixSmartDateStrEither :: Day -> Text -> Either (ParseError Char MPErr) String fixSmartDateStrEither d = either Left (Right . showDate) . fixSmartDateStrEither' d -fixSmartDateStrEither' :: Day -> Text -> Either (ParseError Char Dec) Day+fixSmartDateStrEither' :: Day -> Text -> Either (ParseError Char MPErr) Day fixSmartDateStrEither' d s = case parsewith smartdateonly (T.toLower s) of                                Right sd -> Right $ fixSmartDate d sd                                Left e -> Left e@@ -550,14 +550,14 @@ Returns a SmartDate, to be converted to a full date later (see fixSmartDate). Assumes any text in the parse stream has been lowercased. -}-smartdate :: Parser SmartDate+smartdate :: SimpleTextParser SmartDate smartdate = do   -- XXX maybe obscures date errors ? see ledgerdate   (y,m,d) <- choice' [yyyymmdd, ymd, ym, md, y, d, month, mon, today, yesterday, tomorrow, lastthisnextthing]   return (y,m,d)  -- | Like smartdate, but there must be nothing other than whitespace after the date.-smartdateonly :: Parser SmartDate+smartdateonly :: SimpleTextParser SmartDate smartdateonly = do   d <- smartdate   many spacenonewline@@ -579,7 +579,7 @@ failIfInvalidMonth s = unless (validMonth s) $ fail $ "bad month number: " ++ s failIfInvalidDay s   = unless (validDay s)   $ fail $ "bad day number: " ++ s -yyyymmdd :: Parser SmartDate+yyyymmdd :: SimpleTextParser SmartDate yyyymmdd = do   y <- count 4 digitChar   m <- count 2 digitChar@@ -588,7 +588,7 @@   failIfInvalidDay d   return (y,m,d) -ymd :: Parser SmartDate+ymd :: SimpleTextParser SmartDate ymd = do   y <- some digitChar   failIfInvalidYear y@@ -600,7 +600,7 @@   failIfInvalidDay d   return $ (y,m,d) -ym :: Parser SmartDate+ym :: SimpleTextParser SmartDate ym = do   y <- some digitChar   failIfInvalidYear y@@ -609,19 +609,19 @@   failIfInvalidMonth m   return (y,m,"") -y :: Parser SmartDate+y :: SimpleTextParser SmartDate y = do   y <- some digitChar   failIfInvalidYear y   return (y,"","") -d :: Parser SmartDate+d :: SimpleTextParser SmartDate d = do   d <- some digitChar   failIfInvalidDay d   return ("","",d) -md :: Parser SmartDate+md :: SimpleTextParser SmartDate md = do   m <- some digitChar   failIfInvalidMonth m@@ -636,48 +636,54 @@ -- weekdays       = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"] -- weekdayabbrevs = ["mon","tue","wed","thu","fri","sat","sun"] -monthIndex s = maybe 0 (+1) $ lowercase s `elemIndex` months-monIndex s   = maybe 0 (+1) $ lowercase s `elemIndex` monthabbrevs+#if MIN_VERSION_megaparsec(6,0,0)+lc = T.toLower+#else+lc = lowercase+#endif -month :: Parser SmartDate+monthIndex t = maybe 0 (+1) $ lc t `elemIndex` months+monIndex t   = maybe 0 (+1) $ lc t `elemIndex` monthabbrevs++month :: SimpleTextParser SmartDate month = do   m <- choice $ map (try . string) months   let i = monthIndex m   return ("",show i,"") -mon :: Parser SmartDate+mon :: SimpleTextParser SmartDate mon = do   m <- choice $ map (try . string) monthabbrevs   let i = monIndex m   return ("",show i,"") -today,yesterday,tomorrow :: Parser SmartDate+today,yesterday,tomorrow :: SimpleTextParser SmartDate today     = string "today"     >> return ("","","today") yesterday = string "yesterday" >> return ("","","yesterday") tomorrow  = string "tomorrow"  >> return ("","","tomorrow") -lastthisnextthing :: Parser SmartDate+lastthisnextthing :: SimpleTextParser SmartDate lastthisnextthing = do-  r <- choice [-        string "last"-       ,string "this"-       ,string "next"+  r <- choice $ map mptext [+        "last"+       ,"this"+       ,"next"       ]   many spacenonewline  -- make the space optional for easier scripting-  p <- choice [-        string "day"-       ,string "week"-       ,string "month"-       ,string "quarter"-       ,string "year"+  p <- choice $ map mptext [+        "day"+       ,"week"+       ,"month"+       ,"quarter"+       ,"year"       ] -- XXX support these in fixSmartDate --       ++ (map string $ months ++ monthabbrevs ++ weekdays ++ weekdayabbrevs) -  return ("",r,p)+  return ("", T.unpack r, T.unpack p)  -- |--- >>> let p = parsewith (periodexpr (parsedate "2008/11/26")) :: T.Text -> Either (ParseError Char Dec) (Interval, DateSpan)+-- >>> let p = parsewith (periodexpr (parsedate "2008/11/26")) :: T.Text -> Either (ParseError Char MPErr) (Interval, DateSpan) -- >>> p "from aug to oct" -- Right (NoInterval,DateSpan 2008/08/01-2008/09/30) -- >>> p "aug to oct"@@ -688,7 +694,7 @@ -- Right (Days 1,DateSpan 2008/08/01-) -- >>> p "every week to 2009" -- Right (Weeks 1,DateSpan -2008/12/31)-periodexpr :: Day -> Parser (Interval, DateSpan)+periodexpr :: Day -> SimpleTextParser (Interval, DateSpan) periodexpr rdate = choice $ map try [                     intervalanddateperiodexpr rdate,                     intervalperiodexpr,@@ -696,7 +702,7 @@                     (return (NoInterval,DateSpan Nothing Nothing))                    ] -intervalanddateperiodexpr :: Day -> Parser (Interval, DateSpan)+intervalanddateperiodexpr :: Day -> SimpleTextParser (Interval, DateSpan) intervalanddateperiodexpr rdate = do   many spacenonewline   i <- reportinginterval@@ -704,20 +710,20 @@   s <- periodexprdatespan rdate   return (i,s) -intervalperiodexpr :: Parser (Interval, DateSpan)+intervalperiodexpr :: SimpleTextParser (Interval, DateSpan) intervalperiodexpr = do   many spacenonewline   i <- reportinginterval   return (i, DateSpan Nothing Nothing) -dateperiodexpr :: Day -> Parser (Interval, DateSpan)+dateperiodexpr :: Day -> SimpleTextParser (Interval, DateSpan) dateperiodexpr rdate = do   many spacenonewline   s <- periodexprdatespan rdate   return (NoInterval, s)  -- Parse a reporting interval.-reportinginterval :: Parser Interval+reportinginterval :: SimpleTextParser Interval reportinginterval = choice' [                        tryinterval "day"     "daily"     Days,                        tryinterval "week"    "weekly"    Weeks,@@ -757,25 +763,28 @@       thsuffix = choice' $ map string ["st","nd","rd","th"]        -- Parse any of several variants of a basic interval, eg "daily", "every day", "every N days".-      tryinterval :: String -> String -> (Int -> Interval) -> Parser Interval+      tryinterval :: String -> String -> (Int -> Interval) -> SimpleTextParser Interval       tryinterval singular compact intcons =-          choice' [-           do string compact-              return $ intcons 1,-           do string "every"-              many spacenonewline-              string singular-              return $ intcons 1,-           do string "every"-              many spacenonewline-              n <- fmap read $ some digitChar-              many spacenonewline-              string plural-              return $ intcons n-           ]-          where plural = singular ++ "s"+        choice' [+          do mptext compact'+             return $ intcons 1,+          do mptext "every"+             many spacenonewline+             mptext singular'+             return $ intcons 1,+          do mptext "every"+             many spacenonewline+             n <- fmap read $ some digitChar+             many spacenonewline+             mptext plural'+             return $ intcons n+          ]+        where+          compact'  = T.pack compact+          singular' = T.pack singular+          plural'   = T.pack $ singular ++ "s" -periodexprdatespan :: Day -> Parser DateSpan+periodexprdatespan :: Day -> SimpleTextParser DateSpan periodexprdatespan rdate = choice $ map try [                             doubledatespan rdate,                             fromdatespan rdate,@@ -783,7 +792,7 @@                             justdatespan rdate                            ] -doubledatespan :: Day -> Parser DateSpan+doubledatespan :: Day -> SimpleTextParser DateSpan doubledatespan rdate = do   optional (string "from" >> many spacenonewline)   b <- smartdate@@ -792,7 +801,7 @@   e <- smartdate   return $ DateSpan (Just $ fixSmartDate rdate b) (Just $ fixSmartDate rdate e) -fromdatespan :: Day -> Parser DateSpan+fromdatespan :: Day -> SimpleTextParser DateSpan fromdatespan rdate = do   b <- choice [     do@@ -806,13 +815,13 @@     ]   return $ DateSpan (Just $ fixSmartDate rdate b) Nothing -todatespan :: Day -> Parser DateSpan+todatespan :: Day -> SimpleTextParser DateSpan todatespan rdate = do   choice [string "to", string "-"] >> many spacenonewline   e <- smartdate   return $ DateSpan Nothing (Just $ fixSmartDate rdate e) -justdatespan :: Day -> Parser DateSpan+justdatespan :: Day -> SimpleTextParser DateSpan justdatespan rdate = do   optional (string "in" >> many spacenonewline)   d <- smartdate
Hledger/Data/StringFormat.hs view
@@ -19,9 +19,9 @@ import Data.Char (isPrint) import Data.Maybe import Test.HUnit-import Text.Megaparsec-import Text.Megaparsec.String+import Text.Megaparsec.Compat +import Hledger.Utils.Parse import Hledger.Utils.String (formatString)  -- | A format specification/template to use when rendering a report line item as text.@@ -86,7 +86,7 @@  defaultStringFormatStyle = BottomAligned -stringformatp :: Parser StringFormat+stringformatp :: SimpleStringParser StringFormat stringformatp = do   alignspec <- optional (try $ char '%' >> oneOf "^_,")   let constructor =@@ -97,10 +97,10 @@           _        -> defaultStringFormatStyle   constructor <$> many componentp -componentp :: Parser StringFormatComponent+componentp :: SimpleStringParser StringFormatComponent componentp = formatliteralp <|> formatfieldp -formatliteralp :: Parser StringFormatComponent+formatliteralp :: SimpleStringParser StringFormatComponent formatliteralp = do     s <- some c     return $ FormatLiteral s@@ -109,7 +109,7 @@       c =     (satisfy isPrintableButNotPercentage <?> "printable character")           <|> try (string "%%" >> return '%') -formatfieldp :: Parser StringFormatComponent+formatfieldp :: SimpleStringParser StringFormatComponent formatfieldp = do     char '%'     leftJustified <- optional (char '-')@@ -124,7 +124,7 @@         Just text -> Just m where ((m,_):_) = readDec text         _ -> Nothing -fieldp :: Parser ReportItemField+fieldp :: SimpleStringParser ReportItemField fieldp = do         try (string "account" >> return AccountField)     <|> try (string "depth_spacer" >> return DepthSpacerField)
Hledger/Query.hs view
@@ -1,7 +1,7 @@ {-|  A general query system for matching things (accounts, postings,-transactions..)  by various criteria, and a parser for query expressions.+transactions..)  by various criteria, and a SimpleTextParser for query expressions.  -} @@ -55,8 +55,7 @@ import Data.Time.Calendar import Safe (readDef, headDef) import Test.HUnit-import Text.Megaparsec-import Text.Megaparsec.Text+import Text.Megaparsec.Compat  import Hledger.Utils hiding (words') import Hledger.Data.Types@@ -185,23 +184,23 @@ words'' :: [T.Text] -> T.Text -> [T.Text] words'' prefixes = fromparse . parsewith maybeprefixedquotedphrases -- XXX     where-      maybeprefixedquotedphrases :: Parser [T.Text]+      maybeprefixedquotedphrases :: SimpleTextParser [T.Text]       maybeprefixedquotedphrases = choice' [prefixedQuotedPattern, singleQuotedPattern, doubleQuotedPattern, pattern] `sepBy` some spacenonewline-      prefixedQuotedPattern :: Parser T.Text+      prefixedQuotedPattern :: SimpleTextParser T.Text       prefixedQuotedPattern = do-        not' <- fromMaybe "" `fmap` (optional $ string "not:")-        let allowednexts | null not' = prefixes-                         | otherwise = prefixes ++ [""]-        next <- fmap T.pack $ choice' $ map (string . T.unpack) allowednexts+        not' <- fromMaybe "" `fmap` (optional $ mptext "not:")+        let allowednexts | T.null not' = prefixes+                         | otherwise   = prefixes ++ [""]+        next <- choice' $ map mptext allowednexts         let prefix :: T.Text-            prefix = T.pack not' <> next+            prefix = not' <> next         p <- singleQuotedPattern <|> doubleQuotedPattern         return $ prefix <> stripquotes p-      singleQuotedPattern :: Parser T.Text+      singleQuotedPattern :: SimpleTextParser T.Text       singleQuotedPattern = between (char '\'') (char '\'') (many $ noneOf ("'" :: [Char])) >>= return . stripquotes . T.pack-      doubleQuotedPattern :: Parser T.Text+      doubleQuotedPattern :: SimpleTextParser T.Text       doubleQuotedPattern = between (char '"') (char '"') (many $ noneOf ("\"" :: [Char])) >>= return . stripquotes . T.pack-      pattern :: Parser T.Text+      pattern :: SimpleTextParser T.Text       pattern = fmap T.pack $ many (noneOf (" \n\r" :: [Char]))  tests_words'' = [
Hledger/Read/Common.hs view
@@ -36,8 +36,7 @@ import Data.Time.LocalTime import Safe import System.Time (getClockTime)-import Text.Megaparsec hiding (parse,State)-import Text.Megaparsec.Text+import Text.Megaparsec.Compat  import Hledger.Data import Hledger.Utils@@ -47,12 +46,12 @@ --- * parsing utils  -- | Run a string parser with no state in the identity monad.-runTextParser, rtp :: TextParser Identity a -> Text -> Either (ParseError Char Dec) a+runTextParser, rtp :: TextParser Identity a -> Text -> Either (ParseError Char MPErr) a runTextParser p t =  runParser p "" t rtp = runTextParser  -- | Run a journal parser with a null journal-parsing state.-runJournalParser, rjp :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char Dec) a)+runJournalParser, rjp :: Monad m => TextParser m a -> Text -> m (Either (ParseError Char MPErr) a) runJournalParser p t = runParserT p "" t rjp = runJournalParser @@ -89,7 +88,7 @@                         Left e  -> throwError e     Left e   -> throwError $ parseErrorPretty e -parseAndFinaliseJournal' :: JournalParser ParsedJournal -> Bool -> FilePath -> Text -> ExceptT String IO Journal+parseAndFinaliseJournal' :: JournalParser Identity ParsedJournal -> Bool -> FilePath -> Text -> ExceptT String IO Journal parseAndFinaliseJournal' parser assrt f txt = do   t <- liftIO getClockTime   y <- liftIO getCurrentYear@@ -100,32 +99,32 @@                         Left e  -> throwError e     Left e   -> throwError $ parseErrorPretty e -setYear :: Year -> JournalStateParser m ()+setYear :: Year -> JournalParser m () setYear y = modify' (\j -> j{jparsedefaultyear=Just y}) -getYear :: JournalStateParser m (Maybe Year)+getYear :: JournalParser m (Maybe Year) getYear = fmap jparsedefaultyear get -setDefaultCommodityAndStyle :: (CommoditySymbol,AmountStyle) -> JournalStateParser m ()+setDefaultCommodityAndStyle :: (CommoditySymbol,AmountStyle) -> JournalParser m () setDefaultCommodityAndStyle cs = modify' (\j -> j{jparsedefaultcommodity=Just cs}) -getDefaultCommodityAndStyle :: JournalStateParser m (Maybe (CommoditySymbol,AmountStyle))+getDefaultCommodityAndStyle :: JournalParser m (Maybe (CommoditySymbol,AmountStyle)) getDefaultCommodityAndStyle = jparsedefaultcommodity `fmap` get -pushAccount :: AccountName -> JournalStateParser m ()+pushAccount :: AccountName -> JournalParser m () pushAccount acct = modify' (\j -> j{jaccounts = acct : jaccounts j}) -pushParentAccount :: AccountName -> JournalStateParser m ()+pushParentAccount :: AccountName -> JournalParser m () pushParentAccount acct = modify' (\j -> j{jparseparentaccounts = acct : jparseparentaccounts j}) -popParentAccount :: JournalStateParser m ()+popParentAccount :: JournalParser m () popParentAccount = do   j <- get   case jparseparentaccounts j of     []       -> unexpected (Tokens ('E' :| "nd of apply account block with no beginning"))     (_:rest) -> put j{jparseparentaccounts=rest} -getParentAccount :: JournalStateParser m AccountName+getParentAccount :: JournalParser m AccountName getParentAccount = fmap (concatAccountNames . reverse . jparseparentaccounts) get  addAccountAlias :: MonadState Journal m => AccountAlias -> m ()@@ -181,7 +180,7 @@ codep :: TextParser m String codep = try (do { some spacenonewline; char '(' <?> "codep"; anyChar `manyTill` char ')' } ) <|> return "" -descriptionp :: JournalStateParser m String+descriptionp :: JournalParser m String descriptionp = many (noneOf (";\n" :: [Char]))  --- ** dates@@ -190,7 +189,7 @@ -- Hyphen (-) and period (.) are also allowed as separators. -- The year may be omitted if a default year has been set. -- Leading zeroes may be omitted.-datep :: JournalStateParser m Day+datep :: JournalParser m Day datep = do   -- hacky: try to ensure precise errors for invalid dates   -- XXX reported error position is not too good@@ -220,7 +219,7 @@ -- Seconds are optional. -- The timezone is optional and ignored (the time is always interpreted as a local time). -- Leading zeroes may be omitted (except in a timezone).-datetimep :: JournalStateParser m LocalTime+datetimep :: JournalParser m LocalTime datetimep = do   day <- datep   lift $ some spacenonewline@@ -248,7 +247,7 @@   -- return $ localTimeToUTC tz' $ LocalTime day $ TimeOfDay h' m' (fromIntegral s')   return $ LocalTime day $ TimeOfDay h' m' (fromIntegral s') -secondarydatep :: Day -> JournalStateParser m Day+secondarydatep :: Day -> JournalParser m Day secondarydatep primarydate = do   char '='   -- kludgy way to use primary date for default year@@ -274,7 +273,7 @@ --- ** account names  -- | Parse an account name, then apply any parent account prefix and/or account aliases currently in effect.-modifiedaccountnamep :: JournalStateParser m AccountName+modifiedaccountnamep :: JournalParser m AccountName modifiedaccountnamep = do   parent <- getParentAccount   aliases <- getAccountAliases@@ -313,7 +312,7 @@ -- | Parse whitespace then an amount, with an optional left or right -- currency symbol and optional price, or return the special -- "missing" marker amount.-spaceandamountormissingp :: Monad m => JournalStateParser m MixedAmount+spaceandamountormissingp :: Monad m => JournalParser m MixedAmount spaceandamountormissingp =   try (do         lift $ some spacenonewline@@ -337,7 +336,7 @@ -- | Parse a single-commodity amount, with optional symbol on the left or -- right, optional unit or total price, and optional (ignored) -- ledger-style balance assertion or fixed lot price declaration.-amountp :: Monad m => JournalStateParser m Amount+amountp :: Monad m => JournalParser m Amount amountp = try leftsymbolamountp <|> try rightsymbolamountp <|> nosymbolamountp  #ifdef TESTS@@ -377,7 +376,7 @@   return $ case multiplier of Just '*' -> True                               _        -> False -leftsymbolamountp :: Monad m => JournalStateParser m Amount+leftsymbolamountp :: Monad m => JournalParser m Amount leftsymbolamountp = do   sign <- lift signp   m <- lift multiplierp@@ -390,7 +389,7 @@   return $ applysign $ Amount c q p s m   <?> "left-symbol amount" -rightsymbolamountp :: Monad m => JournalStateParser m Amount+rightsymbolamountp :: Monad m => JournalParser m Amount rightsymbolamountp = do   m <- lift multiplierp   (q,prec,mdec,mgrps) <- lift numberp@@ -401,7 +400,7 @@   return $ Amount c q p s m   <?> "right-symbol amount" -nosymbolamountp :: Monad m => JournalStateParser m Amount+nosymbolamountp :: Monad m => JournalParser m Amount nosymbolamountp = do   m <- lift multiplierp   (q,prec,mdec,mgrps) <- lift numberp@@ -427,7 +426,7 @@ simplecommoditysymbolp :: TextParser m CommoditySymbol simplecommoditysymbolp = T.pack <$> some (noneOf nonsimplecommoditychars) -priceamountp :: Monad m => JournalStateParser m Price+priceamountp :: Monad m => JournalParser m Price priceamountp =     try (do           lift (many spacenonewline)@@ -443,7 +442,7 @@             return $ UnitPrice a))          <|> return NoPrice -partialbalanceassertionp :: Monad m => JournalStateParser m (Maybe Amount)+partialbalanceassertionp :: Monad m => JournalParser m (Maybe Amount) partialbalanceassertionp =     try (do           lift (many spacenonewline)@@ -464,7 +463,7 @@ --          <|> return Nothing  -- http://ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices-fixedlotpricep :: Monad m => JournalStateParser m (Maybe Amount)+fixedlotpricep :: Monad m => JournalParser m (Maybe Amount) fixedlotpricep =     try (do           lift (many spacenonewline)@@ -564,7 +563,7 @@  --- ** comments -multilinecommentp :: JournalStateParser m ()+multilinecommentp :: JournalParser m () multilinecommentp = do   string "comment" >> lift (many spacenonewline) >> newline   go@@ -573,13 +572,13 @@          <|> (anyLine >> go)     anyLine = anyChar `manyTill` newline -emptyorcommentlinep :: JournalStateParser m ()+emptyorcommentlinep :: JournalParser m () emptyorcommentlinep = do   lift (many spacenonewline) >> (commentp <|> (lift (many spacenonewline) >> newline >> return ""))   return ()  -- | Parse a possibly multi-line comment following a semicolon.-followingcommentp :: JournalStateParser m Text+followingcommentp :: JournalParser m Text followingcommentp =   -- ptrace "followingcommentp"   do samelinecomment <- lift (many spacenonewline) >> (try semicoloncommentp <|> (newline >> return ""))@@ -641,16 +640,16 @@    return (comment, tags, mdate, mdate2) -commentp :: JournalStateParser m Text+commentp :: JournalParser m Text commentp = commentStartingWithp commentchars  commentchars :: [Char] commentchars = "#;*" -semicoloncommentp :: JournalStateParser m Text+semicoloncommentp :: JournalParser m Text semicoloncommentp = commentStartingWithp ";" -commentStartingWithp :: [Char] -> JournalStateParser m Text+commentStartingWithp :: [Char] -> JournalParser m Text commentStartingWithp cs = do   -- ptrace "commentStartingWith"   oneOf cs@@ -681,7 +680,7 @@     Left _  -> [] -- shouldn't happen  -- | Parse all tags found in a string.-tagsp :: Parser [Tag]+tagsp :: SimpleTextParser [Tag] tagsp = -- do   -- pdbg 0 $ "tagsp"   many (try (nontagp >> tagp))@@ -690,7 +689,7 @@ -- -- >>> rtp nontagp "\na b:, \nd:e, f" -- Right "\na "-nontagp :: Parser String+nontagp :: SimpleTextParser String nontagp = -- do   -- pdbg 0 "nontagp"   -- anyChar `manyTill` (lookAhead (try (tagorbracketeddatetagsp Nothing >> return ()) <|> eof))@@ -704,7 +703,7 @@ -- >>> rtp tagp "a:b b , c AuxDate: 4/2" -- Right ("a","b b") ---tagp :: Parser Tag+tagp :: SimpleTextParser Tag tagp = do   -- pdbg 0 "tagp"   n <- tagnamep@@ -714,7 +713,7 @@ -- | -- >>> rtp tagnamep "a:" -- Right "a"-tagnamep :: Parser Text+tagnamep :: SimpleTextParser Text tagnamep = -- do   -- pdbg 0 "tagnamep"   T.pack <$> some (noneOf (": \t\n" :: [Char])) <* char ':'@@ -761,13 +760,13 @@ datetagp mdefdate = do   -- pdbg 0 "datetagp"   string "date"-  n <- T.pack . fromMaybe "" <$> optional (string "2")+  n <- fromMaybe "" <$> optional (mptext "2")   char ':'   startpos <- getPosition   v <- lift tagvaluep   -- re-parse value as a date.   j <- get-  let ep :: Either (ParseError Char Dec) Day+  let ep :: Either (ParseError Char MPErr) Day       ep = parseWithState'              j{jparsedefaultyear=first3.toGregorian <$> mdefdate}              -- The value extends to a comma, newline, or end of file.@@ -827,7 +826,7 @@   -- looks sufficiently like a bracketed date, now we   -- re-parse as dates and throw any errors   j <- get-  let ep :: Either (ParseError Char Dec) (Maybe Day, Maybe Day)+  let ep :: Either (ParseError Char MPErr) (Maybe Day, Maybe Day)       ep = parseWithState'              j{jparsedefaultyear=first3.toGregorian <$> mdefdate}              (do
Hledger/Read/CsvReader.hs view
@@ -38,7 +38,6 @@ import Data.List.Compat import Data.Maybe import Data.Ord-import qualified Data.Set as S import Data.Text (Text) import qualified Data.Text as T import Data.Time.Calendar (Day)@@ -54,8 +53,7 @@ import System.IO (stderr) import Test.HUnit hiding (State) import Text.CSV (parseCSV, CSV)-import Text.Megaparsec hiding (parse, State)-import Text.Megaparsec.Text+import Text.Megaparsec.Compat hiding (parse) import qualified Text.Parsec as Parsec import Text.Printf (hPrintf,printf) @@ -130,21 +128,24 @@   -- let (headerlines, datalines) = identifyHeaderLines records   --     mfieldnames = lastMay headerlines -  -- convert to transactions and return as a journal-  let txns = snd $ mapAccumL-                     (\pos r -> (pos,-                                 transactionFromCsvRecord-                                   (let SourcePos name line col =  pos in-                                    SourcePos name (unsafePos $ unPos line + 1) col)-                                   rules-                                    r))-                     (initialPos parsecfilename) records+  let +    -- convert CSV records to transactions+    txns = snd $ mapAccumL+                   (\pos r -> +                      let+                        SourcePos name line col = pos+                        line' = (mpMkPos . (+1) . mpUnPos) line+                        pos' = SourcePos name line' col+                      in+                        (pos, transactionFromCsvRecord pos' rules r)+                   )+                   (initialPos parsecfilename) records    -- heuristic: if the records appear to have been in reverse date order,   -- reverse them all as well as doing a txn date sort,   -- so that same-day txns' original order is preserved-      txns' | length txns > 1 && tdate (head txns) > tdate (last txns) = reverse txns-            | otherwise = txns+    txns' | length txns > 1 && tdate (head txns) > tdate (last txns) = reverse txns+          | otherwise = txns    when (not rulesfileexists) $ do     hPrintf stderr "created default conversion rules file %s, edit this for better results\n" rulesfile@@ -300,7 +301,7 @@   rconditionalblocks :: [ConditionalBlock] } deriving (Show, Eq) -type CsvRulesParser a = StateT CsvRules Parser a+type CsvRulesParser a = StateT CsvRules SimpleTextParser a  type DirectiveName    = String type CsvFieldName     = String@@ -382,14 +383,11 @@     Right r -> do                r_ <- liftIO $ runExceptT $ validateRules r                ExceptT $ case r_ of-                 Left e -> return $ Left $ parseErrorPretty $ toParseError e+                 Left  s -> return $ Left $ parseErrorPretty $ mpMkParseError rulesfile s                  Right r -> return $ Right r-  where-    toParseError :: forall s. Ord s => s -> ParseError Char s-    toParseError s = (mempty :: ParseError Char s) { errorCustom = S.singleton s}  -- | Parse this text as CSV conversion rules. The file path is for error messages.-parseCsvRules :: FilePath -> T.Text -> Either (ParseError Char Dec) CsvRules+parseCsvRules :: FilePath -> T.Text -> Either (ParseError Char MPErr) CsvRules -- parseCsvRules rulesfile s = runParser csvrulesfile nullrules{baseAccount=takeBaseName rulesfile} rulesfile s parseCsvRules rulesfile s =   runParser (evalStateT rulesp rules) rulesfile s@@ -441,10 +439,10 @@ directivep :: CsvRulesParser (DirectiveName, String) directivep = (do   lift $ pdbg 3 "trying directive"-  d <- choiceInState $ map string directives+  d <- fmap T.unpack $ choiceInState $ map (lift . mptext . T.pack) directives   v <- (((char ':' >> lift (many spacenonewline)) <|> lift (some spacenonewline)) >> directivevalp)        <|> (optional (char ':') >> lift (many spacenonewline) >> lift eolof >> return "")-  return (d,v)+  return (d, v)   ) <?> "directive"  directives =@@ -496,7 +494,9 @@   <?> "field assignment"  journalfieldnamep :: CsvRulesParser String-journalfieldnamep = lift (pdbg 2 "trying journalfieldnamep") >> choiceInState (map string journalfieldnames)+journalfieldnamep = do+  lift (pdbg 2 "trying journalfieldnamep")+  T.unpack <$> choiceInState (map (lift . mptext . T.pack) journalfieldnames)  -- Transaction fields and pseudo fields for CSV conversion.  -- Names must precede any other name they contain, for the parser @@ -556,7 +556,7 @@   <?> "record matcher"  matchoperatorp :: CsvRulesParser String-matchoperatorp = choiceInState $ map string+matchoperatorp = fmap T.unpack $ choiceInState $ map mptext   ["~"   -- ,"!~"   -- ,"="
Hledger/Read/JournalReader.hs view
@@ -90,7 +90,7 @@ import Test.Framework import Text.Megaparsec.Error #endif-import Text.Megaparsec hiding (parse)+import Text.Megaparsec.Compat hiding (parse) import Text.Printf import System.FilePath @@ -187,7 +187,7 @@       let curdir = takeDirectory (sourceName parentpos)       filepath <- expandPath curdir filename `orRethrowIOError` (show parentpos ++ " locating " ++ filename)       txt      <- readFileAnyLineEnding filepath `orRethrowIOError` (show parentpos ++ " reading " ++ filepath)-      (ej1::Either (ParseError Char Dec) ParsedJournal) <-+      (ej1::Either (ParseError Char MPErr) ParsedJournal) <-         runParserT            (evalStateT               (choiceInState@@ -227,7 +227,7 @@     (Right <$> io)     `C.catch` \(e::C.IOException) -> return $ Left $ printf "%s:\n%s" msg (show e) -accountdirectivep :: JournalStateParser m ()+accountdirectivep :: JournalParser m () accountdirectivep = do   string "account"   lift (some spacenonewline)@@ -237,7 +237,7 @@   modify' (\j -> j{jaccounts = acct : jaccounts j})  -indentedlinep :: JournalStateParser m String+indentedlinep :: JournalParser m String indentedlinep = lift (some spacenonewline) >> (rstrip <$> lift restofline)  -- | Parse a one-line or multi-line commodity directive.@@ -253,7 +253,7 @@ -- -- >>> Right _ <- rejp commoditydirectiveonelinep "commodity $1.00" -- >>> Right _ <- rejp commoditydirectiveonelinep "commodity $1.00 ; blah\n"-commoditydirectiveonelinep :: Monad m => JournalStateParser m ()+commoditydirectiveonelinep :: Monad m => JournalParser m () commoditydirectiveonelinep = do   string "commodity"   lift (some spacenonewline)@@ -292,7 +292,7 @@     else parserErrorAt pos $          printf "commodity directive symbol \"%s\" and format directive symbol \"%s\" should be the same" expectedsym acommodity -applyaccountdirectivep :: JournalStateParser m ()+applyaccountdirectivep :: JournalParser m () applyaccountdirectivep = do   string "apply" >> lift (some spacenonewline) >> string "account"   lift (some spacenonewline)@@ -300,12 +300,12 @@   newline   pushParentAccount parent -endapplyaccountdirectivep :: JournalStateParser m ()+endapplyaccountdirectivep :: JournalParser m () endapplyaccountdirectivep = do   string "end" >> lift (some spacenonewline) >> string "apply" >> lift (some spacenonewline) >> string "account"   popParentAccount -aliasdirectivep :: JournalStateParser m ()+aliasdirectivep :: JournalParser m () aliasdirectivep = do   string "alias"   lift (some spacenonewline)@@ -336,12 +336,12 @@   repl <- rstrip <$> anyChar `manyTill` eolof   return $ RegexAlias re repl -endaliasesdirectivep :: JournalStateParser m ()+endaliasesdirectivep :: JournalParser m () endaliasesdirectivep = do   string "end aliases"   clearAccountAliases -tagdirectivep :: JournalStateParser m ()+tagdirectivep :: JournalParser m () tagdirectivep = do   string "tag" <?> "tag directive"   lift (some spacenonewline)@@ -349,13 +349,13 @@   lift restofline   return () -endtagdirectivep :: JournalStateParser m ()+endtagdirectivep :: JournalParser m () endtagdirectivep = do   (string "end tag" <|> string "pop") <?> "end tag or pop directive"   lift restofline   return () -defaultyeardirectivep :: JournalStateParser m ()+defaultyeardirectivep :: JournalParser m () defaultyeardirectivep = do   char 'Y' <?> "default year"   lift (many spacenonewline)@@ -364,7 +364,7 @@   failIfInvalidYear y   setYear y' -defaultcommoditydirectivep :: Monad m => JournalStateParser m ()+defaultcommoditydirectivep :: Monad m => JournalParser m () defaultcommoditydirectivep = do   char 'D' <?> "default commodity"   lift (some spacenonewline)@@ -372,7 +372,7 @@   lift restofline   setDefaultCommodityAndStyle (acommodity, astyle) -marketpricedirectivep :: Monad m => JournalStateParser m MarketPrice+marketpricedirectivep :: Monad m => JournalParser m MarketPrice marketpricedirectivep = do   char 'P' <?> "market price"   lift (many spacenonewline)@@ -384,7 +384,7 @@   lift restofline   return $ MarketPrice date symbol price -ignoredpricecommoditydirectivep :: JournalStateParser m ()+ignoredpricecommoditydirectivep :: JournalParser m () ignoredpricecommoditydirectivep = do   char 'N' <?> "ignored-price commodity"   lift (some spacenonewline)@@ -392,7 +392,7 @@   lift restofline   return () -commodityconversiondirectivep :: Monad m => JournalStateParser m ()+commodityconversiondirectivep :: Monad m => JournalParser m () commodityconversiondirectivep = do   char 'C' <?> "commodity conversion"   lift (some spacenonewline)
Hledger/Read/TimeclockReader.hs view
@@ -60,7 +60,7 @@ import           Data.Text (Text) import qualified Data.Text as T import           Test.HUnit-import           Text.Megaparsec hiding (parse)+import           Text.Megaparsec.Compat hiding (parse)  import           Hledger.Data -- XXX too much reuse ?@@ -105,7 +105,7 @@                           ] <?> "timeclock entry, or default year or historical price directive"  -- | Parse a timeclock entry.-timeclockentryp :: JournalStateParser m TimeclockEntry+timeclockentryp :: JournalParser m TimeclockEntry timeclockentryp = do   sourcepos <- genericSourcePos <$> lift getPosition   code <- oneOf ("bhioO" :: [Char])
Hledger/Read/TimedotReader.hs view
@@ -42,7 +42,7 @@ import Data.Maybe import Data.Text (Text) import Test.HUnit-import Text.Megaparsec hiding (parse)+import Text.Megaparsec.Compat hiding (parse)  import Hledger.Data import Hledger.Read.Common@@ -66,12 +66,12 @@ parse :: Maybe FilePath -> Bool -> FilePath -> Text -> ExceptT String IO Journal parse _ = parseAndFinaliseJournal timedotfilep -timedotfilep :: JournalStateParser m ParsedJournal+timedotfilep :: JournalParser m ParsedJournal timedotfilep = do many timedotfileitemp                   eof                   get     where-      timedotfileitemp :: JournalStateParser m ()+      timedotfileitemp :: JournalParser m ()       timedotfileitemp = do         ptrace "timedotfileitemp"         choice [@@ -89,7 +89,7 @@ -- biz.research . -- inc.client1  .... .... .... .... .... .... -- @-timedotdayp :: JournalStateParser m [Transaction]+timedotdayp :: JournalParser m [Transaction] timedotdayp = do   ptrace " timedotdayp"   d <- datep <* lift eolof@@ -101,7 +101,7 @@ -- @ -- fos.haskell  .... .. -- @-timedotentryp :: JournalStateParser m Transaction+timedotentryp :: JournalParser m Transaction timedotentryp = do   ptrace "  timedotentryp"   pos <- genericSourcePos <$> getPosition@@ -125,14 +125,14 @@         }   return t -timedotdurationp :: JournalStateParser m Quantity+timedotdurationp :: JournalParser m Quantity timedotdurationp = try timedotnumberp <|> timedotdotsp  -- | Parse a duration written as a decimal number of hours (optionally followed by the letter h). -- @ -- 1.5h -- @-timedotnumberp :: JournalStateParser m Quantity+timedotnumberp :: JournalParser m Quantity timedotnumberp = do    (q, _, _, _) <- lift numberp    lift (many spacenonewline)@@ -144,7 +144,7 @@ -- @ -- .... .. -- @-timedotdotsp :: JournalStateParser m Quantity+timedotdotsp :: JournalParser m Quantity timedotdotsp = do   dots <- filter (not.isSpace) <$> many (oneOf (". " :: [Char]))   return $ (/4) $ fromIntegral $ length dots
Hledger/Reports/MultiBalanceReports.hs view
@@ -155,7 +155,7 @@           dbg1 "displayedAccts" $           (if tree_ opts then expandAccountNames else id) $           nub $ map (clipOrEllipsifyAccountName depth) $-          if empty_ opts then nub $ sort $ startAccts ++ postedAccts else postedAccts+          if empty_ opts || (balancetype_ opts) == HistoricalBalance then nub $ sort $ startAccts ++ postedAccts else postedAccts        acctBalChangesPerSpan :: [[(ClippedAccountName, MixedAmount)]] =           dbg1 "acctBalChangesPerSpan"
Hledger/Utils/Parse.hs view
@@ -1,38 +1,42 @@-{-# LANGUAGE FlexibleContexts, TypeFamilies #-}+{-# LANGUAGE CPP, TypeFamilies #-} module Hledger.Utils.Parse where  import Control.Monad.Except+import Control.Monad.State.Strict (StateT, evalStateT) import Data.Char+import Data.Functor.Identity (Identity(..)) import Data.List import Data.Text (Text)-import Text.Megaparsec hiding (State)-import Data.Functor.Identity (Identity(..))+import Text.Megaparsec.Compat import Text.Printf -import Control.Monad.State.Strict (StateT, evalStateT)- import Hledger.Data.Types import Hledger.Utils.UTF8IOCompat (error') --- | A parser of strict text with generic user state, monad and return type.-type TextParser m a = ParsecT Dec Text m a+-- | A parser of string to some type.+type SimpleStringParser a = Parsec MPErr String a -type JournalStateParser m a = StateT Journal (ParsecT Dec Text m) a+-- | A parser of strict text to some type.+type SimpleTextParser = Parsec MPErr Text  -- XXX an "a" argument breaks the CsvRulesParser declaration somehow -type JournalParser a = StateT Journal (ParsecT Dec Text Identity) a+-- | A parser of text in some monad.+type TextParser m a = ParsecT MPErr Text m a --- | A journal parser that runs in IO and can throw an error mid-parse.-type ErroringJournalParser m a = StateT Journal (ParsecT Dec Text (ExceptT String m)) a+-- | A parser of text in some monad, with a journal as state.+type JournalParser m a = StateT Journal (ParsecT MPErr Text m) a +-- | A parser of text in some monad, with a journal as state, that can throw an error string mid-parse.+type ErroringJournalParser m a = StateT Journal (ParsecT MPErr Text (ExceptT String m)) a+ -- | Backtracking choice, use this when alternatives share a prefix. -- Consumes no input if all choices fail. choice' :: [TextParser m a] -> TextParser m a-choice' = choice . map Text.Megaparsec.try+choice' = choice . map try  -- | Backtracking choice, use this when alternatives share a prefix. -- Consumes no input if all choices fail.-choiceInState :: [StateT s (ParsecT Dec Text m) a] -> StateT s (ParsecT Dec Text m) a-choiceInState = choice . map Text.Megaparsec.try+choiceInState :: [StateT s (ParsecT MPErr Text m) a] -> StateT s (ParsecT MPErr Text m) a+choiceInState = choice . map try  parsewith :: Parsec e Text a -> Text -> Either (ParseError Char e) a parsewith p = runParser p ""@@ -40,10 +44,15 @@ parsewithString :: Parsec e String a -> String -> Either (ParseError Char e) a parsewithString p = runParser p "" -parseWithState :: Monad m => st -> StateT st (ParsecT Dec Text m) a -> Text -> m (Either (ParseError Char Dec) a)+parseWithState :: Monad m => st -> StateT st (ParsecT MPErr Text m) a -> Text -> m (Either (ParseError Char MPErr) a) parseWithState ctx p s = runParserT (evalStateT p ctx) "" s -parseWithState' :: (Stream s, ErrorComponent e) => st -> StateT st (ParsecT e s Identity) a -> s -> (Either (ParseError (Token s) e) a)+parseWithState' :: (+  Stream s +#if !MIN_VERSION_megaparsec(6,0,0)+  ,ErrorComponent e+#endif+  ) => st -> StateT st (ParsecT e s Identity) a -> s -> (Either (ParseError (Token s) e) a) parseWithState' ctx p s = runParser (evalStateT p ctx) "" s  fromparse :: (Show t, Show e) => Either (ParseError t e) a -> a@@ -61,7 +70,7 @@ nonspace :: TextParser m Char nonspace = satisfy (not . isSpace) -spacenonewline :: (Stream s, Char ~ Token s) => ParsecT Dec s m Char+spacenonewline :: (Stream s, Char ~ Token s) => ParsecT MPErr s m Char spacenonewline = satisfy (`elem` " \v\f\t")  restofline :: TextParser m String
Hledger/Utils/String.hs view
@@ -49,7 +49,7 @@  import Data.Char import Data.List-import Text.Megaparsec+import Text.Megaparsec.Compat import Text.Printf (printf)  import Hledger.Utils.Parse
+ Text/Megaparsec/Compat.hs view
@@ -0,0 +1,73 @@+-- | Paper over some differences between megaparsec 5 and 6,+-- making it possible to write code that supports both.++{-# LANGUAGE CPP, FlexibleContexts #-}++module Text.Megaparsec.Compat (+   module Text.Megaparsec+#if MIN_VERSION_megaparsec(6,0,0)+  ,module Text.Megaparsec.Char+#endif+  ,MPErr+  ,mptext+  ,mpMkPos+  ,mpUnPos+  ,mpMkParseError+  )+where++import qualified Data.Set as S+import Data.Text+import Text.Megaparsec++#if MIN_VERSION_megaparsec(6,0,0)++import Text.Megaparsec.Char+import Data.List.NonEmpty (fromList)+import Data.Void (Void)++-- | A basic parse error type.+type MPErr = Void++-- | Make a simple parse error.+mpMkParseError :: FilePath -> String -> ParseError Char String+mpMkParseError f s = FancyError (fromList [initialPos f]) (S.singleton $ ErrorFail s)++-- | Make a Pos. With a negative argument, throws InvalidPosException (megaparsec >= 6)+-- or calls error (megaparsec < 6).+mpMkPos :: Int -> Pos+mpMkPos = mkPos ++-- | Unmake a Pos.+mpUnPos :: Pos -> Int+mpUnPos = unPos++-- | Parse and return some Text.  +mptext :: MonadParsec e Text m => Tokens Text -> m (Tokens Text) +mptext = string++#else++import Text.Megaparsec.Prim (MonadParsec)++-- | A basic parse error type.+type MPErr = Dec++-- | Make a simple parse error.+mpMkParseError :: FilePath -> String -> ParseError Char String+mpMkParseError f s = (mempty :: ParseError Char String){errorCustom = S.singleton $ f ++ ": " ++ s}++-- | Make a Pos. With a negative argument, throws InvalidPosException (megaparsec >= 6)+-- or calls error (megaparsec < 6).+mpMkPos :: Int -> Pos+mpMkPos = unsafePos . fromIntegral ++-- | Unmake a Pos.+mpUnPos :: Pos -> Int+mpUnPos = fromIntegral . unPos ++-- | Parse and return some Text.  +mptext :: MonadParsec e Text m => Text -> m Text+mptext = fmap pack . string . unpack++#endif
doc/hledger_csv.5 view
@@ -1,5 +1,5 @@ -.TH "hledger_csv" "5" "June 2017" "hledger 1.3" "hledger User Manuals"+.TH "hledger_csv" "5" "August 2017" "hledger 1.3.1" "hledger User Manuals"   
doc/hledger_csv.5.info view
@@ -3,8 +3,8 @@  File: hledger_csv.5.info,  Node: Top,  Next: CSV RULES,  Up: (dir) -hledger_csv(5) hledger 1.3-**************************+hledger_csv(5) hledger 1.3.1+****************************  hledger can read CSV files, converting each CSV record into a journal entry (transaction), if you provide some conversion hints in a "rules@@ -201,21 +201,21 @@  Tag Table: Node: Top74-Node: CSV RULES810-Ref: #csv-rules920-Node: skip1163-Ref: #skip1259-Node: date-format1431-Ref: #date-format1560-Node: field list2066-Ref: #field-list2205-Node: field assignment2910-Ref: #field-assignment3067-Node: conditional block3571-Ref: #conditional-block3727-Node: include4623-Ref: #include4734-Node: CSV TIPS4965-Ref: #csv-tips5061+Node: CSV RULES814+Ref: #csv-rules924+Node: skip1167+Ref: #skip1263+Node: date-format1435+Ref: #date-format1564+Node: field list2070+Ref: #field-list2209+Node: field assignment2914+Ref: #field-assignment3071+Node: conditional block3575+Ref: #conditional-block3731+Node: include4627+Ref: #include4738+Node: CSV TIPS4969+Ref: #csv-tips5065  End Tag Table
doc/hledger_csv.5.txt view
@@ -171,4 +171,4 @@   -hledger 1.3                        June 2017                    hledger_csv(5)+hledger 1.3.1                     August 2017                   hledger_csv(5)
doc/hledger_journal.5 view
@@ -1,6 +1,6 @@ .\"t -.TH "hledger_journal" "5" "June 2017" "hledger 1.3" "hledger User Manuals"+.TH "hledger_journal" "5" "August 2017" "hledger 1.3.1" "hledger User Manuals"   
doc/hledger_journal.5.info view
@@ -4,8 +4,8 @@  File: hledger_journal.5.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir) -hledger_journal(5) hledger 1.3-******************************+hledger_journal(5) hledger 1.3.1+********************************  hledger's usual data source is a plain text file containing journal entries in hledger journal format.  This file represents a standard@@ -1047,83 +1047,83 @@  Tag Table: Node: Top78-Node: FILE FORMAT2292-Ref: #file-format2418-Node: Transactions2625-Ref: #transactions2748-Node: Postings3313-Ref: #postings3442-Node: Dates4437-Ref: #dates4554-Node: Simple dates4619-Ref: #simple-dates4747-Node: Secondary dates5113-Ref: #secondary-dates5269-Node: Posting dates6832-Ref: #posting-dates6963-Node: Status8337-Ref: #status8461-Node: Account names10175-Ref: #account-names10315-Node: Amounts10802-Ref: #amounts10940-Node: Virtual Postings13041-Ref: #virtual-postings13202-Node: Balance Assertions14422-Ref: #balance-assertions14599-Node: Assertions and ordering15495-Ref: #assertions-and-ordering15683-Node: Assertions and included files16383-Ref: #assertions-and-included-files16626-Node: Assertions and multiple -f options16959-Ref: #assertions-and-multiple--f-options17215-Node: Assertions and commodities17347-Ref: #assertions-and-commodities17584-Node: Assertions and subaccounts18280-Ref: #assertions-and-subaccounts18514-Node: Assertions and virtual postings19035-Ref: #assertions-and-virtual-postings19244-Node: Balance Assignments19386-Ref: #balance-assignments19555-Node: Prices20674-Ref: #prices20809-Node: Transaction prices20860-Ref: #transaction-prices21007-Node: Market prices23163-Ref: #market-prices23300-Node: Comments24260-Ref: #comments24384-Node: Tags25497-Ref: #tags25617-Node: Implicit tags27046-Ref: #implicit-tags27154-Node: Directives27671-Ref: #directives27786-Node: Account aliases27979-Ref: #account-aliases28125-Node: Basic aliases28729-Ref: #basic-aliases28874-Node: Regex aliases29564-Ref: #regex-aliases29734-Node: Multiple aliases30449-Ref: #multiple-aliases30623-Node: end aliases31121-Ref: #end-aliases31263-Node: account directive31364-Ref: #account-directive31546-Node: apply account directive31842-Ref: #apply-account-directive32040-Node: Multi-line comments32699-Ref: #multi-line-comments32891-Node: commodity directive33019-Ref: #commodity-directive33205-Node: Default commodity34077-Ref: #default-commodity34252-Node: Default year34789-Ref: #default-year34956-Node: Including other files35379-Ref: #including-other-files35538-Node: EDITOR SUPPORT35935-Ref: #editor-support36055+Node: FILE FORMAT2296+Ref: #file-format2422+Node: Transactions2629+Ref: #transactions2752+Node: Postings3317+Ref: #postings3446+Node: Dates4441+Ref: #dates4558+Node: Simple dates4623+Ref: #simple-dates4751+Node: Secondary dates5117+Ref: #secondary-dates5273+Node: Posting dates6836+Ref: #posting-dates6967+Node: Status8341+Ref: #status8465+Node: Account names10179+Ref: #account-names10319+Node: Amounts10806+Ref: #amounts10944+Node: Virtual Postings13045+Ref: #virtual-postings13206+Node: Balance Assertions14426+Ref: #balance-assertions14603+Node: Assertions and ordering15499+Ref: #assertions-and-ordering15687+Node: Assertions and included files16387+Ref: #assertions-and-included-files16630+Node: Assertions and multiple -f options16963+Ref: #assertions-and-multiple--f-options17219+Node: Assertions and commodities17351+Ref: #assertions-and-commodities17588+Node: Assertions and subaccounts18284+Ref: #assertions-and-subaccounts18518+Node: Assertions and virtual postings19039+Ref: #assertions-and-virtual-postings19248+Node: Balance Assignments19390+Ref: #balance-assignments19559+Node: Prices20678+Ref: #prices20813+Node: Transaction prices20864+Ref: #transaction-prices21011+Node: Market prices23167+Ref: #market-prices23304+Node: Comments24264+Ref: #comments24388+Node: Tags25501+Ref: #tags25621+Node: Implicit tags27050+Ref: #implicit-tags27158+Node: Directives27675+Ref: #directives27790+Node: Account aliases27983+Ref: #account-aliases28129+Node: Basic aliases28733+Ref: #basic-aliases28878+Node: Regex aliases29568+Ref: #regex-aliases29738+Node: Multiple aliases30453+Ref: #multiple-aliases30627+Node: end aliases31125+Ref: #end-aliases31267+Node: account directive31368+Ref: #account-directive31550+Node: apply account directive31846+Ref: #apply-account-directive32044+Node: Multi-line comments32703+Ref: #multi-line-comments32895+Node: commodity directive33023+Ref: #commodity-directive33209+Node: Default commodity34081+Ref: #default-commodity34256+Node: Default year34793+Ref: #default-year34960+Node: Including other files35383+Ref: #including-other-files35542+Node: EDITOR SUPPORT35939+Ref: #editor-support36059  End Tag Table
doc/hledger_journal.5.txt view
@@ -835,4 +835,4 @@   -hledger 1.3                        June 2017                hledger_journal(5)+hledger 1.3.1                     August 2017               hledger_journal(5)
doc/hledger_timeclock.5 view
@@ -1,5 +1,5 @@ -.TH "hledger_timeclock" "5" "June 2017" "hledger 1.3" "hledger User Manuals"+.TH "hledger_timeclock" "5" "August 2017" "hledger 1.3.1" "hledger User Manuals"   
doc/hledger_timeclock.5.info view
@@ -4,8 +4,8 @@  File: hledger_timeclock.5.info,  Node: Top,  Up: (dir) -hledger_timeclock(5) hledger 1.3-********************************+hledger_timeclock(5) hledger 1.3.1+**********************************  hledger can read timeclock files.  As with Ledger, these are (a subset of) timeclock.el's format, containing clock-in and clock-out entries as
doc/hledger_timeclock.5.txt view
@@ -79,4 +79,4 @@   -hledger 1.3                        June 2017              hledger_timeclock(5)+hledger 1.3.1                     August 2017             hledger_timeclock(5)
doc/hledger_timedot.5 view
@@ -1,5 +1,5 @@ -.TH "hledger_timedot" "5" "June 2017" "hledger 1.3" "hledger User Manuals"+.TH "hledger_timedot" "5" "August 2017" "hledger 1.3.1" "hledger User Manuals"   
doc/hledger_timedot.5.info view
@@ -4,8 +4,8 @@  File: hledger_timedot.5.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir) -hledger_timedot(5) hledger 1.3-******************************+hledger_timedot(5) hledger 1.3.1+********************************  Timedot is a plain text format for logging dated, categorised quantities (eg time), supported by hledger.  It is convenient for approximate and@@ -106,7 +106,7 @@  Tag Table: Node: Top78-Node: FILE FORMAT882-Ref: #file-format985+Node: FILE FORMAT886+Ref: #file-format989  End Tag Table
doc/hledger_timedot.5.txt view
@@ -120,4 +120,4 @@   -hledger 1.3                        June 2017                hledger_timedot(5)+hledger 1.3.1                     August 2017               hledger_timedot(5)
hledger-lib.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.17.0.+-- This file has been generated from package.yaml by hpack version 0.17.1. -- -- see: https://github.com/sol/hpack  name:           hledger-lib-version:        1.3+version:        1.3.1 synopsis:       Core data types, parsers and functionality for the hledger accounting tools description:    This is a reusable library containing hledger's core functionality.                 .@@ -72,7 +72,7 @@     , directory     , filepath     , hashtables >= 1.2-    , megaparsec >=5.0 && < 5.4+    , megaparsec >=5.0 && < 6.2     , mtl     , mtl-compat     , old-time@@ -141,6 +141,7 @@       Hledger.Utils.Text       Hledger.Utils.Tree       Hledger.Utils.UTF8IOCompat+      Text.Megaparsec.Compat   other-modules:       Paths_hledger_lib   default-language: Haskell2010@@ -168,7 +169,7 @@     , directory     , filepath     , hashtables >= 1.2-    , megaparsec >=5.0 && < 5.4+    , megaparsec >=5.0 && < 6.2     , mtl     , mtl-compat     , old-time@@ -186,6 +187,13 @@   if impl(ghc <7.6)     build-depends:         ghc-prim+  if flag(oldtime)+    build-depends:+        time <1.5+      , old-locale+  else+    build-depends:+        time >=1.5   other-modules:       Hledger       Hledger.Data@@ -230,6 +238,7 @@       Hledger.Utils.Text       Hledger.Utils.Tree       Hledger.Utils.UTF8IOCompat+      Text.Megaparsec.Compat   default-language: Haskell2010  test-suite hunittests@@ -255,7 +264,7 @@     , directory     , filepath     , hashtables >= 1.2-    , megaparsec >=5.0 && < 5.4+    , megaparsec >=5.0 && < 6.2     , mtl     , mtl-compat     , old-time@@ -326,4 +335,5 @@       Hledger.Utils.Text       Hledger.Utils.Tree       Hledger.Utils.UTF8IOCompat+      Text.Megaparsec.Compat   default-language: Haskell2010