-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Core data types, parsers and utilities for the hledger accounting tool. -- -- hledger is a library and set of user tools for working with financial -- data (or anything that can be tracked in a double-entry accounting -- ledger.) It is a haskell port and friendly fork of John Wiegley's -- Ledger. hledger provides command-line, curses and web interfaces, and -- aims to be a reliable, practical tool for daily use. @package hledger-lib @version 0.21 -- | UTF-8 aware string IO functions that will work across multiple -- platforms and GHC versions. Includes code from Text.Pandoc.UTF8 ((C) -- 2010 John MacFarlane). -- -- Example usage: -- -- import Prelude hiding -- (readFile,writeFile,appendFile,getContents,putStr,putStrLn) import -- UTF8IOCompat -- (readFile,writeFile,appendFile,getContents,putStr,putStrLn) import -- UTF8IOCompat -- (SystemString,fromSystemString,toSystemString,error',userError') -- -- 2013410 update: we now trust that current GHC versions & -- platforms do the right thing, so this file is a no-op and on its way -- to being removed. Not carefully tested. module Hledger.Utils.UTF8IOCompat -- | The readFile function reads a file and returns the contents of -- the file as a string. The file is read lazily, on demand, as with -- getContents. readFile :: FilePath -> IO String -- | The computation writeFile file str function writes the -- string str, to the file file. writeFile :: FilePath -> String -> IO () -- | The computation appendFile file str function appends -- the string str, to the file file. -- -- Note that writeFile and appendFile write a literal -- string to a file. To write a value of any printable type, as with -- print, use the show function to convert the value to a -- string first. -- --
-- main = appendFile "squares" (show [(x,x*x) | x <- [0,0.1..2]]) --appendFile :: FilePath -> String -> IO () -- | The getContents operation returns all user input as a single -- string, which is read lazily as it is needed (same as -- hGetContents stdin). getContents :: IO String -- | Computation hGetContents hdl returns the list of -- characters corresponding to the unread portion of the channel or file -- managed by hdl, which is put into an intermediate state, -- semi-closed. In this state, hdl is effectively closed, -- but items are read from hdl on demand and accumulated in a -- special list returned by hGetContents hdl. -- -- Any operation that fails because a handle is closed, also fails if a -- handle is semi-closed. The only exception is hClose. A -- semi-closed handle becomes closed: -- --
-- Journal -- a journal is read from one or more data files. It contains.. -- [Transaction] -- journal transactions (aka entries), which have date, status, code, description and.. -- [Posting] -- multiple account postings, 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 -- a filtered copy of the original journal, containing only the transactions and postings we are interested in -- [Account] -- all accounts, in tree order beginning with a "root" account", with their balances and sub/parent accounts ---- -- For more detailed documentation on each type, see the corresponding -- modules. module Hledger.Data.Types type SmartDate = (String, String, String) data WhichDate PrimaryDate :: WhichDate SecondaryDate :: WhichDate data DateSpan DateSpan :: (Maybe Day) -> (Maybe Day) -> DateSpan data Interval NoInterval :: Interval Days :: Int -> Interval Weeks :: Int -> Interval Months :: Int -> Interval Quarters :: Int -> Interval Years :: Int -> Interval DayOfMonth :: Int -> Interval DayOfWeek :: Int -> Interval type AccountName = String data Side L :: Side R :: Side type Commodity = String type Quantity = Double -- | An amount's price (none, per unit, or total) in another commodity. -- Note the price should be a positive number, although this is not -- enforced. data Price NoPrice :: Price UnitPrice :: Amount -> Price TotalPrice :: Amount -> Price -- | Display style for an amount. data AmountStyle AmountStyle :: Side -> Bool -> Int -> Char -> Char -> [Int] -> AmountStyle -- | does the symbol appear on the left or the right ? ascommodityside :: AmountStyle -> Side -- | space between symbol and quantity ? ascommodityspaced :: AmountStyle -> Bool -- | number of digits displayed after the decimal point asprecision :: AmountStyle -> Int -- | character used as decimal point asdecimalpoint :: AmountStyle -> Char -- | character used for separating digit groups (eg thousands) asseparator :: AmountStyle -> Char -- | positions of digit group separators, counting leftward from decimal -- point asseparatorpositions :: AmountStyle -> [Int] data Amount Amount :: Commodity -> Quantity -> Price -> AmountStyle -> Amount acommodity :: Amount -> Commodity aquantity :: Amount -> Quantity -- | the (fixed) price for this amount, if any aprice :: Amount -> Price astyle :: Amount -> AmountStyle newtype MixedAmount Mixed :: [Amount] -> MixedAmount data PostingType RegularPosting :: PostingType VirtualPosting :: PostingType BalancedVirtualPosting :: PostingType type Tag = (String, String) data Posting Posting :: Maybe Day -> Maybe Day -> Bool -> AccountName -> MixedAmount -> String -> PostingType -> [Tag] -> Maybe MixedAmount -> Maybe Transaction -> Posting -- | this posting's date, if different from the transaction's pdate :: Posting -> Maybe Day -- | this posting's secondary date, if different from the transaction's pdate2 :: Posting -> Maybe Day pstatus :: Posting -> Bool paccount :: Posting -> AccountName pamount :: Posting -> MixedAmount -- | this posting's non-tag comment lines, as a single non-indented string pcomment :: Posting -> String ptype :: Posting -> PostingType ptags :: Posting -> [Tag] -- | optional: the expected balance in the account after this posting pbalanceassertion :: Posting -> Maybe MixedAmount -- | this posting's parent transaction (co-recursive types). Tying this -- knot gets tedious, Maybe makes it easier/optional. ptransaction :: Posting -> Maybe Transaction data Transaction Transaction :: Day -> Maybe Day -> Bool -> String -> String -> String -> [Tag] -> [Posting] -> String -> Transaction tdate :: Transaction -> Day tdate2 :: Transaction -> Maybe Day tstatus :: Transaction -> Bool tcode :: Transaction -> String tdescription :: Transaction -> String -- | this transaction's non-tag comment lines, as a single non-indented -- string tcomment :: Transaction -> String ttags :: Transaction -> [Tag] -- | this transaction's postings tpostings :: Transaction -> [Posting] tpreceding_comment_lines :: Transaction -> String data ModifierTransaction ModifierTransaction :: String -> [Posting] -> ModifierTransaction mtvalueexpr :: ModifierTransaction -> String mtpostings :: ModifierTransaction -> [Posting] data PeriodicTransaction PeriodicTransaction :: String -> [Posting] -> PeriodicTransaction ptperiodicexpr :: PeriodicTransaction -> String ptpostings :: PeriodicTransaction -> [Posting] data TimeLogCode SetBalance :: TimeLogCode SetRequiredHours :: TimeLogCode In :: TimeLogCode Out :: TimeLogCode FinalOut :: TimeLogCode data TimeLogEntry TimeLogEntry :: TimeLogCode -> LocalTime -> String -> TimeLogEntry tlcode :: TimeLogEntry -> TimeLogCode tldatetime :: TimeLogEntry -> LocalTime tlcomment :: TimeLogEntry -> String data HistoricalPrice HistoricalPrice :: Day -> Commodity -> Amount -> HistoricalPrice hdate :: HistoricalPrice -> Day hcommodity :: HistoricalPrice -> Commodity hamount :: HistoricalPrice -> Amount type Year = Integer -- | A journal context is some data which can change in the course -- of parsing a journal. An example is the default year, which changes -- when a Y directive is encountered. At the end of parsing, the final -- context is saved for later use by eg the add command. data JournalContext Ctx :: !(Maybe Year) -> !(Maybe (Commodity, AmountStyle)) -> ![AccountName] -> ![(AccountName, AccountName)] -> JournalContext -- | the default year most recently specified with Y ctxYear :: JournalContext -> !(Maybe Year) -- | the default commodity and amount style most recently specified with D ctxCommodityAndStyle :: JournalContext -> !(Maybe (Commodity, AmountStyle)) -- | the current stack of parent accounts/account name components specified -- with account directive(s). Concatenated, these are the account -- prefix prepended to parsed account names. ctxAccount :: JournalContext -> ![AccountName] -- | the current list of account name aliases in effect ctxAliases :: JournalContext -> ![(AccountName, AccountName)] data Journal Journal :: [ModifierTransaction] -> [PeriodicTransaction] -> [Transaction] -> [TimeLogEntry] -> [HistoricalPrice] -> String -> JournalContext -> [(FilePath, String)] -> ClockTime -> Map Commodity AmountStyle -> Journal jmodifiertxns :: Journal -> [ModifierTransaction] jperiodictxns :: Journal -> [PeriodicTransaction] jtxns :: Journal -> [Transaction] open_timelog_entries :: Journal -> [TimeLogEntry] historical_prices :: Journal -> [HistoricalPrice] -- | any trailing comments from the journal file final_comment_lines :: Journal -> String -- | the context (parse state) at the end of parsing jContext :: Journal -> JournalContext -- | the file path and raw text of the main and any included journal files. -- The main file is first followed by any included files in the order -- encountered (XXX reversed, cf journalAddFile). files :: Journal -> [(FilePath, String)] -- | when this journal was last read from its file(s) filereadtime :: Journal -> ClockTime -- | how to display amounts in each commodity jcommoditystyles :: Journal -> Map Commodity AmountStyle -- | A JournalUpdate is some transformation of a Journal. It can do I/O or -- raise an error. type JournalUpdate = ErrorT String IO (Journal -> Journal) -- | The id of a data format understood by hledger, eg journal or -- csv. type Format = String -- | A hledger journal reader is a triple of format name, format-detecting -- predicate, and a parser to Journal. data Reader Reader :: Format -> (FilePath -> String -> Bool) -> (Maybe FilePath -> FilePath -> String -> ErrorT String IO Journal) -> Reader rFormat :: Reader -> Format rDetector :: Reader -> FilePath -> String -> Bool rParser :: Reader -> Maybe FilePath -> FilePath -> String -> ErrorT String IO Journal data HledgerFormatField AccountField :: HledgerFormatField DefaultDateField :: HledgerFormatField DescriptionField :: HledgerFormatField TotalField :: HledgerFormatField DepthSpacerField :: HledgerFormatField FieldNo :: Int -> HledgerFormatField data FormatString FormatLiteral :: String -> FormatString FormatField :: Bool -> (Maybe Int) -> (Maybe Int) -> HledgerFormatField -> FormatString -- | An account, with name, balances and links to parent/subaccounts which -- let you walk up or down the account tree. data Account Account :: AccountName -> MixedAmount -> [Account] -> MixedAmount -> Maybe Account -> Bool -> Account -- | this account's full name aname :: Account -> AccountName -- | this account's balance, excluding subaccounts aebalance :: Account -> MixedAmount -- | sub-accounts anumpostings :: Int -- ^ number of postings to this -- account derived from the above: asubs :: Account -> [Account] -- | this account's balance, including subaccounts aibalance :: Account -> MixedAmount -- | parent account aparent :: Account -> Maybe Account -- | used in the accounts report to label elidable parents aboring :: Account -> Bool -- | A Ledger has the journal it derives from, and the accounts derived -- from that. Accounts are accessible both list-wise and tree-wise, since -- each one knows its parent and subs; the first account is the root of -- the tree and always exists. data Ledger Ledger :: Journal -> [Account] -> Ledger ljournal :: Ledger -> Journal laccounts :: Ledger -> [Account] instance Typeable Journal instance Eq WhichDate instance Show WhichDate instance Eq DateSpan instance Show DateSpan instance Ord DateSpan instance Eq Interval instance Show Interval instance Ord Interval instance Eq Side instance Show Side instance Read Side instance Ord Side instance Eq AmountStyle instance Ord AmountStyle instance Show AmountStyle instance Read AmountStyle instance Eq Amount instance Ord Amount instance Eq Price instance Ord Price instance Eq MixedAmount instance Ord MixedAmount instance Eq PostingType instance Show PostingType instance Eq Transaction instance Eq ModifierTransaction instance Eq PeriodicTransaction instance Eq TimeLogCode instance Ord TimeLogCode instance Eq TimeLogEntry instance Ord TimeLogEntry instance Eq HistoricalPrice instance Read JournalContext instance Show JournalContext instance Eq JournalContext instance Eq Journal instance Show HledgerFormatField instance Eq HledgerFormatField instance Show FormatString instance Eq FormatString instance Show Reader instance Eq Posting module Hledger.Data.FormatStrings parseFormatString :: String -> Either String [FormatString] formatStrings :: GenParser Char st [FormatString] formatValue :: Bool -> Maybe Int -> Maybe Int -> String -> String data FormatString FormatLiteral :: String -> FormatString FormatField :: Bool -> (Maybe Int) -> (Maybe Int) -> HledgerFormatField -> FormatString data HledgerFormatField AccountField :: HledgerFormatField DefaultDateField :: HledgerFormatField DescriptionField :: HledgerFormatField TotalField :: HledgerFormatField DepthSpacerField :: HledgerFormatField FieldNo :: Int -> HledgerFormatField tests :: Test -- | 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.Utils lowercase :: [Char] -> [Char] uppercase :: [Char] -> [Char] strip :: [Char] -> String lstrip :: String -> String rstrip :: [Char] -> [Char] stripbrackets :: String -> String elideLeft :: Int -> [Char] -> [Char] elideRight :: Int -> [Char] -> [Char] underline :: String -> String -- | Wrap a string in single quotes, and -prefix any embedded single -- quotes, if it contains whitespace and is not already single- or -- double-quoted. quoteIfSpaced :: String -> String escapeSingleQuotes :: String -> String escapeQuotes :: String -> String -- | Quote-aware version of words - don't split on spaces which are inside -- quotes. NB correctly handles a'b but not ''a''. Can -- raise an error if parsing fails. words' :: String -> [String] -- | Quote-aware version of unwords - single-quote strings which contain -- whitespace unwords' :: [String] -> String -- | Single-quote this string if it contains whitespace or double-quotes singleQuoteIfNeeded :: [Char] -> [Char] whitespacechars :: [Char] -- | Strip one matching pair of single or double quotes on the ends of a -- string. stripquotes :: String -> String isSingleQuoted :: [Char] -> Bool isDoubleQuoted :: [Char] -> Bool 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 difforzero :: (Num a, Ord a) => a -> a -> a regexMatch :: String -> String -> Maybe (RegexResult, MatchList) regexMatchCI :: String -> String -> Maybe (RegexResult, MatchList) regexMatches :: String -> String -> Bool regexMatchesCI :: String -> String -> Bool containsRegex :: String -> String -> Bool regexReplace :: String -> String -> String -> String regexReplaceCI :: String -> String -> String -> String regexReplaceBy :: String -> (String -> String) -> String -> String regexToCaseInsensitive :: String -> String regexSplit :: String -> String -> [String] regexMatchesRegexCompat :: String -> String -> Bool regexMatchesCIRegexCompat :: String -> String -> Bool splitAtElement :: Eq a => a -> [a] -> [[a]] root :: Tree a -> a subs :: Tree a -> Forest a branches :: Tree a -> Forest 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 -- | An efficient-to-build tree suggested by Cale Gibbard, probably better -- than accountNameTreeFrom. newtype FastTree a T :: (Map a (FastTree a)) -> FastTree a emptyTree :: FastTree a mergeTrees :: Ord a => FastTree a -> FastTree a -> FastTree a treeFromPath :: [a] -> FastTree a treeFromPaths :: Ord a => [[a]] -> FastTree a -- | 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 showable - like strace, with a label prepended lstrace :: 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 tracewith :: (a -> String) -> a -> a -- | Parsec trace - show the current parsec position and next input, and -- the provided string if it's non-null. ptrace :: String -> GenParser Char st () debugLevel :: Float -- | Print a message to the console if the global debugLevel is greater -- than the level we are called with. dbg :: Monad m => Float -> String -> m () -- | Print a message and parsec position info to the console if the global -- debugLevel is greater than the level we are called with. pdbg :: -- GenParser m => Float -> String -> m () pdbg :: Float -> String -> ParsecT [Char] st Identity () -- | Backtracking choice, use this when alternatives share a prefix. -- Consumes no input if all choices fail. 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 parseerror :: ParseError -> a showParseError :: ParseError -> String showDateParseError :: ParseError -> String nonspace :: GenParser Char st Char spacenonewline :: GenParser Char st Char restofline :: GenParser Char st String eolof :: GenParser Char st () getCurrentLocalTime :: IO LocalTime -- | Get a Test's label, or the empty string. testName :: Test -> String -- | Flatten a Test containing TestLists into a list of single tests. flattenTests :: Test -> [Test] -- | Filter TestLists in a Test, recursively, preserving the structure. filterTests :: (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 successful, printing the parse error on -- failure. assertParseFailure :: (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 -- | Apply a function the specified number of times. Possibly uses O(n) -- stack ? applyN :: Int -> (a -> a) -> a -> a -- | Convert a possibly relative, possibly tilde-containing file path to an -- absolute one, given the current directory. ~username is not supported. -- Leave - unchanged. expandPath :: MonadIO m => FilePath -> FilePath -> m FilePath firstJust :: Eq a => [Maybe a] -> Maybe a -- | Read a file in universal newline mode, handling whatever newline -- convention it may contain. readFile' :: FilePath -> IO String -- | The trace function outputs the trace message given as its first -- argument, before returning the second argument as its result. -- -- For example, this returns the value of f x but first outputs -- the message. -- --
-- trace ("calling f with x = " ++ show x) (f x)
--
--
-- The trace function should only be used for debugging, or
-- for monitoring execution. The function is not referentially
-- transparent: its type indicates that it is a pure function but it has
-- the side effect of outputting the trace message.
trace :: String -> a -> a
-- | A string received from or being passed to the operating system, such
-- as a file path, command-line argument, or environment variable name or
-- value. With GHC versions before 7.2 on some platforms (posix) these
-- are typically encoded. When converting, we assume the encoding is
-- UTF-8 (cf
-- http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html#UTF8).
type SystemString = String
-- | Convert a system string to an ordinary string, decoding from UTF-8 if
-- it appears to be UTF8-encoded and GHC version is less than 7.2.
fromSystemString :: SystemString -> String
-- | Convert a unicode string to a system string, encoding with UTF-8 if we
-- are on a posix platform with GHC < 7.2.
toSystemString :: String -> SystemString
-- | A SystemString-aware version of error.
error' :: String -> a
-- | A SystemString-aware version of userError.
userError' :: String -> IOError
-- | Convert a generic value into a pretty String, if possible.
ppShow :: Show a => a -> String
instance Show a => Show (FastTree a)
instance Eq a => Eq (FastTree a)
instance Ord a => Ord (FastTree a)
-- | 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
acctsepchar :: Char
accountNameComponents :: AccountName -> [String]
accountNameFromComponents :: [String] -> AccountName
accountLeafName :: AccountName -> String
accountNameLevel :: AccountName -> Int
accountNameDrop :: Int -> AccountName -> AccountName
-- |
expandAccountNames :: [AccountName] -> [AccountName]
-- | a:b:c -> [a,a:b,a:b:c]
expandAccountName :: 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
nullaccountnametree :: Tree [Char]
-- | 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 -- | Convert an account name to a regular expression matching it and its -- subaccounts. accountNameToAccountRegex :: String -> String -- | Convert an account name to a regular expression matching it but not -- its subaccounts. accountNameToAccountOnlyRegex :: String -> String -- | Convert an exact account-matching regular expression to a plain -- account name. accountRegexToAccountName :: String -> String -- | Does this string look like an exact account-matching regular -- expression ? isAccountRegex :: String -> Bool tests_Hledger_Data_AccountName :: Test -- | 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 nonsimplecommoditychars :: String quoteCommoditySymbolIfNeeded :: [Char] -> [Char] commodity :: [Char] commoditysymbols :: [([Char], [Char])] -- | Look up one of the sample commodities' symbol by name. comm :: String -> Commodity -- | Find the conversion rate between two commodities. Currently returns 1. conversionRate :: Commodity -> Commodity -> Double tests_Hledger_Data_Commodity :: Test -- | A simple Amount is some quantity of money, shares, or anything -- else. It has a (possibly null) Commodity and a numeric -- quantity: -- --
-- $1 -- £-50 -- EUR 3.44 -- GOOG 500 -- 1.5h -- 90 apples -- 0 ---- -- It may also have an assigned Price, representing this amount's -- per-unit or total cost in a different commodity. If present, this is -- rendered like so: -- --
-- EUR 2 @ $1.50 (unit price) -- EUR 2 @@ $3 (total price) ---- -- A MixedAmount is zero or more simple amounts, so can represent -- multiple commodities; this is the type most often used: -- --
-- 0 -- $50 + EUR 3 -- 16h + $13.55 + AAPL 500 + 6 oranges ---- -- When a mixed amount has been "normalised", it has no more than one -- amount in each commodity and no zero amounts; or it has just a single -- zero amount and no others. -- -- Limited arithmetic with simple and mixed amounts is supported, best -- used with similar amounts since it mostly ignores assigned prices and -- commodity exchange rates. module Hledger.Data.Amount -- | The empty simple amount. amount :: Amount -- | The empty simple amount. nullamt :: Amount -- | A temporary value for parsed transactions which had no amount -- specified. missingamt :: Amount num :: Quantity -> Amount usd :: Quantity -> Amount eur :: Quantity -> Amount gbp :: Quantity -> Amount hrs :: Quantity -> Amount -- | Set an amount's unit price. at :: Amount -> Amount -> Amount -- | Set an amount's total price. (@@) :: Amount -> Amount -> Amount -- | Convert an amount to the specified commodity, ignoring and discarding -- any assigned prices and assuming an exchange rate of 1. amountWithCommodity :: Commodity -> Amount -> Amount -- | Convert an amount to the commodity of its assigned price, if any. -- Notes: -- --
-- 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 -- | Split a DateSpan into one or more consecutive spans at the specified -- interval. splitSpan :: Interval -> DateSpan -> [DateSpan] -- | Convert a SmartDate to an absolute date using the provided reference -- date. fixSmartDate :: Day -> SmartDate -> Day -- | Convert a smart date string to an explicit yyyy/mm/dd string using the -- provided reference date, or raise an error. fixSmartDateStr :: Day -> String -> String -- | A safe version of fixSmartDateStr. fixSmartDateStrEither :: Day -> String -> Either ParseError String fixSmartDateStrEither' :: Day -> String -> Either ParseError Day -- | Count the days in a DateSpan, or if it is open-ended return Nothing. daysInSpan :: DateSpan -> Maybe Integer maybePeriod :: Day -> String -> Maybe (Interval, DateSpan) -- | Make a datespan from two valid date strings parseable by parsedate (or -- raise an error). Eg: mkdatespan "201111" "20111231". mkdatespan :: String -> String -> DateSpan -- | A Posting represents a change (by some MixedAmount) of -- the balance in some Account. Each Transaction contains -- two or more postings which should add up to 0. Postings reference -- their parent transaction, so we can look up the date or description -- there. module Hledger.Data.Posting nullposting :: Posting posting :: Posting post :: AccountName -> Amount -> Posting -- | Is this posting cleared? If this posting was individually marked as -- cleared, returns True. Otherwise, return the parent transaction's -- cleared status or, if there is no parent transaction, return False. postingCleared :: Posting -> Bool isReal :: Posting -> Bool isVirtual :: Posting -> Bool isBalancedVirtual :: Posting -> Bool isEmptyPosting :: Posting -> Bool hasAmount :: Posting -> Bool -- | Tags for this posting including any inherited from its parent -- transaction. postingAllTags :: Posting -> [Tag] -- | Tags for this transaction including any inherited from above, when -- that is implemented. transactionAllTags :: Transaction -> [Tag] relatedPostings :: Posting -> [Posting] -- | Get a posting's (primary) date - it's own primary date if specified, -- otherwise the parent transaction's primary date, or the null date if -- there is no parent transaction. postingDate :: Posting -> Day -- | Get a posting's secondary (secondary) date, which is the first of: -- posting's secondary date, transaction's secondary date, posting's -- primary date, transaction's primary date, or the null date if there is -- no parent transaction. postingDate2 :: Posting -> Day -- | Does this posting fall within the given date span ? isPostingInDateSpan :: DateSpan -> Posting -> Bool -- | Get the minimal date span which contains all the postings, or the null -- date span if there are none. postingsDateSpan :: [Posting] -> DateSpan accountNamesFromPostings :: [Posting] -> [AccountName] accountNamePostingType :: AccountName -> PostingType accountNameWithoutPostingType :: AccountName -> AccountName accountNameWithPostingType :: PostingType -> AccountName -> AccountName -- | Prefix one account name to another, preserving posting type indicators -- like concatAccountNames. joinAccountNames :: AccountName -> AccountName -> AccountName -- | Join account names into one. If any of them has () or [] posting type -- indicators, these (the first type encountered) will also be applied to -- the resulting account name. concatAccountNames :: [AccountName] -> AccountName -- | Rewrite an account name using the first applicable alias from the -- given list, if any. accountNameApplyAliases :: [(AccountName, AccountName)] -> AccountName -> AccountName sumPostings :: [Posting] -> MixedAmount showPosting :: Posting -> String showComment :: String -> String tests_Hledger_Data_Posting :: Test instance Show Posting -- | An Account has a name, a list of subaccounts, an optional -- parent account, and subaccounting-excluding and -including balances. module Hledger.Data.Account nullacct :: Account -- | Derive an account tree with balances from a set of postings. -- (*ledger's core feature.) The accounts are returned in a list, but -- retain their tree structure; the first one is the root of the tree. accountsFromPostings :: [Posting] -> [Account] -- | Convert an AccountName tree to an Account tree nameTreeToAccount :: AccountName -> FastTree AccountName -> Account -- | Tie the knot so all subaccounts' parents are set correctly. tieAccountParents :: Account -> Account -- | Get this account's parent accounts, from the nearest up to the root. parentAccounts :: Account -> [Account] -- | List the accounts at each level of the account tree. accountsLevels :: Account -> [[Account]] -- | Map a (non-tree-structure-modifying) function over this and sub -- accounts. mapAccounts :: (Account -> Account) -> Account -> Account -- | Is the predicate true on any of this account or its subaccounts ? anyAccounts :: (Account -> Bool) -> Account -> Bool -- | Add subaccount-inclusive balances to an account tree. -- , also noting -- -- whether it has an interesting balance or interesting subs to help -- -- with eliding later. sumAccounts :: Account -> Account -- | Remove all subaccounts below a certain depth. clipAccounts :: Int -> Account -> Account -- | Remove all leaf accounts and subtrees matching a predicate. pruneAccounts :: (Account -> Bool) -> Account -> Maybe Account -- | Flatten an account tree into a list, which is sometimes convenient. -- Note since accounts link to their parents/subs, the account tree -- remains intact and can still be used. It's a tree/list! flattenAccounts :: Account -> [Account] -- | Filter an account tree (to a list). filterAccounts :: (Account -> Bool) -> Account -> [Account] -- | Search an account list by name. lookupAccount :: AccountName -> [Account] -> Maybe Account printAccounts :: Account -> IO () showAccounts :: Account -> String showAccountsBoringFlag :: Account -> String showAccountDebug :: PrintfType ([Char] -> t) => Account -> t tests_Hledger_Data_Account :: Test instance Eq Account instance Show Account -- | A Transaction represents a movement of some commodity(ies) -- between two or more accounts. It consists of multiple account -- Postings which balance to zero, a date, and optional extras -- like description, cleared status, and tags. module Hledger.Data.Transaction nulltransaction :: Transaction -- | Ensure a transaction's postings refer back to it. txnTieKnot :: Transaction -> Transaction -- | 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 hasRealPostings :: Transaction -> Bool realPostings :: Transaction -> [Posting] virtualPostings :: Transaction -> [Posting] balancedVirtualPostings :: Transaction -> [Posting] transactionsPostings :: [Transaction] -> [Posting] -- | 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 Commodity AmountStyle) -> Transaction -> Bool transactionDate2 :: Transaction -> Day -- | Get the sums of a transaction's real, virtual, and balanced virtual -- postings. transactionPostingBalances :: Transaction -> (MixedAmount, MixedAmount, MixedAmount) -- | Ensure this transaction is balanced, possibly inferring a missing -- amount or conversion price, or return an error message. -- -- Balancing is affected by commodity display precisions, so those may be -- provided. -- -- We can infer a missing real amount when there are multiple real -- postings and exactly one of them is amountless (likewise for balanced -- virtual postings). Inferred amounts are converted to cost basis when -- possible. -- -- We can infer a conversion price when all real amounts are specified -- and the sum of real postings' amounts is exactly two -- non-explicitly-priced amounts in different commodities (likewise for -- balanced virtual postings). balanceTransaction :: Maybe (Map Commodity AmountStyle) -> Transaction -> Either String 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 tests_Hledger_Data_Transaction :: Test 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 tests_Hledger_Data_TimeLog :: Test instance Read TimeLogCode instance Show TimeLogCode instance Show TimeLogEntry -- | A general query system for matching things (accounts, postings, -- transactions..) by various criteria, and a parser for query -- expressions. module Hledger.Query -- | A query is a composition of search criteria, which can be used to -- match postings, transactions, accounts and more. data Query -- | always match Any :: Query -- | never match None :: Query -- | negate this match Not :: Query -> Query -- | match if any of these match Or :: [Query] -> Query -- | match if all of these match And :: [Query] -> Query -- | match if code matches this regexp Code :: String -> Query -- | match if description matches this regexp Desc :: String -> Query -- | match postings whose account matches this regexp Acct :: String -> Query -- | match if primary date in this date span Date :: DateSpan -> Query -- | match if secondary date in this date span Date2 :: DateSpan -> Query -- | match if cleared status has this value Status :: Bool -> Query -- | match if realness (involves a real non-virtual account ?) has -- this value Real :: Bool -> Query -- | match if the amount's numeric quantity is less thangreater -- thanequal to some value Amt :: Ordering -> Quantity -> Query -- | if true, show zero-amount postings/accounts which are usually not -- shown more of a query option than a query criteria ? Empty :: Bool -> Query -- | match if account depth is less than or equal to this value Depth :: Int -> Query -- | match if a tag with this exact name, and with value matching the -- regexp if provided, exists Tag :: String -> (Maybe String) -> Query -- | A query option changes a query's/report's behaviour and output in some -- way. data QueryOpt -- | show an account register focussed on this account QueryOptInAcctOnly :: AccountName -> QueryOpt -- | as above but include sub-accounts in the account register | -- QueryOptCostBasis -- ^ show amounts converted to cost where possible | -- QueryOptDate2 -- ^ show secondary dates instead of primary dates QueryOptInAcct :: AccountName -> QueryOpt -- | Convert a query expression containing zero or more space-separated -- terms to a query and zero or more query options. A query term is -- either: -- --
-- 2012/3/24 gift -- expenses:gifts $10 -- assets:cash --module Hledger.Read.JournalReader reader :: Reader -- | 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 getParentAccount :: GenParser tok JournalContext String -- | 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. journal :: GenParser Char JournalContext (JournalUpdate, JournalContext) directive :: GenParser Char JournalContext JournalUpdate defaultyeardirective :: GenParser Char JournalContext JournalUpdate historicalpricedirective :: GenParser Char JournalContext HistoricalPrice -- | Parse a date and time in YYYYMMDD HH:MM[:SS][+-ZZZZ] format. -- Any timezone will be ignored; the time is treated as local time. Fewer -- digits are allowed, except in the timezone. The year may be omitted if -- a default year has already been set. datetime :: GenParser Char JournalContext LocalTime code :: GenParser Char JournalContext String -- | 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. accountname :: GenParser Char st AccountName -- | 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 :: GenParser Char JournalContext Amount -- | Parse an amount from a string, or get an error. amountp' :: String -> Amount -- | Parse a mixed amount from a string, or get an error. mamountp' :: String -> MixedAmount emptyline :: GenParser Char JournalContext () -- | A reader for the timelog file format generated by timeclock.el -- (http://www.emacswiki.org/emacs/TimeClock). Example: -- --
-- i 2007/03/10 12:26:00 hledger -- o 2007/03/10 17:26:02 ---- -- 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. --module Hledger.Read.TimelogReader reader :: Reader tests_Hledger_Read_TimelogReader :: Test -- | A reader for CSV data, using an extra rules file to help interpret the -- data. module Hledger.Read.CsvReader reader :: Reader type CsvRecord = [String] rulesFileFor :: FilePath -> FilePath parseRulesFile :: FilePath -> IO (Either ParseError CsvRules) transactionFromCsvRecord :: CsvRules -> CsvRecord -> Transaction tests_Hledger_Read_CsvReader :: Test instance Show CsvRules instance Eq CsvRules -- | This is the entry point to hledger's reading system, which can read -- Journals from various data formats. Use this module if you want to -- parse journal data or read journal files. Generally it should not be -- necessary to import modules below this one. module Hledger.Read -- | All the data formats we can read. formats = map rFormat readers -- -- Get the default journal file path specified by the environment. Like -- ledger, we look first for the LEDGER_FILE environment variable, and if -- that does not exist, for the legacy LEDGER environment variable. If -- neither is set, or the value is blank, return the hard-coded default, -- which is .hledger.journal in the users's home directory (or -- in the current directory, if we cannot determine a home directory). defaultJournalPath :: IO String -- | Read the default journal file specified by the environment, or raise -- an error. defaultJournal :: IO Journal -- | Read a journal from this string, trying whatever readers seem -- appropriate: -- --