-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Core types and utilities for working with hledger (or c++ ledger) data. -- -- This is the reusable core of the hledger financial app; use it to -- build hledger and c++-ledger compatible finance tools. @package hledger-lib @version 0.13 -- | Standard imports and utilities which are useful everywhere, or needed -- low in the module hierarchy. This is the bottom of hledger's module -- graph. module Hledger.Data.Utils underline :: String -> String unbracket :: String -> String -- | Join multi-line strings as side-by-side rectangular strings of the -- same height, top-padded. concatTopPadded :: [String] -> String -- | Join multi-line strings as side-by-side rectangular strings of the -- same height, bottom-padded. concatBottomPadded :: [String] -> String -- | Compose strings vertically and right-aligned. vConcatRightAligned :: [String] -> String -- | Convert a multi-line string to a rectangular string top-padded to the -- specified height. padtop :: Int -> String -> String -- | Convert a multi-line string to a rectangular string bottom-padded to -- the specified height. padbottom :: Int -> String -> String -- | Convert a multi-line string to a rectangular string left-padded to the -- specified width. padleft :: Int -> String -> String -- | Convert a multi-line string to a rectangular string right-padded to -- the specified width. padright :: Int -> String -> String -- | Clip a multi-line string to the specified width and height from the -- top left. cliptopleft :: Int -> Int -> String -> String -- | Clip and pad a multi-line string to fill the specified width and -- height. fitto :: Int -> Int -> String -> String -- | A platform string is a string value from or for the operating system, -- such as a file path or command-line argument (or environment -- variable's name or value ?). On some platforms (such as unix) these -- are not real unicode strings but have some encoding such as UTF-8. -- This alias does no type enforcement but aids code clarity. type PlatformString = String -- | Convert a possibly encoded platform string to a real unicode string. -- We decode the UTF-8 encoding recommended for unix systems (cf -- http:www.dwheeler.comessaysfixing-unix-linux-filenames.html) -- and leave anything else unchanged. fromPlatformString :: PlatformString -> String -- | Convert a unicode string to a possibly encoded platform string. On -- unix we encode with the recommended UTF-8 (cf -- http:www.dwheeler.comessaysfixing-unix-linux-filenames.html) -- and elsewhere we leave it unchanged. toPlatformString :: String -> PlatformString -- | A version of error that's better at displaying unicode. error' :: String -> a -- | A version of userError that's better at displaying unicode. userError' :: String -> IOError difforzero :: (Num a, Ord a) => a -> a -> a containsRegex :: String -> String -> Bool splitAtElement :: Eq a => a -> [a] -> [[a]] -- | List just the leaf nodes of a tree leaves :: Tree a -> [a] -- | get the sub-tree rooted at the first (left-most, depth-first) -- occurrence of the specified node value subtreeat :: Eq a => a -> Tree a -> Maybe (Tree a) -- | get the sub-tree for the specified node value in the first tree in -- forest in which it occurs. subtreeinforest :: Eq a => a -> [Tree a] -> Maybe (Tree a) -- | remove all nodes past a certain depth treeprune :: Int -> Tree a -> Tree a -- | apply f to all tree nodes treemap :: (a -> b) -> Tree a -> Tree b -- | remove all subtrees whose nodes do not fulfill predicate treefilter :: (a -> Bool) -> Tree a -> Tree a -- | is predicate true in any node of tree ? treeany :: (a -> Bool) -> Tree a -> Bool -- | show a compact ascii representation of a tree showtree :: Show a => Tree a -> String -- | show a compact ascii representation of a forest showforest :: Show a => Forest a -> String -- | trace (print on stdout at runtime) a showable expression (for easily -- tracing in the middle of a complex expression) strace :: Show a => a -> a -- | labelled trace - like strace, with a label prepended ltrace :: Show a => String -> a -> a -- | monadic trace - like strace, but works as a standalone line in a monad mtrace :: (Monad m, Show a) => a -> m a -- | trace an expression using a custom show function choice' :: [GenParser tok st a] -> GenParser tok st a parsewith :: Parser a -> String -> Either ParseError a parseWithCtx :: b -> GenParser Char b a -> String -> Either ParseError a fromparse :: Either ParseError a -> a nonspace :: GenParser Char st Char spacenonewline :: GenParser Char st Char restofline :: GenParser Char st String getCurrentLocalTime :: IO LocalTime -- | Get a Test's label, or the empty string. tname :: Test -> String -- | Flatten a Test containing TestLists into a list of single tests. tflatten :: Test -> [Test] -- | Filter TestLists in a Test, recursively, preserving the structure. tfilter :: (Test -> Bool) -> Test -> Test -- | Simple way to assert something is some expected value, with no label. is :: (Eq a, Show a) => a -> a -> Assertion -- | Assert a parse result is successful, printing the parse error on -- failure. assertParse :: (Either ParseError a) -> Assertion -- | Assert a parse result is some expected value, printing the parse error -- on failure. assertParseEqual :: (Show a, Eq a) => (Either ParseError a) -> a -> Assertion printParseError :: Show a => a -> IO () isLeft :: Either a b -> Bool isRight :: Either a b -> Bool -- | Most data types are defined here to avoid import cycles. Here is an -- overview of the hledger data model: -- --
-- Journal -- a journal is derived from one or more data files. It contains.. -- [Transaction] -- journal transactions, which have date, status, code, description and.. -- [Posting] -- multiple account postings (entries), which have account name and amount. -- [HistoricalPrice] -- historical commodity prices -- -- Ledger -- a ledger is derived from a journal, by applying a filter specification and doing some further processing. It contains.. -- Journal -- the filtered journal, containing only the transactions and postings we are interested in -- Tree AccountName -- account names referenced in the journal's transactions, as a tree -- Map AccountName Account -- per-account postings and balances from the journal's transactions, as a map from account name to account info ---- -- For more detailed documentation on each type, see the corresponding -- modules. -- -- Evolution of transaction/entry/posting terminology: -- --
-- 2004 -- 2004/10 -- 2004/10/1 -- 10/1 -- 21 -- october, oct -- yesterday, today, tomorrow -- this/next/last week/day/month/quarter/year ---- -- Returns a SmartDate, to be converted to a full date later (see -- fixSmartDate). Assumes any text in the parse stream has been -- lowercased. smartdate :: GenParser Char st SmartDate -- | Like smartdate, but there must be nothing other than whitespace after -- the date. smartdateonly :: GenParser Char st SmartDate validMonth :: String -> Bool validDay :: String -> Bool validYear :: String -> Bool failIfInvalidMonth :: Monad m => String -> m () failIfInvalidDay :: Monad m => String -> m () failIfInvalidYear :: Monad m => String -> m () yyyymmdd :: GenParser Char st SmartDate ymd :: GenParser Char st SmartDate ym :: GenParser Char st SmartDate y :: GenParser Char st SmartDate d :: GenParser Char st SmartDate md :: GenParser Char st SmartDate month :: GenParser Char st SmartDate mon :: GenParser Char st SmartDate yesterday :: GenParser Char st SmartDate tomorrow :: GenParser Char st SmartDate today :: GenParser Char st SmartDate lastthisnextthing :: GenParser Char st SmartDate periodexpr :: Day -> GenParser Char st (Interval, DateSpan) intervalanddateperiodexpr :: Day -> GenParser Char st (Interval, DateSpan) intervalperiodexpr :: GenParser Char st (Interval, DateSpan) dateperiodexpr :: Day -> GenParser Char st (Interval, DateSpan) periodexprinterval :: GenParser Char st Interval periodexprdatespan :: Day -> GenParser Char st DateSpan doubledatespan :: Day -> GenParser Char st DateSpan fromdatespan :: Day -> GenParser Char st DateSpan todatespan :: Day -> GenParser Char st DateSpan justdatespan :: Day -> GenParser Char st DateSpan mkdatespan :: String -> String -> DateSpan -- | A Commodity is a symbol representing a currency or some other -- kind of thing we are tracking, and some display preferences that tell -- how to display Amounts of the commodity - is the symbol on the -- left or right, are thousands separated by comma, significant decimal -- places and so on. module Hledger.Data.Commodity -- | Look up one of the hard-coded default commodities. For use in tests. comm :: String -> Commodity -- | Find the conversion rate between two commodities. Currently returns 1. conversionRate :: Commodity -> Commodity -> Double -- | Convert a list of commodities to a map from commodity symbols to -- unique, display-preference-canonicalised commodities. canonicaliseCommodities :: [Commodity] -> Map String Commodity -- | An Amount is some quantity of money, shares, or anything else. -- -- A simple amount is a Commodity, quantity pair: -- --
-- $1 -- -50 -- EUR 3.44 -- GOOG 500 -- 1.5h -- 90 apples -- 0 ---- -- An amount may also have a per-unit price, or conversion rate, in terms -- of some other commodity. If present, this is displayed after @: -- --
-- EUR 3 @ $1.35 ---- -- A MixedAmount is zero or more simple amounts. Mixed amounts are -- usually normalised so that there is no more than one amount in each -- commodity, and no zero amounts (or, there is just a single zero amount -- and no others.): -- --
-- $50 + EUR 3 -- 16h + $13.55 + AAPL 500 + 6 oranges -- 0 ---- -- We can do limited arithmetic with simple or mixed amounts: either -- price-preserving arithmetic with similarly-priced amounts, or -- price-discarding arithmetic which ignores and discards prices. module Hledger.Data.Amount -- | Apply a binary arithmetic operator to two amounts, converting to the -- second one's commodity (and display precision), discarding any price -- information. (Using the second commodity is best since sum and other -- folds start with a no-commodity amount.) amountop :: (Double -> Double -> Double) -> Amount -> Amount -> Amount -- | Convert an amount to the specified commodity using the appropriate -- exchange rate (which is currently always 1). convertAmountTo :: Commodity -> Amount -> Amount -- | Convert mixed amount to the specified commodity convertMixedAmountTo :: Commodity -> MixedAmount -> Amount -- | Convert an amount to the commodity of its saved price, if any. costOfAmount :: Amount -> Amount -- | Get the string representation of an amount, based on its commodity's -- display settings. showAmount :: Amount -> String -- | Get the string representation of an amount, based on its commodity's -- display settings except using the specified precision. showAmountWithPrecision :: Int -> Amount -> String -- | Get the unambiguous string representation of an amount, for debugging. showAmountDebug :: Amount -> String -- | Get the string representation of an amount, without any @ price. showAmountWithoutPrice :: Amount -> String -- | Get the string representation of an amount, without any price or -- commodity symbol. showAmountWithoutPriceOrCommodity :: Amount -> String -- | Get the string representation of the number part of of an amount, -- using the display precision from its commodity. showAmount' :: Amount -> String -- | Add thousands-separating commas to a decimal number string punctuatethousands :: String -> String -- | Does this amount appear to be zero when displayed with its given -- precision ? isZeroAmount :: Amount -> Bool -- | Is this amount really zero, regardless of the display precision -- ? Since we are using floating point, for now just test to some high -- precision. isReallyZeroAmount :: Amount -> Bool -- | Is this amount negative ? The price is ignored. isNegativeAmount :: Amount -> Bool -- | Access a mixed amount's components. amounts :: MixedAmount -> [Amount] -- | Does this mixed amount appear to be zero - empty, or containing only -- simple amounts which appear to be zero ? isZeroMixedAmount :: MixedAmount -> Bool -- | Is this mixed amount really zero ? See isReallyZeroAmount. isReallyZeroMixedAmount :: MixedAmount -> Bool -- | Is this mixed amount negative, if it can be normalised to a single -- commodity ? isNegativeMixedAmount :: MixedAmount -> Maybe Bool -- | Is this mixed amount really zero, after converting to cost -- commodities where possible ? isReallyZeroMixedAmountCost :: MixedAmount -> Bool -- | MixedAmount derives Eq in Types.hs, but that doesn't know that we want -- $0 = EUR0 = 0. Yet we don't want to drag all this code in there. When -- zero equality is important, use this, for now; should be used -- everywhere. mixedAmountEquals :: MixedAmount -> MixedAmount -> Bool -- | Get the string representation of a mixed amount, showing each of its -- component amounts. NB a mixed amount can have an empty amounts list in -- which case it shows as "". showMixedAmount :: MixedAmount -> String setMixedAmountPrecision :: Int -> MixedAmount -> MixedAmount -- | Get the string representation of a mixed amount, showing each of its -- component amounts with the specified precision, ignoring their -- commoditys' display precision settings. NB a mixed amount can have an -- empty amounts list in which case it shows as "". showMixedAmountWithPrecision :: Int -> MixedAmount -> String -- | Get an unambiguous string representation of a mixed amount for -- debugging. showMixedAmountDebug :: MixedAmount -> String -- | Get the string representation of a mixed amount, but without any @ -- prices. showMixedAmountWithoutPrice :: MixedAmount -> String -- | Get the string representation of a mixed amount, and if it appears to -- be all zero just show a bare 0, ledger-style. showMixedAmountOrZero :: MixedAmount -> String -- | Get the string representation of a mixed amount, or a bare 0, without -- any @ prices. showMixedAmountOrZeroWithoutPrice :: MixedAmount -> String -- | Simplify a mixed amount by combining any component amounts which have -- the same commodity and the same price. Also removes zero amounts, or -- adds a single zero amount if there are no amounts at all. normaliseMixedAmount :: MixedAmount -> MixedAmount -- | Set a mixed amount's commodity to the canonicalised commodity from the -- provided commodity map. canonicaliseMixedAmount :: Maybe (Map String Commodity) -> MixedAmount -> MixedAmount -- | Set an amount's commodity to the canonicalised commodity from the -- provided commodity map. canonicaliseAmount :: Maybe (Map String Commodity) -> Amount -> Amount -- | Simplify a mixed amount by combining any component amounts which have -- the same commodity, ignoring and discarding their unit prices if any. -- Also removes zero amounts, or adds a single zero amount if there are -- no amounts at all. normaliseMixedAmountIgnoringPrice :: MixedAmount -> MixedAmount sumMixedAmountsPreservingHighestPrecision :: [MixedAmount] -> MixedAmount normaliseMixedAmountPreservingHighestPrecision :: MixedAmount -> MixedAmount sumAmountsPreservingHighestPrecision :: [Amount] -> Amount amountopPreservingHighestPrecision :: (Double -> Double -> Double) -> Amount -> Amount -> Amount -- | Convert a mixed amount's component amounts to the commodity of their -- saved price, if any. costOfMixedAmount :: MixedAmount -> MixedAmount -- | The empty simple amount. nullamt :: Amount -- | The empty mixed amount. nullmixedamt :: MixedAmount -- | A temporary value for parsed transactions which had no amount -- specified. missingamt :: MixedAmount instance Show HistoricalPrice instance Ord MixedAmount instance Num MixedAmount instance Ord Amount instance Num Amount instance Show MixedAmount instance Show Amount -- | AccountNames are strings like assets:cash:petty, with -- multiple components separated by :. From a set of these we -- derive the account hierarchy. module Hledger.Data.AccountName accountNameComponents :: AccountName -> [String] accountNameFromComponents :: [String] -> AccountName accountLeafName :: AccountName -> String accountNameLevel :: AccountName -> Int accountNameDrop :: Int -> AccountName -> AccountName -- | expandAccountNames :: [AccountName] -> [AccountName] -- | topAccountNames :: [AccountName] -> [AccountName] parentAccountName :: AccountName -> AccountName parentAccountNames :: AccountName -> [AccountName] isAccountNamePrefixOf :: AccountName -> AccountName -> Bool isSubAccountNameOf :: AccountName -> AccountName -> Bool -- | From a list of account names, select those which are direct -- subaccounts of the given account name. subAccountNamesFrom :: [AccountName] -> AccountName -> [AccountName] -- | Convert a list of account names to a tree. accountNameTreeFrom :: [AccountName] -> Tree AccountName newtype Tree' a T :: (Map a (Tree' a)) -> Tree' a mergeTrees :: Ord a => Tree' a -> Tree' a -> Tree' a pathtree :: [a] -> Tree' a fromPaths :: Ord a => [[a]] -> Tree' a converttree :: Tree' AccountName -> [Tree AccountName] expandTreeNames :: Tree AccountName -> Tree AccountName accountNameTreeFrom4 :: [AccountName] -> Tree AccountName -- | Elide an account name to fit in the specified width. From the ledger -- 2.6 news: -- --
-- What Ledger now does is that if an account name is too long, it will -- start abbreviating the first parts of the account name down to two -- letters in length. If this results in a string that is still too -- long, the front will be elided -- not the end. For example: -- -- Expenses:Cash ; OK, not too long -- Ex:Wednesday:Cash ; Expenses was abbreviated to fit -- Ex:We:Afternoon:Cash ; Expenses and Wednesday abbreviated -- ; Expenses:Wednesday:Afternoon:Lunch:Snack:Candy:Chocolate:Cash -- ..:Af:Lu:Sn:Ca:Ch:Cash ; Abbreviated and elided! --elideAccountName :: Int -> AccountName -> AccountName clipAccountName :: Int -> AccountName -> AccountName instance Show a => Show (Tree' a) instance Eq a => Eq (Tree' a) instance Ord a => Ord (Tree' a) -- | A Posting represents a MixedAmount being added to or -- subtracted from a single Account. Each Transaction -- contains two or more postings which should add up to 0. Postings also -- reference their parent transaction, so we can get a date or -- description for a posting (from the transaction). Strictly speaking, -- "entry" is probably a better name for these. module Hledger.Data.Posting showPosting :: Posting -> String showPostingForRegister :: Posting -> String isReal :: Posting -> Bool isVirtual :: Posting -> Bool isBalancedVirtual :: Posting -> Bool hasAmount :: Posting -> Bool accountNamesFromPostings :: [Posting] -> [AccountName] sumPostings :: [Posting] -> MixedAmount postingDate :: Posting -> Day postingCleared :: Posting -> Bool -- | Does this posting fall within the given date span ? isPostingInDateSpan :: DateSpan -> Posting -> Bool isEmptyPosting :: Posting -> Bool -- | Get the minimal date span which contains all the postings, or DateSpan -- Nothing Nothing if there are none. postingsDateSpan :: [Posting] -> DateSpan instance Show Posting -- | A Transaction consists of two or more related Postings -- which balance to zero, representing a movement of some commodity(ies) -- between accounts, plus a date and optional metadata like description -- and cleared status. module Hledger.Data.Transaction nulltransaction :: Transaction -- | Show a journal transaction, formatted for the print command. ledger -- 2.x's standard format looks like this: -- --
-- yyyymmdd[ *][ CODE] description......... [ ; comment...............] -- account name 1..................... ...$amount1[ ; comment...............] -- account name 2..................... ..$-amount1[ ; comment...............] -- -- pcodewidth = no limit -- 10 -- mimicking ledger layout. -- pdescwidth = no limit -- 20 -- I don't remember what these mean, -- pacctwidth = 35 minimum, no maximum -- they were important at the time. -- pamtwidth = 11 -- pcommentwidth = no limit -- 22 --showTransaction :: Transaction -> String showTransactionUnelided :: Transaction -> String showTransactionForPrint :: Bool -> Transaction -> String showTransaction' :: Bool -> Bool -> Transaction -> String -- | Show an account name, clipped to the given width if any, and -- appropriately bracketed/parenthesised for the given posting type. showAccountName :: Maybe Int -> PostingType -> AccountName -> String realPostings :: Transaction -> [Posting] virtualPostings :: Transaction -> [Posting] balancedVirtualPostings :: Transaction -> [Posting] -- | Get the sums of a transaction's real, virtual, and balanced virtual -- postings. transactionPostingBalances :: Transaction -> (MixedAmount, MixedAmount, MixedAmount) -- | Is this transaction balanced ? A balanced transaction's real -- (non-virtual) postings sum to 0, and any balanced virtual postings -- also sum to 0. isTransactionBalanced :: Maybe (Map String Commodity) -> Transaction -> Bool -- | Ensure that this entry is balanced, possibly auto-filling a missing -- amount first. We can auto-fill if there is just one non-virtual -- transaction without an amount. The auto-filled balance will be -- converted to cost basis if possible. If the entry can not be balanced, -- return an error message instead. balanceTransaction :: Maybe (Map String Commodity) -> Transaction -> Either String Transaction nonzerobalanceerror :: Transaction -> String -- | Convert the primary date to either the actual or effective date. journalTransactionWithDate :: WhichDate -> Transaction -> Transaction -- | Ensure a transaction's postings refer back to it. txnTieKnot :: Transaction -> Transaction -- | Set a posting's parent transaction. settxn :: Transaction -> Posting -> Posting instance Show PeriodicTransaction instance Show ModifierTransaction instance Show Transaction -- | A TimeLogEntry is a clock-in, clock-out, or other directive in -- a timelog file (see timeclock.el or the command-line version). These -- can be converted to Transactions and queried like a ledger. module Hledger.Data.TimeLog -- | Convert time log entries to journal transactions. When there is no -- clockout, add one with the provided current time. Sessions crossing -- midnight are split into days to give accurate per-day totals. timeLogEntriesToTransactions :: LocalTime -> [TimeLogEntry] -> [Transaction] -- | Convert a timelog clockin and clockout entry to an equivalent journal -- transaction, representing the time expenditure. Note this entry is not -- balanced, since we omit the "assets:time" transaction for simpler -- output. entryFromTimeLogInOut :: TimeLogEntry -> TimeLogEntry -> Transaction instance Read TimeLogCode instance Show TimeLogCode instance Show TimeLogEntry -- | A Journal is a set of Transactions and related data, -- usually parsed from a hledger/ledger journal file or timelog. This is -- the primary hledger data object. module Hledger.Data.Journal nulljournal :: Journal nullctx :: JournalContext journalFilePath :: Journal -> FilePath journalFilePaths :: Journal -> [FilePath] mainfile :: Journal -> (FilePath, String) addTransaction :: Transaction -> Journal -> Journal addModifierTransaction :: ModifierTransaction -> Journal -> Journal addPeriodicTransaction :: PeriodicTransaction -> Journal -> Journal addHistoricalPrice :: HistoricalPrice -> Journal -> Journal addTimeLogEntry :: TimeLogEntry -> Journal -> Journal journalPostings :: Journal -> [Posting] journalAccountNamesUsed :: Journal -> [AccountName] journalAccountNames :: Journal -> [AccountName] journalAccountNameTree :: Journal -> Tree AccountName -- | Keep only transactions we are interested in, as described by the -- filter specification. May also massage the data a little. filterJournalTransactions :: FilterSpec -> Journal -> Journal -- | Keep only postings we are interested in, as described by the filter -- specification. May also massage the data a little. This can leave -- unbalanced transactions. filterJournalPostings :: FilterSpec -> Journal -> Journal -- | Keep only transactions whose description matches the description -- patterns. filterJournalTransactionsByDescription :: [String] -> Journal -> Journal -- | Keep only transactions which fall between begin and end dates. We -- include transactions on the begin date and exclude transactions on the -- end date, like ledger. An empty date string means no restriction. filterJournalTransactionsByDate :: DateSpan -> Journal -> Journal -- | Keep only transactions which have the requested cleared/uncleared -- status, if there is one. filterJournalTransactionsByClearedStatus :: Maybe Bool -> Journal -> Journal -- | Keep only postings which have the requested cleared/uncleared status, -- if there is one. filterJournalPostingsByClearedStatus :: Maybe Bool -> Journal -> Journal -- | Strip out any virtual postings, if the flag is true, otherwise do no -- filtering. filterJournalPostingsByRealness :: Bool -> Journal -> Journal -- | Strip out any postings with zero amount, unless the flag is true. filterJournalPostingsByEmpty :: Bool -> Journal -> Journal -- | Keep only transactions which affect accounts deeper than the specified -- depth. filterJournalTransactionsByDepth :: Maybe Int -> Journal -> Journal -- | Strip out any postings to accounts deeper than the specified depth -- (and any transactions which have no postings as a result). filterJournalPostingsByDepth :: Maybe Int -> Journal -> Journal -- | Keep only transactions which affect accounts matched by the account -- patterns. More precisely: each positive account pattern excludes -- transactions which do not contain a posting to a matched account, and -- each negative account pattern excludes transactions containing a -- posting to a matched account. filterJournalTransactionsByAccount :: [String] -> Journal -> Journal -- | Keep only postings which affect accounts matched by the account -- patterns. This can leave transactions unbalanced. filterJournalPostingsByAccount :: [String] -> Journal -> Journal -- | Convert this journal's transactions' primary date to either the actual -- or effective date. journalSelectingDate :: WhichDate -> Journal -> Journal -- | Do post-parse processing on a journal, to make it ready for use. journalFinalise :: ClockTime -> LocalTime -> FilePath -> String -> JournalContext -> Journal -> Either String Journal -- | Fill in any missing amounts and check that all journal transactions -- balance, or return an error message. This is done after parsing all -- amounts and working out the canonical commodities, since balancing -- depends on display precision. Reports only the first error -- encountered. journalBalanceTransactions :: Journal -> Either String Journal -- | Convert all the journal's amounts to their canonical display settings. -- Ie, all amounts in a given commodity will use (a) the display settings -- of the first, and (b) the greatest precision, of the amounts in that -- commodity. Prices are canonicalised as well, so consider calling -- journalApplyHistoricalPrices before this. journalCanonicaliseAmounts :: Journal -> Journal -- | Apply this journal's historical price records to unpriced amounts -- where possible. journalApplyHistoricalPrices :: Journal -> Journal -- | Get the price for a commodity on the specified day from the price -- database, if known. Does only one lookup step, ie will not look up the -- price of a price. journalHistoricalPriceFor :: Journal -> Day -> Commodity -> Maybe MixedAmount -- | Close any open timelog sessions in this journal using the provided -- current time. journalCloseTimeLogEntries :: LocalTime -> Journal -> Journal -- | Convert all this journal's amounts to cost by applying their prices, -- if any. journalConvertAmountsToCost :: Journal -> Journal -- | Get this journal's unique, display-preference-canonicalised -- commodities, by symbol. journalCanonicalCommodities :: Journal -> Map String Commodity -- | Get all this journal's amounts' commodities, in the order parsed. journalAmountCommodities :: Journal -> [Commodity] -- | Get all this journal's amount and price commodities, in the order -- parsed. journalAmountAndPriceCommodities :: Journal -> [Commodity] -- | Get this amount's commodity and any commodities referenced in its -- price. amountCommodities :: Amount -> [Commodity] -- | Get all this journal's amounts, in the order parsed. journalAmounts :: Journal -> [MixedAmount] -- | The (fully specified) date span containing this journal's -- transactions, or DateSpan Nothing Nothing if there are none. journalDateSpan :: Journal -> DateSpan -- | Check if a set of hledger account/description filter patterns matches -- the given account name or entry description. Patterns are -- case-insensitive regular expressions. Prefixed with not:, they become -- anti-patterns. matchpats :: [String] -> String -> Bool -- | Calculate the account tree and all account balances from a journal's -- postings, returning the results for efficient lookup. journalAccountInfo :: Journal -> (Tree AccountName, Map AccountName Account) -- | Given a list of postings, return an account name tree and three query -- functions that fetch postings, subaccount-excluding-balance and -- subaccount-including-balance by account name. groupPostings :: [Posting] -> (Tree AccountName, AccountName -> [Posting], AccountName -> MixedAmount, AccountName -> MixedAmount) -- | Add subaccount-excluding and subaccount-including balances to a tree -- of account names somewhat efficiently, given a function that looks up -- transactions by account name. calculateBalances :: Tree AccountName -> (AccountName -> [Posting]) -> Tree (AccountName, (MixedAmount, MixedAmount)) -- | Convert a list of postings to a map from account name to that -- account's postings. postingsByAccount :: [Posting] -> Map AccountName [Posting] instance Show Journal -- | Utilities common to hledger journal readers. module Hledger.Read.Utils juSequence :: [JournalUpdate] -> JournalUpdate -- | Given a JournalUpdate-generating parsec parser, file path and data -- string, parse and post-process a Journal so that it's ready to use, or -- give an error. parseJournalWith :: (GenParser Char JournalContext (JournalUpdate, JournalContext)) -> FilePath -> String -> ErrorT String IO Journal setYear :: Integer -> GenParser tok JournalContext () getYear :: GenParser tok JournalContext (Maybe Integer) setCommodity :: Commodity -> GenParser tok JournalContext () getCommodity :: GenParser tok JournalContext (Maybe Commodity) pushParentAccount :: String -> GenParser tok JournalContext () popParentAccount :: GenParser tok JournalContext () getParentAccount :: GenParser tok JournalContext String -- | Convert a possibly relative, possibly tilde-containing file path to an -- absolute one. using the current directory from a parsec source -- position. ~username is not supported. expandPath :: MonadIO m => SourcePos -> FilePath -> m FilePath fileSuffix :: FilePath -> String -- | An Account stores -- --
-- The ledger file format is quite simple, but also very flexible. It supports -- many options, though typically the user can ignore most of them. They are -- summarized below. The initial character of each line determines what the -- line means, and how it should be interpreted. Allowable initial characters -- are: -- -- NUMBER A line beginning with a number denotes an entry. It may be followed by any -- number of lines, each beginning with whitespace, to denote the entrys account -- transactions. The format of the first line is: -- -- DATE[=EDATE] [*|!] [(CODE)] DESC -- -- If * appears after the date (with optional eective date), it indicates the entry -- is cleared, which can mean whatever the user wants it t omean. If ! appears -- after the date, it indicates d the entry is pending; i.e., tentatively cleared from -- the users point of view, but not yet actually cleared. If a CODE appears in -- parentheses, it may be used to indicate a check number, or the type of the -- transaction. Following these is the payee, or a description of the transaction. -- The format of each following transaction is: -- -- ACCOUNT AMOUNT [; NOTE] -- -- The ACCOUNT may be surrounded by parentheses if it is a virtual -- transactions, or square brackets if it is a virtual transactions that must -- balance. The AMOUNT can be followed by a per-unit transaction cost, -- by specifying AMOUNT, or a complete transaction cost with @ AMOUNT. -- Lastly, the NOTE may specify an actual and/or eective date for the -- transaction by using the syntax [ACTUAL_DATE] or [=EFFECTIVE_DATE] or -- [ACTUAL_DATE=EFFECtIVE_DATE]. -- -- = An automated entry. A value expression must appear after the equal sign. -- After this initial line there should be a set of one or more transactions, just as -- if it were normal entry. If the amounts of the transactions have no commodity, -- they will be applied as modifiers to whichever real transaction is matched by -- the value expression. -- -- ~ A period entry. A period expression must appear after the tilde. -- After this initial line there should be a set of one or more transactions, just as -- if it were normal entry. -- -- ! A line beginning with an exclamation mark denotes a command directive. It -- must be immediately followed by the command word. The supported commands -- are: -- -- !include -- Include the stated ledger file. -- !account -- The account name is given is taken to be the parent of all transac- -- tions that follow, until !end is seen. -- !end Ends an account block. -- -- ; A line beginning with a colon indicates a comment, and is ignored. -- -- Y If a line begins with a capital Y, it denotes the year used for all subsequent -- entries that give a date without a year. The year should appear immediately -- after the Y, for example: Y2004. This is useful at the beginning of a file, to -- specify the year for that file. If all entries specify a year, however, this command -- has no eect. -- -- P Specifies a historical price for a commodity. These are usually found in a pricing -- history file (see the -Q option). The syntax is: -- -- P DATE SYMBOL PRICE -- -- N SYMBOL Indicates that pricing information is to be ignored for a given symbol, nor will -- quotes ever be downloaded for that symbol. Useful with a home currency, such -- as the dollar ($). It is recommended that these pricing options be set in the price -- database file, which defaults to ~/.pricedb. The syntax for this command is: -- -- N SYMBOL -- -- D AMOUNT Specifies the default commodity to use, by specifying an amount in the expected -- format. The entry command will use this commodity as the default when none -- other can be determined. This command may be used multiple times, to set -- the default flags for dierent commodities; whichever is seen last is used as the -- default commodity. For example, to set US dollars as the default commodity, -- while also setting the thousands flag and decimal flag for that commodity, use: -- -- D $1,000.00 -- -- C AMOUNT1 = AMOUNT2 -- Specifies a commodity conversion, where the first amount is given to be equiv- -- alent to the second amount. The first amount should use the decimal precision -- desired during reporting: -- -- C 1.00 Kb = 1024 bytes -- -- i, o, b, h -- These four relate to timeclock support, which permits ledger to read timelog -- files. See the timeclocks documentation for more info on the syntax of its -- timelog files. --module Hledger.Read.JournalReader tests_JournalReader :: Test reader :: Reader -- | Top-level journal parser. Returns a single composite, I/O performing, -- error-raising JournalUpdate (and final JournalContext) -- which can be applied to an empty journal to get the final result. journalFile :: GenParser Char JournalContext (JournalUpdate, JournalContext) journalAddFile :: (FilePath, String) -> Journal -> Journal someamount :: GenParser Char JournalContext MixedAmount -- | Parse an account name. Account names may have single spaces inside -- them, and are terminated by two or more spaces. They should have one -- or more components of at least one character, separated by the account -- separator char. ledgeraccountname :: GenParser Char st AccountName ledgerExclamationDirective :: GenParser Char JournalContext JournalUpdate ledgerHistoricalPrice :: GenParser Char JournalContext HistoricalPrice ledgerDefaultYear :: GenParser Char JournalContext JournalUpdate emptyLine :: GenParser Char JournalContext () ledgerdatetime :: GenParser Char JournalContext LocalTime -- | A reader for the timelog file format generated by timeclock.el. -- -- From timeclock.el 2.6: -- --
-- A timelog contains data in the form of a single entry per line. -- Each entry has the form: -- -- CODE YYYYMMDD HH:MM:SS [COMMENT] -- -- CODE is one of: b, h, i, o or O. COMMENT is optional when the code is -- i, o or O. The meanings of the codes are: -- -- b Set the current time balance, or "time debt". Useful when -- archiving old log data, when a debt must be carried forward. -- The COMMENT here is the number of seconds of debt. -- -- h Set the required working time for the given day. This must -- be the first entry for that day. The COMMENT in this case is -- the number of hours in this workday. Floating point amounts -- are allowed. -- -- i Clock in. The COMMENT in this case should be the name of the -- project worked on. -- -- o Clock out. COMMENT is unnecessary, but can be used to provide -- a description of how the period went, for example. -- -- O Final clock out. Whatever project was being worked on, it is -- now finished. Useful for creating summary reports. ---- -- Example: -- --
-- i 20070310 12:26:00 hledger -- o 20070310 17:26:02 --module Hledger.Read.TimelogReader tests_TimelogReader :: Test reader :: Reader -- | Read hledger data from various data formats, and related utilities. module Hledger.Read tests_Hledger_Read :: Test -- | Read a journal from this file, using the specified data format or -- trying all known formats, or give an error string; also create the -- file if it doesn't exist. readJournalFile :: Maybe String -> FilePath -> IO (Either String Journal) -- | Read a Journal from this string, using the specified data format or -- trying all known formats, or give an error string. readJournal :: Maybe String -> String -> IO (Either String Journal) -- | Read a Journal from this string (and file path), auto-detecting the -- data format, or give a useful error string. Tries to parse each known -- data format in turn. If none succeed, gives the error message specific -- to the intended data format, which if not specified is guessed from -- the file suffix and possibly the data. journalFromPathAndString :: Maybe String -> FilePath -> String -> IO (Either String Journal) -- | Get the user's default journal file path. myJournalPath :: IO String -- | Get the user's default timelog file path. myTimelogPath :: IO String -- | Read the user's default journal file, or give an error. myJournal :: IO Journal -- | Read the user's default timelog file, or give an error. myTimelog :: IO Journal