-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A command-line double-entry accounting tool. -- -- hledger reads a plain text general journal or time log describing your -- transactions and displays precise balance and register reports on the -- console. It is a remix, in haskell, of John Wiegley's excellent c++ -- ledger. hledger aims to be a practical, accessible tool for end users -- and a useful library for finance-minded haskell programmers. @package hledger @version 0.13 module Hledger.Cli.Version version :: [Char] -- | Given a program name, return a human-readable version string. For -- development builds, at least non-cabal builds, the patch level (ie the -- number of patches applied since last release tag) will also be -- included. progversionstr :: String -> String -- | Given a program name, return a precise platform-specific executable -- name suitable for naming downloadable binaries. Can raise an error if -- the version and patch level was not defined correctly at build time. binaryfilename :: String -> String -- | Command-line options for the application. module Hledger.Cli.Options -- | The program name which, if we are invoked as (via symlink or -- renaming), causes us to default to reading the user's time log instead -- of their journal. -- -- Command-line options we accept. options_cli :: [OptDescr Opt] -- | An option value from a command-line flag. data Opt File :: String -> Opt value :: Opt -> String NoNewAccts :: Opt Begin :: String -> Opt value :: Opt -> String End :: String -> Opt value :: Opt -> String Period :: String -> Opt value :: Opt -> String Cleared :: Opt UnCleared :: Opt CostBasis :: Opt Depth :: String -> Opt value :: Opt -> String Display :: String -> Opt value :: Opt -> String Effective :: Opt Empty :: Opt Real :: Opt Flat :: Opt Drop :: String -> Opt value :: Opt -> String NoTotal :: Opt SubTotal :: Opt DailyOpt :: Opt WeeklyOpt :: Opt MonthlyOpt :: Opt QuarterlyOpt :: Opt YearlyOpt :: Opt Help :: Opt Verbose :: Opt Version :: Opt BinaryFilename :: Opt Debug :: Opt DebugVty :: Opt BaseUrl :: String -> Opt value :: Opt -> String Port :: String -> Opt value :: Opt -> String ChartOutput :: String -> Opt value :: Opt -> String ChartItems :: String -> Opt value :: Opt -> String ChartSize :: String -> Opt value :: Opt -> String -- | Parse the command-line arguments into options and arguments using the -- specified option descriptors. Any smart dates in the options are -- converted to explicit YYYYMMDD format based on the current -- time. If parsing fails, raise an error, displaying the problem along -- with the provided usage string. parseArgumentsWith :: [OptDescr Opt] -> IO ([Opt], [String]) argsError :: String -> IO () -- | Convert any fuzzy dates within these option values to explicit ones, -- based on today's date. fixOptDates :: [Opt] -> IO [Opt] -- | Figure out the overall date span we should report on, based on any -- beginendperiod options provided. If there is a period option, -- the others are ignored. dateSpanFromOpts :: Day -> [Opt] -> DateSpan -- | Figure out the reporting interval, if any, specified by the options. -- If there is a period option, the others are ignored. intervalFromOpts :: [Opt] -> Interval -- | Get the value of the (last) depth option, if any. depthFromOpts :: [Opt] -> Maybe Int -- | Get the value of the (last) drop option, if any, otherwise 0. dropFromOpts :: [Opt] -> Int -- | Get the value of the (last) display option, if any. displayExprFromOpts :: [Opt] -> Maybe String -- | Get the value of the (last) baseurl option, if any. baseUrlFromOpts :: [Opt] -> Maybe String -- | Get the value of the (last) port option, if any. portFromOpts :: [Opt] -> Maybe Int -- | Get a maybe boolean representing the last cleared/uncleared option if -- any. -- -- Were we invoked as "hours" ? usingTimeProgramName :: IO Bool -- | Get the journal file path from options, an environment variable, or a -- default journalFilePathFromOpts :: [Opt] -> IO String -- | Gather filter pattern arguments into a list of account patterns and a -- list of description patterns. We interpret pattern arguments as -- follows: those prefixed with desc: are description patterns, -- all others are account patterns; also patterns prefixed with -- not: are negated. not: should come after desc: if both are -- used. parsePatternArgs :: [String] -> ([String], [String]) -- | Convert application options to the library's generic filter -- specification. optsToFilterSpec :: [Opt] -> [String] -> LocalTime -> FilterSpec instance Show Opt instance Eq Opt -- | Utilities for top-level modules and ghci. See also Hledger.Read and -- Hledger.Data.Utils. module Hledger.Cli.Utils -- | Parse the user's specified journal file and run a hledger command on -- it, or throw an error. withJournalDo :: [Opt] -> [String] -> String -> ([Opt] -> [String] -> Journal -> IO ()) -> IO () -- | Get a journal from the given string and options, or throw an error. readJournalWithOpts :: [Opt] -> String -> IO Journal -- | Re-read a journal from its data file, or return an error string. journalReload :: Journal -> IO (Either String Journal) -- | Re-read a journal from its data file mostly, only if the file has -- changed since last read (or if there is no file, ie data read from -- stdin). The provided options are mostly ignored. Return a journal or -- the error message while reading it, and a flag indicating whether it -- was re-read or not. journalReloadIfChanged :: [Opt] -> Journal -> IO (Either String Journal, Bool) -- | Has the journal's main data file changed since the journal was last -- read ? journalFileIsNewer :: Journal -> IO Bool -- | Has the specified file (presumably one of journal's data files) -- changed since journal was last read ? journalSpecifiedFileIsNewer :: Journal -> FilePath -> IO Bool -- | Get the last modified time of the specified file, or if it does not -- exist or there is some other error, the current time. fileModificationTime :: FilePath -> IO ClockTime -- | Attempt to open a web browser on the given url, all platforms. openBrowserOn :: String -> IO ExitCode -- | Back up this file with a (incrementing) numbered suffix, then -- overwrite it with this new text, or give an error. writeFileWithBackup :: FilePath -> String -> IO () -- | Back up this file with a (incrementing) numbered suffix then overwrite -- it with this new text, or give an error, but only if the text is -- different from the current file contents, and return a flag indicating -- whether we did anything. writeFileWithBackupIfChanged :: FilePath -> String -> IO Bool readFileStrictly :: FilePath -> IO String -- | A ledger-compatible balance command. -- -- ledger's balance command is easy to use but not easy to describe -- precisely. In the examples below we'll use sample.journal, which has -- the following account tree: -- --
--   assets
--     bank
--       checking
--       saving
--     cash
--   expenses
--     food
--     supplies
--   income
--     gifts
--     salary
--   liabilities
--     debts
--   
-- -- The balance command shows accounts with their aggregate balances. -- Subaccounts are displayed indented below their parent. Each balance is -- the sum of any transactions in that account plus any balances from -- subaccounts: -- --
--   $ hledger -f sample.journal balance
--                   $-1  assets
--                    $1    bank:saving
--                   $-2    cash
--                    $2  expenses
--                    $1    food
--                    $1    supplies
--                   $-2  income
--                   $-1    gifts
--                   $-1    salary
--                    $1  liabilities:debts
--   
-- -- Usually, the non-interesting accounts are elided or omitted. Above, -- checking is omitted because it has no subaccounts and a zero -- balance. bank is elided because it has only a single -- displayed subaccount (saving) and it would be showing the -- same balance as that ($1). Ditto for liabilities. We will -- return to this in a moment. -- -- The --depth argument can be used to limit the depth of the balance -- report. So, to see just the top level accounts: -- --
--   $ hledger -f sample.journal balance --depth 1
--                    $-1  assets
--                     $2  expenses
--                    $-2  income
--                     $1  liabilities
--   
-- -- This time liabilities has no displayed subaccounts (due to --depth) -- and is not elided. -- -- With one or more account pattern arguments, the balance command shows -- accounts whose name matches one of the patterns, plus their parents -- (elided) and subaccounts. So with the pattern o we get: -- --
--    $ hledger -f sample.journal balance o
--                     $1  expenses:food
--                    $-2  income
--                    $-1    gifts
--                    $-1    salary
--   --------------------
--                    $-1
--   
-- -- The o pattern matched food and income, so they are -- shown. Unmatched parents of matched accounts are also shown (elided) -- for context (expenses). -- -- Also, the balance report shows the total of all displayed accounts, -- when that is non-zero. Here, it is displayed because the accounts -- shown add up to $-1. -- -- Here is a more precise definition of "interesting" accounts in -- ledger's balance report: -- -- module Hledger.Cli.Balance -- | A balance report is a chart of accounts with balances, and their grand -- total. type BalanceReport = ([BalanceReportItem], MixedAmount) -- | The data for a single balance report line item, representing one -- account. type BalanceReportItem = (AccountName, AccountName, Int, MixedAmount) -- | Print a balance report. balance :: [Opt] -> [String] -> Journal -> IO () -- | Get a balance report with the specified options for this journal. balanceReport :: [Opt] -> FilterSpec -> Journal -> BalanceReport -- | Render a balance report as plain text suitable for console output. balanceReportAsText :: [Opt] -> BalanceReport -> String -- | Convert account data in CSV format (eg downloaded from a bank) to -- journal format, and print it on stdout. See the manual for more -- details. module Hledger.Cli.Convert -- | A set of data definitions and account-matching patterns sufficient to -- convert a particular CSV data file into meaningful journal -- transactions. See above. data CsvRules CsvRules :: Maybe FieldPosition -> Maybe FieldPosition -> Maybe FieldPosition -> Maybe FieldPosition -> Maybe FieldPosition -> Maybe FieldPosition -> Maybe String -> AccountName -> [AccountRule] -> CsvRules dateField :: CsvRules -> Maybe FieldPosition statusField :: CsvRules -> Maybe FieldPosition codeField :: CsvRules -> Maybe FieldPosition descriptionField :: CsvRules -> Maybe FieldPosition amountField :: CsvRules -> Maybe FieldPosition currencyField :: CsvRules -> Maybe FieldPosition baseCurrency :: CsvRules -> Maybe String baseAccount :: CsvRules -> AccountName accountRules :: CsvRules -> [AccountRule] type FieldPosition = Int type AccountRule = ([(String, Maybe String)], AccountName) type CsvRecord = [String] -- | Read the CSV file named as an argument and print equivalent journal -- transactions, using/creating a .rules file. convert :: [Opt] -> [String] -> Journal -> IO () -- | The highest (0-based) field index referenced in the field definitions, -- or -1 if no fields are defined. maxFieldIndex :: CsvRules -> Int rulesFileFor :: FilePath -> FilePath initialRulesFileContent :: String parseCsvRulesFile :: FilePath -> IO (Either ParseError CsvRules) parseCsvRules :: FilePath -> String -> Either ParseError CsvRules csvrulesfile :: GenParser Char CsvRules CsvRules -- | Real independent parser choice, even when alternative matches share a -- prefix. definitions :: GenParser Char CsvRules () accountrule :: GenParser Char CsvRules AccountRule printTxn :: Bool -> CsvRules -> CsvRecord -> IO () transactionFromCsvRecord :: CsvRules -> CsvRecord -> Transaction -- | Convert some date string with unknown format to YYYYMMDD. normaliseDate :: String -> String -- | Apply account matching rules to a transaction description to obtain -- the most appropriate account and a new description. identify :: [AccountRule] -> String -> String -> (String, String) instance Show CsvRules instance Eq CsvRules -- | Print a histogram report. module Hledger.Cli.Histogram -- | Print a histogram of some statistic per reporting interval, such as -- number of postings per day. histogram :: [Opt] -> [String] -> Journal -> IO () showHistogram :: [Opt] -> FilterSpec -> Journal -> String -- | A ledger-compatible print command. module Hledger.Cli.Print -- | A journal report is just a list of transactions. type JournalReport = [JournalReportItem] -- | The data for a single journal report item, representing one -- transaction. type JournalReportItem = Transaction -- | Print journal transactions in standard format. print' :: [Opt] -> [String] -> Journal -> IO () journalReport :: [Opt] -> FilterSpec -> Journal -> JournalReport showTransactions :: FilterSpec -> Journal -> String -- | A ledger-compatible register command. module Hledger.Cli.Register -- | A register report is a list of postings to an account or set of -- accounts, with a running total. Postings may be actual postings, or -- virtual postings aggregated over a reporting interval. type RegisterReport = [RegisterReportItem] -- | The data for a single register report line item, representing one -- posting. type RegisterReportItem = (Maybe (Day, String), Posting, MixedAmount) -- | Print a register report. register :: [Opt] -> [String] -> Journal -> IO () -- | Get a register report with the specified options for this journal. registerReport :: [Opt] -> FilterSpec -> Journal -> RegisterReport -- | Render a register report as plain text suitable for console output. registerReportAsText :: [Opt] -> RegisterReport -> String showPostingWithBalanceForVty :: Bool -> Posting -> MixedAmount -> String tests_Register :: Test -- | A history-aware add command to help with data entry. module Hledger.Cli.Add -- | Read transactions from the terminal, prompting for each field, and -- append them to the journal file. If the journal came from stdin, this -- command has no effect. add :: [Opt] -> [String] -> Journal -> IO () -- | Read a number of transactions from the command line, prompting, -- validating, displaying and appending them to the journal file, until -- end of input (then raise an EOF exception). Any command-line arguments -- are used as the first transaction's description. getAndAddTransactions :: Journal -> [Opt] -> [String] -> Day -> InputT IO () -- | Read a transaction from the command line, with history-aware -- prompting. getTransaction :: Journal -> [Opt] -> [String] -> Day -> InputT IO (Transaction, Day) -- | Read postings from the command line until . is entered, using any -- provided historical postings and the journal context to guess -- defaults. getPostings :: JournalContext -> (AccountName -> Bool) -> Maybe [Posting] -> [Posting] -> InputT IO [Posting] -- | Prompt for and read a string value, optionally with a default value -- and a validator. A validator causes the prompt to repeat until the -- input is valid. May also raise an EOF exception if control-d is -- pressed. askFor :: String -> Maybe String -> Maybe (String -> Bool) -> InputT IO String -- | Append this transaction to the journal's file, and to the journal's -- transaction list. journalAddTransaction :: Journal -> [Opt] -> Transaction -> IO Journal -- | Append data to a journal file; or if the file is -, dump it to -- stdout. appendToJournalFile :: FilePath -> String -> IO () -- | Convert a string of journal data into a register report. registerFromString :: String -> IO String -- | Return a similarity measure, from 0 to 1, for two strings. This is -- Simon White's letter pairs algorithm from -- http:www.catalysoft.comarticlesStrikeAMatch.html with a -- modification for short strings. compareStrings :: String -> String -> Double compareDescriptions :: [Char] -> [Char] -> Double transactionsSimilarTo :: Journal -> [String] -> String -> [(Double, Transaction)] runInteraction :: Journal -> InputT IO a -> IO a type CompletionCache = [AccountName] completionCache :: Journal -> CompletionCache accountCompletion :: CompletionCache -> CompletionFunc IO -- | Print some statistics for the journal. module Hledger.Cli.Stats -- | Print various statistics for the journal. stats :: [Opt] -> [String] -> Journal -> IO () showLedgerStats :: [Opt] -> [String] -> Ledger -> Day -> DateSpan -> String -- | The Commands package defines all the commands offered by the hledger -- application, like "register" and "balance". This module exports all -- the commands; you can also import individual modules if you prefer. module Hledger.Cli.Commands tests_Hledger_Commands :: Test -- | This module contains hledger's unit tests. These are built in to -- hledger, and can be run at any time by doing hledger test -- (or, with a few more options, by doing make unittest in the -- hledger source tree.) -- -- Other kinds of tests: -- -- hledger's functional tests are a set of shell/command-line tests -- defined by .test files in the tests/ subdirectory. These can be run by -- doing make functest in the hledger source tree. -- -- hledger's doctests are shell tests defined in literal blocks in -- haddock documentation in the source, run by doing make -- doctest in the hledger source tree. are They hardly used, but -- here is an example: -- --
--   $ binhledger -f datasample.journal balance o
--                     $1  expenses:food
--                    $-2  income
--                    $-1    gifts
--                    $-1    salary
--   --------------------
--                    $-1
--   
module Hledger.Cli.Tests -- | Run unit tests. runtests :: [Opt] -> [String] -> IO () -- | unit tests, augmenting the ones defined in each module. Where that is -- inconvenient due to import cycles or whatever, we define them here. tests :: Test journalWithAmounts :: [String] -> Journal -- | hledger - a ledger-compatible accounting tool. Copyright (c) 2007-2010 -- Simon Michael simon@joyful.com Released under GPL version 3 or -- later. -- -- hledger is a partial haskell clone of John Wiegley's ledger. It -- generates ledger-compatible register & balance reports from a -- plain text journal, and demonstrates a functional implementation of -- ledger. For more information, see http://hledger.org . -- -- This module provides the main function for the hledger command-line -- executable. It is exposed here so that it can be imported by eg -- benchmark scripts. -- -- You can use the command line: -- --
--   $ hledger --help
--   
-- -- or ghci: -- --
--   $ ghci hledger
--   > j <- readJournalFile "data/sample.journal"
--   > register [] ["income","expenses"] j
--   2008/01/01 income               income:salary                   $-1          $-1
--   2008/06/01 gift                 income:gifts                    $-1          $-2
--   2008/06/03 eat & shop           expenses:food                    $1          $-1
--                                   expenses:supplies                $1            0
--   > balance [Depth "1"] [] l
--                    $-1  assets
--                     $2  expenses
--                    $-2  income
--                     $1  liabilities
--   > l <- myLedger
--   > t <- myTimelog
--   
-- -- See Hledger.Data.Ledger for more examples. module Hledger.Cli.Main main :: IO ()