-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Command-line interface for the hledger accounting system
--   
--   The command-line interface for the hledger accounting system. Its
--   basic function is to read a plain text file describing financial
--   transactions and produce useful reports.
--   
--   hledger is a robust, cross-platform set of tools for tracking money,
--   time, or any other commodity, using double-entry accounting and a
--   simple, editable file format, with command-line, terminal and web
--   interfaces. It is a Haskell rewrite of Ledger, and one of the leading
--   implementations of Plain Text Accounting. Read more at:
--   <a>https://hledger.org</a>
@package hledger
@version 1.50.3

module Hledger.Cli.Anchor
setAccountAnchor :: Maybe Text -> [Text] -> Text -> Cell border text -> Cell border text
dateCell :: Lines border => Maybe Text -> [Text] -> Text -> Day -> Cell border Text
dateSpanCell :: Lines border => Maybe Text -> [Text] -> Text -> DateSpan -> Cell border Text
headerDateSpanCell :: Maybe Text -> [Text] -> DateSpan -> Cell () Text


-- | Instances for obfuscating sensitive data (mainly text, not numbers) in
--   various types.
--   
--   Currently this is deterministic and does not provide much privacy. It
--   has been moved to a hidden --obfuscate flag, with the old --anon flag
--   now raising an error. See
--   <a>https://github.com/simonmichael/hledger/issues/2133</a> .
module Hledger.Cli.Anon
class Anon a

-- | Consistent converter to structure with sensitive data anonymized
anon :: Anon a => a -> a

-- | Anonymize account name preserving hierarchy
anonAccount :: AccountName -> AccountName
instance Hledger.Cli.Anon.Anon Hledger.Data.Types.Journal
instance Hledger.Cli.Anon.Anon Hledger.Data.Types.Posting
instance Hledger.Cli.Anon.Anon Data.Text.Internal.Text
instance Hledger.Cli.Anon.Anon Hledger.Data.Types.Transaction


-- | Read extra CLI arguments from a hledger config file.
module Hledger.Cli.Conf

-- | A hledger config file.
data Conf

-- | The name of a config file section, with surrounding brackets and
--   whitespace removed.
type SectionName = String

-- | Try to read a hledger config from a config file specified by --conf,
--   or the first config file found in any of several default file paths.
--   If --no-conf was used, or if no file was specified or found, this
--   returns a null Conf. If a specified file, or the first file found, can
--   not be read or parsed, this returns an error message. Otherwise this
--   returns the parsed Conf, and the file path.
getConf :: RawOpts -> IO (Either String (Conf, Maybe FilePath))

-- | Like getConf but throws an error on failure.
getConf' :: RawOpts -> IO (Conf, Maybe FilePath)
nullconf :: Conf

-- | Fetch all the arguments/options defined in a section with this name,
--   if it exists. This should be "general" for the unnamed first section,
--   or a hledger command name.
confLookup :: SectionName -> Conf -> [Arg]

-- | Get the highest precedence config file, based on the current
--   directory.
activeConfFile :: IO (Maybe FilePath)

-- | Get the highest precedence local config file: a config file in the
--   current directory or above, that is not a user-wide config file.
activeLocalConfFile :: IO (Maybe FilePath)

-- | Get the highest precedence user-wide config file, based on the current
--   directory. (This may not be the active config file.)
activeUserConfFile :: IO (Maybe FilePath)

-- | Get the possibleConfFiles which exist, based on the current directory.
confFiles :: IO [FilePath]

-- | Get the possibleUserConfFiles which exist, based on the current
--   directory.
userConfFiles :: IO [FilePath]
parseConf :: FilePath -> Text -> Either (ParseErrorBundle Text HledgerParseErrorData) [ConfSection]
instance GHC.Classes.Eq Hledger.Cli.Conf.Conf
instance GHC.Classes.Eq Hledger.Cli.Conf.ConfFileSpec
instance GHC.Classes.Eq Hledger.Cli.Conf.ConfSection
instance GHC.Internal.Show.Show Hledger.Cli.Conf.Conf
instance GHC.Internal.Show.Show Hledger.Cli.Conf.ConfFileSpec
instance GHC.Internal.Show.Show Hledger.Cli.Conf.ConfSection


-- | Embedded documentation files in various formats, and helpers for
--   viewing them.
--   
--   |
module Hledger.Cli.DocFiles
type Topic = String

-- | Print plain text help for this tool. Takes an optional topic argument
--   for convenience but it is currently ignored.
printHelpForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display a man page for this tool, scrolled to the given topic if
--   provided, using "man". When a topic is provided we force man to use
--   "less", ignoring $MANPAGER and $PAGER.
runManForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display an info manual for this topic, opened at the given topic if
--   provided, using the "info" executable in $PATH. Topic can be an exact
--   heading or a heading prefix; info will favour an exact match.
runInfoForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display plain text help for this tool, scrolled to the given topic if
--   any, using the users $PAGER or "less". When a topic is provided we
--   always use less, ignoring $PAGER.
--   
--   This is less robust than the newer Hledger.Utils.IO.runPager, but that
--   one doesn't yet support scrolling to a topic.
runPagerForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display one of the hledger tldr pages, using "tldr".
runTldrForPage :: TldrPage -> IO ()

module Hledger.Cli.Version

-- | A Cabal/Hackage-compatible package version string: one or more
--   dot-separated integers.
type PackageVersionString = String

-- | The number parts parsed from a PackageVersionString.
type Version = NonEmpty Int
nullversion :: NonEmpty Int

-- | Parse a valid Cabal/Hackage-compatible package version.
toVersion :: PackageVersionString -> Maybe Version
showVersion :: Version -> String
isReleaseVersion :: Version -> Bool

-- | A hledger version string, as shown by hledger --version. This can
--   vary; some examples:
--   
--   <ul>
--   <li>dev builds: hledger 1.42.99-g2288f5193-20250422, mac-aarch64</li>
--   <li>release builds: hledger 1.42.1, mac-aarch64</li>
--   <li>older versions: hledger 1.21</li>
--   </ul>
type HledgerVersionString = String

-- | The name and package version of a hledger binary, and the build's git
--   hash, the release date, and the binary's intended operating machine
--   and machine architecture, if we can detect these. Also, a copy of the
--   --version output from which it was parsed.
data HledgerBinaryInfo
HledgerBinaryInfo :: String -> ProgramName -> Version -> String -> Maybe GitHash -> Maybe Day -> Maybe OsName -> Maybe ArchName -> HledgerBinaryInfo
[hbinVersionOutput] :: HledgerBinaryInfo -> String
[hbinProgramName] :: HledgerBinaryInfo -> ProgramName
[hbinPackageVersion] :: HledgerBinaryInfo -> Version
[hbinPackageVersionStr] :: HledgerBinaryInfo -> String
[hbinGitHash] :: HledgerBinaryInfo -> Maybe GitHash
[hbinReleaseDate] :: HledgerBinaryInfo -> Maybe Day
[hbinOs] :: HledgerBinaryInfo -> Maybe OsName
[hbinArch] :: HledgerBinaryInfo -> Maybe ArchName
nullbinaryinfo :: HledgerBinaryInfo

-- | The program name from a hledger version string: hledger, hledger-ui,
--   hledger-web..
type ProgramName = String

-- | The git hash from a hledger version string, excluding the g prefix.
type GitHash = String

-- | The machine architecture from a hledger version string. This is the
--   value of <tt>System.Info.arch</tt>, eg: aarch64, alpha, arm, hppa,
--   hppa1_1, i386, ia64, loongarch32, loongarch64, m68k, mips, mipseb,
--   mipsel, nios2, powerpc, powerpc64, powerpc64le, riscv32, riscv64,
--   rs6000, s390, s390x, sh4, sparc, sparc64, vax, x86_64..
type ArchName = String

-- | Parse hledger's --version output.
--   
--   <pre>
--   &gt;&gt;&gt; isRight $ parseHledgerVersion "hledger 1.21"
--   True
--   
--   &gt;&gt;&gt; isRight $ parseHledgerVersion "hledger 1.42.1, mac-aarch64"
--   True
--   
--   &gt;&gt;&gt; isRight $ parseHledgerVersion "hledger 1.42.99-g2288f5193-20250422, mac-aarch64"
--   True
--   </pre>
parseHledgerVersion :: HledgerVersionString -> Either String HledgerBinaryInfo

-- | The "1.50.3" string defined with -D in this package's
--   package.yaml/.cabal file (by Shake setversion), if any. Normally a
--   dotted number string with 1-3 components.
packageversion :: PackageVersionString

-- | Just the first 1-2 components of packageversion.
packagemajorversion :: PackageVersionString

-- | Given possible git state info from the build directory (or a git
--   error, which is ignored), and the debug build flag, executable name
--   and package version for the package being built, make the best version
--   string we can. Here is the logic:
--   
--   <ul>
--   <li>Program name, OS and architecture are always shown.</li>
--   <li>The package version is always shown.</li>
--   <li>If there is git info at build time, the latest commit hash and
--   commit date are shown, and (TODO, requires githash to use -uno for
--   giDirty): if the working copy has uncommitted changes a + sign is
--   appended.</li>
--   <li>(TODO, requires adding --match support to githash: If there are
--   tags matching THISPKG-[0-9]*, the latest one is used to calculate
--   patch level (number of commits since tag), and if non-zero, it and the
--   branch name are shown.)</li>
--   <li>If the debug build flag was enabled for the package being built,
--   and for hledger-lib (both are needed), "ghc-debug support" is
--   shown.</li>
--   </ul>
--   
--   Some example outputs:
--   
--   <ul>
--   <li>A homebrew binary, not built in git repo: hledger-ui 1.24,
--   mac-aarch64</li>
--   <li>A CI release build, built in git repo at release tag: hledger-ui
--   1.24.1-g455b35293-20211210, mac-x86_64</li>
--   <li>(TODO) A dev build, built in git repo: hledger-ui
--   1.24.1+1-g4abd8ef10-20211210 (1.24-branch), mac-x86_64</li>
--   </ul>
--   
--   This function requires git log to show the default (rfc2822-style)
--   date format, so that must not be overridden by a log.date git config
--   variable.
--   
--   The GitInfo if any, fetched by template haskell, is passed down from a
--   top-level module, reducing wasteful recompilation. The status of the
--   debug build flag is also passed down, since it is specific to each
--   hledger package.
--   
--   This is used indirectly by at least hledger, hledger-ui, and
--   hledger-web, so output should be suitable for all of those.
versionStringWith :: Either String GitInfo -> Bool -> ProgramName -> PackageVersionString -> HledgerVersionString
instance GHC.Classes.Eq Hledger.Cli.Version.HledgerBinaryInfo
instance GHC.Internal.Show.Show Hledger.Cli.Version.HledgerBinaryInfo


-- | Common cmdargs modes and flags, a command-line options type, and
--   related utilities used by hledger commands.
module Hledger.Cli.CliOptions

-- | The name of this program's executable.
progname :: ProgramName

-- | Generate the version string for this program. The template haskell
--   call is here rather than in Hledger.Cli.Version to avoid wasteful
--   recompilation.
prognameandversion :: String
binaryinfo :: HledgerBinaryInfo

-- | Common input-related flags: --file, --rules, --conf, --alias...
inputflags :: [Flag RawOpts]

-- | Common report-related flags: --period, --cost, etc.
reportflags :: [Flag RawOpts]
helpflags :: [Flag RawOpts]
terminalflags :: [Flag RawOpts]
helpflagstitle :: String

-- | Flags for selecting flat/tree mode, used for reports organised by
--   account. With a True argument, shows some extra help about
--   inclusive/exclusive amounts.
flattreeflags :: Bool -> [Flag RawOpts]

-- | hledger CLI's --conf/--no-conf flags.
confflags :: [Flag RawOpts]
hiddenflags :: [Flag RawOpts]

-- | Common legacy flags that are accepted but not shown in --help, when
--   running the main mode.
hiddenflagsformainmode :: [Flag RawOpts]

-- | Common output-related flags: --output-file, --output-format...
outputFormatFlag :: [String] -> Flag RawOpts
outputFileFlag :: Flag RawOpts
generalflagsgroup1 :: (String, [Flag RawOpts])
generalflagsgroup2 :: (String, [Flag RawOpts])
generalflagsgroup3 :: (String, [Flag RawOpts])
mkgeneralflagsgroups1 :: [Flag RawOpts] -> [(String, [Flag RawOpts])]
mkgeneralflagsgroups2 :: [Flag RawOpts] -> [(String, [Flag RawOpts])]
mkgeneralflagsgroups3 :: [Flag RawOpts] -> [(String, [Flag RawOpts])]
cligeneralflagsgroups1 :: [(String, [Flag RawOpts])]
cligeneralflagsgroups2 :: [(String, [Flag RawOpts])]
cligeneralflagsgroups3 :: [(String, [Flag RawOpts])]

-- | An empty cmdargs mode to use as a template. Modes describe the
--   top-level command, ie the program, or a subcommand, telling cmdargs
--   how to parse a command line and how to generate the command's usage
--   text.
defMode :: Mode RawOpts

-- | A cmdargs mode suitable for a hledger built-in command with the given
--   names (primary name + optional aliases). The usage message shows
--   [QUERY] as argument.
defCommandMode :: [Name] -> Mode RawOpts

-- | A cmdargs mode representing the hledger add-on command with the given
--   name, providing hledger's common input<i>reporting</i>help flags. Just
--   used when invoking addons.
addonCommandMode :: Name -> Mode RawOpts

-- | Build a cmdarg mode for a hledger command, from a help template and
--   flag/argument specifications. Reduces boilerplate a little, though the
--   complicated cmdargs flag and argument specs are still required.
hledgerCommandMode :: CommandHelpStr -> [Flag RawOpts] -> [(String, [Flag RawOpts])] -> [Flag RawOpts] -> ([Arg RawOpts], Maybe (Arg RawOpts)) -> Mode RawOpts
argsFlag :: FlagHelp -> Arg RawOpts

-- | Get a mode's usage message as a nicely wrapped string.
showModeUsage :: Mode a -> String

-- | Add command aliases to the command's help string.
withAliases :: String -> [String] -> String

-- | Get all sorted unique filenames in the current user's PATH. We do not
--   currently filter out non-file objects or files without execute
--   permission.
likelyExecutablesInPath :: IO [String]

-- | Command line options, used in the <tt>hledger</tt> package and above.
--   This is the "opts" used throughout hledger CLI code. representing the
--   options and arguments that were provided at startup on the
--   command-line.
data CliOpts
CliOpts :: RawOpts -> String -> [FilePath] -> InputOpts -> ReportSpec -> Maybe FilePath -> Maybe String -> Maybe Bool -> Maybe YNA -> Int -> Bool -> Maybe String -> Int -> POSIXTime -> CliOpts
[rawopts_] :: CliOpts -> RawOpts
[command_] :: CliOpts -> String
[file_] :: CliOpts -> [FilePath]
[inputopts_] :: CliOpts -> InputOpts
[reportspec_] :: CliOpts -> ReportSpec
[output_file_] :: CliOpts -> Maybe FilePath
[output_format_] :: CliOpts -> Maybe String

-- | <ul>
--   <li>-pager</li>
--   </ul>
[pageropt_] :: CliOpts -> Maybe Bool

-- | <ul>
--   <li>-color. Controls use of ANSI color and ANSI styles.</li>
--   </ul>
[coloropt_] :: CliOpts -> Maybe YNA

-- | debug level, set by <tt>--debug[=N]</tt>. See also <a>debugLevel</a>.
[debug_] :: CliOpts -> Int
[no_new_accounts_] :: CliOpts -> Bool

-- | the --width value provided, if any
[width_] :: CliOpts -> Maybe String

-- | estimated usable screen width, based on 1. the width reported by the
--   terminal, if supported 2. the default (80)
[available_width_] :: CliOpts -> Int
[progstarttime_] :: CliOpts -> POSIXTime
class HasCliOpts c
cliOpts :: HasCliOpts c => Lens' c CliOpts
available_width :: HasCliOpts c => Lens' c Int
coloropt :: HasCliOpts c => Lens' c (Maybe YNA)
command :: HasCliOpts c => Lens' c String
debug__ :: HasCliOpts c => Lens' c Int
file__ :: HasCliOpts c => Lens' c [FilePath]
inputopts :: HasCliOpts c => Lens' c InputOpts
no_new_accounts :: HasCliOpts c => Lens' c Bool
output_file :: HasCliOpts c => Lens' c (Maybe FilePath)
output_format :: HasCliOpts c => Lens' c (Maybe String)
pageropt :: HasCliOpts c => Lens' c (Maybe Bool)
progstarttime :: HasCliOpts c => Lens' c POSIXTime
rawopts__ :: HasCliOpts c => Lens' c RawOpts
reportspec :: HasCliOpts c => Lens' c ReportSpec
width__ :: HasCliOpts c => Lens' c (Maybe String)
defcliopts :: CliOpts
getHledgerCliOpts :: Mode RawOpts -> IO CliOpts

-- | A helper for addon commands: this parses options and arguments from
--   the current command line using the given hledger-style cmdargs mode,
--   and returns a CliOpts. Or, with --help or -h present, it prints long
--   or short help, and exits the program. When --debug is present, also
--   prints some debug output. Note this is not used by the main hledger
--   executable.
--   
--   The help texts are generated from the mode. Long help includes the
--   full usage description generated by cmdargs (including all supported
--   options), framed by whatever pre- and postamble text the mode
--   specifies. It's intended that this forms a complete help document or
--   manual.
--   
--   Short help is a truncated version of the above: the preamble and the
--   first part of the usage, up to the first line containing "flags:"
--   (normally this marks the start of the common hledger flags); plus a
--   mention of --help and the (presumed supported) common hledger options
--   not displayed.
--   
--   Tips: Empty lines in the pre/postamble are removed by cmdargs; add a
--   space character to preserve them.
getHledgerCliOpts' :: Mode RawOpts -> [String] -> IO CliOpts

-- | Parse raw option string values to the desired final data types. Any
--   relative smart dates will be converted to fixed dates based on today's
--   date. Parsing failures will raise an error. Also records the terminal
--   width, if supported.
rawOptsToCliOpts :: RawOpts -> IO CliOpts

-- | Drop the arguments ("args") from this CliOpts' rawopts field.
cliOptsDropArgs :: CliOpts -> CliOpts

-- | cmdargs eats the first double-dash (--) argument when parsing a
--   command line, which causes problems for the run and repl commands.
--   Sometimes we work around this by duplicating that first -- argument.
--   This doesn't break anything that we know of yet.
argsAddDoubleDash :: (Eq a, IsString a) => [a] -> [a]

-- | All the output formats known by any command, for outputFormatFromOpts.
--   To automatically infer it from -o/--output-file, it needs to be listed
--   here.
outputFormats :: [String]
defaultOutputFormat :: String

-- | A command's name, optional official abbreviation, and help preamble
--   &amp; postamble, as a specially formatted single string. Used to
--   generate the CLI help, and also the command's doc in the hledger
--   manual. See parseCommandHelp for the format.
type CommandHelpStr = String

-- | Parse a command's embedded help text (<tt>Somecommand.txt</tt>). That
--   text is generated by <tt>Shake cmdhelp</tt> from the command's doc
--   source (<tt>Somecommand.md</tt>). <tt>Somecommand.md</tt> should be
--   formatted as follows:
--   
--   <ul>
--   <li>First line: the command name, as a markdown heading.</li>
--   <li>Optional third line: the command's official abbreviated name,
--   parenthesised.</li>
--   <li>From third or fifth line to a <tt>```flags</tt> line: the command
--   help preamble. Usually one sentence or paragraph; any blank lines will
--   not be rendered.</li>
--   <li>A fenced code block beginning with <tt>```flags</tt>, containing a
--   <tt>Flags:</tt> line, followed by a snapshot of the command-specific
--   flags help as generated by cmdargs or "none" if there are no
--   command-specific flags. This should contain no blank lines (no extra
--   newlines in the cmdargs command mode help strings). This is shown
--   as-is in manuals, and regenerated at runtime for --help output.</li>
--   <li>Any remaining lines: the command help postamble.</li>
--   </ul>
--   
--   (Note the difference between <tt>Somecommand.md</tt>, which is the
--   markdown source file, and <tt>Somecommand.txt</tt>, which is the plain
--   text file generated by <tt>Shake cmdhelp</tt>, which this function
--   parses.)
parseCommandHelp :: CommandHelpStr -> Maybe CommandHelp

-- | Get the (tilde-expanded, absolute) journal file path from 1. options,
--   2. an environment variable, or 3. the default. Actually, returns one
--   or more file paths. There will be more than one if multiple -f options
--   were provided. File paths can have a READER: prefix naming a
--   reader/data format.
journalFilePathFromOpts :: CliOpts -> IO (NonEmpty String)

-- | Like journalFilePathFromOpts, but does not use defaultJournalPath
journalFilePathFromOptsNoDefault :: CliOpts -> IO (Maybe (NonEmpty String))

-- | Get the (tilde-expanded) rules file path from options, if any.
rulesFilePathFromOpts :: CliOpts -> IO (Maybe FilePath)

-- | Get the expanded, absolute output file path specified by an
--   -o/--output-file options, or nothing, meaning stdout.
outputFileFromOpts :: CliOpts -> IO (Maybe FilePath)

-- | Get the output format from the --output-format option, otherwise from
--   a recognised file extension in the --output-file option, otherwise the
--   default (txt).
outputFormatFromOpts :: CliOpts -> String

-- | Default width for hledger console output, when not otherwise
--   specified.
defaultWidth :: Int

-- | Replace any numeric flags (eg -2) with their long form (--depth 2), as
--   I'm guessing cmdargs doesn't support this directly.
replaceNumericFlags :: [String] -> [String]
ensureDebugFlagHasVal :: [String] -> [String]

-- | Get the width in characters to use for the register command's console
--   output, and also the description column width if specified (following
--   the main width, comma-separated). The widths will be as follows: <tt>
--   no --width flag - overall width is the available width (or terminal
--   width, or 80); description width is unspecified (auto) --width W -
--   overall width is W, description width is auto --width W,D - overall
--   width is W, description width is D </tt> Will raise a parse error for
--   a malformed --width argument.
registerWidthsFromOpts :: CliOpts -> (Int, Maybe Int)

-- | Get the most appropriate documentation topic for a mode. Currently,
--   that is either the hledger, hledger-ui or hledger-web manual.
topicForMode :: Mode a -> Topic
data UsedOrDeclared
Used :: UsedOrDeclared
Declared :: UsedOrDeclared
Undeclared :: UsedOrDeclared
Unused :: UsedOrDeclared
usedOrDeclaredFromOpts :: CliOpts -> Maybe UsedOrDeclared
instance Data.Default.Internal.Default Hledger.Cli.CliOptions.CliOpts
instance GHC.Classes.Eq Hledger.Cli.CliOptions.UsedOrDeclared
instance Hledger.Data.Balancing.HasBalancingOpts Hledger.Cli.CliOptions.CliOpts
instance Hledger.Cli.CliOptions.HasCliOpts Hledger.Cli.CliOptions.CliOpts
instance Hledger.Read.InputOptions.HasInputOpts Hledger.Cli.CliOptions.CliOpts
instance Hledger.Reports.ReportOptions.HasReportOpts Hledger.Cli.CliOptions.CliOpts
instance Hledger.Reports.ReportOptions.HasReportOptsNoUpdate Hledger.Cli.CliOptions.CliOpts
instance Hledger.Reports.ReportOptions.HasReportSpec Hledger.Cli.CliOptions.CliOpts
instance GHC.Internal.Show.Show Hledger.Cli.CliOptions.CliOpts
instance GHC.Internal.Show.Show Hledger.Cli.CliOptions.CommandHelp
instance GHC.Internal.Show.Show Hledger.Cli.CliOptions.UsedOrDeclared


-- | Utilities for top-level modules and ghci. See also Hledger.Read and
--   Hledger.Utils.
module Hledger.Cli.Utils

-- | Standard error message for a bad output format specified with -O/-o.
unsupportedOutputFormatError :: String -> String

-- | Parse the user's specified journal file(s) as a Journal, maybe apply
--   some transformations according to options, and run a hledger command
--   with it. Or, throw an error.
withJournal :: CliOpts -> (Journal -> IO a) -> IO a
withJournalDo :: CliOpts -> (Journal -> IO a) -> IO a

-- | Write some output to stdout or to a file selected by --output-file. If
--   the file exists it will be overwritten.
writeOutput :: CliOpts -> String -> IO ()

-- | Write some output, to a file specified by --output-file if any,
--   otherwise to stdout. If writing to a file and the file exists, it will
--   be overwritten. If writing to stdout, a pager is used when appropriate
--   and possible.
writeOutputLazyText :: CliOpts -> Text -> IO ()

-- | Apply some journal transformations, if enabled by options, that should
--   happen late. These happen after parsing, finalising the journal,
--   strict checks, and .latest filtering/updating, but before report
--   calculation. They are, in processing order: --pivot, --anonymise error
--   message, --obfuscate.
journalTransform :: CliOpts -> Journal -> Journal

-- | Re-read the journal file(s) specified by options, applying any
--   transformations specified by options. Or return an error string. Reads
--   the full journal, without filtering.
journalReload :: CliOpts -> ExceptT String IO Journal

-- | Re-read the option-specified journal file(s), but only if any of them
--   has changed since last read. (If the file is standard input, this will
--   either do nothing or give an error, not tested yet). Returns a journal
--   or error message, and a flag indicating whether it was re-read or not.
--   Like withJournal and journalReload, reads the full journal, without
--   filtering.
journalReloadIfChanged :: CliOpts -> Day -> Journal -> ExceptT String IO (Journal, Bool)

-- | Has the specified file changed since the journal was last read ?
--   Typically this is one of the journal's journalFilePaths. These are not
--   always real files, so the file's existence is tested first; for
--   non-files the answer is always no.
journalFileIsNewer :: Journal -> FilePath -> IO Bool

-- | Attempt to open a web browser on the given url, all platforms.
openBrowserOn :: String -> IO ExitCode

-- | Back up this file with a (incrementing) numbered suffix, then
--   overwrite it with this new text, or give an error.
writeFileWithBackup :: FilePath -> String -> IO ()

-- | Back up this file with a (incrementing) numbered suffix then overwrite
--   it with this new text, or give an error, but only if the text is
--   different from the current file contents, and return a flag indicating
--   whether we did anything.
--   
--   The given text should have unix line endings (n); the existing file
--   content will be normalised to unix line endings before comparing the
--   two. If the file is overwritten, the new file will have the current
--   system's native line endings (n on unix, rn on windows). This could be
--   different from the file's previous line endings, if working with a DOS
--   file on unix or vice-versa.
writeFileWithBackupIfChanged :: FilePath -> Text -> IO Bool
pivotByOpts :: CliOpts -> Journal -> Journal
anonymiseByOpts :: CliOpts -> Journal -> Journal
journalSimilarTransaction :: CliOpts -> Journal -> Text -> Maybe Transaction

-- | Render a <a>PostingsReport</a> or <a>AccountTransactionsReport</a> as
--   Text, determining the appropriate starting widths and increasing as
--   necessary.
postingsOrTransactionsReportAsText :: Bool -> CliOpts -> (Int -> Int -> (a, [WideBuilder], [WideBuilder]) -> Builder) -> (a -> MixedAmount) -> (a -> MixedAmount) -> [a] -> Builder
tests_Cli_Utils :: TestTree

module Hledger.Cli.Commands.Tags
tagsmode :: Mode RawOpts
tags :: CliOpts -> Journal -> IO ()


-- | Print some statistics for the journal.
module Hledger.Cli.Commands.Stats
statsmode :: Mode RawOpts

-- | Print various statistics for the journal.
stats :: CliOpts -> Journal -> IO ()


-- | Check and show the status of the hledger installation.
module Hledger.Cli.Commands.Setup
setupmode :: Mode RawOpts

-- | Test and print the status of various aspects of the hledger
--   installation. May also show extra info and hints on how to fix
--   problems. The goal is to detect and show as much useful information as
--   possible, and to complete this task reliably regardless of what we
--   find, without premature termination or misformatting.
--   
--   The tests are grouped into setup* routines, so named because they
--   might do more than just test in future.
--   
--   This is the second version of setup. If it finds that the currently
--   running hledger is not the one installed in PATH (by comparing
--   --version output), it refuses to proceed further until that has been
--   done. This means it can rely on all the latest features and use the
--   hledger API within this process, simplifying things greatly.
setup :: CliOpts -> Journal -> IO ()
instance GHC.Classes.Eq Hledger.Cli.Commands.Setup.YNU
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Setup.YNU


-- | The <tt>run</tt> command allows you to run multiple commands via REPL
--   or from the supplied file(s).
module Hledger.Cli.Commands.Run

-- | Command line options for this command.
runmode :: Mode RawOpts

-- | The actual run command.
run :: Maybe DefaultRunJournal -> (String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO ())) -> [String] -> CliOpts -> IO ()
replmode :: Mode RawOpts

-- | The actual repl command.
repl :: (String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO ())) -> [String] -> CliOpts -> IO ()

-- | The fake run/repl command introduced to break circular dependency.
--   This module needs access to <tt>findBuiltinCommand</tt>, which is
--   defined in Hledger.Cli.Commands However, Hledger.Cli.Commands imports
--   this module, which creates circular dependency. We expose this
--   do-nothing function so that it could be included in the list of all
--   commands inside Hledger.Cli.Commands and ensure that "run" is
--   recognized as a valid command by the Hledger.Cli top-level command
--   line parser. That parser, however, would not call run'. It has a
--   special case for "run", and will call "run" (see below), passing it
--   <tt>findBuiltinCommand</tt>, thus breaking circular dependency.
runOrReplStub :: CliOpts -> Journal -> IO ()
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Run.DefaultRunJournal


-- | The <tt>roi</tt> command prints internal rate of return and
--   time-weighted rate of return for and investment.
module Hledger.Cli.Commands.Roi
roimode :: Mode RawOpts
roi :: CliOpts -> Journal -> IO ()
instance GHC.Classes.Eq Hledger.Cli.Commands.Roi.TwrPeriod
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Roi.OneSpan
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Roi.TwrPeriod


-- | A ledger-compatible <tt>register</tt> command.
module Hledger.Cli.Commands.Register
registermode :: Mode RawOpts

-- | Print a (posting) register report.
register :: CliOpts -> Journal -> IO ()

-- | Render a register report as plain text suitable for console output.
postingsReportAsText :: CliOpts -> PostingsReport -> Text

-- | Render one register report line item as plain text. Layout is like so:
--   <tt> <a>width (specified, terminal width, or 80)
--   --------------------</a> date (10) description account amount (12)
--   balance (12) DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa
--   AAAAAAAAAAAA AAAAAAAAAAAA </tt> If description's width is specified,
--   account will use the remaining space. Otherwise, description and
--   account divide up the space equally.
--   
--   With a report interval, the layout is like so: <tt> <a>width
--   (specified, terminal width, or 80) --------------------</a> date (21)
--   account amount (12) balance (12) DDDDDDDDDDDDDDDDDDDDD
--   aaaaaaaaaaaaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA </tt>
--   
--   date and description are shown for the first posting of a transaction
--   only.
--   
--   Returns a string which can be multi-line, eg if the running balance
--   has multiple commodities. Does not yet support formatting control like
--   balance reports.
--   
--   Also returns the natural width (without padding) of the amount and
--   balance fields.
postingsReportItemAsText :: CliOpts -> Int -> Int -> (PostingsReportItem, [WideBuilder], [WideBuilder]) -> Builder
tests_Register :: TestTree


-- | A ledger-compatible <tt>print</tt> command.
module Hledger.Cli.Commands.Print
printmode :: Mode RawOpts

-- | Print journal transactions in standard format.
print' :: CliOpts -> Journal -> IO ()
roundFlag :: Flag RawOpts

-- | Get the --round option's value, if any. Can fail with a parse error.
roundFromRawOpts :: RawOpts -> Maybe Rounding

-- | Set these amount styles' rounding strategy when they are being applied
--   to amounts, according to the value of the --round option, if any.
amountStylesSetRoundingFromRawOpts :: RawOpts -> Map CommoditySymbol AmountStyle -> Map CommoditySymbol AmountStyle

-- | Replace this transaction's postings with the original postings if any,
--   but keep the current possibly rewritten account names, and the
--   inferred values of any auto postings. This is mainly for showing
--   transactions with the amounts in their original journal format.
transactionWithMostlyOriginalPostings :: Transaction -> Transaction

module Hledger.Cli.Commands.Rewrite
rewritemode :: Mode RawOpts
rewrite :: CliOpts -> Journal -> IO ()
instance GHC.Internal.Data.Foldable.Foldable Hledger.Cli.Commands.Rewrite.DiffLine
instance GHC.Internal.Base.Functor Hledger.Cli.Commands.Rewrite.DiffLine
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Hledger.Cli.Commands.Rewrite.DiffLine a)
instance GHC.Internal.Data.Traversable.Traversable Hledger.Cli.Commands.Rewrite.DiffLine

module Hledger.Cli.Commands.Prices
pricesmode :: Mode RawOpts
prices :: CliOpts -> Journal -> IO ()
instance Hledger.Data.Types.HasAmounts Hledger.Data.Types.PriceDirective


-- | The <tt>payees</tt> command lists all unique payees (description part
--   before a |) seen in transactions, sorted alphabetically.
module Hledger.Cli.Commands.Payees

-- | Command line options for this command.
payeesmode :: Mode RawOpts

-- | The payees command.
payees :: CliOpts -> Journal -> IO ()


-- | The <tt>notes</tt> command lists all unique notes (description part
--   after a |) seen in transactions, sorted alphabetically.
module Hledger.Cli.Commands.Notes

-- | Command line options for this command.
notesmode :: Mode RawOpts

-- | The notes command.
notes :: CliOpts -> Journal -> IO ()


-- | The help command.
--   
--   |
module Hledger.Cli.Commands.Help
helpmode :: Mode RawOpts

-- | Display the hledger manual in various formats. You can select a docs
--   viewer with one of the `--info`, `--man`, `--pager` flags. Otherwise
--   it will use the first available of: info, man, $PAGER, less, stdout
--   (and always stdout if output is non-interactive).
help' :: CliOpts -> Journal -> IO ()


-- | The <tt>files</tt> command lists included files.
module Hledger.Cli.Commands.Files

-- | Command line options for this command.
filesmode :: Mode RawOpts

-- | The files command.
files :: CliOpts -> Journal -> IO ()


-- | The <tt>diff</tt> command compares two diff.
module Hledger.Cli.Commands.Diff

-- | Command line options for this command.
diffmode :: Mode RawOpts

-- | The diff command.
diff :: CliOpts -> Journal -> IO ()
instance GHC.Classes.Eq Hledger.Cli.Commands.Diff.PostingWithPath
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Diff.PostingWithPath


-- | The <tt>descriptions</tt> command lists all unique descriptions seen
--   in transactions, sorted alphabetically.
module Hledger.Cli.Commands.Descriptions

-- | Command line options for this command.
descriptionsmode :: Mode RawOpts

-- | The descriptions command.
descriptions :: CliOpts -> Journal -> IO ()


-- | The <tt>demo</tt> command lists and plays small hledger demos in the
--   terminal, using asciinema.
module Hledger.Cli.Commands.Demo

-- | Command line options for this command.
demomode :: Mode RawOpts

-- | The demo command.
demo :: CliOpts -> Journal -> IO ()


-- | The <tt>commodities</tt> command lists commodity/currency symbols.
module Hledger.Cli.Commands.Commodities

-- | Command line options for this command.
commoditiesmode :: Mode RawOpts
commodities :: CliOpts -> Journal -> IO ()


-- | The <tt>codes</tt> command lists the codes seen in transactions, in
--   the order parsed.
module Hledger.Cli.Commands.Codes

-- | Command line options for this command.
codesmode :: Mode RawOpts

-- | The codes command.
codes :: CliOpts -> Journal -> IO ()

module Hledger.Cli.Commands.Close
closemode :: Mode RawOpts
close :: CliOpts -> Journal -> IO ()
instance GHC.Classes.Eq Hledger.Cli.Commands.Close.CloseMode
instance GHC.Internal.Read.Read Hledger.Cli.Commands.Close.CloseMode
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Close.CloseMode

module Hledger.Cli.Commands.Check
checkmode :: Mode RawOpts
check :: CliOpts -> Journal -> IO ()
instance GHC.Internal.Enum.Bounded Hledger.Cli.Commands.Check.Check
instance GHC.Internal.Enum.Enum Hledger.Cli.Commands.Check.Check
instance GHC.Classes.Eq Hledger.Cli.Commands.Check.Check
instance GHC.Classes.Ord Hledger.Cli.Commands.Check.Check
instance GHC.Internal.Read.Read Hledger.Cli.Commands.Check.Check
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Check.Check


-- | A ledger-compatible <tt>balance</tt> command, with additional support
--   for multi-column reports.
--   
--   Here is a description/specification for the balance command. See also
--   <a>Hledger.Reports</a> -&gt; "Balance reports".
--   
--   <i>Basic balance report</i>
--   
--   With no report interval (<tt>--monthly</tt> etc.), hledger's balance
--   command emulates ledger's, showing accounts indented according to
--   hierarchy, along with their total amount posted (including
--   subaccounts).
--   
--   Here's an example. With <tt>examples/sample.journal</tt>, which
--   defines the following account tree:
--   
--   <pre>
--   assets
--     bank
--       checking
--       saving
--     cash
--   expenses
--     food
--     supplies
--   income
--     gifts
--     salary
--   liabilities
--     debts
--   </pre>
--   
--   the basic <tt>balance</tt> command gives this output:
--   
--   <pre>
--    $ hledger -f sample.journal balance
--                    $-1  assets
--                     $1    bank:saving
--                    $-2    cash
--                     $2  expenses
--                     $1    food
--                     $1    supplies
--                    $-2  income
--                    $-1    gifts
--                    $-1    salary
--                     $1  liabilities:debts
--   --------------------
--                      0
--   </pre>
--   
--   Subaccounts are displayed indented below their parent. Only the
--   account leaf name (the final part) is shown. (With <tt>--flat</tt>,
--   account names are shown in full and unindented.)
--   
--   Each account's "balance" is the sum of postings in that account and
--   any subaccounts during the report period. When the report period
--   includes all transactions, this is equivalent to the account's current
--   balance.
--   
--   The overall total of the highest-level displayed accounts is shown
--   below the line. (The <tt>--no-total/-N</tt> flag prevents this.)
--   
--   <i>Eliding and omitting</i>
--   
--   Accounts which have a zero balance, and no non-zero subaccount
--   balances, are normally omitted from the report. (The
--   <tt>--empty/-E</tt> flag forces such accounts to be displayed.) Eg,
--   above <tt>checking</tt> is omitted because it has a zero balance and
--   no subaccounts.
--   
--   Accounts which have a single subaccount also being displayed, with the
--   same balance, are normally elided into the subaccount's line. (The
--   <tt>--no-elide</tt> flag prevents this.) Eg, above <tt>bank</tt> is
--   elided to <tt>bank:saving</tt> because it has only a single displayed
--   subaccount (<tt>saving</tt>) and their balance is the same ($1).
--   Similarly, <tt>liabilities</tt> is elided to
--   <tt>liabilities:debts</tt>.
--   
--   <i>Date limiting</i>
--   
--   The default report period is that of the whole journal, including all
--   known transactions. The <tt>--begin/-b</tt>, <tt>--end/-e</tt>,
--   <tt>--period/-p</tt> options or <tt>date:</tt>/<tt>date2:</tt>
--   patterns can be used to report only on transactions before and/or
--   after specified dates.
--   
--   <i>Depth limiting</i>
--   
--   The <tt>--depth</tt> option can be used to limit the depth of the
--   balance report. Eg, to see just the top level accounts (still
--   including their subaccount balances):
--   
--   <pre>
--   $ hledger -f sample.journal balance --depth 1
--                    $-1  assets
--                     $2  expenses
--                    $-2  income
--                     $1  liabilities
--   --------------------
--                      0
--   </pre>
--   
--   <i>Account limiting</i>
--   
--   With one or more account pattern arguments, the report is restricted
--   to accounts whose name matches one of the patterns, plus their parents
--   and subaccounts. Eg, adding the pattern <tt>o</tt> to the first
--   example gives:
--   
--   <pre>
--    $ hledger -f sample.journal balance o
--                     $1  expenses:food
--                    $-2  income
--                    $-1    gifts
--                    $-1    salary
--   --------------------
--                    $-1
--   </pre>
--   
--   <ul>
--   <li>The <tt>o</tt> pattern matched <tt>food</tt> and <tt>income</tt>,
--   so they are shown.</li>
--   <li><tt>food</tt>'s parent (<tt>expenses</tt>) is shown even though
--   the pattern didn't match it, to clarify the hierarchy. The usual
--   eliding rules cause it to be elided here.</li>
--   <li><tt>income</tt>'s subaccounts are also shown.</li>
--   </ul>
--   
--   <i>Multi-column balance report</i>
--   
--   hledger's balance command will show multiple columns when a reporting
--   interval is specified (eg with <tt>--monthly</tt>), one column for
--   each sub-period.
--   
--   There are three accumulation strategies for multi-column balance
--   report, indicated by the heading:
--   
--   <ul>
--   <li>A "period balance" (or "flow") report (with <tt>--change</tt>, the
--   default) shows the change of account balance in each period, which is
--   equivalent to the sum of postings in each period. Here, checking's
--   balance increased by 10 in Feb:</li>
--   </ul>
--   
--   <pre>
--   Change of balance (flow):
--   
--                    Jan   Feb   Mar
--   assets:checking   20    10    -5
--   </pre>
--   
--   <ul>
--   <li>A "cumulative balance" report (with <tt>--cumulative</tt>) shows
--   the accumulated ending balance across periods, starting from zero at
--   the report's start date. Here, 30 is the sum of checking postings
--   during Jan and Feb:</li>
--   </ul>
--   
--   <pre>
--   Ending balance (cumulative):
--   
--                    Jan   Feb   Mar
--   assets:checking   20    30    25
--   </pre>
--   
--   <ul>
--   <li>A "historical balance" report (with <tt>--historical/-H</tt>) also
--   shows ending balances, but it includes the starting balance from any
--   postings before the report start date. Here, 130 is the balance from
--   all checking postings at the end of Feb, including pre-Jan postings
--   which created a starting balance of 100:</li>
--   </ul>
--   
--   <pre>
--   Ending balance (historical):
--   
--                    Jan   Feb   Mar
--   assets:checking  120   130   125
--   </pre>
--   
--   <i>Eliding and omitting, 2</i>
--   
--   Here's a (imperfect?) specification for the eliding/omitting
--   behaviour:
--   
--   <ul>
--   <li>Each account is normally displayed on its own line.</li>
--   <li>An account less deep than the report's max depth, with just one
--   interesting subaccount, and the same balance as the subaccount, is
--   non-interesting, and prefixed to the subaccount's line, unless
--   <tt>--no-elide</tt> is in effect.</li>
--   <li>An account with a zero inclusive balance and less than two
--   interesting subaccounts is not displayed at all, unless
--   <tt>--empty</tt> is in effect.</li>
--   <li>Multi-column balance reports show full account names with no
--   eliding (like <tt>--flat</tt>). Accounts (and periods) are omitted as
--   described below.</li>
--   </ul>
--   
--   <i>Which accounts to show in balance reports</i>
--   
--   By default:
--   
--   <ul>
--   <li>single-column: accounts with non-zero balance in report period.
--   (With <tt>--flat</tt>: accounts with non-zero balance and
--   postings.)</li>
--   <li>change: accounts with postings and non-zero period balance in any
--   period</li>
--   <li>cumulative: accounts with non-zero cumulative balance in any
--   period</li>
--   <li>historical: accounts with non-zero historical balance in any
--   period</li>
--   </ul>
--   
--   With <tt>-E/--empty</tt>:
--   
--   <ul>
--   <li>single-column: accounts with postings in report period</li>
--   <li>change: accounts with postings in report period</li>
--   <li>cumulative: accounts with postings in report period</li>
--   <li>historical: accounts with non-zero starting balance + accounts
--   with postings in report period</li>
--   </ul>
--   
--   <i>Which periods (columns) to show in balance reports</i>
--   
--   An empty period/column is one where no report account has any
--   postings. A zero period/column is one where no report account has a
--   non-zero period balance.
--   
--   Currently,
--   
--   by default:
--   
--   <ul>
--   <li>single-column: N/A</li>
--   <li>change: all periods within the overall report period, except for
--   leading and trailing empty periods</li>
--   <li>cumulative: all periods within the overall report period, except
--   for leading and trailing empty periods</li>
--   <li>historical: all periods within the overall report period, except
--   for leading and trailing empty periods</li>
--   </ul>
--   
--   With <tt>-E/--empty</tt>:
--   
--   <ul>
--   <li>single-column: N/A</li>
--   <li>change: all periods within the overall report period</li>
--   <li>cumulative: all periods within the overall report period</li>
--   <li>historical: all periods within the overall report period</li>
--   </ul>
--   
--   <i>What to show in empty cells</i>
--   
--   An empty periodic balance report cell is one which has no
--   corresponding postings. An empty cumulative/historical balance report
--   cell is one which has no corresponding or prior postings, ie the
--   account doesn't exist yet. Currently, empty cells show 0.
module Hledger.Cli.Commands.Balance

-- | Command line options for this command.
balancemode :: Mode RawOpts

-- | The balance command, prints a balance report.
balance :: CliOpts -> Journal -> IO ()

-- | Render a single-column balance report as plain text.
balanceReportAsText :: ReportOpts -> BalanceReport -> Builder

-- | Render a single-column balance report as CSV.
balanceReportAsCsv :: ReportOpts -> BalanceReport -> CSV

-- | Render a single-column balance report as FODS.
balanceReportAsSpreadsheet :: ReportOpts -> BalanceReport -> [[Cell NumLines Text]]

-- | Render one balance report line item as plain text suitable for console
--   output (or whatever string format is specified). Note, prices will not
--   be rendered, and differently-priced quantities of the same commodity
--   will appear merged. The output will be one or more lines depending on
--   the format and number of commodities.
balanceReportItemAsText :: ReportOpts -> BalanceReportItem -> (Builder, [Int])

-- | Render a budget report as plain text suitable for console output.
budgetReportAsText :: ReportOpts -> BudgetReport -> Text

-- | Render a budget report as CSV. Like multiBalanceReportAsCsv, but
--   includes alternating actual and budget amount columns.
budgetReportAsCsv :: ReportOpts -> BudgetReport -> [[Text]]
budgetReportAsSpreadsheet :: ReportOpts -> BudgetReport -> [[Cell NumLines Text]]
multiBalanceRowAsCellBuilders :: AmountFormat -> ReportOpts -> [DateSpan] -> RowClass -> (DateSpan -> Cell NumLines Text) -> PeriodicReportRow a MixedAmount -> [[Cell NumLines WideBuilder]]
multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[Text]]
multiBalanceRowAsText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]]

-- | Render a multi-column balance report as plain text suitable for
--   console output.
multiBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> Text

-- | Render a multi-column balance report as CSV. The CSV will always
--   include the initial headings row, and will include the final totals
--   row unless --no-total is set.
multiBalanceReportAsCsv :: ReportOpts -> MultiBalanceReport -> CSV

-- | Render a multi-column balance report as HTML.
multiBalanceReportAsHtml :: ReportOpts -> MultiBalanceReport -> Html

-- | Build a <a>Table</a> from a multi-column balance report.
multiBalanceReportAsTable :: ReportOpts -> MultiBalanceReport -> Table Text Text WideBuilder

-- | Given a table representing a multi-column balance report, render it in
--   a format suitable for console output. Amounts with more than two
--   commodities will be elided unless --no-elide is used.
multiBalanceReportTableAsText :: ReportOpts -> Table Text Text WideBuilder -> Builder

-- | Render the ODS table rows for a MultiBalanceReport. Returns the
--   heading row, 0 or more body rows, and the totals row if enabled.
multiBalanceReportAsSpreadsheet :: ReportOpts -> MultiBalanceReport -> ((Int, Int), [[Cell NumLines Text]])

-- | Render the Spreadsheet table rows (CSV, ODS, HTML) for a
--   MultiBalanceReport. Returns the heading row, 0 or more body rows, and
--   the totals row if enabled.
multiBalanceReportAsSpreadsheetParts :: AmountFormat -> ReportOpts -> MultiBalanceReport -> ([Cell NumLines Text], [[Cell NumLines Text]], [[Cell NumLines Text]])
multiBalanceHasTotalsColumn :: ReportOpts -> Bool
addTotalBorders :: [[Cell border text]] -> [[Cell NumLines text]]
simpleDateSpanCell :: DateSpan -> Cell NumLines Text
tidyColumnLabels :: [Text]
nbsp :: Text
data RowClass
Value :: RowClass
Total :: RowClass
tests_Balance :: TestTree
instance GHC.Internal.Enum.Bounded Hledger.Cli.Commands.Balance.RowClass
instance GHC.Internal.Enum.Enum Hledger.Cli.Commands.Balance.RowClass
instance GHC.Classes.Eq Hledger.Cli.Commands.Balance.RowClass
instance GHC.Classes.Ord Hledger.Cli.Commands.Balance.RowClass
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Balance.RowClass


-- | Common helpers for making multi-section balance report commands like
--   balancesheet, cashflow, and incomestatement.
module Hledger.Cli.CompoundBalanceCommand

-- | Description of a compound balance report command, from which we
--   generate the command's cmdargs mode and IO action. A compound balance
--   report command shows one or more sections/subreports, each with its
--   own title and subtotals row, in a certain order, plus a grand totals
--   row if there's more than one section. Examples are the balancesheet,
--   cashflow and incomestatement commands.
--   
--   Compound balance reports do sign normalisation: they show all account
--   balances as normally positive, unlike the ordinary BalanceReport and
--   most hledger commands which show income<i>liability</i>equity balances
--   as normally negative. Each subreport specifies the normal sign of its
--   amounts, and whether it should be added to or subtracted from the
--   grand total.
data CompoundBalanceCommandSpec
CompoundBalanceCommandSpec :: CommandHelpStr -> String -> [CBCSubreportSpec DisplayName] -> BalanceAccumulation -> CompoundBalanceCommandSpec

-- | the command's name(s) and documentation
[cbcdoc] :: CompoundBalanceCommandSpec -> CommandHelpStr

-- | overall report title
[cbctitle] :: CompoundBalanceCommandSpec -> String

-- | subreport details
[cbcqueries] :: CompoundBalanceCommandSpec -> [CBCSubreportSpec DisplayName]

-- | how to accumulate balances (per-period, cumulative, historical)
--   (overrides command line flags)
[cbcaccum] :: CompoundBalanceCommandSpec -> BalanceAccumulation

-- | Generate a cmdargs option-parsing mode from a compound balance command
--   specification.
compoundBalanceCommandMode :: CompoundBalanceCommandSpec -> Mode RawOpts

-- | Generate a runnable command from a compound balance command
--   specification.
compoundBalanceCommand :: CompoundBalanceCommandSpec -> CliOpts -> Journal -> IO ()


-- | The <tt>incomestatement</tt> command prints a simple income statement
--   (profit &amp; loss report).
module Hledger.Cli.Commands.Incomestatement
incomestatementmode :: Mode RawOpts
incomestatement :: CliOpts -> Journal -> IO ()


-- | The <tt>cashflow</tt> command prints a simplified cashflow statement.
--   It just shows the change in all "cash" accounts for the period
--   (without the traditional segmentation into operating, investing, and
--   financing cash flows.)
module Hledger.Cli.Commands.Cashflow
cashflowmode :: Mode RawOpts
cashflow :: CliOpts -> Journal -> IO ()


-- | The <tt>balancesheetequity</tt> command prints a simple balance sheet.
module Hledger.Cli.Commands.Balancesheetequity
balancesheetequitymode :: Mode RawOpts
balancesheetequity :: CliOpts -> Journal -> IO ()


-- | The <tt>balancesheet</tt> command prints a simple balance sheet.
module Hledger.Cli.Commands.Balancesheet
balancesheetmode :: Mode RawOpts
balancesheet :: CliOpts -> Journal -> IO ()


-- | The <tt>aregister</tt> command lists a single account's transactions,
--   like the account register in hledger-ui and hledger-web, and unlike
--   the register command which lists postings across multiple accounts.
module Hledger.Cli.Commands.Aregister
aregistermode :: Mode RawOpts

-- | Print an account register report for a specified account.
aregister :: CliOpts -> Journal -> IO ()
tests_Aregister :: TestTree


-- | A history-aware, tab-completing interactive add command to help with
--   data entry.
module Hledger.Cli.Commands.Add
addmode :: Mode RawOpts

-- | Read multiple transactions from the console, prompting for each field,
--   and append them to the journal file. If the journal came from stdin,
--   this command has no effect.
add :: CliOpts -> Journal -> IO ()

-- | Append a string, typically one or more transactions, to a journal
--   file, or if the file is "-", dump it to stdout. Tries to avoid excess
--   whitespace.
--   
--   XXX This writes unix line endings (n), some at least, even if the file
--   uses dos line endings (rn), which could leave mixed line endings in
--   the file. See also writeFileWithBackupIfChanged.
appendToJournalFileOrStdout :: FilePath -> Text -> IO ()

-- | Append this transaction to the journal's file and transaction list.
journalAddTransaction :: Journal -> CliOpts -> Transaction -> IO Journal
instance GHC.Internal.Exception.Type.Exception Hledger.Cli.Commands.Add.RestartTransactionException
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Add.EntryState
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Add.PrevInput
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Add.RestartTransactionException
instance GHC.Internal.Show.Show Hledger.Cli.Commands.Add.TxnParams

module Hledger.Cli.Commands.Import
importmode :: Mode RawOpts
importcmd :: CliOpts -> Journal -> IO ()


-- | Print a bar chart of posting activity per day, or other report
--   interval.
module Hledger.Cli.Commands.Activity
activitymode :: Mode RawOpts
barchar :: Char

-- | Print a bar chart of number of postings per report interval.
activity :: CliOpts -> Journal -> IO ()
showHistogram :: ReportSpec -> Journal -> String
printDayWith :: (PrintfArg t1, PrintfType t2, Show a) => (t3 -> t1) -> ((a, b), t3) -> t2
countBar :: Foldable t => t a -> [Char]


-- | The <tt>accounts</tt> command lists account names:
--   
--   <ul>
--   <li>in flat mode (default), it lists the full names of accounts posted
--   to by matched postings, clipped to the specified depth, possibly with
--   leading components dropped.</li>
--   <li>in tree mode, it shows the indented short names of accounts posted
--   to by matched postings, and their parents, to the specified
--   depth.</li>
--   </ul>
module Hledger.Cli.Commands.Accounts

-- | Command line options for this command.
accountsmode :: Mode RawOpts

-- | The accounts command.
accounts :: CliOpts -> Journal -> IO ()


-- | hledger's built-in commands, and helpers for printing the commands
--   list.
--   
--   New built-in commands should be added in four places below: the export
--   list, the import list, builtinCommands, commandsList.
module Hledger.Cli.Commands

-- | Display the commands list.
commands :: CliOpts -> Journal -> IO ()

-- | The test command, which runs the hledger and hledger-lib packages'
--   unit tests. Arguments following a -- argument will be passed to the
--   tasty test runner, and any arguments before -- will be passed as
--   test-selecting -p patterns.
--   
--   Unlike most hledger commands, this one does not read the user's
--   journal. A <a>Journal</a> argument remains in the type signature, but
--   it should not be used (and would raise an error).
testcmd :: CliOpts -> Journal -> IO ()

-- | The cmdargs subcommand mode (for command-line parsing) and IO action
--   (for doing the command's work) for each builtin command. Command
--   actions take parsed CLI options and a (lazy) finalised journal.
builtinCommands :: [(Mode RawOpts, CliOpts -> Journal -> IO ())]

-- | All names and aliases of the builtin commands.
builtinCommandNames :: [String]
addonCommandNames :: IO [String]

-- | Canonical names of the known addon commands which have a slot in the
--   commands list, in alphabetical order.
knownAddonCommandNames :: [String]

-- | Look up a builtin command's mode and action by exact command name or
--   alias.
findBuiltinCommand :: String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO ())

-- | Canonical names of all commands which have a slot in the commands
--   list, in alphabetical order. These include the builtin commands and
--   the known addon commands.
knownCommands :: [String]

-- | Print the commands list, with a pager if appropriate, customising the
--   commandsList template above with the given version string and the
--   installed addons. Uninstalled known addons will be removed from the
--   list, installed known addons will have the + prefix removed, and
--   installed unknown addons will be added under Misc.
printCommandsList :: String -> [String] -> IO ()
tests_Hledger_Cli :: TestTree


-- | This is the root module of the <tt>hledger</tt> 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:
--   
--   <ul>
--   <li>hledger-lib:Hledger</li>
--   <li><a>The README files</a></li>
--   <li><a>The high-level developer docs</a></li>
--   </ul>
--   
--   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:
--   
--   <pre>
--   $ hledger
--   </pre>
--   
--   or ghci:
--   
--   <pre>
--   $ make ghci
--   ghci&gt; Right j &lt;- runExceptT $ readJournalFile definputopts "examples/sample.journal"  -- or: j &lt;- defaultJournal
--   ghci&gt; :t j
--   j :: Journal
--   ghci&gt; 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&gt; 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&gt; 
--   </pre>
--   
--   etc.
--   
--   SPDX-License-Identifier: GPL-3.0-or-later Copyright (c) 2007-2025
--   (each year in this range) Simon Michael <a>simon@joyful.com</a> 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 <a>https://www.gnu.org/licenses/</a>.
module Hledger.Cli

-- | 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. <a>https://github.com/ndmitchell/cmdargs/issues/36</a> is
--   the wishlist issue; implementing that would simplify hledger's CLI
--   processing a lot.
main :: IO ()

-- | 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.
mainmode :: [Name] -> Mode RawOpts

-- | 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.
argsToCliOpts :: [String] -> [String] -> IO CliOpts
process :: Mode a -> [String] -> Either String a
data Arg a
Arg :: Update a -> FlagHelp -> Bool -> Arg a
[argValue] :: Arg a -> Update a
[argType] :: Arg a -> FlagHelp
[argRequire] :: Arg a -> Bool
expandArgsAt :: [String] -> IO [String]
joinArgs :: [String] -> String
splitArgs :: String -> [String]
class Remap (m :: Type -> Type)
remap :: Remap m => (a -> b) -> (b -> (a, a -> b)) -> m a -> m b
data Flag a
Flag :: [Name] -> FlagInfo -> Update a -> FlagHelp -> Help -> Flag a
[flagNames] :: Flag a -> [Name]
[flagInfo] :: Flag a -> FlagInfo
[flagValue] :: Flag a -> Update a
[flagType] :: Flag a -> FlagHelp
[flagHelp] :: Flag a -> Help
type Update a = String -> a -> Either String a
data FlagInfo
FlagReq :: FlagInfo
FlagOpt :: String -> FlagInfo
FlagOptRare :: String -> FlagInfo
FlagNone :: FlagInfo
data Mode a
Mode :: Group (Mode a) -> [Name] -> a -> (a -> Either String a) -> (a -> Maybe [String]) -> Bool -> Help -> [String] -> ([Arg a], Maybe (Arg a)) -> Group (Flag a) -> Mode a
[modeGroupModes] :: Mode a -> Group (Mode a)
[modeNames] :: Mode a -> [Name]
[modeValue] :: Mode a -> a
[modeCheck] :: Mode a -> a -> Either String a
[modeReform] :: Mode a -> a -> Maybe [String]
[modeExpandAt] :: Mode a -> Bool
[modeHelp] :: Mode a -> Help
[modeHelpSuffix] :: Mode a -> [String]
[modeArgs] :: Mode a -> ([Arg a], Maybe (Arg a))
[modeGroupFlags] :: Mode a -> Group (Flag a)
data Group a
Group :: [a] -> [a] -> [(Help, [a])] -> Group a
[groupUnnamed] :: Group a -> [a]
[groupHidden] :: Group a -> [a]
[groupNamed] :: Group a -> [(Help, [a])]
type FlagHelp = String
type Help = String
parseBool :: String -> Maybe Bool
fromGroup :: Group a -> [a]
toGroup :: [a] -> Group a
modeModes :: Mode a -> [Mode a]
modeFlags :: Mode a -> [Flag a]
fromFlagOpt :: FlagInfo -> String
checkMode :: Mode a -> Maybe String
remap2 :: Remap m => (a -> b) -> (b -> a) -> m a -> m b
remapUpdate :: (a -> b) -> (b -> (a, a -> b)) -> Update a -> Update b
modeEmpty :: a -> Mode a
mode :: Name -> a -> Help -> Arg a -> [Flag a] -> Mode a
modes :: String -> a -> Help -> [Mode a] -> Mode a
flagNone :: [Name] -> (a -> a) -> Help -> Flag a
flagOpt :: String -> [Name] -> Update a -> FlagHelp -> Help -> Flag a
flagReq :: [Name] -> Update a -> FlagHelp -> Help -> Flag a
flagArg :: Update a -> FlagHelp -> Arg a
flagBool :: [Name] -> (Bool -> a -> a) -> Help -> Flag a
data Complete
CompleteValue :: String -> Complete
CompleteFile :: String -> FilePath -> Complete
CompleteDir :: String -> FilePath -> Complete
complete :: Mode a -> [String] -> (Int, Int) -> [Complete]
data HelpFormat
HelpFormatDefault :: HelpFormat
HelpFormatOne :: HelpFormat
HelpFormatAll :: HelpFormat
HelpFormatBash :: HelpFormat
HelpFormatZsh :: HelpFormat
helpText :: [String] -> HelpFormat -> Mode a -> [Text]
processArgs :: Mode a -> IO a
processValue :: Mode a -> [String] -> a
processValueIO :: Mode a -> [String] -> IO a
flagHelpSimple :: (a -> a) -> Flag a
flagHelpFormat :: (HelpFormat -> TextFormat -> a -> a) -> Flag a
flagVersion :: (a -> a) -> Flag a
flagNumericVersion :: (a -> a) -> Flag a
flagsVerbosity :: (Verbosity -> a -> a) -> [Flag a]


-- | A convenient module to import in hledger scripts, aiming to provide
--   the most useful imports and reduce boilerplate. |
module Hledger.Cli.Script
process :: Mode a -> [String] -> Either String a

-- | A space efficient, packed, unboxed Unicode text type.
data Text

-- | Flipped version of <a>&lt;$</a>.
--   
--   <h4><b>Examples</b></h4>
--   
--   Replace the contents of a <tt><a>Maybe</a> <a>Int</a></tt> with a
--   constant <a>String</a>:
--   
--   <pre>
--   &gt;&gt;&gt; Nothing $&gt; "foo"
--   Nothing
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Just 90210 $&gt; "foo"
--   Just "foo"
--   </pre>
--   
--   Replace the contents of an <tt><a>Either</a> <a>Int</a>
--   <a>Int</a></tt> with a constant <a>String</a>, resulting in an
--   <tt><a>Either</a> <a>Int</a> <a>String</a></tt>:
--   
--   <pre>
--   &gt;&gt;&gt; Left 8675309 $&gt; "foo"
--   Left 8675309
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Right 8675309 $&gt; "foo"
--   Right "foo"
--   </pre>
--   
--   Replace each element of a list with a constant <a>String</a>:
--   
--   <pre>
--   &gt;&gt;&gt; [1,2,3] $&gt; "foo"
--   ["foo","foo","foo"]
--   </pre>
--   
--   Replace the second element of a pair with a constant <a>String</a>:
--   
--   <pre>
--   &gt;&gt;&gt; (1,2) $&gt; "foo"
--   (1,"foo")
--   </pre>
($>) :: Functor f => f a -> b -> f b
infixl 4 $>
type Name = String

-- | Formatter for <a>RealFloat</a> values.
formatRealFloat :: RealFloat a => a -> FieldFormatter

-- | Flipped version of <a>&lt;$&gt;</a>.
--   
--   <pre>
--   (<a>&lt;&amp;&gt;</a>) = <a>flip</a> <a>fmap</a>
--   </pre>
--   
--   <h4><b>Examples</b></h4>
--   
--   Apply <tt>(+1)</tt> to a list, a <a>Just</a> and a <a>Right</a>:
--   
--   <pre>
--   &gt;&gt;&gt; Just 2 &lt;&amp;&gt; (+1)
--   Just 3
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; [1,2,3] &lt;&amp;&gt; (+1)
--   [2,3,4]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Right 3 &lt;&amp;&gt; (+1)
--   Right 4
--   </pre>
(<&>) :: Functor f => f a -> (a -> b) -> f b
infixl 1 <&>
data Arg a
Arg :: Update a -> FlagHelp -> Bool -> Arg a
[argValue] :: Arg a -> Update a
[argType] :: Arg a -> FlagHelp
[argRequire] :: Arg a -> Bool

-- | Type of a function that will parse modifier characters from the format
--   string.
type ModifierParser = String -> FormatParse

-- | This is the type of a field formatter reified over its argument.
type FieldFormatter = FieldFormat -> ShowS

-- | The "format parser" walks over argument-type-specific modifier
--   characters to find the primary format character. This is the type of
--   its result.
data FormatParse
FormatParse :: String -> Char -> String -> FormatParse

-- | Any modifiers found.
[fpModifiers] :: FormatParse -> String

-- | Primary format character.
[fpChar] :: FormatParse -> Char

-- | Rest of the format string.
[fpRest] :: FormatParse -> String

-- | Description of field formatting for <a>formatArg</a>. See UNIX
--   <tt>printf(3)</tt> for a description of how field formatting works.
data FieldFormat
FieldFormat :: Maybe Int -> Maybe Int -> Maybe FormatAdjustment -> Maybe FormatSign -> Bool -> String -> Char -> FieldFormat

-- | Total width of the field.
[fmtWidth] :: FieldFormat -> Maybe Int

-- | Secondary field width specifier.
[fmtPrecision] :: FieldFormat -> Maybe Int

-- | Kind of filling or padding to be done.
[fmtAdjust] :: FieldFormat -> Maybe FormatAdjustment

-- | Whether to insist on a plus sign for positive numbers.
[fmtSign] :: FieldFormat -> Maybe FormatSign

-- | Indicates an "alternate format". See <tt>printf(3)</tt> for the
--   details, which vary by argument spec.
[fmtAlternate] :: FieldFormat -> Bool

-- | Characters that appeared immediately to the left of <a>fmtChar</a> in
--   the format and were accepted by the type's <a>parseFormat</a>.
--   Normally the empty string.
[fmtModifiers] :: FieldFormat -> String

-- | The format character <a>printf</a> was invoked with. <a>formatArg</a>
--   should fail unless this character matches the type. It is normal to
--   handle many different format characters for a single type.
[fmtChar] :: FieldFormat -> Char

-- | How to handle the sign of a numeric field. These are mutually
--   exclusive, with <a>SignPlus</a> taking precedence.
data FormatSign
SignPlus :: FormatSign
SignSpace :: FormatSign

-- | Whether to left-adjust or zero-pad a field. These are mutually
--   exclusive, with <a>LeftAdjust</a> taking precedence.
data FormatAdjustment
LeftAdjust :: FormatAdjustment
ZeroPad :: FormatAdjustment

-- | This class, with only the one instance, is used as a workaround for
--   the fact that <a>String</a>, as a concrete type, is not allowable as a
--   typeclass instance. <a>IsChar</a> is exported for
--   backward-compatibility.
class IsChar c

toChar :: IsChar c => c -> Char

fromChar :: IsChar c => Char -> c

-- | Typeclass of <a>printf</a>-formattable values. The <a>formatArg</a>
--   method takes a value and a field format descriptor and either fails
--   due to a bad descriptor or produces a <a>ShowS</a> as the result. The
--   default <a>parseFormat</a> expects no modifiers: this is the normal
--   case. Minimal instance: <a>formatArg</a>.
class PrintfArg a

formatArg :: PrintfArg a => a -> FieldFormatter

parseFormat :: PrintfArg a => a -> ModifierParser

-- | The <a>HPrintfType</a> class provides the variable argument magic for
--   <a>hPrintf</a>. Its implementation is intentionally not visible from
--   this module.
class HPrintfType t

-- | The <a>PrintfType</a> class provides the variable argument magic for
--   <a>printf</a>. Its implementation is intentionally not visible from
--   this module. If you attempt to pass an argument of a type which is not
--   an instance of this class to <a>printf</a> or <a>hPrintf</a>, then the
--   compiler will report it as a missing instance of <a>PrintfArg</a>.
class PrintfType t

-- | Format a variable number of arguments with the C-style formatting
--   string.
--   
--   <pre>
--   &gt;&gt;&gt; printf "%s, %d, %.4f" "hello" 123 pi
--   hello, 123, 3.1416
--   </pre>
--   
--   The return value is either <a>String</a> or <tt>(<a>IO</a> a)</tt>
--   (which should be <tt>(<a>IO</a> ())</tt>, but Haskell's type system
--   makes this hard).
--   
--   The format string consists of ordinary characters and <i>conversion
--   specifications</i>, which specify how to format one of the arguments
--   to <a>printf</a> in the output string. A format specification is
--   introduced by the <tt>%</tt> character; this character can be
--   self-escaped into the format string using <tt>%%</tt>. A format
--   specification ends with a <i>format character</i> that provides the
--   primary information about how to format the value. The rest of the
--   conversion specification is optional. In order, one may have flag
--   characters, a width specifier, a precision specifier, and
--   type-specific modifier characters.
--   
--   Unlike C <tt>printf(3)</tt>, the formatting of this <a>printf</a> is
--   driven by the argument type; formatting is type specific. The types
--   formatted by <a>printf</a> "out of the box" are:
--   
--   <ul>
--   <li><a>Integral</a> types, including <a>Char</a></li>
--   <li><a>String</a></li>
--   <li><a>RealFloat</a> types</li>
--   </ul>
--   
--   <a>printf</a> is also extensible to support other types: see below.
--   
--   A conversion specification begins with the character <tt>%</tt>,
--   followed by zero or more of the following flags:
--   
--   <pre>
--   -      left adjust (default is right adjust)
--   +      always use a sign (+ or -) for signed conversions
--   space  leading space for positive numbers in signed conversions
--   0      pad with zeros rather than spaces
--   #      use an \"alternate form\": see below
--   </pre>
--   
--   When both flags are given, <tt>-</tt> overrides <tt>0</tt> and
--   <tt>+</tt> overrides space. A negative width specifier in a <tt>*</tt>
--   conversion is treated as positive but implies the left adjust flag.
--   
--   The "alternate form" for unsigned radix conversions is as in C
--   <tt>printf(3)</tt>:
--   
--   <pre>
--   %o           prefix with a leading 0 if needed
--   %x           prefix with a leading 0x if nonzero
--   %X           prefix with a leading 0X if nonzero
--   %b           prefix with a leading 0b if nonzero
--   %[eEfFgG]    ensure that the number contains a decimal point
--   </pre>
--   
--   Any flags are followed optionally by a field width:
--   
--   <pre>
--   num    field width
--   *      as num, but taken from argument list
--   </pre>
--   
--   The field width is a minimum, not a maximum: it will be expanded as
--   needed to avoid mutilating a value.
--   
--   Any field width is followed optionally by a precision:
--   
--   <pre>
--   .num   precision
--   .      same as .0
--   .*     as num, but taken from argument list
--   </pre>
--   
--   Negative precision is taken as 0. The meaning of the precision depends
--   on the conversion type.
--   
--   <pre>
--   Integral    minimum number of digits to show
--   RealFloat   number of digits after the decimal point
--   String      maximum number of characters
--   </pre>
--   
--   The precision for Integral types is accomplished by zero-padding. If
--   both precision and zero-pad are given for an Integral field, the
--   zero-pad is ignored.
--   
--   Any precision is followed optionally for Integral types by a width
--   modifier; the only use of this modifier being to set the implicit size
--   of the operand for conversion of a negative operand to unsigned:
--   
--   <pre>
--   hh     Int8
--   h      Int16
--   l      Int32
--   ll     Int64
--   L      Int64
--   </pre>
--   
--   The specification ends with a format character:
--   
--   <pre>
--   c      character               Integral
--   d      decimal                 Integral
--   o      octal                   Integral
--   x      hexadecimal             Integral
--   X      hexadecimal             Integral
--   b      binary                  Integral
--   u      unsigned decimal        Integral
--   f      floating point          RealFloat
--   F      floating point          RealFloat
--   g      general format float    RealFloat
--   G      general format float    RealFloat
--   e      exponent format float   RealFloat
--   E      exponent format float   RealFloat
--   s      string                  String
--   v      default format          any type
--   </pre>
--   
--   The "%v" specifier is provided for all built-in types, and should be
--   provided for user-defined type formatters as well. It picks a "best"
--   representation for the given type. For the built-in types the "%v"
--   specifier is converted as follows:
--   
--   <pre>
--   c      Char
--   u      other unsigned Integral
--   d      other signed Integral
--   g      RealFloat
--   s      String
--   </pre>
--   
--   Mismatch between the argument types and the format string, as well as
--   any other syntactic or semantic errors in the format string, will
--   cause an exception to be thrown at runtime.
--   
--   Note that the formatting for <a>RealFloat</a> types is currently a bit
--   different from that of C <tt>printf(3)</tt>, conforming instead to
--   <a>showEFloat</a>, <a>showFFloat</a> and <a>showGFloat</a> (and their
--   alternate versions <a>showFFloatAlt</a> and <a>showGFloatAlt</a>).
--   This is hard to fix: the fixed versions would format in a
--   backward-incompatible way. In any case the Haskell behavior is
--   generally more sensible than the C behavior. A brief summary of some
--   key differences:
--   
--   <ul>
--   <li>Haskell <a>printf</a> never uses the default "6-digit" precision
--   used by C printf.</li>
--   <li>Haskell <a>printf</a> treats the "precision" specifier as
--   indicating the number of digits after the decimal point.</li>
--   <li>Haskell <a>printf</a> prints the exponent of e-format numbers
--   without a gratuitous plus sign, and with the minimum possible number
--   of digits.</li>
--   <li>Haskell <a>printf</a> will place a zero after a decimal point when
--   possible.</li>
--   </ul>
printf :: PrintfType r => String -> r

-- | Similar to <a>printf</a>, except that output is via the specified
--   <a>Handle</a>. The return type is restricted to <tt>(<a>IO</a>
--   a)</tt>.
hPrintf :: HPrintfType r => Handle -> String -> r

-- | Substitute a 'v' format character with the given default format
--   character in the <a>FieldFormat</a>. A convenience for
--   user-implemented types, which should support "%v".
vFmt :: Char -> FieldFormat -> FieldFormat

-- | Formatter for <a>Char</a> values.
formatChar :: Char -> FieldFormatter

-- | Formatter for <a>Int</a> values.
formatInt :: (Integral a, Bounded a) => a -> FieldFormatter

-- | Formatter for <a>Integer</a> values.
formatInteger :: Integer -> FieldFormatter

-- | Raises an <a>error</a> with a printf-specific prefix on the message
--   string.
perror :: String -> a

-- | Calls <a>perror</a> to indicate an unknown format letter for a given
--   type.
errorBadFormat :: Char -> a

-- | Calls <a>perror</a> to indicate that the format string ended early.
errorShortFormat :: a

-- | Calls <a>perror</a> to indicate that there is a missing argument in
--   the argument list.
errorMissingArgument :: a

-- | Calls <a>perror</a> to indicate that there is a type error or similar
--   in the given argument.
errorBadArgument :: a

-- | <i>O(n)</i> Convert a <a>String</a> into a <a>Text</a>. Performs
--   replacement on invalid scalar values, so <tt><a>unpack</a> .
--   <a>pack</a></tt> is not <a>id</a>:
--   
--   <pre>
--   &gt;&gt;&gt; Data.Text.unpack (pack "\55555")
--   "\65533"
--   </pre>
pack :: String -> Text

-- | <i>O(n)</i> Convert a <a>Text</a> into a <a>String</a>.
unpack :: Text -> String
expandArgsAt :: [String] -> IO [String]
joinArgs :: [String] -> String
splitArgs :: String -> [String]
class Remap (m :: Type -> Type)
remap :: Remap m => (a -> b) -> (b -> (a, a -> b)) -> m a -> m b
data Flag a
Flag :: [Name] -> FlagInfo -> Update a -> FlagHelp -> Help -> Flag a
[flagNames] :: Flag a -> [Name]
[flagInfo] :: Flag a -> FlagInfo
[flagValue] :: Flag a -> Update a
[flagType] :: Flag a -> FlagHelp
[flagHelp] :: Flag a -> Help
type Update a = String -> a -> Either String a
data FlagInfo
FlagReq :: FlagInfo
FlagOpt :: String -> FlagInfo
FlagOptRare :: String -> FlagInfo
FlagNone :: FlagInfo
data Mode a
Mode :: Group (Mode a) -> [Name] -> a -> (a -> Either String a) -> (a -> Maybe [String]) -> Bool -> Help -> [String] -> ([Arg a], Maybe (Arg a)) -> Group (Flag a) -> Mode a
[modeGroupModes] :: Mode a -> Group (Mode a)
[modeNames] :: Mode a -> [Name]
[modeValue] :: Mode a -> a
[modeCheck] :: Mode a -> a -> Either String a
[modeReform] :: Mode a -> a -> Maybe [String]
[modeExpandAt] :: Mode a -> Bool
[modeHelp] :: Mode a -> Help
[modeHelpSuffix] :: Mode a -> [String]
[modeArgs] :: Mode a -> ([Arg a], Maybe (Arg a))
[modeGroupFlags] :: Mode a -> Group (Flag a)
data Group a
Group :: [a] -> [a] -> [(Help, [a])] -> Group a
[groupUnnamed] :: Group a -> [a]
[groupHidden] :: Group a -> [a]
[groupNamed] :: Group a -> [(Help, [a])]
type FlagHelp = String
type Help = String
parseBool :: String -> Maybe Bool
fromGroup :: Group a -> [a]
toGroup :: [a] -> Group a
modeModes :: Mode a -> [Mode a]
modeFlags :: Mode a -> [Flag a]
fromFlagOpt :: FlagInfo -> String
checkMode :: Mode a -> Maybe String
remap2 :: Remap m => (a -> b) -> (b -> a) -> m a -> m b
remapUpdate :: (a -> b) -> (b -> (a, a -> b)) -> Update a -> Update b
modeEmpty :: a -> Mode a
mode :: Name -> a -> Help -> Arg a -> [Flag a] -> Mode a
modes :: String -> a -> Help -> [Mode a] -> Mode a
flagNone :: [Name] -> (a -> a) -> Help -> Flag a
flagOpt :: String -> [Name] -> Update a -> FlagHelp -> Help -> Flag a
flagReq :: [Name] -> Update a -> FlagHelp -> Help -> Flag a
flagArg :: Update a -> FlagHelp -> Arg a
flagBool :: [Name] -> (Bool -> a -> a) -> Help -> Flag a
data Complete
CompleteValue :: String -> Complete
CompleteFile :: String -> FilePath -> Complete
CompleteDir :: String -> FilePath -> Complete
complete :: Mode a -> [String] -> (Int, Int) -> [Complete]
data HelpFormat
HelpFormatDefault :: HelpFormat
HelpFormatOne :: HelpFormat
HelpFormatAll :: HelpFormat
HelpFormatBash :: HelpFormat
HelpFormatZsh :: HelpFormat
helpText :: [String] -> HelpFormat -> Mode a -> [Text]
processArgs :: Mode a -> IO a
processValue :: Mode a -> [String] -> a
processValueIO :: Mode a -> [String] -> IO a
flagHelpSimple :: (a -> a) -> Flag a
flagHelpFormat :: (HelpFormat -> TextFormat -> a -> a) -> Flag a
flagVersion :: (a -> a) -> Flag a
flagNumericVersion :: (a -> a) -> Flag a
flagsVerbosity :: (Verbosity -> a -> a) -> [Flag a]

-- | The character that is used to separate the entries in the $PATH
--   environment variable.
--   
--   <pre>
--   Windows: searchPathSeparator == ';'
--   Posix:   searchPathSeparator == ':'
--   </pre>
searchPathSeparator :: Char

-- | Normalise a file
--   
--   <ul>
--   <li>// outside of the drive can be made blank</li>
--   <li>/ -&gt; <a>pathSeparator</a></li>
--   <li>./ -&gt; ""</li>
--   </ul>
--   
--   Does not remove <tt>".."</tt>, because of symlinks.
--   
--   <pre>
--   Posix:   normalise "/file/\\test////" == "/file/\\test/"
--   Posix:   normalise "/file/./test" == "/file/test"
--   Posix:   normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/"
--   Posix:   normalise "../bob/fred/" == "../bob/fred/"
--   Posix:   normalise "/a/../c" == "/a/../c"
--   Posix:   normalise "./bob/fred/" == "bob/fred/"
--   Windows: normalise "c:\\file/bob\\" == "C:\\file\\bob\\"
--   Windows: normalise "c:\\" == "C:\\"
--   Windows: normalise "c:\\\\\\\\" == "C:\\"
--   Windows: normalise "C:.\\" == "C:"
--   Windows: normalise "\\\\server\\test" == "\\\\server\\test"
--   Windows: normalise "//server/test" == "\\\\server\\test"
--   Windows: normalise "c:/file" == "C:\\file"
--   Windows: normalise "/file" == "\\file"
--   Windows: normalise "\\" == "\\"
--   Windows: normalise "/./" == "\\"
--            normalise "." == "."
--   Posix:   normalise "./" == "./"
--   Posix:   normalise "./." == "./"
--   Posix:   normalise "/./" == "/"
--   Posix:   normalise "/" == "/"
--   Posix:   normalise "bob/fred/." == "bob/fred/"
--   Posix:   normalise "//home" == "/home"
--   </pre>
normalise :: FilePath -> FilePath

-- | Remove any trailing path separators
--   
--   <pre>
--   dropTrailingPathSeparator "file/test/" == "file/test"
--             dropTrailingPathSeparator "/" == "/"
--   Windows:  dropTrailingPathSeparator "\\" == "\\"
--   Posix:    not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
--   </pre>
dropTrailingPathSeparator :: FilePath -> FilePath

-- | Contract a filename, based on a relative path. Note that the resulting
--   path will never introduce <tt>..</tt> paths, as the presence of
--   symlinks means <tt>../b</tt> may not reach <tt>a/b</tt> if it starts
--   from <tt>a/c</tt>. For a worked example see <a>this blog post</a>.
--   
--   The corresponding <tt>makeAbsolute</tt> function can be found in
--   <tt>System.Directory</tt>.
--   
--   <pre>
--            makeRelative "/directory" "/directory/file.ext" == "file.ext"
--            Valid x =&gt; makeRelative (takeDirectory x) x `equalFilePath` takeFileName x
--            makeRelative x x == "."
--            Valid x y =&gt; equalFilePath x y || (isRelative x &amp;&amp; makeRelative y x == x) || equalFilePath (y &lt;/&gt; makeRelative y x) x
--   Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"
--   Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"
--   Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"
--   Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"
--   Windows: makeRelative "/Home" "/home/bob" == "bob"
--   Windows: makeRelative "/" "//" == "//"
--   Posix:   makeRelative "/Home" "/home/bob" == "/home/bob"
--   Posix:   makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"
--   Posix:   makeRelative "/fred" "bob" == "bob"
--   Posix:   makeRelative "/file/test" "/file/test/fred" == "fred"
--   Posix:   makeRelative "/file/test" "/file/test/fred/" == "fred/"
--   Posix:   makeRelative "some/path" "some/path/a/b/c" == "a/b/c"
--   </pre>
makeRelative :: FilePath -> FilePath -> FilePath

-- | Combine two paths with a path separator. If the second path starts
--   with a path separator or a drive letter, then it returns the second.
--   The intention is that <tt>readFile (dir <a>&lt;/&gt;</a> file)</tt>
--   will access the same file as <tt>setCurrentDirectory dir; readFile
--   file</tt>.
--   
--   <pre>
--   Posix:   "/directory" &lt;/&gt; "file.ext" == "/directory/file.ext"
--   Windows: "/directory" &lt;/&gt; "file.ext" == "/directory\\file.ext"
--            "directory" &lt;/&gt; "/file.ext" == "/file.ext"
--   Valid x =&gt; (takeDirectory x &lt;/&gt; takeFileName x) `equalFilePath` x
--   </pre>
--   
--   Combined:
--   
--   <pre>
--   Posix:   "/" &lt;/&gt; "test" == "/test"
--   Posix:   "home" &lt;/&gt; "bob" == "home/bob"
--   Posix:   "x:" &lt;/&gt; "foo" == "x:/foo"
--   Windows: "C:\\foo" &lt;/&gt; "bar" == "C:\\foo\\bar"
--   Windows: "home" &lt;/&gt; "bob" == "home\\bob"
--   </pre>
--   
--   Not combined:
--   
--   <pre>
--   Posix:   "home" &lt;/&gt; "/bob" == "/bob"
--   Windows: "home" &lt;/&gt; "C:\\bob" == "C:\\bob"
--   </pre>
--   
--   Not combined (tricky):
--   
--   On Windows, if a filepath starts with a single slash, it is relative
--   to the root of the current drive. In [1], this is (confusingly)
--   referred to as an absolute path. The current behavior of
--   <a>&lt;/&gt;</a> is to never combine these forms.
--   
--   <pre>
--   Windows: "home" &lt;/&gt; "/bob" == "/bob"
--   Windows: "home" &lt;/&gt; "\\bob" == "\\bob"
--   Windows: "C:\\home" &lt;/&gt; "\\bob" == "\\bob"
--   </pre>
--   
--   On Windows, from [1]: "If a file name begins with only a disk
--   designator but not the backslash after the colon, it is interpreted as
--   a relative path to the current directory on the drive with the
--   specified letter." The current behavior of <a>&lt;/&gt;</a> is to
--   never combine these forms.
--   
--   <pre>
--   Windows: "D:\\foo" &lt;/&gt; "C:bar" == "C:bar"
--   Windows: "C:\\foo" &lt;/&gt; "C:bar" == "C:bar"
--   </pre>
(</>) :: FilePath -> FilePath -> FilePath
infixr 5 </>
headDef :: a -> [a] -> a
lastDef :: a -> [a] -> a

-- | The character that separates directories. In the case where more than
--   one character is possible, <a>pathSeparator</a> is the 'ideal' one.
--   
--   <pre>
--   Windows: pathSeparator == '\\'
--   Posix:   pathSeparator ==  '/'
--   isPathSeparator pathSeparator
--   </pre>
pathSeparator :: Char

-- | The list of all possible separators.
--   
--   <pre>
--   Windows: pathSeparators == ['\\', '/']
--   Posix:   pathSeparators == ['/']
--   pathSeparator `elem` pathSeparators
--   </pre>
pathSeparators :: [Char]

-- | Rather than using <tt>(== <a>pathSeparator</a>)</tt>, use this. Test
--   if something is a path separator.
--   
--   <pre>
--   isPathSeparator a == (a `elem` pathSeparators)
--   </pre>
isPathSeparator :: Char -> Bool

-- | Is the character a file separator?
--   
--   <pre>
--   isSearchPathSeparator a == (a == searchPathSeparator)
--   </pre>
isSearchPathSeparator :: Char -> Bool

-- | File extension character
--   
--   <pre>
--   extSeparator == '.'
--   </pre>
extSeparator :: Char

-- | Is the character an extension character?
--   
--   <pre>
--   isExtSeparator a == (a == extSeparator)
--   </pre>
isExtSeparator :: Char -> Bool

-- | Take a string, split it on the <a>searchPathSeparator</a> character.
--   Blank items are ignored on Windows, and converted to <tt>.</tt> on
--   Posix. On Windows path elements are stripped of quotes.
--   
--   Follows the recommendations in
--   <a>http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html</a>
--   
--   <pre>
--   Posix:   splitSearchPath "File1:File2:File3"  == ["File1","File2","File3"]
--   Posix:   splitSearchPath "File1::File2:File3" == ["File1",".","File2","File3"]
--   Windows: splitSearchPath "File1;File2;File3"  == ["File1","File2","File3"]
--   Windows: splitSearchPath "File1;;File2;File3" == ["File1","File2","File3"]
--   Windows: splitSearchPath "File1;\"File2\";File3" == ["File1","File2","File3"]
--   </pre>
splitSearchPath :: String -> [FilePath]

-- | Get a list of <tt>FILEPATH</tt>s in the $PATH variable.
getSearchPath :: IO [FilePath]

-- | Split on the extension. <a>addExtension</a> is the inverse.
--   
--   <pre>
--   splitExtension "/directory/path.ext" == ("/directory/path",".ext")
--   uncurry (&lt;&gt;) (splitExtension x) == x
--   Valid x =&gt; uncurry addExtension (splitExtension x) == x
--   splitExtension "file.txt" == ("file",".txt")
--   splitExtension "file" == ("file","")
--   splitExtension "file/file.txt" == ("file/file",".txt")
--   splitExtension "file.txt/boris" == ("file.txt/boris","")
--   splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
--   splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
--   splitExtension "file/path.txt/" == ("file/path.txt/","")
--   </pre>
splitExtension :: FilePath -> (String, String)

-- | Get the extension of a file, returns <tt>""</tt> for no extension,
--   <tt>.ext</tt> otherwise.
--   
--   <pre>
--   takeExtension "/directory/path.ext" == ".ext"
--   takeExtension x == snd (splitExtension x)
--   Valid x =&gt; takeExtension (addExtension x "ext") == ".ext"
--   Valid x =&gt; takeExtension (replaceExtension x "ext") == ".ext"
--   </pre>
takeExtension :: FilePath -> String

-- | Remove the current extension and add another, equivalent to
--   <a>replaceExtension</a>.
--   
--   <pre>
--   "/directory/path.txt" -&lt;.&gt; "ext" == "/directory/path.ext"
--   "/directory/path.txt" -&lt;.&gt; ".ext" == "/directory/path.ext"
--   "foo.o" -&lt;.&gt; "c" == "foo.c"
--   </pre>
(-<.>) :: FilePath -> String -> FilePath
infixr 7 -<.>

-- | Set the extension of a file, overwriting one if already present,
--   equivalent to <a>-&lt;.&gt;</a>.
--   
--   <pre>
--   replaceExtension "/directory/path.txt" "ext" == "/directory/path.ext"
--   replaceExtension "/directory/path.txt" ".ext" == "/directory/path.ext"
--   replaceExtension "file.txt" ".bob" == "file.bob"
--   replaceExtension "file.txt" "bob" == "file.bob"
--   replaceExtension "file" ".bob" == "file.bob"
--   replaceExtension "file.txt" "" == "file"
--   replaceExtension "file.fred.bob" "txt" == "file.fred.txt"
--   replaceExtension x y == addExtension (dropExtension x) y
--   </pre>
replaceExtension :: FilePath -> String -> FilePath

-- | Add an extension, even if there is already one there, equivalent to
--   <a>addExtension</a>.
--   
--   <pre>
--   "/directory/path" &lt;.&gt; "ext" == "/directory/path.ext"
--   "/directory/path" &lt;.&gt; ".ext" == "/directory/path.ext"
--   </pre>
(<.>) :: FilePath -> String -> FilePath
infixr 7 <.>

-- | Remove last extension, and the "." preceding it.
--   
--   <pre>
--   dropExtension "/directory/path.ext" == "/directory/path"
--   dropExtension x == fst (splitExtension x)
--   </pre>
dropExtension :: FilePath -> FilePath

-- | Add an extension, even if there is already one there, equivalent to
--   <a>&lt;.&gt;</a>.
--   
--   <pre>
--   addExtension "/directory/path" "ext" == "/directory/path.ext"
--   addExtension "file.txt" "bib" == "file.txt.bib"
--   addExtension "file." ".bib" == "file..bib"
--   addExtension "file" ".bib" == "file.bib"
--   addExtension "/" "x" == "/.x"
--   addExtension x "" == x
--   Valid x =&gt; takeFileName (addExtension (addTrailingPathSeparator x) "ext") == ".ext"
--   Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt"
--   </pre>
addExtension :: FilePath -> String -> FilePath

-- | Does the given filename have an extension?
--   
--   <pre>
--   hasExtension "/directory/path.ext" == True
--   hasExtension "/directory/path" == False
--   null (takeExtension x) == not (hasExtension x)
--   </pre>
hasExtension :: FilePath -> Bool

-- | Does the given filename have the specified extension?
--   
--   <pre>
--   "png" `isExtensionOf` "/directory/file.png" == True
--   ".png" `isExtensionOf` "/directory/file.png" == True
--   ".tar.gz" `isExtensionOf` "bar/foo.tar.gz" == True
--   "ar.gz" `isExtensionOf` "bar/foo.tar.gz" == False
--   "png" `isExtensionOf` "/directory/file.png.jpg" == False
--   "csv/table.csv" `isExtensionOf` "/data/csv/table.csv" == False
--   </pre>
isExtensionOf :: String -> FilePath -> Bool

-- | Drop the given extension from a FilePath, and the <tt>"."</tt>
--   preceding it. Returns <a>Nothing</a> if the FilePath does not have the
--   given extension, or <a>Just</a> and the part before the extension if
--   it does.
--   
--   This function can be more predictable than <a>dropExtensions</a>,
--   especially if the filename might itself contain <tt>.</tt> characters.
--   
--   <pre>
--   stripExtension "hs.o" "foo.x.hs.o" == Just "foo.x"
--   stripExtension "hi.o" "foo.x.hs.o" == Nothing
--   dropExtension x == fromJust (stripExtension (takeExtension x) x)
--   dropExtensions x == fromJust (stripExtension (takeExtensions x) x)
--   stripExtension ".c.d" "a.b.c.d"  == Just "a.b"
--   stripExtension ".c.d" "a.b..c.d" == Just "a.b."
--   stripExtension "baz"  "foo.bar"  == Nothing
--   stripExtension "bar"  "foobar"   == Nothing
--   stripExtension ""     x          == Just x
--   </pre>
stripExtension :: String -> FilePath -> Maybe FilePath

-- | Split on all extensions.
--   
--   <pre>
--   splitExtensions "/directory/path.ext" == ("/directory/path",".ext")
--   splitExtensions "file.tar.gz" == ("file",".tar.gz")
--   uncurry (&lt;&gt;) (splitExtensions x) == x
--   Valid x =&gt; uncurry addExtension (splitExtensions x) == x
--   </pre>
splitExtensions :: FilePath -> (FilePath, String)

-- | Drop all extensions.
--   
--   <pre>
--   dropExtensions "/directory/path.ext" == "/directory/path"
--   dropExtensions "file.tar.gz" == "file"
--   not $ hasExtension $ dropExtensions x
--   not $ any isExtSeparator $ takeFileName $ dropExtensions x
--   </pre>
dropExtensions :: FilePath -> FilePath

-- | Get all extensions.
--   
--   <pre>
--   takeExtensions "/directory/path.ext" == ".ext"
--   takeExtensions "file.tar.gz" == ".tar.gz"
--   </pre>
takeExtensions :: FilePath -> String

-- | Replace all extensions of a file with a new extension. Note that
--   <a>replaceExtension</a> and <a>addExtension</a> both work for adding
--   multiple extensions, so only required when you need to drop all
--   extensions first.
--   
--   <pre>
--   replaceExtensions "file.fred.bob" "txt" == "file.txt"
--   replaceExtensions "file.fred.bob" "tar.gz" == "file.tar.gz"
--   </pre>
replaceExtensions :: FilePath -> String -> FilePath

-- | Split a path into a drive and a path. On Posix, / is a Drive.
--   
--   <pre>
--   uncurry (&lt;&gt;) (splitDrive x) == x
--   Windows: splitDrive "file" == ("","file")
--   Windows: splitDrive "c:/file" == ("c:/","file")
--   Windows: splitDrive "c:\\file" == ("c:\\","file")
--   Windows: splitDrive "\\\\shared\\test" == ("\\\\shared\\","test")
--   Windows: splitDrive "\\\\shared" == ("\\\\shared","")
--   Windows: splitDrive "\\\\?\\UNC\\shared\\file" == ("\\\\?\\UNC\\shared\\","file")
--   Windows: splitDrive "\\\\?\\UNCshared\\file" == ("\\\\?\\","UNCshared\\file")
--   Windows: splitDrive "\\\\?\\d:\\file" == ("\\\\?\\d:\\","file")
--   Windows: splitDrive "/d" == ("","/d")
--   Posix:   splitDrive "/test" == ("/","test")
--   Posix:   splitDrive "//test" == ("//","test")
--   Posix:   splitDrive "test/file" == ("","test/file")
--   Posix:   splitDrive "file" == ("","file")
--   </pre>
splitDrive :: FilePath -> (FilePath, FilePath)

-- | Join a drive and the rest of the path.
--   
--   <pre>
--   Valid x =&gt; uncurry joinDrive (splitDrive x) == x
--   Windows: joinDrive "C:" "foo" == "C:foo"
--   Windows: joinDrive "C:\\" "bar" == "C:\\bar"
--   Windows: joinDrive "\\\\share" "foo" == "\\\\share\\foo"
--   Windows: joinDrive "/:" "foo" == "/:\\foo"
--   </pre>
joinDrive :: FilePath -> FilePath -> FilePath

-- | Get the drive from a filepath.
--   
--   <pre>
--   takeDrive x == fst (splitDrive x)
--   </pre>
takeDrive :: FilePath -> FilePath

-- | Delete the drive, if it exists.
--   
--   <pre>
--   dropDrive x == snd (splitDrive x)
--   </pre>
dropDrive :: FilePath -> FilePath

-- | Does a path have a drive.
--   
--   <pre>
--   not (hasDrive x) == null (takeDrive x)
--   Posix:   hasDrive "/foo" == True
--   Windows: hasDrive "C:\\foo" == True
--   Windows: hasDrive "C:foo" == True
--            hasDrive "foo" == False
--            hasDrive "" == False
--   </pre>
hasDrive :: FilePath -> Bool

-- | Is an element a drive
--   
--   <pre>
--   Posix:   isDrive "/" == True
--   Posix:   isDrive "/foo" == False
--   Windows: isDrive "C:\\" == True
--   Windows: isDrive "C:\\foo" == False
--            isDrive "" == False
--   </pre>
isDrive :: FilePath -> Bool

-- | Split a filename into directory and file. <a>&lt;/&gt;</a> is the
--   inverse. The first component will often end with a trailing slash.
--   
--   <pre>
--   splitFileName "/directory/file.ext" == ("/directory/","file.ext")
--   Valid x =&gt; uncurry (&lt;/&gt;) (splitFileName x) == x || fst (splitFileName x) == "./"
--   Valid x =&gt; isValid (fst (splitFileName x))
--   splitFileName "file/bob.txt" == ("file/", "bob.txt")
--   splitFileName "file/" == ("file/", "")
--   splitFileName "bob" == ("./", "bob")
--   Posix:   splitFileName "/" == ("/","")
--   Windows: splitFileName "c:" == ("c:","")
--   Windows: splitFileName "\\\\?\\A:\\fred" == ("\\\\?\\A:\\","fred")
--   Windows: splitFileName "\\\\?\\A:" == ("\\\\?\\A:","")
--   </pre>
splitFileName :: FilePath -> (String, String)

-- | Set the filename.
--   
--   <pre>
--   replaceFileName "/directory/other.txt" "file.ext" == "/directory/file.ext"
--   Valid x =&gt; replaceFileName x (takeFileName x) == x
--   </pre>
replaceFileName :: FilePath -> String -> FilePath

-- | Drop the filename. Unlike <a>takeDirectory</a>, this function will
--   leave a trailing path separator on the directory.
--   
--   <pre>
--   dropFileName "/directory/file.ext" == "/directory/"
--   dropFileName x == fst (splitFileName x)
--   isPrefixOf (takeDrive x) (dropFileName x)
--   </pre>
dropFileName :: FilePath -> FilePath

-- | Get the file name.
--   
--   <pre>
--   takeFileName "/directory/file.ext" == "file.ext"
--   takeFileName "test/" == ""
--   isSuffixOf (takeFileName x) x
--   takeFileName x == snd (splitFileName x)
--   Valid x =&gt; takeFileName (replaceFileName x "fred") == "fred"
--   Valid x =&gt; takeFileName (x &lt;/&gt; "fred") == "fred"
--   Valid x =&gt; isRelative (takeFileName x)
--   </pre>
takeFileName :: FilePath -> FilePath

-- | Get the base name, without an extension or path.
--   
--   <pre>
--   takeBaseName "/directory/file.ext" == "file"
--   takeBaseName "file/test.txt" == "test"
--   takeBaseName "dave.ext" == "dave"
--   takeBaseName "" == ""
--   takeBaseName "test" == "test"
--   takeBaseName (addTrailingPathSeparator x) == ""
--   takeBaseName "file/file.tar.gz" == "file.tar"
--   </pre>
takeBaseName :: FilePath -> String

-- | Set the base name.
--   
--   <pre>
--   replaceBaseName "/directory/other.ext" "file" == "/directory/file.ext"
--   replaceBaseName "file/test.txt" "bob" == "file/bob.txt"
--   replaceBaseName "fred" "bill" == "bill"
--   replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar"
--   Valid x =&gt; replaceBaseName x (takeBaseName x) == x
--   </pre>
replaceBaseName :: FilePath -> String -> FilePath

-- | Is an item either a directory or the last character a path separator?
--   
--   <pre>
--   hasTrailingPathSeparator "test" == False
--   hasTrailingPathSeparator "test/" == True
--   </pre>
hasTrailingPathSeparator :: FilePath -> Bool

-- | Add a trailing file path separator if one is not already present.
--   
--   <pre>
--   hasTrailingPathSeparator (addTrailingPathSeparator x)
--   hasTrailingPathSeparator x ==&gt; addTrailingPathSeparator x == x
--   Posix:    addTrailingPathSeparator "test/rest" == "test/rest/"
--   </pre>
addTrailingPathSeparator :: FilePath -> FilePath

-- | Get the directory name, move up one level.
--   
--   <pre>
--             takeDirectory "/directory/other.ext" == "/directory"
--             isPrefixOf (takeDirectory x) x || takeDirectory x == "."
--             takeDirectory "foo" == "."
--             takeDirectory "/" == "/"
--             takeDirectory "/foo" == "/"
--             takeDirectory "/foo/bar/baz" == "/foo/bar"
--             takeDirectory "/foo/bar/baz/" == "/foo/bar/baz"
--             takeDirectory "foo/bar/baz" == "foo/bar"
--   Windows:  takeDirectory "foo\\bar" == "foo"
--   Windows:  takeDirectory "foo\\bar\\\\" == "foo\\bar"
--   Windows:  takeDirectory "C:\\" == "C:\\"
--   </pre>
takeDirectory :: FilePath -> FilePath

-- | Set the directory, keeping the filename the same.
--   
--   <pre>
--   replaceDirectory "root/file.ext" "/directory/" == "/directory/file.ext"
--   Valid x =&gt; replaceDirectory x (takeDirectory x) `equalFilePath` x
--   </pre>
replaceDirectory :: FilePath -> String -> FilePath

-- | An alias for <a>&lt;/&gt;</a>.
combine :: FilePath -> FilePath -> FilePath

-- | Split a path by the directory separator.
--   
--   <pre>
--   splitPath "/directory/file.ext" == ["/","directory/","file.ext"]
--   concat (splitPath x) == x
--   splitPath "test//item/" == ["test//","item/"]
--   splitPath "test/item/file" == ["test/","item/","file"]
--   splitPath "" == []
--   Windows: splitPath "c:\\test\\path" == ["c:\\","test\\","path"]
--   Posix:   splitPath "/file/test" == ["/","file/","test"]
--   </pre>
splitPath :: FilePath -> [FilePath]

-- | Just as <a>splitPath</a>, but don't add the trailing slashes to each
--   element.
--   
--   <pre>
--            splitDirectories "/directory/file.ext" == ["/","directory","file.ext"]
--            splitDirectories "test/file" == ["test","file"]
--            splitDirectories "/test/file" == ["/","test","file"]
--   Windows: splitDirectories "C:\\test\\file" == ["C:\\", "test", "file"]
--            Valid x =&gt; joinPath (splitDirectories x) `equalFilePath` x
--            splitDirectories "" == []
--   Windows: splitDirectories "C:\\test\\\\\\file" == ["C:\\", "test", "file"]
--            splitDirectories "/test///file" == ["/","test","file"]
--   </pre>
splitDirectories :: FilePath -> [FilePath]

-- | Join path elements back together.
--   
--   <pre>
--   joinPath z == foldr (&lt;/&gt;) "" z
--   joinPath ["/","directory/","file.ext"] == "/directory/file.ext"
--   Valid x =&gt; joinPath (splitPath x) == x
--   joinPath [] == ""
--   Posix: joinPath ["test","file","path"] == "test/file/path"
--   </pre>
joinPath :: [FilePath] -> FilePath

-- | Equality of two <tt>FILEPATH</tt>s. If you call
--   <tt>System.Directory.canonicalizePath</tt> first this has a much
--   better chance of working. Note that this doesn't follow symlinks or
--   DOSNAM~1s.
--   
--   Similar to <a>normalise</a>, this does not expand <tt>".."</tt>,
--   because of symlinks.
--   
--   <pre>
--            x == y ==&gt; equalFilePath x y
--            normalise x == normalise y ==&gt; equalFilePath x y
--            equalFilePath "foo" "foo/"
--            not (equalFilePath "/a/../c" "/c")
--            not (equalFilePath "foo" "/foo")
--   Posix:   not (equalFilePath "foo" "FOO")
--   Windows: equalFilePath "foo" "FOO"
--   Windows: not (equalFilePath "C:" "C:/")
--   </pre>
equalFilePath :: FilePath -> FilePath -> Bool

-- | Is a FilePath valid, i.e. could you create a file like it? This
--   function checks for invalid names, and invalid characters, but does
--   not check if length limits are exceeded, as these are typically
--   filesystem dependent.
--   
--   <pre>
--            isValid "" == False
--            isValid "\0" == False
--   Posix:   isValid "/random_ path:*" == True
--   Posix:   isValid x == not (null x)
--   Windows: isValid "c:\\test" == True
--   Windows: isValid "c:\\test:of_test" == False
--   Windows: isValid "test*" == False
--   Windows: isValid "c:\\test\\nul" == False
--   Windows: isValid "c:\\test\\prn.txt" == False
--   Windows: isValid "c:\\nul\\file" == False
--   Windows: isValid "\\\\" == False
--   Windows: isValid "\\\\\\foo" == False
--   Windows: isValid "\\\\?\\D:file" == False
--   Windows: isValid "foo\tbar" == False
--   Windows: isValid "nul .txt" == False
--   Windows: isValid " nul.txt" == True
--   </pre>
isValid :: FilePath -> Bool

-- | Take a FilePath and make it valid; does not change already valid
--   FILEPATHs.
--   
--   <pre>
--   isValid (makeValid x)
--   isValid x ==&gt; makeValid x == x
--   makeValid "" == "_"
--   makeValid "file\0name" == "file_name"
--   Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"
--   Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
--   Windows: makeValid "test*" == "test_"
--   Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
--   Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
--   Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
--   Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file"
--   Windows: makeValid "\\\\\\foo" == "\\\\drive"
--   Windows: makeValid "\\\\?\\D:file" == "\\\\?\\D:\\file"
--   Windows: makeValid "nul .txt" == "nul _.txt"
--   </pre>
makeValid :: FilePath -> FilePath

-- | Is a path relative, or is it fixed to the root?
--   
--   <pre>
--   Windows: isRelative "path\\test" == True
--   Windows: isRelative "c:\\test" == False
--   Windows: isRelative "c:test" == True
--   Windows: isRelative "c:\\" == False
--   Windows: isRelative "c:/" == False
--   Windows: isRelative "c:" == True
--   Windows: isRelative "\\\\foo" == False
--   Windows: isRelative "\\\\?\\foo" == False
--   Windows: isRelative "\\\\?\\UNC\\foo" == False
--   Windows: isRelative "/foo" == True
--   Windows: isRelative "\\foo" == True
--   Posix:   isRelative "test/path" == True
--   Posix:   isRelative "/test" == False
--   Posix:   isRelative "/" == False
--   </pre>
--   
--   According to [1]:
--   
--   <ul>
--   <li>"A UNC name of any format [is never relative]."</li>
--   <li>"You cannot use the "\?" prefix with a relative path."</li>
--   </ul>
isRelative :: FilePath -> Bool

-- | <pre>
--   not . <a>isRelative</a>
--   </pre>
--   
--   <pre>
--   isAbsolute x == not (isRelative x)
--   </pre>
isAbsolute :: FilePath -> Bool
foldl1May :: (a -> a -> a) -> [a] -> Maybe a
foldr1May :: (a -> a -> a) -> [a] -> Maybe a
foldl1Note :: Partial => String -> (a -> a -> a) -> [a] -> a
foldr1Note :: Partial => String -> (a -> a -> a) -> [a] -> a
minimumMay :: Ord a => [a] -> Maybe a
maximumMay :: Ord a => [a] -> Maybe a
minimumNote :: (Partial, Ord a) => String -> [a] -> a
maximumNote :: (Partial, Ord a) => String -> [a] -> a
minimumByMay :: (a -> a -> Ordering) -> [a] -> Maybe a
maximumByMay :: (a -> a -> Ordering) -> [a] -> Maybe a
minimumByNote :: Partial => String -> (a -> a -> Ordering) -> [a] -> a
maximumByNote :: Partial => String -> (a -> a -> Ordering) -> [a] -> a
maximumBoundBy :: a -> (a -> a -> Ordering) -> [a] -> a
minimumBoundBy :: a -> (a -> a -> Ordering) -> [a] -> a
maximumBound :: Ord a => a -> [a] -> a
minimumBound :: Ord a => a -> [a] -> a
maximumBounded :: (Ord a, Bounded a) => [a] -> a
minimumBounded :: (Ord a, Bounded a) => [a] -> a
findJust :: (a -> Bool) -> [a] -> a
findJustDef :: a -> (a -> Bool) -> [a] -> a
findJustNote :: Partial => String -> (a -> Bool) -> [a] -> a
minimumDef :: Ord a => a -> [a] -> a
maximumDef :: Ord a => a -> [a] -> a
minimumByDef :: a -> (a -> a -> Ordering) -> [a] -> a
maximumByDef :: a -> (a -> a -> Ordering) -> [a] -> a
foldl1Def :: a -> (a -> a -> a) -> [a] -> a
foldr1Def :: a -> (a -> a -> a) -> [a] -> a
abort :: Partial => String -> a
tailErr :: Partial => [a] -> [a]
headErr :: Partial => [a] -> a
tailMay :: [a] -> Maybe [a]
tailDef :: [a] -> [a] -> [a]
tailNote :: Partial => String -> [a] -> [a]
tailSafe :: [a] -> [a]
initMay :: [a] -> Maybe [a]
initDef :: [a] -> [a] -> [a]
initNote :: Partial => String -> [a] -> [a]
initSafe :: [a] -> [a]
headMay :: [a] -> Maybe a
lastMay :: [a] -> Maybe a
headNote :: Partial => String -> [a] -> a
lastNote :: Partial => String -> [a] -> a
foldl1May' :: (a -> a -> a) -> [a] -> Maybe a
foldl1Note' :: Partial => String -> (a -> a -> a) -> [a] -> a
scanr1May :: (a -> a -> a) -> [a] -> Maybe [a]
scanl1May :: (a -> a -> a) -> [a] -> Maybe [a]
scanr1Def :: [a] -> (a -> a -> a) -> [a] -> [a]
scanl1Def :: [a] -> (a -> a -> a) -> [a] -> [a]
scanr1Note :: Partial => String -> (a -> a -> a) -> [a] -> [a]
scanl1Note :: Partial => String -> (a -> a -> a) -> [a] -> [a]
cycleMay :: [a] -> Maybe [a]
cycleDef :: [a] -> [a] -> [a]
cycleNote :: Partial => String -> [a] -> [a]
fromJustDef :: a -> Maybe a -> a
fromJustNote :: Partial => String -> Maybe a -> a
assertNote :: Partial => String -> Bool -> a -> a
atMay :: [a] -> Int -> Maybe a
atDef :: a -> [a] -> Int -> a
atNote :: Partial => String -> [a] -> Int -> a
readEitherSafe :: Read a => String -> Either String a
readMay :: Read a => String -> Maybe a
readDef :: Read a => a -> String -> a
readNote :: (Partial, Read a) => String -> String -> a
lookupJust :: (Eq a, Partial) => a -> [(a, b)] -> b
lookupJustDef :: Eq a => b -> a -> [(a, b)] -> b
lookupJustNote :: (Partial, Eq a) => String -> a -> [(a, b)] -> b
elemIndexJust :: (Partial, Eq a) => a -> [a] -> Int
elemIndexJustDef :: Eq a => Int -> a -> [a] -> Int
elemIndexJustNote :: (Partial, Eq a) => String -> a -> [a] -> Int
findIndexJust :: (a -> Bool) -> [a] -> Int
findIndexJustDef :: Int -> (a -> Bool) -> [a] -> Int
findIndexJustNote :: Partial => String -> (a -> Bool) -> [a] -> Int
toEnumMay :: (Enum a, Bounded a) => Int -> Maybe a
toEnumDef :: (Enum a, Bounded a) => a -> Int -> a
toEnumNote :: (Partial, Enum a, Bounded a) => String -> Int -> a
toEnumSafe :: (Enum a, Bounded a) => Int -> a
succMay :: (Enum a, Eq a, Bounded a) => a -> Maybe a
succDef :: (Enum a, Eq a, Bounded a) => a -> a -> a
succNote :: (Partial, Enum a, Eq a, Bounded a) => String -> a -> a
succSafe :: (Enum a, Eq a, Bounded a) => a -> a
predMay :: (Enum a, Eq a, Bounded a) => a -> Maybe a
predDef :: (Enum a, Eq a, Bounded a) => a -> a -> a
predNote :: (Partial, Enum a, Eq a, Bounded a) => String -> a -> a
predSafe :: (Enum a, Eq a, Bounded a) => a -> a
indexMay :: Ix a => (a, a) -> a -> Maybe Int
indexDef :: Ix a => Int -> (a, a) -> a -> Int
indexNote :: (Partial, Ix a) => String -> (a, a) -> a -> Int
foldl1Def' :: a -> (a -> a -> a) -> [a] -> a

-- | 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.
argsToCliOpts :: [String] -> [String] -> IO CliOpts
