HORIZON HASKELLDocslts/ghc-10.0.x8c2f8e82026-10-19Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8c2f8e8 · 2026-10-19

Modulehledger-1.52.4GHC2021

Hledger.Cli

This is the root module of the hledger package, providing hledger's command-line interface. The main function, commands, command-line options, and utilities useful to other hledger command-line programs are exported. It also re-exports hledger-lib:Hledger and cmdargs:System.Concole.CmdArgs.Explicit

See also:

hledger is a Haskell rewrite of John Wiegley's "ledger". It generates financial reports from a plain text general journal. You can use the command line:

$ hledger

or ghci:

$ make ghci
ghci> Right j <- runExceptT $ readJournalFile definputopts "examples/sample.journal"  -- or: j <- defaultJournal
ghci> :t j
j :: Journal
ghci> stats defcliopts j
Main file                : examples/sample.journal
Included files           : 
Transactions span        : 2008-01-01 to 2009-01-01 (366 days)
Last transaction         : 2008-12-31 (733772 days from now)
Transactions             : 5 (0.0 per day)
Transactions last 30 days: 0 (0.0 per day)
Transactions last 7 days : 0 (0.0 per day)
Payees/descriptions      : 5
Accounts                 : 8 (depth 3)
Commodities              : 1 ($)
Market prices            : 0 ()

Run time (throughput)    : 1695276900.00s (0 txns/s)
ghci> balance defcliopts j
                  $1  assets:bank:saving
                 $-2  assets:cash
                  $1  expenses:food
                  $1  expenses:supplies
                 $-1  income:gifts
                 $-1  income:salary
                  $1  liabilities:debts
--------------------
                   0  
ghci> 

etc.

SPDX-License-Identifier: GPL-3.0-or-later Copyright (c) 2007-2025 (each year in this range) Simon Michael simon@joyful.com and contributors.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

  • 150 types
  • 9 classes
  • 1166 values
  • Packagehledger-1.52.4
  • Exports1328
  • LanguageGHC2021
  • LicenceGPL-3.0-or-later
  • SourceCli.hs
valuemain :: IO ()
#

hledger CLI's main procedure.

Here we will parse the command line, read any config file, and search for hledger-* addon executables in the user's PATH, then choose the appropriate builtin operation or addon operation to run, then run it in the right way, usually reading input data (eg a journal) first.

When making a CLI usable and robust with main command, builtin subcommands, various kinds of addon commands, and config files that add general and command-specific options, while balancing circular dependencies, environment, idioms, legacy, and libraries with their own requirements and limitations: things get crazy, and there is a tradeoff against complexity and bug risk. We try to provide the most intuitive, expressive and robust CLI that's feasible while keeping the CLI processing below sufficiently comprehensible, troubleshootable, and tested. It's an ongoing quest. See also: Hledger.Cli.CliOptions, cli.test, addons.test, --debug and --debug=8.

Probably the biggest source of complexity here is that cmdargs can't parse a command line containing undeclared flags, but this arises often with our addon commands and builtin/custom commands which haven't implemented all options, so we have to work hard to work around this. https://github.com/ndmitchell/cmdargs/issues/36 is the wishlist issue; implementing that would simplify hledger's CLI processing a lot.

valuemainmode :: [Name] -> Mode RawOpts
#

The overall cmdargs mode describing hledger's command-line options and subcommands. The names of known addons are provided so they too can be recognised as commands.

valueargsToCliOpts :: [String] -> [String] -> IO CliOpts
#

A helper for addons/scripts: this parses hledger CliOpts from these command line arguments and add-on command names, roughly how hledger main does. If option parsing/validating fails, it exits the program with usageError. Unlike main, this does not read extra args from a config file or search for addons; to do those things, mimic the code in main for now.

Re-exports

1283 declarations
valuecharWidth :: Char -> Int
#

Returns width of a character in a monospace font: 0 for a combining character, 1 for a regular character, 2 for an East Asian wide character. Ambiguous characters are treated as width 1.

valuetrace :: String -> a -> a
#

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 and outputs the message to stderr. Depending on your terminal (settings), they may or may not be mixed.

Example2 expressions
let x = 123; f = showtrace ("calling f with x = " ++ show x) (f x)calling f with x = 123"123"

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.

valuetraceIO :: String -> IO ()
#

The traceIO function outputs the trace message from the IO monad. This sequences the output with respect to other IO actions.

valuetraceShowId :: Show a => a -> a
#

Like traceShow but returns the shown value instead of a third value.

Example1 expression
traceShowId (1+2+3, "hello" ++ "world")(6,"helloworld")(6,"helloworld")

Derive 1. an account tree and 2. each account's total exclusive and inclusive changes associated with dates from a list of postings and a function for associating a date to each posting (usually representing the start dates of report subperiods). This is the core of the balance command (and of *ledger). The accounts are returned as a tree.

valueaccountTree :: Monoid a => AccountName -> [AccountName] -> Account a
#

Convert a list of account names to a tree of Account objects, with just the account names filled in and an empty balance. A single root account with the given name is added.

Derive 1. an account tree and 2. each account's total exclusive and inclusive changes associated with dates from a list of postings and a function for associating a date to each posting (usually representing the start dates of report subperiods). This is the core of the balance command (and of *ledger). The accounts are returned as a list in flattened tree order, and also reference each other as a tree. (The first account is the root of the tree.)

Remove subaccounts below the specified depth, aggregating their balance at the depth limit (accounts at the depth limit will have any sub-balances merged into their exclusive balance). If the depth is Nothing, return the original accounts

valueflattenAccounts :: Account a -> [Account a]
#

Flatten an account tree into a list, which is sometimes convenient. Note since accounts link to their parents/subs, the tree's structure remains intact and can still be used. It's a tree/list!

Sort account names by the order in which they were declared in the journal, at each level of the account tree (ie within each group of siblings). Undeclared accounts are sorted last and alphabetically. This is hledger's default sort for reports organised by account. The account list is converted to a tree temporarily, adding any missing parents; these can be kept (suitable for a tree-mode report) or removed (suitable for a flat-mode report).

Sort each group of siblings in an account tree by declaration order, then account name. So each group will contain first the declared accounts, in the same order as their account directives were parsed, and then the undeclared accounts, sorted by account name.

Remove some number of account name components from the front of the account name. If the special "unbudgeted" top-level account is present, it is preserved and dropping affects the rest of the account name.

The level (depth) of an account name.

Example3 expressions
accountNameLevel ""  -- special case0accountNameLevel "assets"1accountNameLevel "assets:cash"2

Regular expressions matching common English top-level account names, used as a fallback when account types are not declared.

Clip an account name to a given DepthSpec, first checking whether it matches any of the regular expressions controlling depth. If so, clip to the depth of the most specific of those matches, i.e. the one which starts matching the latest as you progress up the parents of the account. Otherwise clip to the flat depth provided, or return the full name if Nothing.

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.

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!
valueescapeName :: AccountName -> Text
#

Escape an AccountName for use within a regular expression. >>> putStr . T.unpack $ escapeName "First?!#$*?$(*) !^#*? %)*!#" First?!#$*?$\* !^#*? %)*!#

Sorted unique account names implied by these account names, ie these plus all their parent accounts up to the root. Eg: ["a:b:c","d:e"] -> ["a","a:b","a:b:c","d","d:e"]

Calculate the depth to which an account name should be clipped for a given DepthSpec.

First checking whether the account name matches any of the regular expressions controlling depth. If so, clip to the depth of the most specific of those matches, i.e. the one which starts matching the latest as you progress up the parents of the account. Otherwise clip to the flat depth provided, or return the full name if Nothing.

A top-level account prefixed to some accounts in budget reports. Defined here so it can be ignored by accountNameDrop.

valueamountCost :: Amount -> Amount
#

Convert a amount to its total cost in another commodity, using its attached cost amount if it has one. Notes:

  • cost amounts must be MixedAmounts with exactly one component Amount (or there will be a runtime error XXX)

  • cost amounts should be positive in the Journal (though this is currently not enforced)

valueamountIsZero :: Amount -> Bool
#

Is this Amount (and its total cost, if it has one) exactly zero, ignoring its display precision ?

valueamountLooksZero :: Amount -> Bool
#

Do this Amount and (and its total cost, if it has one) appear to be zero when rendered with its display precision ? The display precision should usually have a specific value here; if unset, it will be treated like NaturalPrecision.

Increase an amount's display precision, if needed, to enough decimal places to show it exactly (showing all significant decimal digits, without trailing zeros). If the amount's display precision is unset, it will be treated as precision 0.

We often want to display "infinite decimal" amounts rounded to some readable number of digits, while still displaying amounts with a large but "non infinite" number of decimal digits (eg 10 or 100 or 200 digits) in full. This helper is like amountSetFullPrecision, but with some refinements:

  1. A maximum display precision can be specified, setting a hard upper limit.

  2. If no limit is specified, and the internal precision is the maximum (255), indicating an infinite decimal, display precision is set to a smaller default (8).

This function always sets an explicit display precision (ie, Precision n).

valueamounts :: MixedAmount -> [Amount]
#

Get a mixed amount's component amounts, with some cleanups. The following descriptions are old and possibly wrong:

  • amounts in the same commodity are combined unless they have different costs or total costs

  • multiple zero amounts, all with the same non-null commodity, are replaced by just the last of them, preserving the commodity and amount style (all but the last zero amount are discarded)

  • multiple zero amounts with multiple commodities, or no commodities, are replaced by one commodity-less zero amount

  • an empty amount list is replaced by one commodity-less zero amount

  • the special "missing" mixed amount remains unchanged

Get a mixed amount's component amounts, with some cleanups. This is a new version of amounts, with updated descriptions and optimised for print to show commodityful zeros.

  • If it contains the "missing amount" marker, only that is returned (discarding any additional amounts).

  • Or if it contains any non-zero amounts, only those are returned (discarding any zeroes).

  • Or if it contains any zero amounts (possibly more than one, possibly in different commodities), all of those are returned.

  • Otherwise the null amount is returned.

valueamountsRaw :: MixedAmount -> [Amount]
#

Get a mixed amount's component amounts without normalising zero and missing amounts. This is used for JSON serialisation, so the order is important. In particular, we want the Amounts given in the order of the MixedAmountKeys, i.e. lexicographically first by commodity, then by cost commodity, then by unit cost from most negative to most positive.

Given a list of amounts, in parse order (roughly speaking; see journalStyleInfluencingAmounts), build a map from their commodity names to standard commodity display formats. Can return an error message eg if inconsistent number formats are found.

Though, these amounts may have come from multiple files, so we shouldn't assume they use consistent number formats. Currently we don't enforce that even within a single file, and this function never reports an error.

valuecshowAmount :: Amount -> String
#

Colour version. For a negative amount, adds ANSI codes to change the colour, currently to hard-coded red.

cshowAmount = wbUnpack . showAmountB def{displayColour=True}

The fallback display precision used when showing amounts representing an infinite decimal.

Return an unnormalised MixedAmount containing just the amounts in the requested commodity from the original mixed amount.

The result will contain at least one Amount of the requested commodity, even if the original mixed amount did not (with quantity zero in that case, and this would be discarded when the mixed amount is next normalised).

The result can contain more than one Amount of the requested commodity, eg because there were several with different costs, or simply because the original mixed amount was was unnormalised.

Like defaultFmt but show zero amounts with commodity symbol and styling, like non-zero amounts.

valuegetAmounts :: Amount -> [Amount]
#

Get an amount and its attached cost amount if any. Returns one or two amounts.

valueinvertAmount :: Amount -> Amount
#

Invert an amount (replace its quantity q with 1/q). The amount's transacted price, if any, is not changed. An amount with zero quantity is left unchanged.

Does this MixedAmount include the "missing amount" marker ? Note: currently does not test for equality with missingmixedamt, instead it looks for missingamt among the Amounts. missingamt should always be alone, but detect it even if not.

valuemaIsNonZero :: MixedAmount -> Bool
#

Is this mixed amount non-zero, ignoring its display precision?

A convenient alias for not . mixedAmountIsZero.

valuemaIsZero :: MixedAmount -> Bool
#

Is this mixed amount exactly zero, ignoring its display precision?

A convenient alias for mixedAmountIsZero.

A (slightly more) machine-readable amount format; like oneLineNoCostFmt but don't show digit group marks.

valuemissingamt :: Amount
#

A special amount used as a marker, meaning "no explicit amount provided here, infer it when needed". It is nullamt with commodity symbol AUTO.

A special mixed amount used as a marker, meaning "no explicit amount provided here, infer it when needed".

In each component amount, increase the display precision sufficiently to render it exactly if possible, but not more than the given max precision, and if no max precision is given and the amount has infinite decimals, limit display precision to a hard-coded smaller number (8). See amountSetFullPrecisionUpTo.

valuenullamt :: Amount
#

The empty simple amount - a zero with no commodity symbol or cost and the default amount display style.

Set an amount's internal decimal precision as well as its display precision. This rounds or pads its Decimal quantity to the specified number of decimal places. Rounding is done with Data.Decimal's default roundTo function: "If the value ends in 5 then it is rounded to the nearest even value (Banker's Rounding)".

valueshowAmount :: Amount -> String
#

Render an amount using its display style and the default amount format. Zero-equivalent amounts are shown as just "0". The special "missing" amount is shown as the empty string.

Render an amount using its display style and the given amount format, as a builder for efficiency. (This can be converted to a Text with wbToText or to a String with wbUnpack). The special "missing" amount is displayed as the empty string.

Get a string representation of an amount for debugging, appropriate to the current debug level. 9 shows maximum detail.

Like showAmount, but show a zero amount's commodity if it has one.

showAmountWithZeroCommodity = wbUnpack . showAmountB defaultFmt{displayZeryCommodity=True}

Get the string representation of an amount, without any @ cost.

showAmountWithoutCost = wbUnpack . showAmountB noCostFmt

Render a mixed amount using its amount display styles and the default amount format, after normalising it (to at most one amount in each of its commodities). See showMixedAmountB for special cases.

Render a mixed amount using its amount display styles and the given amount format, as a builder for efficiency. (This can be converted to a Text with wbToText or to a String with wbUnpack).

Warning: this (and its showMixedAmount aliases above) basically assumes amounts have no costs. It can show misleading costs or not show costs which are there.

If a maximum width is given then:

  • If displayed on one line, it will display as many Amounts as can fit in the given width, and further Amounts will be elided. There will always be at least one amount displayed, even if this will exceed the requested maximum width.

  • If displayed on multiple lines, any Amounts longer than the maximum width will be elided.

Zero-equivalent amounts are shown as just "0".

The special "missing" amount is shown as the empty string (?).

Like showMixedAmountOneLineWithoutCost, but show at most the given width, with an elision indicator if there are more. With a True argument, adds ANSI codes to show negative amounts in red. See showMixedAmountB for special cases.

Helper for showMixedAmountB (and postingAsLines, ...) to show a list of Amounts on multiple lines. This returns the list of WideBuilders: one for each Amount, and padded/elided to the appropriate width. This does not honour displayOneLine; all amounts will be displayed as if displayOneLine were False.

Get the string representation of a mixed amount, without showing any costs. With a True argument, adds ANSI codes to show negative amounts in red. See showMixedAmountB for special cases.

Unify a MixedAmount to a single commodity value if possible. This consolidates amounts of the same commodity and discards zero amounts; but this one insists on simplifying to a single commodity, and will return Nothing if this is not possible.

Balance this isolated transaction, ensuring that its postings (and its balanced virtual postings) sum to 0, by inferring a missing amount or conversion price(s) if needed. Or if balancing is not possible, because the amounts don't sum to 0 or because there's more than one missing amount, return an error message.

Note this is not as accurate as balanceTransactionInJournal, which considers the whole journal when calculating balance assignments and balance assertions.

Infer any missing amounts and/or conversion costs (as needed to balance transactions and satisfy balance assignments); and check that all transactions are balanced; and (optional) check that all balance assertions pass. Or, return an error message (just the first error encountered).

Assumes journalStyleAmounts has been called, since amount styles affect transaction balancing.

This does multiple things at once because amount inferring, balance assignments, balance assertions and posting dates are interdependent.

valuecurrencyCodeToSymbol :: CurrencyCode -> Maybe CurrencySymbol
#

Look for a currency symbol corresponding to this ISO 4217 currency code.

Example1 expression
currencyCodeToSymbol "CZK"  -- Just "Kč"Just "K\269"
valuecurrencySymbolToCode :: CurrencySymbol -> Maybe CurrencyCode
#

Look for a ISO 4217 currency code corresponding to this currency symbol.

Example2 expressions
currencySymbolToCode ""NothingcurrencySymbolToCode "$"Just "USD"
valuedaysSpan :: [Day] -> DateSpan
#

Calculate the minimal DateSpan containing all of the given Days (in the usual exclusive-end-date sense: beginning on the earliest, and ending on the day after the latest).

valuefixSmartDate :: Day -> SmartDate -> EFDay
#

Convert a SmartDate to a specific date using the provided reference date. This date will be exact or flexible depending on whether the day was specified exactly. (Missing least-significant parts produces a flex date.)

Examples:
Example32 expressions
:set -XOverloadedStringslet t = fixSmartDateStr (fromGregorian 2008 11 26)t "0000-01-01""0000-01-01"t "1999-12-02""1999-12-02"t "1999.12.02""1999-12-02"t "1999/3/2""1999-03-02"t "19990302""1999-03-02"t "2008/2""2008-02-01"t "0020/2""0020-02-01"t "1000""1000-01-01"t "4/2""2008-04-02"t "2""2008-11-02"t "January""2008-01-01"t "feb""2008-02-01"t "today""2008-11-26"t "yesterday""2008-11-25"t "tomorrow""2008-11-27"t "this day""2008-11-26"t "last day""2008-11-25"t "next day""2008-11-27"t "this week"  -- last monday"2008-11-24"t "last week"  -- previous monday"2008-11-17"t "next week"  -- next monday"2008-12-01"t "this month""2008-11-01"t "last month""2008-10-01"t "next month""2008-12-01"t "this quarter""2008-10-01"t "last quarter""2008-07-01"t "next quarter""2009-01-01"t "this year""2008-01-01"t "last year""2007-01-01"t "next year""2009-01-01"

refdate is Wednesday, 2008-11-26 >>> t "last wednesday" "2008-11-19" >>> t "this wednesday" "2008-12-03" >>> t "next wednesday" "2008-12-03" >>> t "last january" "2008-01-01" >>> t "this january" "2009-01-01" >>> t "next january" "2009-01-01" >>> t "last november" "2007-11-01" >>> t "this november" "2009-11-01" >>> t "next november" "2009-11-01"

Example5 expressions
t "in 5 days""2008-12-01"t "in 7 months""2009-06-01"t "in -2 weeks""2008-11-10"t "1 quarter ago""2008-07-01"t "1 week ahead""2008-12-01"
valuefixSmartDateStr :: Day -> Text -> Text
#

Convert a smart date string to an explicit yyyy/mm/dd string using the provided reference date, or raise an error.

valueisEmptySpan :: DateSpan -> Bool
#

Is this an empty span, ie closed with the end date on or before the start date ?

Select the DateSpan containing a given Day, if any, from a given list of DateSpans.

If the DateSpans are non-overlapping, this returns the unique containing DateSpan, if it exists. If the DateSpans are overlapping, it will return the containing DateSpan with the latest start date, and then latest end date.

valuenextNthWeekdayOfMonth :: Int -> WeekDay -> Day -> Day
#

Find the next occurrence of some nth weekday of a month, on or after the given date d.

Example4 expressions
let wed22nd = fromGregorian 2017 11 22nextNthWeekdayOfMonth 3 3 wed22nd  -- next third wednesday2017-12-20nextNthWeekdayOfMonth 4 3 wed22nd  -- next fourth wednesday2017-11-22nextNthWeekdayOfMonth 5 3 wed22nd  -- next fifth wednesday2017-11-29
valuenextmonthandday :: Month -> MonthDay -> Day -> Day
#

Find the next occurrence of the specified month and day of month, on or after the given date. The month should be 1-12 and the day of month should be 1-31, or an error will be raised.

Example4 expressions
let wed22nd = fromGregorian 2017 11 22nextmonthandday 11 21 wed22nd2018-11-21nextmonthandday 11 22 wed22nd2017-11-22nextmonthandday 11 23 wed22nd2017-11-23
valuenextnthdayofmonth :: MonthDay -> Day -> Day
#

Find the next occurrence of the specified day of month, on or after the given date. The day of month should be 1-31, or an error will be raised.

Example4 expressions
let wed22nd = fromGregorian 2017 11 22nextnthdayofmonth 21 wed22nd2017-12-21nextnthdayofmonth 22 wed22nd2017-11-22nextnthdayofmonth 23 wed22nd2017-11-23

For given date d find week-long interval that starts on nth day of week and covers it.

Examples: 2017-11-22 is Wed. Week-long intervals that cover it and start on Mon, Tue or Wed will start in the same week. However intervals that start on Thu or Fri should start in prev week: >>> let wed22nd = fromGregorian 2017 11 22 >>> nthdayofweekcontaining 1 wed22nd 2017-11-20 >>> nthdayofweekcontaining 2 wed22nd 2017-11-21 >>> nthdayofweekcontaining 3 wed22nd 2017-11-22 >>> nthdayofweekcontaining 4 wed22nd 2017-11-16 >>> nthdayofweekcontaining 5 wed22nd 2017-11-17

valueparsedate :: String -> Maybe Day
#

A simple date parsing helper: parses these YMD date string formats: `YYYY-MM-DD`, `YYYYMMDD`, YYYY.MM.DD or YYYYMMDD, where the month and day each have two digits and the year has one or more.

This is different from the Smart Dates of the CLI and period expressions ("smartdate", below) and not quite the same as the Simple Dates of the journal ("datep", in Hledger.Read.Common). It's mainly for internal or interactive use, eg when debugging - but currently is also used in a few user-facing places, such as: parsing --value's argument, parsing .latest files, and parsing hledger's --version output (which uses unseparated dates).

Unseparated dates were added in 2025 for convenience. Note it means many integers will now parse successfully.

Example7 expressions
parsedate "2008/02/03"Just 2008-02-03parsedate "2008/02/03/"Nothingparsedate "2008/02/30"Nothingparsedate "2025-01-01"Just 2025-01-01parsedate "2025.01.01"Just 2025-01-01parsedate "20250101"Just 2025-01-01parsedate "00101"Just 0000-01-01

Parse a period expression, specifying a date span and optionally a reporting interval. Requires a reference "today" date for resolving any relative start/end dates (only; it is not needed for parsing the reporting interval).

Example26 expressions
let p = parsePeriodExpr (fromGregorian 2008 11 26)p "from Aug to Oct"Right (NoInterval,DateSpan 2008-08-01..2008-09-30)p "aug to oct"Right (NoInterval,DateSpan 2008-08-01..2008-09-30)p "2009q2"Right (NoInterval,DateSpan 2009Q2)p "Q3"Right (NoInterval,DateSpan 2008Q3)p "every 3 days in Aug"Right (Days 3,DateSpan 2008-08)p "daily from aug"Right (Days 1,DateSpan 2008-08-01..)p "every week to 2009"Right (Weeks 1,DateSpan ..2008-12-31)p "every 2nd day of month"Right (MonthDay 2,DateSpan ..)p "every 2nd day"Right (MonthDay 2,DateSpan ..)p "every 2nd day 2009.."Right (MonthDay 2,DateSpan 2009-01-01..)p "every 2nd day 2009-"Right (MonthDay 2,DateSpan 2009-01-01..)p "every 29th Nov"Right (MonthAndDay 11 29,DateSpan ..)p "every 29th nov ..2009"Right (MonthAndDay 11 29,DateSpan ..2008-12-31)p "every nov 29th"Right (MonthAndDay 11 29,DateSpan ..)p "every Nov 29th 2009.."Right (MonthAndDay 11 29,DateSpan 2009-01-01..)p "every 11/29 from 2009"Right (MonthAndDay 11 29,DateSpan 2009-01-01..)p "every 11/29 since 2009"Right (MonthAndDay 11 29,DateSpan 2009-01-01..)p "every 2nd Thursday of month to 2009"Right (NthWeekdayOfMonth 2 4,DateSpan ..2008-12-31)p "every 1st monday of month to 2009"Right (NthWeekdayOfMonth 1 1,DateSpan ..2008-12-31)p "every tue"Right (DaysOfWeek [2],DateSpan ..)p "every 2nd day of week"Right (DaysOfWeek [2],DateSpan ..)p "every 2nd day of month"Right (MonthDay 2,DateSpan ..)p "every 2nd day"Right (MonthDay 2,DateSpan ..)p "every 2nd day 2009.."Right (MonthDay 2,DateSpan 2009-01-01..)p "every 2nd day of month 2009.."Right (MonthDay 2,DateSpan 2009-01-01..)
valueprevNthWeekdayOfMonth :: Int -> WeekDay -> Day -> Day
#

Find the previous occurrence of some nth weekday of a month, on or before the given date d.

Example3 expressions
let wed22nd = fromGregorian 2017 11 22prevNthWeekdayOfMonth 4 3 wed22nd2017-11-22prevNthWeekdayOfMonth 5 2 wed22nd2017-10-31
valueshowDateSpan :: DateSpan -> Text
#

Render a datespan as a display string, abbreviating into a compact form if possible. Warning, hides whether dates are Exact or Flex.

Parse a date in any of the formats allowed in Ledger's period expressions, and some others. Assumes any text in the parse stream has been lowercased. Returns a SmartDate, to be converted to a full date later (see fixSmartDate).

Examples:

2004                                        (start of year, which must have 4+ digits)
2004/10                                     (start of month, which must be 1-12)
2004/10/1                                   (exact date, day must be 1-31)
10/1                                        (month and day in current year)
21                                          (day in current month)
october, oct                                (start of month in current year)
yesterday, today, tomorrow                  (-1, 0, 1 days from today)
last/this/next day/week/month/quarter/year  (-1, 0, 1 periods from the current period)
last/this/next monday/mon                   (the previous or next named weekday; this=next)
last/next january/jan                       (previous or next start of named month; this disallowed to avoid confusion)
in n days/weeks/months/quarters/years       (n periods from the current period)
n days/weeks/months/quarters/years ago      (-n periods from the current period)
20181201                                    (8 digit YYYYMMDD with valid year month and day)
201812                                      (6 digit YYYYMM with valid year and month)

Note malformed digit sequences might give surprising results:

201813                                      (6 digits with an invalid month is parsed as start of 6-digit year)
20181301                                    (8 digits with an invalid month is parsed as start of 8-digit year)
20181232                                    (8 digits with an invalid day gives an error)
201801012                                   (9+ digits beginning with a valid YYYYMMDD gives an error)

Eg:

YYYYMMDD is parsed as year-month-date if those parts are valid (>=4 digits, 1-12, and 1-31 respectively): >>> parsewith (smartdate <* eof) "20181201" Right (SmartCompleteDate 2018-12-01)

YYYYMM is parsed as year-month-01 if year and month are valid: >>> parsewith (smartdate <* eof) "201804" Right (SmartAssumeStart 2018 (Just 4))

With an invalid month, it's parsed as a year: >>> parsewith (smartdate <* eof) "201813" Right (SmartAssumeStart 201813 Nothing)

A 9+ digit number beginning with valid YYYYMMDD gives an error: >>> parsewith (smartdate <* eof) "201801012" Left (...)

Big numbers not beginning with a valid YYYYMMDD are parsed as a year: >>> parsewith (smartdate <* eof) "201813012" Right (SmartAssumeStart 201813012 Nothing)

Fill any unspecified dates in the first span with the dates from the second one (if specified there). Sort of a one-way spanIntersect. This one can create an invalid span that'll always be empty.

Example1 expression
:{ DateSpan (Just $ Exact $ fromGregorian 2024 1 1) Nothing `spanDefaultsFrom` DateSpan (Just $ Exact $ fromGregorian 2024 1 1) (Just $ Exact $ fromGregorian 2024 1 2):}DateSpan 2024-01-01
Example1 expression
:{ DateSpan (Just $ Exact $ fromGregorian 2025 1 1) Nothing `spanDefaultsFrom` DateSpan (Just $ Exact $ fromGregorian 2024 1 1) (Just $ Exact $ fromGregorian 2024 1 2):}DateSpan 2025-01-01..2024-01-01

Extend the definite start/end dates of the first span, if needed, to include the definite start/end dates of the second span. Andor, replace open startend dates in the first span with definite start/end dates from the second. Unlike spanUnion, open start/end dates in the second are ignored.

Example9 expressions
ys2024 = fromGregorian 2024 01 01ys2025 = fromGregorian 2025 01 01to2024 = DateSpan Nothing               (Just $ Exact ys2024)all2024 = DateSpan (Just $ Exact ys2024) (Just $ Exact ys2025)partof2024 = DateSpan (Just $ Exact $ fromGregorian 2024 03 01) (Just $ Exact $ fromGregorian 2024 09 01)spanExtend to2024 all2024DateSpan 2024spanExtend all2024 to2024DateSpan 2024spanExtend partof2024 all2024DateSpan 2024spanExtend all2024 partof2024DateSpan 2024

Calculate the intersection of two datespans.

For non-intersecting spans, gives an empty span beginning on the second's start date: >>> DateSpan (Just $ Flex $ fromGregorian 2018 01 01) (Just $ Flex $ fromGregorian 2018 01 03) spanIntersect DateSpan (Just $ Flex $ fromGregorian 2018 01 03) (Just $ Flex $ fromGregorian 2018 01 05) DateSpan 2018-01-03..2018-01-02

Calculate the union of two datespans. If either span is open-ended, the union will be too.

Example6 expressions
ys2024 = fromGregorian 2024 01 01ys2025 = fromGregorian 2025 01 01to2024 = DateSpan Nothing               (Just $ Exact ys2024)in2024 = DateSpan (Just $ Exact ys2024) (Just $ Exact ys2025)spanUnion to2024 in2024DateSpan ..2024-12-31spanUnion in2024 to2024DateSpan ..2024-12-31

A smarter version of spanDefaultsFrom that avoids creating invalid spans ending before they begin. Kept separate for now to reduce risk.

Example1 expression
:{ DateSpan (Just $ Exact $ fromGregorian 2025 1 1) Nothing `spanValidDefaultsFrom` DateSpan (Just $ Exact $ fromGregorian 2024 1 1) (Just $ Exact $ fromGregorian 2024 1 2):}DateSpan 2025-01-01..
valuespansSpan :: [DateSpan] -> DateSpan
#

Get overall span enclosing multiple sequentially ordered spans. The start and end date will be exact or flexible depending on the first span's start date and last span's end date.

valueyearp :: TextParser m Integer
#

Parse a year number from a Text, making sure that at least four digits are used.

Construct a DayPartition from a non-empty list of period boundary dates (start dates plus a final exclusive end date).

Example1 expression
boundariesToDayPartition (fromGregorian 2025 01 01 :| [fromGregorian 2025 02 01])DayPartition {dayPartitionToPeriodData = PeriodData{ pdpre = 2024-12-31, pdperiods = fromList [(2025-01-01,2025-01-31)]}}

Find the start and end dates of the period within a DayPartition which contains a given day. If the day is after the end of the last period, it is assumed to be within the last period. If the day is before the start of the first period (ie, in the historical period), only the historical period's end date is returned.

Get the natural start for the given interval that falls on or before the given day, when applicable. Works for Weeks, Months, Quarters, Years, eg.

Split a DateSpan into a DayPartition consisting of consecutive exact spans of the specified Interval, or Nothing if the span is invalid. If no interval is specified, the original span is returned. If the original span is the null date span, ie unbounded, Nothing is returned. If the original span is empty, eg if the end date is <= the start date, Nothing is returned.

Date adjustment

Some intervals respect the "adjust" flag (years, quarters, months, weeks, every Nth weekday of month seem to be the ones that need it). This will move the start date earlier, if needed, to the previous natural interval boundary (first of year, first of quarter, first of month, monday, previous Nth weekday of month). Related: #1982 #2218

The end date is always moved later if needed to the next natural interval boundary, so that the last period is the same length as the others.

Examples
Example14 expressions
let t i y1 m1 d1 y2 m2 d2 = fmap dayPartitionToNonEmpty . splitSpan True i $ DateSpan (Just $ Flex $ fromGregorian y1 m1 d1) (Just $ Flex $ fromGregorian y2 m2 d2)t NoInterval 2008 01 01 2009 01 01Just ((2008-01-01,2008-12-31) :| [])t (Quarters 1) 2008 01 01 2009 01 01Just ((2008-01-01,2008-03-31) :| [(2008-04-01,2008-06-30),(2008-07-01,2008-09-30),(2008-10-01,2008-12-31)])splitSpan True (Quarters 1) nulldatespanNothingt (Days 1) 2008 01 01 2008 01 01  -- an empty datespanNothingt (Quarters 1) 2008 01 01 2008 01 01Nothingt (Months 1) 2008 01 01 2008 04 01Just ((2008-01-01,2008-01-31) :| [(2008-02-01,2008-02-29),(2008-03-01,2008-03-31)])t (Months 2) 2008 01 01 2008 04 01Just ((2008-01-01,2008-02-29) :| [(2008-03-01,2008-04-30)])t (Weeks 1) 2008 01 01 2008 01 15Just ((2007-12-31,2008-01-06) :| [(2008-01-07,2008-01-13),(2008-01-14,2008-01-20)])t (Weeks 2) 2008 01 01 2008 01 15Just ((2007-12-31,2008-01-13) :| [(2008-01-14,2008-01-27)])t (MonthDay 2) 2008 01 01 2008 04 01Just ((2008-01-02,2008-02-01) :| [(2008-02-02,2008-03-01),(2008-03-02,2008-04-01)])t (NthWeekdayOfMonth 2 4) 2011 01 01 2011 02 15Just ((2010-12-09,2011-01-12) :| [(2011-01-13,2011-02-09),(2011-02-10,2011-03-09)])t (DaysOfWeek [2]) 2011 01 01 2011 01 15Just ((2010-12-28,2011-01-03) :| [(2011-01-04,2011-01-10),(2011-01-11,2011-01-17)])t (MonthAndDay 11 29) 2012 10 01 2013 10 15Just ((2012-11-29,2013-11-28) :| [])

Given an account name and its account directive, and a problem tag within the latter: render it as a megaparsec-style excerpt, showing the original line number and marked column or region. Returns the file path, line number, column(s) if known, and the rendered excerpt, or as much of these as is possible. The returned columns will be accurate for the rendered error message but not for the original journal data.

Given a problem posting and a function calculating the best column(s) for marking the error region: look up error info from the parent transaction, and render the transaction as a megaparsec-style excerpt, showing the original line number on the problem posting's line, and a column indicator. Returns the file path, line number, column(s) if known, and the rendered excerpt, or as much of these as is possible. A limitation: columns will be accurate for the rendered error message but not for the original journal data.

Given a problem price directive, and maybe a function to calculate the error region's column(s) (currently ignored): generate a megaparsec-style error message with highlighted excerpt. Returns the source file path, line number, column(s) if known, and the rendered excerpt, or as much of these as possible. Columns will be accurate for the rendered error message, not for the original journal entry.

Given a problem transaction and a function calculating the best column(s) for marking the error region: render it as a megaparsec-style excerpt, showing the original line number on the transaction line, and a column(s) marker. Returns the file path, line number, column(s) if known, and the rendered excerpt, or as much of these as is possible. The returned columns will be accurate for the rendered error message but not for the original journal data.

Within each posting's amount, keep only the parts matching the query, and remove any postings with all amounts removed. This can leave unbalanced transactions.

All raw amounts appearing in this journal, with MixedAmounts flattened, in no particular order. (Including from posting amounts, cost amounts, P directives, and the last D directive.)

The account name to use for conversion postings generated by --infer-equity. This is the first account declared with type V/Conversion, or otherwise the defaultBaseConversionAccount (equity:conversion).

Sorted unique commodity symbols mentioned anywhere in this journal. (Including commodity directives, P directives, the last D directive, posting amounts and cost amounts.)

Sorted unique commodity symbols used anywhere in this journal, including commodity directives, P directives, the last D directive, posting amounts and cost amounts.

Get the canonical amount styles for this journal, whether (in order of precedence): set globally in InputOpts, declared by commodity directives, declared by a default commodity (D) directive, or inferred from posting amounts, as a map from symbol to style. Styles from directives are assumed to specify the decimal mark.

Merge two journals into one. Transaction counts are summed, map fields are combined, the second's list fields are appended to the first's, the second's parse state is kept.

All the accounts in this journal which are declared or inferred as V/Conversion type. This does not include new account names which might be generated by --infer-equity, currently.

The fully specified exact date span enclosing the dates (primary or secondary) of all this journal's transactions and postings, or DateSpan Nothing Nothing if there are none.

The fully specified date span enclosing the dates (primary and secondary) of all this journal's transactions and postings, or DateSpan Nothing Nothing if there are none.

valuejournalEndDate :: Bool -> Journal -> Maybe Day
#

The "exclusive end date" of this journal: the day following its latest transaction or posting date, or Nothing if there are none.

Collect and save inferred amount styles for each commodity based on P directive amounts, posting amounts but not cost amounts, and maybe the last D amount, in that commodity. Can return an error message eg if inconsistent number formats are found.

Infer transaction-implied market prices from commodity-exchanging transactions, if any. It's best to call this after transactions have been balanced and posting amounts have appropriate prices attached.

Apply any transaction modifier rules in the journal (adding automated postings to transactions, eg). Or if a modifier rule fails to parse, return the error message. A reference date is provided to help interpret relative dates in transaction modifier queries. The first argument selects whether to add visible tags to generated postings & modified transactions.

valuejournalPivot :: Text -> Journal -> Journal
#

Apply the pivot transformation to all postings in a journal, replacing their account name by their value for the given field or tag.

To all postings in the journal, add any tags from their account (including those inherited from parent accounts). If a tag already exists on the posting, it is not changed (the account tag will be ignored).

To all postings in the journal, add any tags from their amount's commodities. If a tag already exists on the posting, it is not changed (the commodity tag will be ignored).

Remove all tags from the journal's postings except those provided by their account. This is useful for the accounts report. It does not remove tag declarations from the posting comments.

Reverse all lists of parsed items, which during parsing were prepended to, so that the items are in parse order. Part of post-parse finalisation.

Apply this journal's commodity display styles to all of its amounts. This does no display rounding, keeping decimal digits as they were; it is suitable for an early cleanup pass before calculations. Reports may want to do additional rounding/styling at render time. This can return an error message eg if inconsistent number formats are found.

Identify and tag (1) equity conversion postings and (2) postings which have (or could have ?) redundant costs. And if the addcosts flag is true, also add any costs which can be inferred from equity conversion postings. This is always called before transaction balancing to tag the redundant-cost postings so they can be ignored. With --infer-costs, it is called again after transaction balancing (when it has more information to work with) to infer costs from equity postings. See transactionTagCostsAndEquityAndMaybeInferCosts for more details, and hledger manual > Cost reporting for more background.

valuejournalTransactionsSimilarTo
  1. :: Journal
  2. -> Text
  3. -> Query
  4. -> SimilarityScore
  5. -> Int
  6. -> [(DateWeightedSimilarityScore, Age, SimilarityScore, Transaction)]
#

Find up to N most similar and most recent transactions matching the given transaction description and query and exceeding the given description similarity score (0 to 1, see compareDescriptions). Returns transactions along with their age in days compared to the latest transaction date, their description similarity score, and a heuristically date-weighted variant of this that favours more recent transactions.

Check all balance assertions in the journal and return an error message if any of them fail. (Technically, this also tries to balance the journal and can return balancing failure errors; ensure the journal is already balanced (with journalBalanceTransactions) to avoid this.)

Check that all the commodities used in this journal's postings and P directives have been declared by commodity directives, returning an error message otherwise.

Check that all the journal's tags (on accounts, transactions, postings..) have been declared with tag directives, returning an error message otherwise.

valuereadJsonFile :: FromJSON a => FilePath -> IO a
#

Read a JSON file and decode it to the target type, or raise an error if we can't. Eg: readJsonFile "a.json" :: IO Transaction

valuetoJsonText :: ToJSON a => a -> Text
#

Show a JSON-convertible haskell value as pretty-printed JSON text.

valuewriteJsonFile :: ToJSON a => FilePath -> a -> IO ()
#

Write a JSON-convertible haskell value to a pretty-printed JSON file. Eg: writeJsonFile "a.json" nulltransaction

The (fully specified) date span containing all the ledger's (filtered) transactions, or DateSpan Nothing Nothing if there are none.

Filter a journal's transactions with the given query, then build a Ledger, containing the journal plus the tree of all its accounts with their subaccount-inclusive and subaccount-exclusive balances. If the query includes a depth limit, the ledger's journal will be depth limited, but the ledger's account tree will not.

Get this ledger's root account, which is a dummy "root" account above all others. This should always be first in the account list, if somehow not this returns a null account.

Convert DateSpans to Periods.

Example1 expression
dateSpanAsPeriod $ DateSpan (Just $ Exact $ fromGregorian 2000 1 1) (Just $ Exact $ fromGregorian 2000 2 1)MonthPeriod 2000 1
valueisStandardPeriod :: Period -> Bool
#

Is this period a "standard" period, referencing a particular day, week, month, quarter, or year ? Periods of other durations, or infinite duration, or not starting on a standard period boundary, are not.

Convert Periods to exact DateSpans.

Example1 expression
periodAsDateSpan (MonthPeriod 2000 1) == DateSpan (Just $ Flex $ fromGregorian 2000 1 1) (Just $ Flex $ fromGregorian 2000 2 1)True
valueperiodGrow :: Period -> Period
#

Enlarge a standard period to the next larger enclosing standard period, if there is one. Eg, a day becomes the enclosing week. A week becomes whichever month the week's thursday falls into. A year becomes all (unlimited). Non-standard periods (arbitrary dates, or open-ended) are unaffected.

valueperiodMoveTo :: Day -> Period -> Period
#

Move a standard period stepwise so that it encloses the given date. Non-standard periods are unaffected.

valueperiodNext :: Period -> Period
#

Move a standard period to the following period of same duration. Non-standard periods are unaffected.

valueperiodNextIn :: DateSpan -> Period -> Period
#

Move a standard period to the following period of same duration, staying within enclosing dates. Non-standard periods are unaffected.

valueperiodPrevious :: Period -> Period
#

Move a standard period to the preceding period of same duration. Non-standard periods are unaffected.

Move a standard period to the preceding period of same duration, staying within enclosing dates. Non-standard periods are unaffected.

valueperiodShrink :: Day -> Period -> Period
#

Shrink a period to the next smaller standard period inside it, choosing the subperiod which contains today's date if possible, otherwise the first subperiod. It goes like this: unbounded periods and nonstandard periods (between two arbitrary dates) -> current year -> current quarter if it's in selected year, otherwise first quarter of selected year -> current month if it's in selected quarter, otherwise first month of selected quarter -> current week if it's in selected month, otherwise first week of selected month -> today if it's in selected week, otherwise first day of selected week, unless that's in previous month, in which case first day of month containing selected week. Shrinking a day has no effect.

valueshowPeriod :: Period -> Text
#

Render a period as a compact display string suitable for user output.

Example2 expressions
showPeriod (WeekPeriod (fromGregorian 2016 7 25))"2016-W30"showPeriod (WeekPeriod (fromGregorian 2024 12 30))"2025-W01"
valueshowPeriodAbbrev :: Period -> Text
#

Like showPeriod, but if it's a month or week period show an abbreviated form. >>> showPeriodAbbrev (WeekPeriod (fromGregorian 2016 7 25)) W30 >>> showPeriodAbbrev (WeekPeriod (fromGregorian 2024 12 30)) W01

valuesimplifyPeriod :: Period -> Period
#

Convert PeriodBetweens to a more abstract period where possible.

Example8 expressions
simplifyPeriod $ PeriodBetween (fromGregorian 1 1 1) (fromGregorian 2 1 1)YearPeriod 1simplifyPeriod $ PeriodBetween (fromGregorian 2000 10 1) (fromGregorian 2001 1 1)QuarterPeriod 2000 4simplifyPeriod $ PeriodBetween (fromGregorian 2000 2 1) (fromGregorian 2000 3 1)MonthPeriod 2000 2simplifyPeriod $ PeriodBetween (fromGregorian 2016 7 25) (fromGregorian 2016 8 1)WeekPeriod 2016-07-25simplifyPeriod $ PeriodBetween (fromGregorian 2000 1 1) (fromGregorian 2000 1 2)DayPeriod 2000-01-01simplifyPeriod $ PeriodBetween (fromGregorian 2000 2 28) (fromGregorian 2000 3 1)PeriodBetween 2000-02-28 2000-03-01simplifyPeriod $ PeriodBetween (fromGregorian 2000 2 29) (fromGregorian 2000 3 1)DayPeriod 2000-02-29simplifyPeriod $ PeriodBetween (fromGregorian 2000 12 31) (fromGregorian 2001 1 1)DayPeriod 2000-12-31
valuelookupPeriodData :: Day -> PeriodData a -> Maybe (Day, a)
#

Get the data for the period containing the given Day, and that period's start date. If the day is after the end of the last period, it is assumed to be within the last period. If the day is before the start of the first period (ie, in the historical period), return Nothing.

Get the data for the period containing the given Day, and that period's start date. If the day is after the end of the last period, it is assumed to be within the last period. If the day is before the start of the first period (ie, in the historical period), return the data for the historical period and no start date.

Generate transactions from PeriodicTransaction within a DateSpan. This should be a closed span with both start and end dates specified; an open ended span will generate no transactions.

Note that new transactions require txnTieKnot post-processing. The new transactions will have three tags added: - a recur:PERIODICEXPR tag whose value is the generating periodic expression - a generated-transaction: tag - a hidden _generated-transaction: tag which does not appear in the comment.

Example2 expressions
import Data.Time (fromGregorian)_ptgen "monthly from 2017/1 to 2017/4"2017-01-01    ; generated-transaction: ~ monthly from 2017/1 to 2017/4    a           $1.002017-02-01    ; generated-transaction: ~ monthly from 2017/1 to 2017/4    a           $1.002017-03-01    ; generated-transaction: ~ monthly from 2017/1 to 2017/4    a           $1.00
Example1 expression
_ptgen "monthly from 2017/1 to 2017/5"2017-01-01    ; generated-transaction: ~ monthly from 2017/1 to 2017/5    a           $1.002017-02-01    ; generated-transaction: ~ monthly from 2017/1 to 2017/5    a           $1.002017-03-01    ; generated-transaction: ~ monthly from 2017/1 to 2017/5    a           $1.002017-04-01    ; generated-transaction: ~ monthly from 2017/1 to 2017/5    a           $1.00
Example1 expression
_ptgen "every 2nd day of month from 2017/02 to 2017/04"2017-02-02    ; generated-transaction: ~ every 2nd day of month from 2017/02 to 2017/04    a           $1.002017-03-02    ; generated-transaction: ~ every 2nd day of month from 2017/02 to 2017/04    a           $1.00
Example1 expression
_ptgen "every 30th day of month from 2017/1 to 2017/5"2017-01-30    ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5    a           $1.002017-02-28    ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5    a           $1.002017-03-30    ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5    a           $1.002017-04-30    ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5    a           $1.00
Example1 expression
_ptgen "every 2nd Thursday of month from 2017/1 to 2017/4"2017-01-12    ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4    a           $1.002017-02-09    ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4    a           $1.002017-03-09    ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4    a           $1.00
Example1 expression
_ptgen "every nov 29th from 2017 to 2019"2017-11-29    ; generated-transaction: ~ every nov 29th from 2017 to 2019    a           $1.002018-11-29    ; generated-transaction: ~ every nov 29th from 2017 to 2019    a           $1.00
Example1 expression
_ptgen "2017/1"2017-01-01    ; generated-transaction: ~ 2017/1    a           $1.00
Example1 expression
let reportperiod="daily from 2018/01/03" in let (i,s) = parsePeriodExpr' nulldate reportperiod in runPeriodicTransaction True (nullperiodictransaction{ptperiodexpr=reportperiod, ptspan=s, ptinterval=i, ptpostings=["a" `post` usd 1]}) (DateSpan (Just $ Flex $ fromGregorian 2018 01 01) (Just $ Flex $ fromGregorian 2018 01 03))[]
Example1 expression
_ptgenspan "every 3 months from 2019-05" (DateSpan (Just $ Flex $ fromGregorian 2020 01 01) (Just $ Flex $ fromGregorian 2020 02 01))
Example3 expressions
_ptgenspan "every 3 months from 2019-05" (DateSpan (Just $ Flex $ fromGregorian 2020 02 01) (Just $ Flex $ fromGregorian 2020 03 01))2020-02-01    ; generated-transaction: ~ every 3 months from 2019-05    a           $1.00_ptgenspan "every 3 days from 2018" (DateSpan (Just $ Flex $ fromGregorian 2018 01 01) (Just $ Flex $ fromGregorian 2018 01 05))2018-01-01    ; generated-transaction: ~ every 3 days from 2018    a           $1.002018-01-04    ; generated-transaction: ~ every 3 days from 2018    a           $1.00_ptgenspan "every 3 days from 2018" (DateSpan (Just $ Flex $ fromGregorian 2018 01 02) (Just $ Flex $ fromGregorian 2018 01 05))2018-01-04    ; generated-transaction: ~ every 3 days from 2018    a           $1.00
valuecommentAddTag :: Text -> Tag -> Text
#

Add a tag to a comment, comma-separated from any prior content. A space is inserted following the colon, before the value.

valuecommentAddTagNextLine :: Text -> Tag -> Text
#

Add a tag on its own line to a comment, preserving any prior content. A space is inserted following the colon, before the value.

valuecommentJoin :: Text -> Text -> Text
#

Join two parts of a comment, eg a tag and another tag, or a tag and a non-tag, on a single line. Interpolates a comma and space unless one of the parts is empty.

Special tags hledger sometimes adds to mark various things. These should be hidden tag names, beginning with _. With --verbose-tags, the equivalent visible tags will also be added. These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.

Special tags hledger sometimes adds to mark various things. These should be hidden tag names, beginning with _. With --verbose-tags, the equivalent visible tags will also be added. These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.

Special tags hledger sometimes adds to mark various things. These should be hidden tag names, beginning with _. With --verbose-tags, the equivalent visible tags will also be added. These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.

Special tags hledger sometimes adds to mark various things. These should be hidden tag names, beginning with _. With --verbose-tags, the equivalent visible tags will also be added. These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.

Special tags hledger sometimes adds to mark various things. These should be hidden tag names, beginning with _. With --verbose-tags, the equivalent visible tags will also be added. These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.

valuepostingAddTags :: Posting -> [Tag] -> Posting
#

Add tags to a posting, discarding any for which the posting already has a value. Note this does not add tags to the posting's comment.

valuepostingAsLines
  1. :: Bool
  2. -> Bool
  3. -> Int
  4. -> Int
  5. -> Posting
  6. -> ([Text], Int, Int)
#

Render one posting, on one or more lines, suitable for print output. Also returns the widths calculated for the account and amount fields.

There will be an indented account name, plus one or more of status flag, posting amount, balance assertion, same-line comment, next-line comments.

If the posting's amount is implicit or if elideamount is true, no amount is shown. If the posting's amount is explicit and multi-commodity, multiple similar postings are shown, one for each commodity, to help produce parseable journal syntax. Or if onelineamounts is true, such amounts are shown on one line, comma-separated (and the output will not be valid journal syntax).

If an amount is zero, any commodity symbol attached to it is shown (and the corresponding commodity display style is used).

By default, 4 spaces (2 if there's a status flag) are shown between account name and start of amount area, which is typically 12 chars wide and contains a right-aligned amount (so 10-12 visible spaces between account name and amount is typical). When given a list of postings to be aligned with, the whitespace will be increased if needed to match the posting with the longest account name. This is used to align the amounts of a transaction's postings.

valuepostingDate :: Posting -> Day
#

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.

valuepostingDate2 :: 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.

valuepostingIndent :: Text -> Text
#

Prepend a suitable indent for a posting (or transaction/posting comment) line.

valuepostingStatus :: Posting -> Status
#

Get a posting's status. This is cleared or pending if those are explicitly set on the posting, otherwise the status of its parent transaction, or unmarked if there is no parent transaction. (Note the ambiguity, unmarked can mean "posting and transaction are both unmarked" or "posting is unmarked and don't know about the transaction".

valuepostingsAsLines :: Bool -> [Posting] -> [Text]
#

Render a transaction's postings as indented lines, suitable for print output.

Normally these will be in valid journal syntax which hledger can reparse (though they may include no-longer-valid balance assertions). Explicit amounts are shown, implicit amounts are not.

Postings with multicommodity explicit amounts are handled as follows: if onelineamounts is true, these amounts are shown on one line, comma-separated, and the output will not be valid journal syntax. Otherwise, they are shown as several similar postings, one per commodity. When the posting has a balance assertion, it is attached to the last of these postings.

Posting amounts will be aligned with each other, starting about 4 columns beyond the widest account name (see postingAsLines for details). The postings will appear balanced (amounts summing to zero). Amounts' display precisions, which may have been limited by commodity directives, will be increased if necessary to ensure this.

valuerenderCommentLines :: Text -> [Text]
#

Render a transaction or posting's comment as indented, semicolon-prefixed comment lines. The first line (unless empty) will have leading space, subsequent lines will have a larger indent.

valueshowPostingLines :: Posting -> [Text]
#

Render a posting, at the appropriate width for aligning with its siblings if any. Used by the rewrite command.

valuechoiceopt
  1. :: (String -> Maybe a)

    "parser" that returns Just value for valid choice

  2. -> RawOpts

    actual options where to look for flag

  3. -> Maybe a

    exclusive choice among those returned as Just from "parser"

#

From a list of RawOpts, get the last one (ie the right-most on the command line) for which the given predicate returns a Just value. Useful for exclusive choice flags like --daily|--weekly|--quarterly...

Example4 expressions
import Safe (readMay)choiceopt Just (RawOpts [("a",""), ("b",""), ("c","")])Just "c"choiceopt (const Nothing) (RawOpts [("a","")])Nothingchoiceopt readMay (RawOpts [("LT",""),("EQ",""),("Neither","")]) :: Maybe OrderingJust EQ
valuecollectopts :: ((String, String) -> Maybe a) -> RawOpts -> [a]
#

Collects processed and filtered list of options preserving their order

Example2 expressions
collectopts (const Nothing) (RawOpts [("x","")])[]collectopts Just (RawOpts [("a",""),("b","")])[("a",""),("b","")]
valueintopt :: String -> RawOpts -> Int
#

Reads the named option's Int argument. If not present it will return 0. An argument that is too small or too large will raise an error.

valuemaybeintopt :: String -> RawOpts -> Maybe Int
#

Reads the named option's Int argument, if it is present. An argument that is too small or too large will raise an error.

Reads the named option's natural-number argument, if it is present. An argument that is negative or too large will raise an error.

valueposintopt :: String -> RawOpts -> Int
#

Reads the named option's natural-number argument. If not present it will return 0. An argument that is negative or too large will raise an error.

valuetoggleopt :: String -> RawOpts -> Bool
#

Like boolopt, except if the flag is repeated on the command line it toggles the value. An even number of repetitions is equivalent to none.

Convert timeclock entries to journal transactions. This is the new, default version added in hledger 1.43 and improved in 1.50. It allows concurrent clocked-in sessions (though not with the same account name), and clock-in/clock-out entries in any order.

Entries are processed in parse order. Sessions crossing midnight are split into days to give accurate per-day totals. At the end, any sessions with no clockout get an implicit clockout with the provided "now" time. If any entries cannot be paired as expected, an error is raised.

Convert timeclock entries to journal transactions. This is the old version from hledger <1.43, now enabled by --old-timeclock. It requires strictly alternating clock-in and clock-entries. It was documented as allowing only one clocked-in session at a time, but in fact it allows concurrent sessions, even with the same account name.

Entries must be a strict alternation of in and out, beginning with in. When there is no clockout, one is added with the provided current time. Sessions crossing midnight are split into days to give accurate per-day totals. If entries are not in the expected in/out order, an error is raised.

Parse a transaction's description into payee and note (aka narration) fields, assuming a convention of separating these with | (like Beancount). Ie, everything up to the first | is the payee, everything after it is the note. When there's no |, payee == note == description.

Render a journal transaction as text similar to the style of Ledger's print command.

Adapted from Ledger 2.x and 3.x standard format:

yyyy-mm-dd[ *][ 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

The output will be parseable journal syntax. To facilitate this, postings with explicit multi-commodity amounts are displayed as multiple similar postings, one per commodity. (Normally does not happen with this function).

Find, associate, and tag the corresponding equity conversion postings and costful or potentially costful postings in this transaction. With a true addcosts argument, also generate and add any equivalent costs that are missing. The (previously detected) names of all equity conversion accounts should be provided.

For every pair of adjacent conversion postings, this first searches for a posting with equivalent cost (1). If no such posting is found, it then searches the costless postings, for one matching one of the conversion amounts (2). If either of these found a candidate posting, it is tagged with costPostingTagName. Then if in addcosts mode, if a costless posting was found, a cost equivalent to the conversion amounts is added to it.

The name reflects the complexity of this and its helpers; clarification is ongoing.

Infer a market price from the given amount and its cost (if any), and make a corresponding price directive on the given date. The price's display precision will be set to show all significant decimal digits; or if they seem to be infinite, defaultPrecisionLimit.

Generate a price oracle (memoising price lookup function) from a journal's directive-declared and transaction-inferred market prices. For best performance, generate this only once per journal, reusing it across reports if there are more than one, as compoundBalanceCommand does. The boolean argument is whether to infer market prices from transactions or not.

Calculate the gain of each component amount, that is the difference between the valued amount and the value of the cost basis (see mixedAmountApplyValuation).

If the commodity we are valuing in is not the same as the commodity of the cost, this will value the cost at the same date as the primary amount. This may not be what you want; for example you may want the cost valued at the posting date. If so, let us know and we can change this behaviour.

Calculate the gain of each component amount, that is the difference between the valued amount and the value of the cost basis.

If the commodity we are valuing in is not the same as the commodity of the cost, this will value the cost at the same date as the primary amount. This may not be what you want; for example you may want the cost valued at the posting date. If so, let us know and we can change this behaviour.

valuefilterQuery :: (Query -> Bool) -> Query -> Query
#

Remove query terms (or whole sub-expressions) from this query which do not match the given predicate. XXX Semantics not completely clear. Also calls simplifyQuery on the result.

valuefilterQueryOrNotQuery :: (Query -> Bool) -> Query -> Query
#

Remove query terms (or whole sub-expressions) from this query which match neither the given predicate nor that predicate negated (eg, if predicate is queryIsAcct, this will keep both "acct:" and "not:acct:" terms). Also calls simplifyQuery on the result. (Since 1.24.1, might be merged into filterQuery in future.) XXX Semantics not completely clear.

Like matchesAccount, but with optional extra matching features:

  • If the account's type is provided, any type: terms in the query must match it (and any negated type: terms must not match it).

  • If the account's tags are provided, any tag: terms must match at least one of them (and any negated tag: terms must match none).

valuematchesDescription :: Query -> Text -> Bool
#

Does the query match this transaction description ? Non-desc: query terms are ignored (this might disrupt some boolean queries).

valuematchesPayeeWIP :: Query -> Payee -> Bool
#

Does the query match this transaction payee ? Tests desc: (and payee: ?) terms, any other terms are ignored. XXX Currently an alias for matchDescription. I'm not sure if more is needed, There's some shenanigan with payee: and "payeeTag" to figure out.

valuematchesPosting :: Query -> Posting -> Bool
#

Does the match expression match this posting ? When matching account name, and the posting has been transformed in some way, we will match either the original or transformed name.

valuematchesTag :: Query -> Tag -> Bool
#

Does the query match the name and optionally the value of this tag ? Non-tag: query terms are ignored (this might disrupt some boolean queries).

valueparseQuery :: Day -> Text -> Either String (Query, [QueryOpt])
#

A version of parseQueryList which acts on a single Text of space-separated terms.

The usual shell quoting rules are assumed. When a pattern contains whitespace, it (or the whole term including prefix) should be enclosed in single or double quotes.

A query term is either:

  1. a search pattern, which matches on one or more fields, eg:

    acct:REGEXP - match the account name with a regular expression desc:REGEXP - match the transaction description date:PERIODEXP - match the date with a period expression

The prefix indicates the field to match, or if there is no prefix account name is assumed.

  1. a query option, which modifies the reporting behaviour in some way. There is currently one of these, which may appear only once:

    inacct:FULLACCTNAME

Period expressions may contain relative dates, so a reference date is required to fully parse these.

Example1 expression
parseQuery nulldate "expenses:dining out"Right (Or [Acct (RegexpCI "expenses:dining"),Acct (RegexpCI "out")],[])
Example1 expression
parseQuery nulldate "\"expenses:dining out\""Right (Acct (RegexpCI "expenses:dining out"),[])
valueparseQueryList :: Day -> [Text] -> Either String (Query, [QueryOpt])
#

Convert a list of space-separated queries to a single query

Multiple terms are combined as follows: 1. multiple account patterns are OR'd together 2. multiple description patterns are OR'd together 3. multiple status patterns are OR'd together 4. then all terms are AND'd together

valuequeryDateSpan :: Bool -> Query -> DateSpan
#

What date span (or with a true argument, what secondary date span) does this query specify ? OR clauses specifying multiple spans return their union (the span enclosing all of them). AND clauses specifying multiple spans return their intersection. NOT clauses are ignored.

What date span does this query specify, treating primary and secondary dates as equivalent ? OR clauses specifying multiple spans return their union (the span enclosing all of them). AND clauses specifying multiple spans return their intersection. NOT clauses are ignored.

valuequeryEndDate :: Bool -> Query -> Maybe Day
#

What end date (or secondary date) does this query specify, if any ? For OR expressions, use the latest of the dates. NOT is ignored.

valuequeryIsDate :: Query -> Bool
#

Is this a simple query of this type (date:) ? Does not match a compound query involving andornot. Likewise for the following functions.

Does this query specify a start date and nothing else (that would filter postings prior to the date) ? When the flag is true, look for a starting secondary date instead.

valuequeryStartDate :: Bool -> Query -> Maybe Day
#

What start date (or secondary date) does this query specify, if any ? For OR expressions, use the earliest of the dates. NOT is ignored.

valuewords'' :: [Text] -> Text -> [Text]
#

Quote-and-prefix-aware version of words - don't split on spaces which are inside quotes, including quotes which may have one of the specified prefixes in front, and maybe an additional not: prefix in front of that.

Read the default journal file specified by the environment, with default input options, or raise an error.

Get the default journal file path - either $LEDGER_FILE or $HOME/.hledger.journal file.

This looks for the LEDGER_FILE environment variable, like Ledger. The value should be a file path, possibly with ~ at the start meaning the current user's home directory. Or the value can be a glob pattern (containing *, ?, [ or {) ), in which case the first matching file path is used. When it's a glob pattern that matches no existing files, an error is raised.

If LEDGER_FILE is unset or set to the empty string, this returns a default file path: .hledger.journal in the user's home directory, or if we can't find the user's home directory, in the current directory.

The referenced file can be nonexistent.

Does any part of this path contain non-. characters and end with a . ? Such paths are not safe to use on Windows (cf #1056).

readJournal iopts mfile txt

Read a Journal from some handle, with strict checks if enabled, or return an error message.

The reader (data format) is chosen based on, in this order:

  • a reader name provided in iopts

  • a reader prefix in the mfile path

  • a file extension in mfile

If none of these is available, or if the reader name is unrecognised, the journal reader is used.

If a file path is not provided, "-" is assumed (and may appear in error messages, files output etc, where it will be a slight lie: it will mean "not from a file", not necessarily "from standard input".

Read a Journal from this file, or from stdin if the file path is -, with strict checks if enabled, or return an error message. XXX or, calls error if the file does not exist.

(Note strict checks are disabled temporarily here when this is called by readJournalFiles). The file path can have a READER: prefix.

The reader (data format) to use is determined from (in priority order): the mformat_ specified in the input options, if any; the file path's READER: prefix, if any; a recognised file name extension. if none of these identify a known reader, the journal reader is used.

The input options can also configure balance assertion checking, automated posting generation, a rules file for converting CSV data, etc.

If using --new, and if latest-file writing is enabled in input options, and not deferred by readJournalFiles, and after passing strict checks if enabled, a .latest.FILE file will be created/updated (for the main file only, not for included files), to remember the latest transaction date processed.

Read a Journal from each specified file path (using readJournalFile) and combine them into one; or return the first error message.

Combining Journals means concatenating them, basically. The parse state resets at the start of each file, which means that directives & aliases do not affect subsequent sibling or parent files. They do affect included child files though. Also the final parse state saved in the Journal does span all files.

Strict checks, if enabled, are temporarily deferred until all files are read, to ensure they see the whole journal, and/or to avoid redundant work. (Some checks, like assertions and ordereddates, might still be doing redundant work ?)

Writing .latest files, if enabled, is also deferred till the end, and is done only if strict checks pass.

Like readJournalFiles, but if the first file does not exist, provides an empty journal with that file path set. Other files must exist as normal. This is useful for commands like add and import that write to the first file, which might not exist yet, while also reading other files for completions etc.

If the specified journal file does not exist (and is not "-"), call error with an informative message. (Using "journal file" generically here; it could be in any of hledger's supported formats.)

valuesaveLatestDates :: LatestDates -> FilePath -> IO ()
#

Save the given latest date(s) seen in the given data FILE, in a hidden file named .latest.FILE, creating it if needed. Unless no latest dates are provided, in which case do nothing.

Parse an account name, plus one following space if present. Account names have one or more parts separated by the account separator character, and are terminated by two or more spaces (or end of input). Each part is at least one character long, may have single spaces inside it, and starts with a non-whitespace. (We should have required them to start with an alphanumeric, but didn't.) Note, this means account names can contain all kinds of punctuation, including ; which usually starts a following comment. Parent parsers usually remove the following comment before using this parser.

Parse a single-commodity amount, applying the default commodity if there is no commodity symbol; optionally followed by, in any order: a Ledger-style cost, Ledger-style valuation expression, and/or Ledger-style cost basis, which is one or more of lot cost, lot date, and/or lot note (we loosely call this triple the lot's cost basis). The cost basis makes it a lot rather than just an amount. Both cost basis info and valuation expression are discarded for now. The main amount's sign is significant; here are the possibilities and their interpretation. Also imagine an optional VALUATIONEXPR added to any of these (omitted for clarity): @

AMT -- acquiring an amount AMT COST -- acquiring an amount at some cost AMT COST COSTBASIS -- acquiring a lot at some cost, saving its cost basis AMT COSTBASIS COST -- like the above AMT COSTBASIS -- like the above with cost same as the cost basis

  • AMT -- releasing an amount

  • AMT SELLPRICE -- releasing an amount at some selling price

  • AMT SELLPRICE COSTBASISSEL -- releasing a lot at some selling price, selecting it by its cost basis

  • AMT COSTBASISSEL SELLPRICE -- like the above

  • AMT COSTBASISSEL -- like the above with selling price same as the selected lot's cost basis amount

COST/SELLPRICE can be UNITAMT, TOTALAMT, () UNITAMT, or (@@) TOTALAMT. The () are ignored. COSTBASIS is one or more of {LOTCOST}, [LOTDATE], (LOTNOTE), in any order, with LOTCOST defaulting to COST. COSTBASISSEL is one or more of {LOTCOST}, [LOTDATE], (LOTNOTE), in any order. {LOTCOST} can be {UNITAMT}, {{TOTALAMT}}, {=UNITAMT}, or {{=TOTALAMT}}. The = is ignored. VALUATIONEXPR can be ((VALUE AMOUNT)) or ((VALUE FUNCTION)).

@ Ledger amount syntax is really complex. Rule of thumb: curly braces, parentheses, and/or square brackets in an amount means a Ledger-style cost basis is involved.

To parse an amount's numeric quantity we need to know which character represents a decimal mark. We find it in one of three ways:

  1. If a decimal mark has been set explicitly in the journal parse state, we use that

  2. Or if the journal has a commodity declaration for the amount's commodity, we get the decimal mark from that

  3. Otherwise we will parse any valid decimal mark appearing in the number, as long as the number appears well formed. (This means we handle files with any supported decimal mark without configuration, but it also allows different decimal marks in different amounts, which is a bit too loose. There's an open issue.)

Parse Ledger-style bracketed posting dates ([DATE=DATE2]), as "date" and/or "date2" tags. Anything that looks like an attempt at this (a square-bracketed sequence of 0123456789/-.= containing at least one digit and one date separator) is also parsed, and will throw an appropriate error.

The dates are parsed in full here so that errors are reported in the right position. A missing year in DATE can be inferred if a default date is provided. A missing year in DATE2 will be inferred from DATE.

Example1 expression
either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[2016/1/2=3/4]"Right [("date",2016-01-02),("date2",2016-03-04)]
Example1 expression
either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[1]"Left ...not a bracketed date...
Example1 expression
either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[2016/1/32]"Left ...1:2:...This is not a valid date...
Example1 expression
either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[1/31]"Left ...1:2:...This partial date can not be parsed because the current year is unknown...
Example1 expression
either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[0123456789/-.=/-.=]"Left ...1:13:...expecting month or day...
valuedatep :: JournalParser m Day
#

Parse a date in YYYY-MM-DD format. Slash (/) and period (.) are also allowed as separators. The year may be omitted if a default year has been set. Leading zeroes may be omitted.

Parse a date and time in YYYY-MM-DD HH:MM[:SS][+-ZZZZ] format. Slash (/) and period (.) are also allowed as date separators. The year may be omitted if a default year has been set. Seconds are optional. The timezone is optional and ignored (the time is always interpreted as a local time). Leading zeroes may be omitted (except in a timezone).

Parse possibly empty text until a semicolon or newline. Whitespace is preserved (for now - perhaps helps preserve alignment of same-line comments ?).

A blank or comment line in journal format: a line that's empty or containing only whitespace or whose first non-whitespace character is semicolon, hash, or star. See also emptyorcommentlinep2.

valueemptyorcommentlinep2 :: [Char] -> TextParser m ()
#

A newer comment line parser. Parses a line which is empty, all blanks, or whose first non-blank character is one of those provided. A final newline is optional.

Parse a comment following a journal item, possibly continued on multiple lines, and return the comment text.

Example5 expressions
rtp followingcommentp ""   -- no commentRight ""rtp followingcommentp ";"    -- just a (empty) same-line comment. newline is addedRight "\n"rtp followingcommentp ";  \n"Right "\n"rtp followingcommentp ";\n ;\n"  -- a same-line and a next-line commentRight "\n\n"rtp followingcommentp "\n ;\n"  -- just a next-line comment. Insert an empty same-line comment so the next-line comment doesn't become a same-line comment.Right "\n\n"

Generate periodic transactions from all periodic transaction rules in the journal. These transactions are added to the in-memory Journal (but not the on-disk file).

The start & end date for generated periodic transactions are determined in a somewhat complicated way; see the hledger manual -> Periodic transactions.

Post-process a Journal that has just been parsed or generated, in this order:

  • add misc info (file path, read time)

  • reverse transactions into their original parse order

  • apply canonical commodity styles

  • propagate account tags to postings

  • maybe add forecast transactions

  • propagate account tags to postings (again to affect forecast transactions)

  • maybe add auto postings

  • propagate account tags to postings (again to affect auto postings)

  • evaluate balance assignments and balance each transaction

  • maybe check balance assertions

  • maybe infer costs from equity postings

  • maybe infer equity postings from costs

  • manye infer market prices from costs

One correctness check (parseable) has already passed when this function is called. Up to four more are performed here:

  • ordereddates (when enabled)

  • assertions (when enabled)

  • autobalanced (and with --strict, balanced ?), in the journalBalanceTransactions step.

Others (commodities, accounts..) are done later by journalStrictChecks.

Parse an account name plus one following space if present (see accountnamep); then apply any parent account prefix and/or account aliases currently in effect, in that order. Ie first add the parent account prefix, then rewrite with aliases. This calls error if any account alias with an invalid regular expression exists. The flag says whether account names may include semicolons; currently account names in journal format may, but account names in timeclock/timedot formats may not.

Parse a string representation of a number for its value and display attributes.

Some international number formats are accepted, eg either period or comma may be used for the decimal mark, and the other of these may be used for separating digit groups in the integer part. See http://en.wikipedia.org/wiki/Decimal_separator for more examples.

This returns: the parsed numeric value, the precision (number of digits seen following the decimal mark), the decimal mark character used if any, and the digit group style if any.

Parse a posting comment and extract its tags and dates.

Postings may be followed by comments, which begin with semicolons and extend to the end of the line. Posting comments may span multiple lines, but comment lines below the posting must be preceded by leading whitespace.

200011 account1 $1 ; a posting comment starting on the same line ... ; extending to the next line

account2 ; a posting comment beginning on the next line

Tags are name-value pairs.

Example2 expressions
let getTags (_,tags,_,_) = tagslet parseTags = fmap getTags . rtp (postingcommentp Nothing)
Example1 expression
parseTags "; name1: val1, name2:all this is value2"Right [("name1","val1"),("name2","all this is value2")]

A tag's name must be immediately followed by a colon, without separating whitespace. The corresponding value consists of all the text following the colon up until the next colon or newline, stripped of leading and trailing whitespace.

Posting dates may be expressed with "date"/"date2" tags or with bracketed date syntax. Posting dates will inherit their year from the transaction date if the year is not specified. We throw parse errors on invalid dates.

Example2 expressions
let getDates (_,_,d1,d2) = (d1, d2)let parseDates = fmap getDates . rtp (postingcommentp (Just 2000))
Example2 expressions
parseDates "; date: 1/2, date2: 1999/12/31"Right (Just 2000-01-02,Just 1999-12-31)parseDates "; [1/2=1999/12/31]"Right (Just 2000-01-02,Just 1999-12-31)

Example: tags, date tags, and bracketed dates >>> rtp (postingcommentp (Just 2000)) "; a:b, date:34, [=56]" Right ("a:b, date:34, [=56]n",[("a","b"),("date","3/4")],Just 2000-03-04,Just 2000-05-06)

Example: extraction of dates from date tags ignores trailing text >>> rtp (postingcommentp (Just 2000)) "; date:34=56" Right ("date:34=56n",[("date","34=56")],Just 2000-03-04,Nothing)

valuerawnumberp :: TextParser m (Either AmbiguousNumber RawNumber)
#

Parse and interpret the structure of a number without external hints. Numbers are digit strings, possibly separated into digit groups by one of two types of separators. (1) Numbers may optionally have a decimal mark, which may be either a period or comma. (2) Numbers may optionally contain digit group marks, which must all be either a period, a comma, or a space.

It is our task to deduce the characters used as decimal mark and digit group mark, based on the allowed syntax. For instance, we make use of the fact that a decimal mark can occur at most once and must be to the right of all digit group marks.

Example3 expressions
parseTest rawnumberp "1,234,567.89"Right (WithSeparators ',' ["1","234","567"] (Just ('.',"89")))parseTest rawnumberp "1,000"Left (AmbiguousNumber "1" ',' "000")parseTest rawnumberp "1 000"Right (WithSeparators ' ' ["1","000"] Nothing)
valuesinglespacep :: TextParser m ()
#

Parse one non-newline whitespace character that is not followed by another one.

Parse a transaction comment and extract its tags.

The first line of a transaction may be followed a 1-or-more-lines comment, beginning with a semicolon possibly preceded by whitespace on the current line, or with an indented semicolon on the next line. Additional lines also must begin with an indented semicolon. See also followingcommentpWith.

200011 ; a transaction comment starting on the same line ... ; extending to the next line account1 $1 account2

Tags are name-value pairs.

Example2 expressions
let getTags (_,tags) = tagslet parseTags = fmap getTags . rtp transactioncommentp
Example1 expression
parseTags "; name1: val1, name2:all this is value2"Right [("name1","val1"),("name2","all this is value2")]

A tag's name must be immediately followed by a colon, without separating whitespace. The corresponding value consists of all the text following the colon up until the next colon or newline, stripped of leading and trailing whitespace.

Get the Maybe the DateSpan to generate forecast options from. This begins on: - the start date supplied to the `--forecast` argument, if present - otherwise, the later of - the report start date if specified with -b-pdate: - the day after the latest normal (non-periodic) transaction in the journal, if any - otherwise today. It ends on: - the end date supplied to the `--forecast` argument, if present - otherwise the report end date if specified with -e-pdate: - otherwise 180 days (6 months) from today.

findReader mformat mpath

Find the reader named by mformat, if provided. ("ssv" and "tsv" are recognised as alternate names for the csv reader, which also handles those formats.) Or, if a file path is provided, find the first reader that handles its file extension, if any.

Generate transactions report items from a list of transactions, using the provided user-specified report query, a query specifying which account to use as the focus, a starting balance, and a sign-setting function. Each transaction is accompanied by the date that should be shown for it in the report. This is not necessarily the transaction date - see transactionRegisterDate.

What date should be shown for a transaction in an account register report ? This will be in context of a particular account (the "this account" query) and any additional report query. It could be:

  • if postings are matched by both thisacctq and reportq, the earliest of those matched postings' dates (or their secondary dates if --date2 was used)

  • the transaction date, or its secondary date if --date2 was used.

Enabling this makes balance --flat --empty also show parent accounts without postings, in addition to those with postings and a zero balance. Disabling it shows only the latter. No longer supported, but leave this here for a bit. flatShowsPostinglessAccounts = True

Generate a simple balance report, containing the matched accounts and their balances (change of balance) during the specified period. If the normalbalance_ option is set, it adjusts the sorting and sign of amounts (see ReportOpts and CompoundBalanceCommand).

When true (the default), this makes balance --flat reports and their implementation clearer. Single/multi-col balance reports currently aren't all correct if this is false.

Remove any date queries and insert queries from the report span. The user's query expanded to the report span if there is one (otherwise any date queries are left as-is, which handles the hledger-ui+future txns case above).

Generate a multicolumn balance report for the matched accounts, showing the change of balance, accumulated balance, or historical balance in each of the specified periods. If the normalbalance_ option is set, it adjusts the sorting and sign of amounts (see ReportOpts and CompoundBalanceCommand). hledger's most powerful and useful report, used by the balance command (in multiperiod mode) and (via compoundBalanceReport) by the bscfis commands.

Get the report interval, if any, specified by the last of -p/--period, -D--daily, -W--weekly, -M/--monthly etc. options. An interval from --period counts only if it is explicitly defined.

Convert this journal's postings' amounts to cost and/or to value, if specified by options (-B--cost-V-X--value etc.). Strip prices if not needed. This should be the main stop for performing costing and valuation. The exception is whenever you need to perform valuation _after_ summing up amounts, as in a historical balance report with --value=end. valuationAfterSum will check for this condition.

Generate a ReportOpts from raw command-line input, given a day and whether to use ANSI colour/styles in standard output. This will fail with a usage error if it is passed - an invalid --format argument, - an invalid --value argument, - if --valuechange is called with a valuation type other than -V/--value=end. - an invalid --pretty argument,

Make a name for the given period in a multiperiod report, given the type of balance being reported and the full set of report periods. This will be used as a column heading (or row heading, in a register summary report). We try to pick a useful name as follows:

  • ending-balance reports: the period's end date

  • balance change reports where the periods are months and all in the same year: the short month name in the current locale

  • all other balance change reports: a description of the datespan, abbreviated to compact form if possible (see showDateSpan).

The effective report span is the start and end dates requested by options or queries. If the start date is unspecified, the earliest transaction or posting date is used. If the end date is unspecified, the latest transaction or posting date (or non-future market price date, when doing an end value report) is used. If none of these things are present, the null date span is returned. The report sub-periods caused by a report interval, if any, are also returned.

If the ReportOpts specify that we will need to consider historical postings, either because this is a historical report, or because the valuation strategy requires historical amounts.

valuesimplifyStatuses :: Ord a => [a] -> [a]
#

Reduce a list of statuses to just one of each status, and if all statuses are present return the empty list.

Update the ReportOpts and the fields derived from it in a ReportSpec, or return an error message if there is a problem such as missing or unparseable options data. This is the safe way to change a ReportSpec, ensuring that all fields (_rsQuery, _rsReportOpts, querystring_, etc.) are in sync.

If the ReportOpts specify that we are performing valuation after summing amounts, return Just of the commodity symbol we're converting to, Just Nothing for the default, and otherwise return Nothing. Used for example with historical reports with --value=end.

valueall1 :: (a -> Bool) -> [a] -> Bool
#

Version of all that fails on an empty list.

valueapplyN :: Int -> (a -> a) -> a -> a
#

Apply a function the specified number of times, which should be > 0 (otherwise does nothing). Possibly uses O(n) stack ?

valuecurry2 :: ((a, b) -> c) -> a -> b -> c
#
valuecurry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
#
valuecurry4 :: ((a, b, c, d) -> e) -> a -> b -> c -> d -> e
#
valuefifth5 :: (a, b, c, d, e) -> e
#
valuefifth6 :: (a, b, c, d, e, f) -> e
#
valuefirst3 :: (a, b, c) -> a
#
valuefirst4 :: (a, b, c, d) -> a
#
valuefirst5 :: (a, b, c, d, e) -> a
#
valuefirst6 :: (a, b, c, d, e, f) -> a
#
valuefourth5 :: (a, b, c, d, e) -> d
#
valuefourth6 :: (a, b, c, d, e, f) -> d
#

Make classy lenses for Hledger options fields. This is intended to be used with BalancingOpts, InputOpt, ReportOpts, ReportSpec, and CliOpts. When run on X, it will create a typeclass named HasX (except for ReportOpts, which will be named HasReportOptsNoUpdate) containing all the lenses for that type. If the field name starts with an underscore, the lens name will be created by stripping the underscore from the front on the name. If the field name ends with an underscore, the field name ends with an underscore, the lens name will be mostly created by stripping the underscore, but a few names for which this would create too many conflicts instead have a second underscore appended. ReportOpts fields for which updating them requires updating the query in ReportSpec are instead names by dropping the trailing underscore and appending NoUpdate to the name, e.g. querystring_ -> querystringNoUpdate.

There are a few reasons for the complicated rules. - We have some legacy field names ending in an underscore (e.g. value_) which we want to temporarily accommodate, before eventually switching to a more modern style (e.g. _rsReportOpts) - Certain fields in ReportOpts need to update the enclosing ReportSpec when they are updated, and it is a common programming error to forget to do this. We append NoUpdate to those lenses which will not update the enclosing field, and reserve the shorter name for manually define lenses (or at least something lens-like) which will update the ReportSpec. cf. the lengthy discussion here and in surrounding comments: https://github.com/simonmichael/hledger/pull/1545#issuecomment-881974554

valuemapM' :: Monad f => (a -> f b) -> [a] -> f [b]
#

Like mapM but uses sequence'.

valuemaximum' :: Integral a => [a] -> a
#

Total version of maximum, for integral types, giving 0 for an empty list.

valuemaximumStrict :: Ord a => [a] -> a
#

Strict version of maximum that doesn’t leak space

valueminimumStrict :: Ord a => [a] -> a
#

Strict version of minimum that doesn’t leak space

valuemulticol :: Int -> [String] -> String
#

Convert a list of strings to a multi-line multi-column list fitting within the given width. Not wide character aware.

valuenumDigitsInteger :: Integer -> Int
#

Find the number of digits of an Integer. The integer should not have more digits than an Int can count. This is probably inefficient.

valuesecond5 :: (a, b, c, d, e) -> b
#
valuesecond6 :: (a, b, c, d, e, f) -> b
#
valuesequence' :: Monad f => [f a] -> f [a]
#

This is a version of sequence based on difference lists. It is slightly faster but we mostly use it because it uses the heap instead of the stack. This has the advantage that Neil Mitchell’s trick of limiting the stack size to discover space leaks doesn’t show this as a false positive.

valuesixth6 :: (a, b, c, d, e, f) -> f
#
valuesumStrict :: Num a => [a] -> a
#

Strict version of sum that doesn’t leak space

valuetakeUntilFails :: (a -> Bool) -> [a] -> [a]
#

Take elements from a list until a predicate fails, and then keep the first failing element as well.

valuethird3 :: (a, b, c) -> c
#
valuethird4 :: (a, b, c, d) -> c
#
valuethird5 :: (a, b, c, d, e) -> c
#
valuethird6 :: (a, b, c, d, e, f) -> c
#
valuetreeLeaves :: Tree a -> [a]
#

Get the leaves of this tree as a list. The topmost node ("root" in hledger account trees) is not counted as a leaf.

valueuncurry2 :: (a -> b -> c) -> (a, b) -> c
#
valueuncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
#
valueuncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
#
valuedbg :: Show a => Int -> String -> a -> a
#

Trace or log a label and showable value, pretty-printed, if the program debug level is at or above the specified level; then return the value.

valuedbgMsg :: Int -> String -> a -> a
#

Trace or log a string if the program debug level is at or above the specified level, then return the second argument.

valuedbgWith :: Int -> (a -> String) -> a -> a
#

Like dbg, but with a custom show function.

valuedbg_ :: Show a => Int -> String -> a -> a
#

Alias for dbg, can be used to avoid namespace clashes.

valuedebugLevel :: Int
#

The program's debug output verbosity, from 0 to 9. The default is 0 meaning no debug output. This can be overridden by running the program with a --debug [1-9] command line option; a --debug flag with no value means 1. Uses unsafePerformIO to read the command line. When running in GHCI, changing this requires reloading this module.

Should the program open a socket allowing control by ghc-debug-brick or similar ghc-debug client ? See GhcDebugMode.

valueghcDebugPause' :: IO ()
#

When ghc-debug support has been built into the program, this calls ghc-debug's pause, otherwise it's a no-op.

valuelbl_ :: String -> String -> String -> String
#

Helper for producing debug messages: concatenates a name (eg a function name), short description of the value being logged, and string representation of the value.

Eg: let lbl = lbl_ "print", dbg1With (lbl "part 1".show) ....

valueprogName :: String
#

The progam name, with any ".log" suffix removed.

valuewithGhcDebug' :: a -> a
#

When ghc-debug support has been built into the program and enabled at runtime with --debug=-N, this calls ghc-debug's withGhcDebug; otherwise it's a no-op.

valuebold' :: String -> String
#

Set various ANSI styles/colours in a string, only if useColorOnStdoutUnsafe says we should.

valuecolor :: ColorIntensity -> Color -> String -> String
#

Wrap a string in ANSI codes to set and reset foreground colour. ColorIntensity is Dull or Vivid (ie normal and bold). Color is one of Black, Red, Green, Yellow, Blue, Magenta, Cyan, White. Eg: color Dull Red "text".

valuecolorOption :: IO YNA
#

Get the value of the rightmost --color or --colour option from the program's command line arguments. Throws an error if the option's value could not be parsed.

valueerror' :: String -> a
#

Call errorWithoutStackTrace, prepending a "Error:" label.

valueexpandGlob :: FilePath -> FilePath -> IO [FilePath]
#

Like expandPath, but treats the expanded path as a glob, and returns zero or more matched absolute file paths, alphabetically sorted. Can raise an error. For a more elaborate glob expander, see findMatchedFiles (used by the include directive).

Expand a single tilde (representing home directory) at the start of a file path. ~username is not supported. This can raise an IO error.

Given a current directory, convert a possibly relative, possibly tilde-prefixed file path to an absolute one. ~username is not supported. If the file path is "-", it is left as-is. This can an raise an IO error.

Like expandPath, but if the path contains glob metacharacters (* ? [ {), treats it as a glob pattern and expands it, returning the first match. Raises an error if the glob pattern matches no files. If the path contains no glob metacharacters, just expands ~ and returns the path, even if the file doesn't exist yet. This is useful for options like -f and LEDGER_FILE that should: - accept non-existent files (for commands like add/import that create them) - expand glob patterns and error if they don't match anything

valuefindPager :: IO (Maybe String)
#

Try to find a pager executable robustly, safely handling various error conditions like an unset PATH var or the specified pager not being found as an executable. The pager can be specified by a path or program name in the PAGER environment variable. If that is unset or has a problem, "less" is tried, then "more". If successful, the pager's path or program name is returned.

valuegetFlag :: [String] -> IO Bool
#

Given one or more long or short flag names, report whether this flag is present in the command line. Concatenated short flags (-a -b written as -ab) are not supported.

valuegetHomeSafe :: IO (Maybe FilePath)
#

Like getHomeDirectory, but in case of IO error (home directory not found, not understood, etc.), returns "".

valuegetOpt :: [String] -> IO (Maybe String)
#

Given one or more long or short option names, read the rightmost value of this option from the command line arguments. If the value is missing raise an error. Concatenated short flags (-a -b written as -ab) are not supported.

An alternative to ansi-terminal's getTerminalSize, based on the more robust-looking terminal-size package.

Tries to get stdout's terminal's current height and width.

Read text from a handle, perhaps using a specified encoding from the encoding package. Or if no encoding is specified, using the handle's current encoding, changing it to UTF-8BOM if it was UTF-8, to ignore any Byte Order Mark at the start. Also it converts Windows line endings to newlines. If decoding fails, this throws an IOException (or possibly a UnicodeException or something else from the encoding package).

valuehandleExit :: IO () -> IO ()
#

This wraps a program's main routine so as to display more consistent, useful, and GHC-version-independent error output when the program exits because of certain common exceptions. It

  1. disables SIGPIPE errors, which are usually harmless, caused when our output is truncated in a piped command.

  2. catches these common exceptions:

  • UnicodeException, caused eg by text decoding errors in pure code

  • IOException, caused by IO errors, including text decoding errors during IO

  • ErrorCall - error / errorWithoutStackTrace calls

  1. compensates for GHC output bugs:

  • removes the trailing newlines added by some GHC 9.10.* versions

  • removes "uncaught exception" output added by some GHC 9.12.* versions

  • ensures a consistent "PROGNAME: " prefix

  1. applies bold bright red ANSI styling to the first line of error output, if that is supported and allowed

  2. for unicode exceptions and I/O exceptions which look like they were unicode-related, it adds a message (in english) explaining the problem and what to do.

Some exceptions this does not catch are ExitCode (exitSuccessexitFailureexitWith) and UserInterrupt (control-C).

valuelessIsWorking :: Maybe [(String, String)] -> IO Bool
#

Test less, by running less --version and looking for a nonzero exit, timeout, or stderr output. Uses the provided environment, containing a LESS variable, if any. We do this because various LESS settings can cause some less versions to fail or cause confusing output without failing.

Compute the LESS environment variable value that hledger will use for the less pager. This used in runPager when invoking less, and also in the setup command for display. It takes the current HLEDGER_LESS and LESS env var values, and whether we are showing colour on stdout, and returns the adjusted LESS value that should be used. Specifically:

  • If HLEDGER_LESS is defined, we use it in place of the LESS environment variable.

  • Otherwise, if LESS is defined, append some preferred options (lessOptions and maybe lessColourOptions) to it.

  • Otherwise, we set LESS to just use those preferred options.

Open a file for reading, using the standard System.IO.openFile. This opens the handle in text mode, using the initial system locale's text encoding.

valuepprint :: Show a => a -> IO ()
#

Pretty print a showable value. An easier alias for pretty-simple's pPrint. This will print in colour if useColorOnStderrUnsafe is true.

valuepprint' :: Show a => a -> IO ()
#

Monochrome version of pprint. This will never print in colour.

valueprintError :: String -> IO ()
#

Print an error message to stderr, with a consistent "programname: " prefix, and applying ANSI styling (bold bright red) to the first line if that is supported and allowed.

valueprogArgs :: [String]
#

The program's command line arguments. Uses unsafePerformIO; tends to stick in GHCI until reloaded, and may or may not detect args provided by a hledger config file.

valuepshow :: Show a => a -> String
#

Pretty show. An easier alias for pretty-simple's pShow. This will probably show in colour if useColorOnStderrUnsafe is true.

valuepshow' :: Show a => a -> String
#

Monochrome version of pshow. This will never show in colour.

Read text from a file, converting any rn line endings to n,, using the system locale's text encoding, ignoring any utf8 BOM prefix (as seen in paypal's 2018 CSV, eg) if that encoding is utf8.

valuerunPager :: String -> IO ()
#

Display the given text on the terminal, trying to use a pager ($PAGER, less, or more) when appropriate (see maybePagerFor), otherwise printing to standard output. Also, if the pager is less, we modify the LESS environment variable (see lessVarValue) and check for problems which could cause confusing output (see lessIsWorking).

Detect whether the terminal currently has a light background colour, if possible, using unsafePerformIO. If the terminal is transparent, its apparent light/darkness may be different.

Detect the terminal's current background lightness (0..1), if possible, using unsafePerformIO. If the terminal is transparent, its apparent lightness may be different.

valuetextToHandle :: Text -> IO Handle
#

Create a handle from which the given text can be read. Its encoding will be UTF-8.

Should ANSI color and styles be used for standard error output ? Considers useColorOnHandle stderr; is not affected by an --output-file option.

Should ANSI color and styles be used for standard output ? Considers useColorOnHandle stdout and hasOutputFile.

Like useColorOnStdout, but using unsafePerformIO. Useful eg for low-level debug code. Sticky in GHCI until reloaded, may not always be affected by --color in a hledger config file, etc.

valuewarn :: String -> a -> a
#

Show a warning message on stderr before returning the given value. Like trace, but prepends a "Warning:" label, and does some ANSI styling of the first line when allowed (using unsafe IO). Currently we use this very sparingly in hledger; we prefer to either quietly work, or loudly raise an error. Varying output can make scripting harder. But on stderr, it shouldn't cause much hassle.

valuewarnIO :: MonadIO m => String -> m ()
#

Like warn, but take extra care to sequence properly in IO.

valuechoice' :: [TextParser m a] -> TextParser m a
#

Backtracking choice, use this when alternatives share a prefix. Consumes no input if all choices fail.

Pretty-print our custom parse errors. It is necessary to use this instead of errorBundlePretty when custom parse errors are thrown.

This function intercepts our custom parse errors and applies final adjustments (finalizeCustomError) before passing them to errorBundlePretty. These adjustments are part of the implementation of the behaviour of our custom parse errors.

Note: We must ensure that the offset of the PosState of the provided ParseErrorBundle is no larger than the offset specified by a ErrorFailAt constructor. This is guaranteed if this offset is set to 0 (that is, the beginning of the source file), which is the case for ParseErrorBundles returned from runParserT.

valuedbgparse :: Int -> String -> TextParser m ()
#

Trace to stderr or log to debug log the provided label (if non-null) and current parser state (position and next input), if the global debug level is at or above the specified level. See also: Hledger.Utils.Debug, megaparsec's dbg. Uses unsafePerformIO. XXX Can be hard to make this evaluate.

valueparseErrorAtRegion
  1. :: Int

    Start offset

  2. -> Int

    End end offset

  3. -> String

    Error message

  4. -> HledgerParseErrorData
#

Fail at a specific source interval, given by the raw offsets of its endpoints from the start of the input stream (the numbers of tokens processed at those points).

Note that care must be taken to ensure that the specified interval does not span multiple lines of the input source. This will not be checked.

'reparseExcerpt s p' "re-parses" the source excerpt s using the parser p. Parse errors raised by p will be re-thrown at the source position of the source excerpt.

In order for the correct source file to be displayed when re-throwing parse errors, we must ensure that the source file during the use of 'reparseExcerpt s p' is the same as that during the use of excerpt_ that generated the source excerpt s. However, we can usually expect this condition to be satisfied because, at the time of writing, the only changes of source file in the codebase take place through include files, and the parser for include files neither accepts nor returns SourceExcerpts.

valueregexMatchText :: Regexp -> Text -> Bool
#

Tests whether a Regexp matches a Text.

This currently unpacks the Text to a String, to work around a performance bug in regex-tdfa (#9), which may or may not be relevant here.

A memoising version of regexReplace. Caches the result for each search pattern, replacement pattern, target string tuple. This won't generate a regular expression parsing error since that is pre-compiled nowadays, but there can still be a runtime error from the replacement pattern, eg with a backreference referring to a nonexistent match group.

valuechomp1 :: String -> String
#

Remove all trailing newline/carriage returns, leaving just one trailing newline.

valueformatString :: Bool -> Maybe Int -> Maybe Int -> String -> String
#

Clip and pad a string to a minimum & maximum width, andor leftright justify it. Works on multi-line strings too (but will rewrite non-unix line endings).

Try to single- and backslash-quote a string as needed to make it usable as an argument on a (sh/bash) shell command line. At least, well enough to handle common currency symbols, like $. Probably broken in many ways.

Example3 expressions
quoteForCommandLine "a""a"quoteForCommandLine "\"""'\"'"quoteForCommandLine "$""'$'"
valuequoteIfNeeded :: String -> String
#

Double-quote this string if it contains whitespace, single quotes or double-quotes, escaping the quotes as needed.

Single-quote this string if it contains whitespace or double-quotes. Does not work for strings containing single quotes.

valuestrWidthAnsi :: String -> Int
#

Like strWidth, but also strips ANSI escape sequences before calculating the width.

This is no longer used in code, as widths are calculated before adding ANSI escape sequences, but is being kept around for now.

valuestrip1By :: (Char -> Bool) -> String -> String
#

Strip a single balanced enclosing pair of a character matching the predicate from the start and end of a string.

valuestrip1Char :: Char -> Char -> String -> String
#

Strip the given starting and ending character from the start and end of a string if both are present.

valuestripAnsi :: String -> String
#

Strip ANSI escape sequences from a string.

Example1 expression
stripAnsi "\ESC[31m-1\ESC[m""-1"
valuestripBy :: (Char -> Bool) -> String -> String
#

Strip a run of zero or more characters matching the predicate from the start and end of a string.

valuetakeEnd :: Int -> [a] -> [a]
#

Take elements from the end of a list.

valuetakeWidth :: Int -> String -> String
#

Double-width-character-aware string truncation. Take as many characters as possible from a string without exceeding the specified width. Eg takeWidth 3 "りんご" = "り".

valuewords' :: 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.

valuefitText :: Maybe Int -> Maybe Int -> Bool -> Bool -> Text -> Text
#

General-purpose wide-char-aware single-line text layout function. It can left- or right-pad a short string to a minimum width. It can left- or right-clip a long string to a maximum width, optionally inserting an ellipsis (the third argument). It clips and pads on the right when the fourth argument is true, otherwise on the left. It treats wide characters as double width.

valueformatText :: Bool -> Maybe Int -> Maybe Int -> Text -> Text
#

Clip and pad a string to a minimum & maximum width, andor leftright justify it. Works on multi-line strings too (but will rewrite non-unix line endings).

valuequoteIfSpaced :: Text -> Text
#

Wrap a string in double quotes, and -prefix any embedded single quotes, if it contains whitespace and is not already single- or double-quoted.

valuereadDecimal :: Text -> Integer
#

Read a decimal number from a Text. Assumes the input consists only of digit characters.

valuestripquotes :: Text -> Text
#

Strip one matching pair of single or double quotes on the ends of a string.

Join several multi-line strings as side-by-side rectangular strings of the same height, bottom-padded. Treats wide characters as double width.

valuetextConcatTopPadded :: [Text] -> Text
#

Join several multi-line strings as side-by-side rectangular strings of the same height, top-padded. Treats wide characters as double width.

valuetextTakeWidth :: Int -> Text -> Text
#

Double-width-character-aware string truncation. Take as many characters as possible from a string without exceeding the specified width. Eg textTakeWidth 3 "りんご" = "り".

valuetextUnbracket :: Text -> Text
#

Remove all matching pairs of square brackets and parentheses from the text.

valuewithResource
  1. :: IO a

    initialize the resource

  2. -> (a -> IO ())

    free the resource

  3. -> (IO a -> TestTree)

    IO a is an action which returns the acquired resource. Despite it being an IO action, the resource it returns will be acquired only once and shared across all the tests in the tree.

  4. -> TestTree
#

Acquire the resource to run this test (sub)tree and release it afterwards.

valueafter
  1. :: DependencyType

    whether to run the tests even if some of the dependencies fail

  2. -> String

    the pattern

  3. -> TestTree

    the subtree that depends on other tests

  4. -> TestTree

    the subtree annotated with dependency information

#

The after combinator declares dependencies between tests.

If a TestTree is wrapped in after, the tests in this tree will not run until certain other tests («dependencies») have finished. These dependencies are specified using an AWK pattern (see the «Patterns» section in the README).

Moreover, if the DependencyType argument is set to AllSucceed and at least one dependency has failed, this test tree will not run at all.

Tasty does not check that the pattern matches any tests (let alone the correct set of tests), so it is on you to supply the right pattern.

Examples

The following test will be executed only after all tests that contain Foo anywhere in their path finish.

after AllFinish "Foo" $
   

testCase "A test that depends on Foo.Bar" $ ...

Note, however, that our test also happens to contain Foo as part of its name, so it also matches the pattern and becomes a dependency of itself. This will result in a Test.Tasty.DependencyLoop exception. To avoid this, either change the test name so that it doesn't mention Foo or make the pattern more specific.

You can use AWK patterns, for instance, to specify the full path to the dependency.

after AllFinish "$0 == \"Tests.Foo.Bar\"" $
   

testCase "A test that depends on Foo.Bar" $ ...

Or only specify the dependency's own name, ignoring the group names:

after AllFinish "$NF == \"Bar\"" $
   

testCase "A test that depends on Foo.Bar" $ ...

valueafter_
  1. :: DependencyType

    whether to run the tests even if some of the dependencies fail

  2. -> Expr

    the pattern

  3. -> TestTree

    the subtree that depends on other tests

  4. -> TestTree

    the subtree annotated with dependency information

#

Like after, but accepts the pattern as a syntax tree instead of a string. Useful for generating a test tree programmatically.

Examples

Only match on the test's own name, ignoring the group names:

after_ AllFinish (EQ (Field NF) (StringLit "Bar")) $
   

testCase "A test that depends on Foo.Bar" $ ...

valuedependentTestGroup
  1. :: TestName

    name of the group

  2. -> DependencyType

    whether to run subsequent tests even if earlier ones have failed

  3. -> [TestTree]

    tests to execute sequentially

  4. -> TestTree
#

Create a named group of test cases or other groups. Tests are executed in order and each test is considered a dependency of the next one. If filtering by TestPattern (--pattern) is in action, any test matching the pattern also shields earlier tests from filtering out, even if they themselves do not match the pattern.

For parallel execution, see testGroup. For ordered test execution, but with default filtering behavior, see inOrderTestGroup.

Note that this is will only work when used with the default TestManager. If you use another manager, like tasty-rerun for instance, sequentiality might possibly be ignored.

valueinOrderTestGroup
  1. :: TestName

    name of the group

  2. -> [TestTree]

    tests to execute sequentially

  3. -> TestTree
#

Create a named group of test cases that will be played sequentially, in the exact order provided. Similarly to testGroup and in contrast to dependentTestGroup, filtering by TestPattern is applied uniformly.

Note that this is will only work when used with the default TestManager. If you use another manager, like tasty-rerun for instance, the fact that these tests should be run in the given order might possibly be ignored.

value(@=?)
  1. :: (Eq a, Show a, HasCallStack)
  2. => a

    The expected value

  3. -> a

    The actual value

  4. -> Assertion
#

Asserts that the specified actual value is equal to the expected value (with the expected value on the left-hand side).

value(@?)
  1. :: (AssertionPredicable t, HasCallStack)
  2. => t

    A value of which the asserted condition is predicated

  3. -> String

    A message that is displayed if the assertion fails

  4. -> Assertion
#

An infix and flipped version of assertBool. E.g. instead of

assertBool "Non-empty list" (null [1])

you can write

null [1] @? "Non-empty list"

@? is also overloaded to accept IO Bool predicates, so instead of

do
  e <- doesFileExist "test"
  e @? "File does not exist"

you can write

doesFileExist "test" @? "File does not exist"
value(@?=)
  1. :: (Eq a, Show a, HasCallStack)
  2. => a

    The actual value

  3. -> a

    The expected value

  4. -> Assertion
#

Asserts that the specified actual value is equal to the expected value (with the actual value on the left-hand side).

valueassertEqual
  1. :: (Eq a, Show a, HasCallStack)
  2. => String

    The message prefix

  3. -> a

    The expected value

  4. -> a

    The actual value

  5. -> Assertion
#

Asserts that the specified actual value is equal to the expected value. The output message will contain the prefix, the expected value, and the actual value.

If the prefix is the empty string (i.e., ""), then the prefix is omitted and only the expected and actual values are output.

valueassertFailure
  1. :: HasCallStack
  2. => String

    A message that is displayed with the assertion failure

  3. -> IO a
#

Unconditionally signals that a failure has occured. All other assertions can be expressed with the form:

   if conditionIsMet
       then return ()
       else assertFailure msg
valueassertString
  1. :: HasCallStack
  2. => String

    The message that is displayed with the assertion failure

  3. -> Assertion
#

Deprecated. Why not use assertBool instead?

Signals an assertion failure if a non-empty message (i.e., a message other than "") is passed.

valuetestCaseSteps :: TestName -> ((String -> IO ()) -> Assertion) -> TestTree
#

Create a multi-step unit test.

Example:

main = defaultMain $ testCaseSteps "Multi-step test" $ \step -> do
  step "Preparing..."
  -- do something

  step "Running part 1"
  -- do something

  step "Running part 2"
  -- do something
  assertFailure "BAM!"

  step "Running part 3"
  -- do something

The step calls are mere annotations. They let you see which steps were performed successfully, and which step failed.

You can think of step as putStrLn, except putStrLn would mess up the output with the console reporter and get lost with the others.

For the example above, the output will be

Multi-step test: FAIL
  Preparing...
  Running part 1
  Running part 2
    BAM!

1 out of 1 tests failed (0.00s)

Note that:

  • Tasty still treats this as a single test, even though it consists of multiple steps.

  • The execution stops after the first failure. When we are looking at a failed test, we know that all displayed steps but the last one were successful, and the last one failed. The steps after the failed one are not displayed, since they didn't run.

typetype HasCallStack = IP "callStack" CallStack
#

Request a CallStack.

NOTE: The implicit parameter ?callStack :: CallStack is an implementation detail and should not be considered part of the CallStack API, we may decide to change the implementation in the future.

datadata AmountFormat
#

Formatting options available when displaying Amounts and MixedAmounts. Similar to AmountStyle but lower level, not attached to amounts or commodities, and can override it in some ways. See also hledger manual > "Amount formatting, parseability", which speaks of human, hledger, and machine output.

Constructors

Instances2Show, Default
  • Show AmountFormatDefined in hledger-lib-1.52.4 · Hledger.Data.Amount
  • Default AmountFormatDefined in hledger-lib-1.52.4 · Hledger.Data.Amount

    By default, display amounts using defaultFmt amount display options.

datadata BalancingOpts
#

Constructors

Instances4Eq, Ord, Show, HasBalancingOpts
classclass HasBalancingOpts c where
#
Instances3HasBalancingOpts
newtypenewtype DayPartition
#

A partition of time into one or more contiguous periods, plus a historical period that precedes them. Note DayPartition does not store per-period data - only the periods' start/end dates.

Instances3Eq, Ord, Show
newtypenewtype RawOpts
#

The result of running cmdargs: an association list of option names to string values.

Instances2Show, Default
  • Show RawOptsDefined in hledger-lib-1.52.4 · Hledger.Data.RawOptions
  • Default RawOptsDefined in hledger-lib-1.52.4 · Hledger.Data.RawOptions
datadata ReportItemField
#

An id identifying which report item field to interpolate. These are drawn from several hledger report types, so are not all applicable for a given report.

Constructors

  • AccountField

    A posting or balance report item's account name

  • DefaultDateField

    A posting or register or entry report item's date

  • DescriptionField

    A posting or register or entry report item's description

  • TotalField

    A balance or posting report item's balance or running total. Always rendered right-justified.

  • DepthSpacerField

    A balance report item's indent level (which may be different from the account name depth). Rendered as this number of spaces, multiplied by the minimum width spec if any.

  • FieldNo Int

    A report item's nth field. May be unimplemented.

Instances2Eq, Show
datadata StringFormat
#

A format specification/template to use when rendering a report line item as text.

A format is a sequence of components; each is either a literal string, or a hledger report item field with specified width and justification whose value will be interpolated at render time.

A component's value may be a multi-line string (or a multi-commodity amount), in which case the final string will be either single-line or a top or bottom-aligned multi-line string depending on the StringFormat variant used.

Currently this is only used in the balance command's single-column mode, which provides a limited StringFormat renderer.

Constructors

Instances3Eq, Show, Default

Constructors

  • FormatLiteral Text

    Literal text to be rendered as-is

  • FormatField Bool (Maybe Int) (Maybe Int) ReportItemField

    A data field to be formatted and interpolated. Parameters:

    • Left justify ? Right justified if false

    • Minimum width ? Will be space-padded if narrower than this

    • Maximum width ? Will be clipped if wider than this

    • Which of the standard hledger report item fields to interpolate

Instances2Eq, Show

How to determine the precision used for checking that transactions are balanced. See #2402.

Constructors

  • TBPOld

    Legacy behaviour, as in hledger <1.50, included to ease upgrades. use precision inferred from the whole journal, overridable by commodity directive or -c. Display precision is also transaction balancing precision; increasing it can break journal reading. Some valid journals are rejected until commodity directives are added. Small unbalanced remainders can be hidden, and in accounts that are never reconciled, can accumulate over time.

  • TBPExact

    Simpler, more robust behaviour, as in Ledger: use precision inferred from the transaction. Display precision and transaction balancing precision are independent; display precision never affects journal reading. Valid journals from ledger or beancount are accepted without needing commodity directives. Every imbalance in a transaction is visibly accounted for in that transaction's journal entry.

Instances6Bounded, Enum, Eq, Ord, Read, Show
datadata Account a
#

An account within a hierarchy, with references to its parent and subaccounts if any, and with per-report-period data of type a. Only the name is required; the other fields may or may not be present.

Constructors

Instances8Functor, Eq, Show, Generic, FromJSON, ToJSON, …
datadata AccountAlias
#
Instances8Eq, Ord, Read, Show, Generic, NFData, …

Extra information about an account that can be derived from its account directive (and the other account directives).

Constructors

Instances7Eq, Show, Generic, NFData, FromJSON, ToJSON, …
datadata AccountType
#

Constructors

  • Asset
  • Liability
  • Equity
  • Revenue
  • Expense
  • Cash

    a subtype of Asset - liquid assets to show in cashflow report

  • Conversion

    a subtype of Equity - account with which to balance commodity conversions

  • Gain

    a subtype of Revenue - realised capital gains/losses

  • UnrealisedGain

    a subtype of Equity - accumulated unrealised capital gains/losses (used by hledger 2)

Instances8Eq, Ord, Show, Generic, NFData, ToJSON, …
datadata Amount
#

Constructors

Instances10Eq, Num, Ord, Show, Generic, NFData, …
datadata AmountCost
#

An amount's per-unit or total cost/selling price in another commodity, as recorded in the journal entry eg with or @. Cost, formerly AKA "transaction price". The amount is always positive.

Instances8Eq, Ord, Show, Generic, NFData, FromJSON, …
datadata AmountPrecision
#

The "display precision" for a hledger amount, by which we mean the number of decimal digits to display to the right of the decimal mark.

Constructors

Instances9Eq, Ord, Read, Show, Generic, NFData, …
datadata AmountStyle
#

Display styles for amounts - things which can be detected during parsing, such as commodity side and spacing, digit group marks, decimal mark, number of decimal digits etc. Every Amount has an AmountStyle. After amounts are parsed from the input, for each Commodity a standard style is inferred and then used when displaying amounts in that commodity. Related to AmountFormat but higher level.

See also: - hledger manual > Commodity styles - hledger manual > Amounts - hledger manual > Commodity display style

Constructors

Instances9Eq, Ord, Read, Show, Generic, NFData, …
datadata BalanceAssertion
#

A balance assertion is a declaration about an account's expected balance at a certain point (posting date and parse order). They provide additional error checking and readability to a journal file.

A balance assignments is an instruction to hledger to adjust an account's balance to a certain amount at a certain point.

The BalanceAssertion type is used for representing both of these.

hledger supports multiple kinds of balance assertions/assignments, which differ in whether they refer to a single commodity or all commodities, and the (subaccount-)inclusive or exclusive account balance.

Constructors

Instances8Eq, Show, Generic, NFData, FromJSON, ToJSON, …
datadata BalanceData
#

Data that's useful in "balance" reports: subaccount-exclusive and -inclusive amounts, typically representing either a balance change or an end balance; and a count of postings.

Constructors

Instances9Eq, Show, Generic, Semigroup, Monoid, FromJSON, …
datadata Commodity
#

Constructors

Instances6Eq, Show, Generic, NFData, ToJSON, Rep
datadata CostBasis
#

The cost basis of an individual lot - some quantity of an asset acquired at a given date and time. This can represent a definite cost basis, which must have a cost and date; the label is optional. Or it can represent a cost basis matcher for selecting lots. Note: cost is always stored as a per-unit cost, even if the user specified total cost with {{}}.

Constructors

Instances8Eq, Ord, Show, Generic, NFData, FromJSON, …
datadata DateSpan
#

A possibly open-ended span of time, from an optional inclusive start date to an optional exclusive end date. Each date can be either exact or flexible. An "exact date span" is a Datepan with exact start and end dates.

Constructors

Instances8Eq, Ord, Show, Generic, NFData, ToJSON, …
typetype DecimalMark = Char
#

One of the decimal marks we support: either period or comma.

datadata DigitGroupStyle
#

A style for displaying digit groups in the integer part of a floating point number. It consists of the character used to separate groups (comma or period, whichever is not used as decimal point), and the size of each group, starting with the one nearest the decimal point. The last group size is assumed to repeat. Eg, comma between thousands is DigitGroups ',' [3].

Constructors

Instances9Eq, Ord, Read, Show, Generic, NFData, …
datadata EFDay
#

A date which is either exact or flexible. Flexible dates are allowed to be adjusted in certain situations.

Constructors

Instances7Eq, Ord, Show, Generic, NFData, ToJSON, …
classclass HasAmounts a where
#

Types with this class have one or more amounts, which can have display styles applied to them.

Instances19HasAmounts, …
datadata Interval
#
Instances8Eq, Ord, Show, Generic, NFData, ToJSON, …
datadata Journal
#

A journal, containing general ledger transactions; also directives and various other things. This is hledger's main data model.

During parsing, it is used as the type alias ParsedJournal. The jparse* fields are mainly used during parsing and included here for convenience. The list fields described as "in parse order" are usually reversed for efficiency during parsing. After parsing, "journalFinalise" converts ParsedJournal to a finalised Journal, which has all lists correctly ordered, and much data inference and validation applied.

Constructors

Instances9Eq, Show, Generic, Semigroup, NFData, ToJSON, …
datadata Ledger
#

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.

Instances4Show, Generic, ToJSON, Rep
datadata MarketPrice
#

A historical market price (exchange rate) from one commodity to another. A more concise form of a PriceDirective, without the amount display info.

Constructors

Instances8Eq, Ord, Show, Generic, NFData, FromJSON, …
newtypenewtype MixedAmount
#
Instances15Eq, Num, Ord, Show, Generic, Semigroup, …
datadata NormalSign
#

Whether an account's balance is normally a positive number (in accounting terms, a debit balance) or a negative number (credit balance). Assets and expenses are normally positive (debit), while liabilities, equity and income are normally negative (credit). https://en.wikipedia.org/wiki/Normal_balance

Instances2Eq, Show
  • Eq NormalSignDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • Show NormalSignDefined in hledger-lib-1.52.4 · Hledger.Data.Types
typetype ParsedJournal = Journal
#

A journal in the process of being parsed, not yet finalised. The data is partial, and list fields are in reverse order.

datadata PayeeDeclarationInfo
#

Extra information found in a payee directive.

Constructors

Instances6Eq, Show, Generic, NFData, ToJSON, Rep
datadata Period
#
Instances8Eq, Ord, Show, Generic, ToJSON, Default, …
datadata PeriodData a
#

A general container for storing data values associated with zero or more contiguous report (sub)periods, and with the (open ended) pre-report period. The report periods are typically all the same length, but need not be.

Report periods are represented only by their start dates, used as the keys of a Map.

Constructors

Instances14Functor, Foldable, Traversable, Foldable1, Eq, Ord, …
datadata PeriodicTransaction
#

A periodic transaction rule, describing a transaction that recurs.

Constructors

Instances6Eq, Show, Generic, NFData, ToJSON, Rep
datadata Posting
#

Constructors

Instances10Eq, Show, Generic, NFData, FromJSON, ToJSON, …
datadata PostingType
#
Instances7Eq, Show, Generic, NFData, FromJSON, ToJSON, …
datadata PriceDirective
#

A market price declaration made by the journal format's P directive. It declares two things: a historical exchange rate between two commodities, and an amount display style for the second commodity.

Instances8Eq, Ord, Show, Generic, NFData, ToJSON, …
datadata Rounding
#

"Rounding strategy" - how to apply an AmountStyle's display precision to a posting amount (and its cost, if any). Mainly used to customise print's output, with --round=none|soft|hard|all.

Constructors

  • NoRounding

    keep display precisions unchanged in amt and cost

  • SoftRounding

    do soft rounding of amt and cost amounts (show more or fewer decimal zeros to approximate the target precision, but don't hide significant digits)

  • HardRounding

    do hard rounding of amt (use the exact target precision, possibly hiding significant digits), and soft rounding of cost

  • AllRounding

    do hard rounding of amt and cost

Instances9Eq, Ord, Read, Show, Generic, NFData, …
datadata SepFormat
#

One of the standard *-separated value file types known by hledger,

Instances3Eq, Ord, Show
  • Eq SepFormatDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • Ord SepFormatDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • Show SepFormatDefined in hledger-lib-1.52.4 · Hledger.Data.Types
datadata Side
#
Instances9Eq, Ord, Read, Show, Generic, NFData, …
  • Eq SideDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • Ord SideDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • Read SideDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • Show SideDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • Generic SideDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • NFData SideDefined in hledger-lib-1.52.4 · Hledger.Data.Types
  • FromJSON SideDefined in hledger-lib-1.52.4 · Hledger.Data.Json · orphan
  • ToJSON SideDefined in hledger-lib-1.52.4 · Hledger.Data.Json · orphan
  • type Rep Side = D1 ('MetaData "Side" "Hledger.Data.Types" "hledger-lib-1.52.4-9hXfdej3TnZFrbN8mI8ppA" 'False) (C1 ('MetaCons "L" 'PrefixI 'False) U1 :+: C1 ('MetaCons "R" 'PrefixI 'False) U1)Defined in hledger-lib-1.52.4 · Hledger.Data.Types
datadata SmartDate
#

A possibly incomplete year-month-day date provided by the user, to be interpreted as either a date or a date span depending on context. Missing parts "on the left" will be filled from the provided reference date, e.g. if the year and month are missing, the reference date's year and month are used. Missing parts "on the right" are assumed, when interpreting as a date, to be 1, (e.g. if the year and month are present but the day is missing, it means first day of that month); or when interpreting as a date span, to be a wildcard (so it would mean all days of that month). See the smartdate parser for more examples.

Or, one of the standard periods and a numeric offset relative to the reference date: (last|this|next) (day|week|month|quarter|year), where "this" means the period containing the reference date.

Or, (last|this|next) weekdayname, where "this" "next".

Or, (last|this|next) monthname, where "this" means the previous 1st if in that month, otherwise the start of the next occurrence of that month.

Instances1Show
  • Show SmartDateDefined in hledger-lib-1.52.4 · Hledger.Data.Types
datadata Status
#

The status of a transaction or posting, recorded with a status mark (nothing, !, or *). What these mean is ultimately user defined.

Instances10Bounded, Enum, Eq, Ord, Show, Generic, …
datadata TMPostingRule
#

A transaction modifier transformation, which adds an extra posting to the matched posting's transaction. Can be like a regular posting, or can have the tmprIsMultiplier flag set, indicating that it's a multiplier for the matched posting's amount.

Instances6Eq, Show, Generic, NFData, ToJSON, Rep
newtypenewtype TagDeclarationInfo
#

Extra information found in a tag directive.

Constructors

Instances6Eq, Show, Generic, NFData, ToJSON, Rep
datadata TimeclockCode
#
Instances8Eq, Ord, Read, Show, Generic, NFData, …
datadata TimeclockEntry
#
Instances7Eq, Ord, Show, Generic, NFData, ToJSON, …
datadata Transaction
#

Constructors

Instances10Eq, Show, Generic, NFData, FromJSON, ToJSON, …
datadata TransactionModifier
#

A transaction modifier rule. This has a query which matches postings in the journal, and a list of transformations to apply to those postings or their transactions. Currently there is one kind of transformation: the TMPostingRule, which adds a posting ("auto posting") to the transaction, optionally setting its amount to the matched posting's amount multiplied by a constant.

Instances6Eq, Show, Generic, NFData, ToJSON, Rep
datadata ConversionOp
#

Which operation to perform on conversion transactions. (There was also an "infer equity postings" operation, but that is now done earlier, in journal finalisation.)

Instances2Eq, Show
datadata ValuationType
#

What kind of value conversion should be done on amounts ? CLI: --value=then|end|now|DATE[,COMM]

Constructors

Instances2Eq, Show
datadata Query
#

A query is a composition of search criteria, which can be used to match postings, transactions, accounts and more.

Constructors

  • Any

    always match

  • None

    never match data queries (in "standard" order, roughly as they appear in a transaction)

  • Date DateSpan

    match primary dates in this date span

  • Date2 DateSpan

    match secondary dates in this date span

  • StatusQ Status

    match this txn/posting status

  • Code Regexp

    match txn codes infix-matched by this regexp

  • Desc Regexp

    match txn descriptions infix-matched by this regexp

  • Tag Regexp (Maybe Regexp)

    match if a tag's name, and optionally its value, is infix-matched by the respective regexps

  • Acct Regexp

    match account names infix-matched by this regexp

  • Type [AccountType]

    match accounts whose type is one of these (or with no types, any account)

  • Depth Int

    match if account depth is less than or equal to this value (or, sometimes used as a display option)

  • DepthAcct Regexp Int

    match if the account matches and account depth is less than or equal to this value (usually used as a display option)

  • Real Bool

    match postings with this "realness" value

  • Amt OrdPlus Quantity

    match if the amount's numeric quantity is less thangreater thanequal to/unsignedly equal to some value

  • Sym Regexp

    match if the commodity symbol is fully-matched by this regexp compound queries (expr:)

  • Not Query

    negate this match

  • And [Query]

    match if all of these match

  • Or [Query]

    match if any of these match compound queries for transactions (any:, all:) If used in a non transaction-matching context, these are equivalent to And.

  • AnyPosting [Query]

    match if any one posting is matched by all of these

  • AllPostings [Query]

    match if all of one or more postings are matched by all of these

Instances3Eq, Show, Default
  • Eq QueryDefined in hledger-lib-1.52.4 · Hledger.Query
  • Show QueryDefined in hledger-lib-1.52.4 · Hledger.Query
  • Default QueryDefined in hledger-lib-1.52.4 · Hledger.Query
datadata QueryOpt
#

A query option changes a query's/report's behaviour and output in some way.

Constructors

Instances2Eq, Show
  • Eq QueryOptDefined in hledger-lib-1.52.4 · Hledger.Query
  • Show QueryOptDefined in hledger-lib-1.52.4 · Hledger.Query
typetype PrefixedFilePath = FilePath
#

A file path optionally prefixed by a reader name and colon (journal:, csv:, timedot:, etc.). The file path part can also be - meaning standard input.

datadata Reader (m :: Type -> Type)
#

A hledger journal reader is a storage format name, a list of file extensions assumed to be in this format, and an IO action that reads data in this format, returning a Journal.

The journal parser used by the latter is also stored separately for direct use by the journal reader's includedirectivep to parse included files. The type variable m is needed for this parser. Lately it requires an InputOpts, basically to support --old-timeclock.

Instances1Show
  • Show (Reader m)Defined in hledger-lib-1.52.4 · Hledger.Read.Common
classclass HasInputOpts c where
#
Instances2HasInputOpts
datadata InputOpts
#

Constructors

  • InputOpts
    • mformat_ :: Maybe StorageFormat

      a file/storage format to try, unless overridden by a filename prefix. Nothing means try all.

    • mrules_file_ :: Maybe FilePath

      a conversion rules file to use (when reading CSV)

    • aliases_ :: [String]

      account name aliases to apply

    • anon_ :: Bool

      do light obfuscation of the data ? Now corresponds to --obfuscate, not the old --anon flag.

    • new_ :: Bool

      read only new transactions since this file was last read ?

    • new_save_ :: Bool

      save latest new transactions state for next time ?

    • pivot_ :: String

      use the given field's value as the account name

    • forecast_ :: Maybe DateSpan

      span in which to generate forecast transactions

    • auto_posting_tags_ :: Bool

      propagate commodity and account tags to postings ? Can be disabled (for beancount export).

    • verbose_tags_ :: Bool

      add user-visible tags when generating/modifying transactions & postings ?

    • reportspan_ :: DateSpan

      a dirty hack keeping the query dates in InputOpts. This rightfully lives in ReportSpec, but is duplicated here.

    • auto_ :: Bool

      generate extra postings according to auto posting rules ?

    • infer_equity_ :: Bool

      infer equity conversion postings from costs ?

    • infer_costs_ :: Bool

      infer costs from equity conversion postings ? distinct from BalancingOpts{infer_balancing_costs_}

    • balancingopts_ :: BalancingOpts

      options for transaction balancing

    • strict_ :: Bool

      do extra correctness checks ?

    • _defer :: Bool

      internal flag: postpone checks, because we are processing multiple files ?

    • _ioDay :: Day

      today's date, for use with forecast transactions XXX this duplicates _rsDay, and should eventually be removed when it's not needed anymore.

    • _oldtimeclock :: Bool

      parse with the old timeclock pairing rules?

Instances5Eq, Ord, Show, HasBalancingOpts, HasInputOpts

An account transactions report represents transactions affecting a particular account (or possibly several accounts, but we don't use that). It is used eg by hledger-ui's and hledger-web's register view, and hledger's aregister report, where we want to show one row per transaction, in the context of the current account. Report items consist of:

  • the transaction, unmodified

  • the transaction as seen in the context of the current account and query, which means:

  • the transaction date is set to the "transaction context date": the earliest of the transaction date and any other posting dates of postings to the current account (matched by the report query).

  • the transaction's postings are filtered, excluding any which are not matched by the report query

  • a text description of the other account(s) posted to/from

  • a flag indicating whether there's more than one other account involved

  • the total increase/decrease to the current account

  • the report transactions' running total after this transaction; or if historical balance is requested (-H), the historical running total. The historical running total includes transactions from before the report start date if one is specified, filtered by the report query. The historical running total may or may not be the account's historical running balance, depending on the report query.

Items are sorted by transaction register date (the earliest date the transaction posts to the current account), most recent first. Reporting intervals are currently ignored.

A simple balance report. It has:

  1. a list of items, one per account, each containing:

  • the full account name

  • the Ledger-style elided short account name (the leaf account name, prefixed by any boring parents immediately above); or with --flat, the full account name again

  • the number of indentation steps for rendering a Ledger-style account tree, taking into account elided boring parents, --no-elide and --flat

  • an amount

  1. the total of all amounts

A budget report tracks expected and actual changes per account and subperiod. Each table cell has an actual change amount and/or a budget goal amount.

A journal entries report is a list of whole transactions as originally entered in the journal (mostly). This is used by eg hledger's print command and hledger-web's journal entries view.

A multi balance report is a kind of periodic report, where the amounts correspond to balance changes or ending balances in a given period. It has:

  1. a list of each column's period (date span)

  2. a list of rows, each containing:

  • the full account name, display name, and display depth

  • A list of amounts, one for each column.

  • the total of the row's amounts for a periodic report

  • the average of the row's amounts

  1. the column totals, and the overall grand total (or zero for cumulative/historical reports) and grand average.

A postings report is a list of postings with a running total, and a little extra transaction info to help with rendering. This is used eg for the register command.

datadata BalanceAccumulation
#

How to accumulate calculated values across periods (columns) in a balance report. "Balance report types -> Accumulation type" in the hledger manual.

Constructors

  • PerPeriod

    No accumulation. Eg, shows the change of balance in each period.

  • Cumulative

    Accumulate changes across periods, starting from zero at report start.

  • Historical

    Accumulate changes across periods, including any from before report start. Eg, shows the historical end balance of each period.

Instances3Eq, Show, Default
datadata BalanceCalculation
#

What to calculate for each cell in a balance report. "Balance report types -> Calculation type" in the hledger manual.

Constructors

  • CalcChange

    Sum of posting amounts in the period.

  • CalcBudget

    Sum of posting amounts and the goal for the period.

  • CalcValueChange

    Change from previous period's historical end value to this period's historical end value.

  • CalcGain

    Change from previous period's gain, i.e. valuation minus cost basis.

  • CalcPostingsCount

    Number of postings in the period.

Instances3Eq, Show, Default
classclass HasReportOptsNoUpdate a => HasReportOpts a where
#

Special lenses for ReportOpts which also update the Query and QueryOpts in ReportSpec. Note that these are not true lenses, as they have a further restriction on the functor. This will work as a normal lens for all common uses, but since they don't obey the lens laws for some fancy cases, they may fail in some exotic circumstances.

Note that setEither/overEither should only be necessary with querystring and reportOpts: the other lenses should never fail.

Examples:
Example5 expressions
import Lens.Micro (set)_rsQuery <$> setEither querystring ["assets"] defreportspecRight (Acct (RegexpCI "assets"))_rsQuery <$> setEither querystring ["(assets"] defreportspecLeft "This regular expression is invalid or unsupported, please correct it:\n(assets"_rsQuery $ set querystring ["assets"] defreportspecAcct (RegexpCI "assets")_rsQuery $ set period (MonthPeriod 2021 08) defreportspecDate DateSpan 2021-08

XXX testing error output isn't working since adding color to it: > import System.Environment > setEnv NO_COLOR "1" >> return (_rsQuery $ set querystring ["(assets"] defreportspec) *** Exception: Error: Updating ReportSpec failed: try using overEither instead of over or setEither instead of set

Methods

Instances3HasReportOpts
classclass HasReportOptsNoUpdate c where
#
Instances3HasReportOptsNoUpdate
datadata ReportOpts
#

Standard options for customising report filtering and output. Most of these correspond to standard hledger command-line options or query arguments, but not all. Some are used only by certain commands, as noted below.

Constructors

Instances4Show, Default, HasReportOpts, HasReportOptsNoUpdate
datadata ReportSpec
#

A fully-determined set of report parameters (report options with all partial values made total, eg the begin and end dates are known, avoiding date/regex errors; plus the reporting date), and the query successfully calculated from them.

If you change the report options or date in one of these, you should use reportOptsToSpec to regenerate the whole thing, avoiding inconsistency.

Constructors

Instances5Show, Default, HasReportOpts, HasReportOptsNoUpdate, HasReportSpec
datadata CBCSubreportSpec a
#

Description of one subreport within a compound balance report. Part of a CompoundBalanceCommandSpec, but also used in hledger-lib.

Constructors

datadata CompoundPeriodicReport a b
#

A compound balance report has:

  • an overall title

  • the period (date span) of each column

  • one or more named, normal-positive multi balance reports, with columns corresponding to the above, and a flag indicating whether they increased or decreased the overall totals

  • a list of overall totals for each column, and their grand total and average

It is used in compound balance report commands like balancesheet, cashflow and incomestatement.

Instances6Functor, Show, Generic, ToJSON, HasAmounts, Rep
datadata DisplayName
#

A full name, display name, and indent level for an account.

Instances4Eq, Ord, Show, ToJSON
  • Eq DisplayNameDefined in hledger-lib-1.52.4 · Hledger.Reports.ReportTypes
  • Ord DisplayNameDefined in hledger-lib-1.52.4 · Hledger.Reports.ReportTypes
  • Show DisplayNameDefined in hledger-lib-1.52.4 · Hledger.Reports.ReportTypes
  • ToJSON DisplayNameDefined in hledger-lib-1.52.4 · Hledger.Reports.ReportTypes
datadata PeriodicReport a b
#

A periodic report is a generic tabular report, where each row corresponds to some label (usually an account name) and each column to a date period. The column periods are usually consecutive subperiods formed by splitting the overall report period by some report interval (daily, weekly, etc.). It has:

  1. a list of each column's period (date span)

  2. a list of rows, each containing:

  • an account label

  • the account's depth

  • A list of amounts, one for each column. Depending on the value type, these can represent balance changes, ending balances, budget performance, etc. (for example, see BalanceAccumulation and Hledger.Cli.Commands.Balance).

  • the total of the row's amounts for a periodic report, or zero for cumulative/historical reports (since summing end balances generally doesn't make sense).

  • the average of the row's amounts

  1. the column totals, and the overall grand total (or zero for cumulative/historical reports) and grand average.

Instances8Bifunctor, Functor, Show, Generic, ToJSON, HasAmounts, …
datadata PeriodicReportRow a b
#
Instances8Bifunctor, Functor, Show, Generic, Semigroup, ToJSON, …
datadata GhcDebugMode
#

Whether ghc-debug support is included in this build, and if so, how it will behave. When hledger is built with the ghcdebug cabal flag (off by default, because of extra deps), it can listen (on unix ?) for connections from ghc-debug clients like ghc-debug-brick, for pausing/resuming the program and inspecting memory usage and profile information.

With a ghc-debug-supporting build, ghc-debug can be enabled by running hledger with a negative --debug level. There are three different modes: --debug=-1 - run normally (can be paused/resumed by a ghc-debug client), --debug=-2 - pause and await client commands at program start (not useful currently), --debug=-3 - pause and await client commands at program end.

Instances3Eq, Ord, Show
datadata YNA
#
Instances2Eq, Show
  • Eq YNADefined in hledger-lib-1.52.4 · Hledger.Utils.IO
  • Show YNADefined in hledger-lib-1.52.4 · Hledger.Utils.IO
datadata FinalParseError' e
#

A type representing "final" parse errors that cannot be backtracked from and are guaranteed to halt parsing. The anti-backtracking behaviour is implemented by an ExceptT layer in the parser's monad stack, using this type as the ExceptT error type.

We have three goals for this type: (1) it should be possible to convert any parse error into a "final" parse error, (2) it should be possible to take a parse error thrown from an include file and re-throw it in the context of the parent file, and (3) the pretty-printing of "final" parse errors should be consistent with that of ordinary parse errors, but should also report the stack of parent files when errors are thrown from included files.

In order to pretty-print a "final" parse error (goal 3), it must be bundled with include filepaths and its full source text. When a "final" parse error is thrown from within a parser, we do not have access to the full source, so we must hold the parse error (FinalParseError) until it can be combined with the full source (and any parent file paths) by the parser's caller (FinalParseErrorBundle).

Instances3Show, Semigroup, Monoid
datadata FinalParseErrorBundle' e
#

A type bundling a ParseError with its full source text, filepath, and stack of include files. Suitable for pretty-printing.

Megaparsec's ParseErrorBundle type already bundles a parse error with its full source text and filepath, so we just add a stack of include files.

Instances1Show

Custom error data for hledger parsers. Specialised for a Text parse stream. ReparseableTextParseErrorData ?

Instances5Eq, Show, ShowErrorComponent, Ord
datadata SourceExcerpt
#

A fragment of source suitable for "re-parsing". The purpose of this data type is to preserve the content and source position of the excerpt so that parse errors raised during "re-parsing" may properly reference the original source.

typetype RegexError = String
#

An error message arising during a regular expression operation. Eg: trying to compile a malformed regular expression, or trying to apply a malformed replacement pattern.

datadata Regexp
#

Regular expression. Extended regular expression-ish syntax ? But does not support eg (?i) syntax.

Instances8Eq, Ord, Read, Show, NFData, ToJSON, …
typetype Replacement = String
#

A replacement pattern. May include numeric backreferences (N).

datadata SourcePos
#

The data type SourcePos represents source positions. It contains the name of the source file, a line number, and a column number. Source line and column positions change intensively during parsing, so we need to make them strict to avoid memory leaks.

Constructors

Instances10Eq, Data, Ord, Read, Show, Generic, …
datadata DependencyType
#

These are the two ways in which one test may depend on the others.

This is the same distinction as the hard vs soft dependencies in TestNG.

Constructors

  • AllSucceed

    The current test tree will be executed after its dependencies finish, and only if all of the dependencies succeed.

  • AllFinish

    The current test tree will be executed after its dependencies finish, regardless of whether they succeed or not.

Instances3Eq, Read, Show
datadata TestTree
#

The main data structure defining a test suite.

It consists of individual test cases and properties, organized in named groups which form a tree-like hierarchy.

There is no generic way to create a test case. Instead, every test provider (tasty-hunit, tasty-smallcheck etc.) provides a function to turn a test case into a TestTree.

Groups can be created using testGroup.

datadata Timeout
#

Timeout to be applied to individual tests.

Constructors

Instances4Eq, Ord, Show, IsOption
  • Eq TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core

    Auto-derived instance, just to allow storing in a Data.Map.Map and such.

  • Ord TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core

    Auto-derived instance, just to allow storing in a Data.Map.Map and such.

  • Show TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core
  • IsOption TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core
classclass Assertable t where
#

Deprecated. This class or type seems dubious. If you have a good use case for it, please create an issue for tasty. Otherwise, it may be removed in a future version.

Allows the extension of the assertion mechanism.

Since an Assertion can be a sequence of Assertions and IO actions, there is a fair amount of flexibility of what can be achieved. As a rule, the resulting Assertion should be the body of a TestCase or part of a TestCase; it should not be used to assert multiple, independent conditions.

If more complex arrangements of assertions are needed, Test and Testable should be used.

Methods

Instances4Assertable
typetype Assertion = IO ()
#

An assertion is simply an IO action. Assertion failure is indicated by throwing an exception, typically HUnitFailure.

Instead of throwing the exception directly, you should use functions like assertFailure and assertBool.

Test cases are composed of a sequence of one or more assertions.

typetype AssertionPredicate = IO Bool
#

Deprecated. This class or type seems dubious. If you have a good use case for it, please create an issue for tasty. Otherwise, it may be removed in a future version.

The result of an assertion that hasn't been evaluated yet.

Most test cases follow the following steps:

  1. Do some processing or an action.

  2. Assert certain conditions.

However, this flow is not always suitable. AssertionPredicate allows for additional steps to be inserted without the initial action to be affected by side effects. Additionally, clean-up can be done before the test case has a chance to end. A potential work flow is:

  1. Write data to a file.

  2. Read data from a file, evaluate conditions.

  3. Clean up the file.

  4. Assert that the side effects of the read operation meet certain conditions.

  5. Assert that the conditions evaluated in step 2 are met.

typetype Year = Integer
#

Year of Common Era (when positive).

System.Console.CmdArgs.Explicit

valueflagHelpFormat :: (HelpFormat -> TextFormat -> a -> a) -> Flag a
#

Create a help flag triggered by -?/--help. The user may optionally modify help by specifying the format, such as:

--help=all          - help for all modes
--help=html         - help in HTML format
--help=100          - wrap the text at 100 characters
--help=100,one      - full text wrapped at 100 characters
valueflagVersion :: (a -> a) -> Flag a
#

Create a version flag triggered by -V/--version.

valueprocessArgs :: Mode a -> IO a
#

Process the flags obtained by getArgs and expandArgsAt with a mode. Displays an error and exits with failure if the command line fails to parse, or returns the associated value. Implemented in terms of process. This function makes use of the following environment variables:

  • $CMDARGS_COMPLETE - causes the program to produce completions using complete, then exit. Completions are based on the result of getArgs, the index of the current argument is taken from $CMDARGS_COMPLETE (set it to - to complete the last argument), and the index within that argument is taken from $CMDARGS_COMPLETE_POS (if set).

  • $CMDARGS_HELPER/$CMDARGS_HELPER_PROG - uses the helper mechanism for entering command line programs as described in System.Console.CmdArgs.Helper.

valueprocessValue :: Mode a -> [String] -> a
#

Process a list of flags (usually obtained from getArgs and expandArgsAt) with a mode. Throws an error if the command line fails to parse, or returns the associated value. Implemeneted in terms of process. This function does not take account of any environment variables that may be set (see processArgs).

If you are in IO you will probably get a better user experience by calling processValueIO.

valuecomplete
  1. :: Mode a

    Mode specifying which arguments are allowed

  2. -> [String]

    Arguments the user has already typed

  3. -> (Int, Int)

    0-based index of the argument they are currently on, and the position in that argument

  4. -> [Complete]
#

Given a current state, return the set of commands you could type now, in preference order.

valueexpandArgsAt :: [String] -> IO [String]
#

Expand @ directives in a list of arguments, usually obtained from getArgs. As an example, given the file test.txt with the lines hello and world:

expandArgsAt ["@test.txt","!"] == ["hello","world","!"]

Any @ directives in the files will be recursively expanded (raising an error if there is infinite recursion).

To supress @ expansion, pass any @ arguments after --.

valueprocess :: Mode a -> [String] -> Either String a
#

Process a list of flags (usually obtained from getArgs/expandArgsAt) with a mode. Returns Left and an error message if the command line fails to parse, or Right and the associated value.

valuejoinArgs :: [String] -> String
#

Given a sequence of arguments, join them together in a manner that could be used on the command line, giving preference to the Windows cmd shell quoting conventions.

For an alternative version, intended for actual running the result in a shell, see "System.Process.showCommandForUser"

valueflagArg :: Update a -> FlagHelp -> Arg a
#

Create an argument flag, with an update function and the type of the argument.

valueflagBool :: [Name] -> (Bool -> a -> a) -> Help -> Flag a
#

Create a boolean flag, with a list of flag names, an update function and some help text.

valueflagNone :: [Name] -> (a -> a) -> Help -> Flag a
#

Create a flag taking no argument value, with a list of flag names, an update function and some help text.

valueflagOpt :: String -> [Name] -> Update a -> FlagHelp -> Help -> Flag a
#

Create a flag taking an optional argument value, with an optional value, a list of flag names, an update function, the type of the argument and some help text.

valueflagReq :: [Name] -> Update a -> FlagHelp -> Help -> Flag a
#

Create a flag taking a required argument value, with a list of flag names, an update function, the type of the argument and some help text.

valuemode :: Name -> a -> Help -> Arg a -> [Flag a] -> Mode a
#

Create a mode with a name, an initial value, some help text, a way of processing arguments and a list of flags.

valuemodeEmpty :: a -> Mode a
#

Create an empty mode specifying only modeValue. All other fields will usually be populated using record updates.

valuemodes :: String -> a -> Help -> [Mode a] -> Mode a
#

Create a list of modes, with a program name, an initial value, some help text and the child modes.

valueremap2 :: Remap m => (a -> b) -> (b -> a) -> m a -> m b
#

Restricted version of remap where the values are isomorphic.

datadata Complete
#

How to complete a command line option. The Show instance is suitable for parsing from shell scripts.

Constructors

Instances3Eq, Ord, Show
  • Eq CompleteDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Complete
  • Ord CompleteDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Complete
  • Show CompleteDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Complete
datadata HelpFormat
#

Specify the format to output the help.

Constructors

Instances7Bounded, Enum, Eq, Ord, Read, Show, …
  • Bounded HelpFormatDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help
  • Enum HelpFormatDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help
  • Eq HelpFormatDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help
  • Ord HelpFormatDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help
  • Read HelpFormatDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help
  • Show HelpFormatDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help
  • Default HelpFormatDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help
datadata Arg a
#

An unnamed argument. Anything not starting with - is considered an argument, apart from "-" which is considered to be the argument "-", and any arguments following "--". For example:

programname arg1 -j - --foo arg3 -- -arg4 --arg5=1 arg6

Would have the arguments:

["arg1","-","arg3","-arg4","--arg5=1","arg6"]

Constructors

  • Arg
    • argValue :: Update a

      A way of processing the argument.

    • argType :: FlagHelp

      The type of data for the argument, i.e. FILE/DIR/EXT

    • argRequire :: Bool

      Is at least one of these arguments required, the command line will fail if none are set

Instances3Remap, Show, Packer
  • Remap ArgDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Show (Arg a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help · orphan
  • Packer a => Packer (Arg a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Helper
datadata Flag a
#

A flag, consisting of a list of flag names and other information.

Constructors

Instances3Remap, Show, Packer
  • Remap FlagDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Show (Flag a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help · orphan
  • Packer a => Packer (Flag a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Helper
datadata FlagInfo
#

The FlagInfo type has the following meaning:

             FlagReq     FlagOpt      FlagOptRare/FlagNone
-xfoo        -x=foo      -x=foo       -x -foo
-x foo       -x=foo      -x foo       -x foo
-x=foo       -x=foo      -x=foo       -x=foo
--xx foo     --xx=foo    --xx foo     --xx foo
--xx=foo     --xx=foo    --xx=foo     --xx=foo

Constructors

Instances4Eq, Ord, Show, Packer
  • Eq FlagInfoDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Ord FlagInfoDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Show FlagInfoDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Packer FlagInfoDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Helper
datadata Group a
#

A group of items (modes or flags). The items are treated as a list, but the group structure is used when displaying the help message.

Constructors

Instances5Functor, Show, Semigroup, Monoid, Packer
  • Functor GroupDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Show a => Show (Group a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Semigroup (Group a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Monoid (Group a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Packer a => Packer (Group a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Helper
typetype Help = String
#

A help message that goes with either a flag or a mode.

datadata Mode a
#

A mode. Do not use the Mode constructor directly, instead use mode to construct the Mode and then record updates. Each mode has three main features:

To produce the help information for a mode, either use helpText or show.

Constructors

Instances3Remap, Show, Packer
  • Remap ModeDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Show (Mode a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Help · orphan
  • Packer a => Packer (Mode a)Defined in cmdargs-0.10.22 · System.Console.CmdArgs.Helper
classclass Remap (m :: Type -> Type) where
#

Like functor, but where the the argument isn't just covariant.

Methods

  • remap :: (a -> b) -> (b -> (a, a -> b)) -> m a -> m b

    Convert between two values.

Instances3Remap
  • Remap ArgDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Remap FlagDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
  • Remap ModeDefined in cmdargs-0.10.22 · System.Console.CmdArgs.Explicit.Type
typetype Update a = String -> a -> Either String a
#

A function to take a string, and a value, and either produce an error message (Left), or a modified value (Right).