;lib: Hledger.Read.Common cleanup
This commit is contained in:
parent
8535939f33
commit
2e5afd0a9f
@ -1,23 +1,36 @@
|
|||||||
--- * doc
|
-- * -*- eval: (orgstruct-mode 1); orgstruct-heading-prefix-regexp:"-- "; -*-
|
||||||
-- Lines beginning "--- *" are collapsible orgstruct nodes. Emacs users,
|
-- ** doc
|
||||||
-- (add-hook 'haskell-mode-hook
|
-- In Emacs, use TAB on lines beginning with "-- *" to collapse/expand sections.
|
||||||
-- (lambda () (set-variable 'orgstruct-heading-prefix-regexp "--- " t))
|
|
||||||
-- 'orgstruct-mode)
|
|
||||||
-- and press TAB on nodes to expand/collapse.
|
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
Some common parsers and helpers used by several readers.
|
File reading/parsing utilities used by multiple readers, and a good
|
||||||
|
amount of the parsers for journal format, to avoid import cycles
|
||||||
|
when JournalReader imports other readers.
|
||||||
|
|
||||||
Some of these might belong in Hledger.Read.JournalReader or Hledger.Read.
|
Some of these might belong in Hledger.Read.JournalReader or Hledger.Read.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
--- * module
|
-- ** language
|
||||||
{-# LANGUAGE CPP, BangPatterns, DeriveDataTypeable, RecordWildCards, NamedFieldPuns, NoMonoLocalBinds, ScopedTypeVariables, FlexibleContexts, TupleSections, OverloadedStrings #-}
|
{-# LANGUAGE BangPatterns #-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE CPP #-}
|
||||||
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE LambdaCase #-}
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
|
{-# LANGUAGE NoMonoLocalBinds #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE PackageImports #-}
|
{-# LANGUAGE PackageImports #-}
|
||||||
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
{-# LANGUAGE TupleSections #-}
|
||||||
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
|
||||||
|
-- ** doctest setup
|
||||||
|
-- $setup
|
||||||
|
-- >>> :set -XOverloadedStrings
|
||||||
|
|
||||||
|
-- ** exports
|
||||||
module Hledger.Read.Common (
|
module Hledger.Read.Common (
|
||||||
Reader (..),
|
Reader (..),
|
||||||
InputOpts (..),
|
InputOpts (..),
|
||||||
@ -99,7 +112,8 @@ module Hledger.Read.Common (
|
|||||||
tests_Common,
|
tests_Common,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
--- * imports
|
|
||||||
|
-- ** imports
|
||||||
import Prelude ()
|
import Prelude ()
|
||||||
import "base-compat-batteries" Prelude.Compat hiding (fail, readFile)
|
import "base-compat-batteries" Prelude.Compat hiding (fail, readFile)
|
||||||
import qualified "base-compat-batteries" Control.Monad.Fail.Compat as Fail (fail)
|
import qualified "base-compat-batteries" Control.Monad.Fail.Compat as Fail (fail)
|
||||||
@ -130,8 +144,9 @@ import Text.Megaparsec.Custom
|
|||||||
import Hledger.Data
|
import Hledger.Data
|
||||||
import Hledger.Utils
|
import Hledger.Utils
|
||||||
|
|
||||||
-- $setup
|
-- ** types
|
||||||
-- >>> :set -XOverloadedStrings
|
|
||||||
|
-- main types; a few more below
|
||||||
|
|
||||||
-- | A hledger journal reader is a triple of storage format name, a
|
-- | A hledger journal reader is a triple of storage format name, a
|
||||||
-- detector of that format, and a parser from that format to Journal.
|
-- detector of that format, and a parser from that format to Journal.
|
||||||
@ -191,7 +206,7 @@ rawOptsToInputOpts rawopts = InputOpts{
|
|||||||
,auto_ = boolopt "auto" rawopts
|
,auto_ = boolopt "auto" rawopts
|
||||||
}
|
}
|
||||||
|
|
||||||
--- * parsing utilities
|
-- ** parsing utilities
|
||||||
|
|
||||||
-- | Run a text parser in the identity monad. See also: parseWithState.
|
-- | Run a text parser in the identity monad. See also: parseWithState.
|
||||||
runTextParser, rtp
|
runTextParser, rtp
|
||||||
@ -226,9 +241,9 @@ journalSourcePos p p' = JournalSourcePos (sourceName p) (fromIntegral . unPos $
|
|||||||
| (unPos $ sourceColumn p') == 1 = unPos (sourceLine p') - 1
|
| (unPos $ sourceColumn p') == 1 = unPos (sourceLine p') - 1
|
||||||
| otherwise = unPos $ sourceLine p' -- might be at end of file withat last new-line
|
| otherwise = unPos $ sourceLine p' -- might be at end of file withat last new-line
|
||||||
|
|
||||||
|
-- | Given a parser to ParsedJournal, input options, file path and
|
||||||
-- | Given a megaparsec ParsedJournal parser, input options, file
|
-- content: run the parser on the content, and finalise the result to
|
||||||
-- path and file content: parse and finalise a Journal, or give an error.
|
-- get a Journal; or throw an error.
|
||||||
parseAndFinaliseJournal :: ErroringJournalParser IO ParsedJournal -> InputOpts
|
parseAndFinaliseJournal :: ErroringJournalParser IO ParsedJournal -> InputOpts
|
||||||
-> FilePath -> Text -> ExceptT String IO Journal
|
-> FilePath -> Text -> ExceptT String IO Journal
|
||||||
parseAndFinaliseJournal parser iopts f txt = do
|
parseAndFinaliseJournal parser iopts f txt = do
|
||||||
@ -376,9 +391,14 @@ journalAddFile f j@Journal{jfiles=fs} = j{jfiles=fs++[f]}
|
|||||||
-- append, unlike the other fields, even though we do a final reverse,
|
-- append, unlike the other fields, even though we do a final reverse,
|
||||||
-- to compensate for additional reversal due to including/monoid-concatting
|
-- to compensate for additional reversal due to including/monoid-concatting
|
||||||
|
|
||||||
--- * parsers
|
-- A version of `match` that is strict in the returned text
|
||||||
|
match' :: TextParser m a -> TextParser m (Text, a)
|
||||||
|
match' p = do
|
||||||
|
(!txt, p) <- match p
|
||||||
|
pure (txt, p)
|
||||||
|
|
||||||
--- ** transaction bits
|
-- ** parsers
|
||||||
|
-- *** transaction bits
|
||||||
|
|
||||||
statusp :: TextParser m Status
|
statusp :: TextParser m Status
|
||||||
statusp =
|
statusp =
|
||||||
@ -401,7 +421,7 @@ descriptionp :: TextParser m Text
|
|||||||
descriptionp = takeWhileP Nothing (not . semicolonOrNewline)
|
descriptionp = takeWhileP Nothing (not . semicolonOrNewline)
|
||||||
where semicolonOrNewline c = c == ';' || c == '\n'
|
where semicolonOrNewline c = c == ';' || c == '\n'
|
||||||
|
|
||||||
--- ** dates
|
-- *** dates
|
||||||
|
|
||||||
-- | Parse a date in YYYY-MM-DD format.
|
-- | Parse a date in YYYY-MM-DD format.
|
||||||
-- Slash (/) and period (.) are also allowed as separators.
|
-- Slash (/) and period (.) are also allowed as separators.
|
||||||
@ -519,7 +539,7 @@ secondarydatep :: Day -> TextParser m Day
|
|||||||
secondarydatep primaryDate = char '=' *> datep' (Just primaryYear)
|
secondarydatep primaryDate = char '=' *> datep' (Just primaryYear)
|
||||||
where primaryYear = first3 $ toGregorian primaryDate
|
where primaryYear = first3 $ toGregorian primaryDate
|
||||||
|
|
||||||
--- ** account names
|
-- *** account names
|
||||||
|
|
||||||
-- | Parse an account name (plus one following space if present),
|
-- | Parse an account name (plus one following space if present),
|
||||||
-- then apply any parent account prefix and/or account aliases currently in effect,
|
-- then apply any parent account prefix and/or account aliases currently in effect,
|
||||||
@ -567,7 +587,7 @@ singlespacedtextsatisfyingp pred = do
|
|||||||
singlespacep :: TextParser m ()
|
singlespacep :: TextParser m ()
|
||||||
singlespacep = void spacenonewline *> notFollowedBy spacenonewline
|
singlespacep = void spacenonewline *> notFollowedBy spacenonewline
|
||||||
|
|
||||||
--- ** amounts
|
-- *** amounts
|
||||||
|
|
||||||
-- | Parse whitespace then an amount, with an optional left or right
|
-- | Parse whitespace then an amount, with an optional left or right
|
||||||
-- currency symbol and optional price, or return the special
|
-- currency symbol and optional price, or return the special
|
||||||
@ -970,7 +990,7 @@ digitgroupp = label "digits"
|
|||||||
makeGroup = uncurry DigitGrp . foldl' step (0, 0) . T.unpack
|
makeGroup = uncurry DigitGrp . foldl' step (0, 0) . T.unpack
|
||||||
step (!l, !a) c = (l+1, a*10 + fromIntegral (digitToInt c))
|
step (!l, !a) c = (l+1, a*10 + fromIntegral (digitToInt c))
|
||||||
|
|
||||||
--- ** comments
|
-- *** comments
|
||||||
|
|
||||||
multilinecommentp :: TextParser m ()
|
multilinecommentp :: TextParser m ()
|
||||||
multilinecommentp = startComment *> anyLine `skipManyTill` endComment
|
multilinecommentp = startComment *> anyLine `skipManyTill` endComment
|
||||||
@ -1224,9 +1244,6 @@ commenttagsanddatesp mYear = do
|
|||||||
|
|
||||||
{-# INLINABLE commenttagsanddatesp #-}
|
{-# INLINABLE commenttagsanddatesp #-}
|
||||||
|
|
||||||
|
|
||||||
--- ** bracketed dates
|
|
||||||
|
|
||||||
-- | Parse Ledger-style bracketed posting dates ([DATE=DATE2]), as
|
-- | Parse Ledger-style bracketed posting dates ([DATE=DATE2]), as
|
||||||
-- "date" and/or "date2" tags. Anything that looks like an attempt at
|
-- "date" and/or "date2" tags. Anything that looks like an attempt at
|
||||||
-- this (a square-bracketed sequence of 0123456789/-.= containing at
|
-- this (a square-bracketed sequence of 0123456789/-.= containing at
|
||||||
@ -1279,16 +1296,7 @@ bracketeddatetagsp mYear1 = do
|
|||||||
|
|
||||||
{-# INLINABLE bracketeddatetagsp #-}
|
{-# INLINABLE bracketeddatetagsp #-}
|
||||||
|
|
||||||
|
-- ** tests
|
||||||
--- ** helper parsers
|
|
||||||
|
|
||||||
-- A version of `match` that is strict in the returned text
|
|
||||||
match' :: TextParser m a -> TextParser m (Text, a)
|
|
||||||
match' p = do
|
|
||||||
(!txt, p) <- match p
|
|
||||||
pure (txt, p)
|
|
||||||
|
|
||||||
--- * tests
|
|
||||||
|
|
||||||
tests_Common = tests "Common" [
|
tests_Common = tests "Common" [
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user