packages feed

hledger-lib 1.4 → 1.5

raw patch · 45 files changed

+5666/−4886 lines, 45 filesdep +extradep ~ansi-terminaldep ~basedep ~cmdargsPVP ok

version bump matches the API change (PVP)

Dependencies added: extra

Dependency ranges changed: ansi-terminal, base, cmdargs, megaparsec, split, text, transformers, utf8-string

API changes (from Hackage documentation)

- Hledger.Read.Common: commentchars :: [Char]
- Hledger.Read.Common: semicoloncommentp :: JournalParser m Text
- Hledger.Reports.BalanceReport: amountValue :: Journal -> Day -> Amount -> Amount
- Hledger.Reports.BalanceReport: balanceReportValue :: Journal -> Day -> BalanceReport -> BalanceReport
- Hledger.Reports.BalanceReport: mixedAmountValue :: Journal -> Day -> MixedAmount -> MixedAmount
- Hledger.Reports.MultiBalanceReports: multiBalanceReportValue :: Journal -> Day -> MultiBalanceReport -> MultiBalanceReport
+ Hledger.Data.Amount: amountValue :: Journal -> Day -> Amount -> Amount
+ Hledger.Data.Amount: mixedAmountValue :: Journal -> Day -> MixedAmount -> MixedAmount
+ Hledger.Data.Journal: journalAccountNamesDeclared :: Journal -> [AccountName]
+ Hledger.Data.Journal: journalAccountNamesDeclaredOrImplied :: Journal -> [AccountName]
+ Hledger.Data.Journal: journalAccountNamesDeclaredOrUsed :: Journal -> [AccountName]
+ Hledger.Data.Journal: journalAccountNamesImplied :: Journal -> [AccountName]
+ Hledger.Data.Types: DayOfYear :: Int -> Int -> Interval
+ Hledger.Data.Types: WeekdayOfMonth :: Int -> Int -> Interval
+ Hledger.Data.Types: instance Data.Default.Class.Default Hledger.Data.Types.DateSpan
+ Hledger.Data.Types: type BalanceAssertion = Maybe (Amount, GenericSourcePos)
+ Hledger.Read.Common: fromRawNumber :: Maybe AmountStyle -> Bool -> (Maybe Char, [String], Maybe (Char, String)) -> (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)
+ Hledger.Read.Common: getAmountStyle :: CommoditySymbol -> JournalParser m (Maybe AmountStyle)
+ Hledger.Read.Common: getDefaultAmountStyle :: JournalParser m (Maybe AmountStyle)
+ Hledger.Read.Common: linecommentp :: JournalParser m Text
+ Hledger.Read.Common: rawnumberp :: TextParser m (Maybe Char, [String], Maybe (Char, String))
+ Hledger.Read.Common: whitespaceChar :: TextParser m Char
+ Hledger.Reports.ReportOptions: [auto_] :: ReportOpts -> Bool
+ Hledger.Reports.ReportOptions: [forecast_] :: ReportOpts -> Bool
+ Hledger.Reports.ReportOptions: specifiedEndDate :: ReportOpts -> IO (Maybe Day)
+ Hledger.Reports.ReportOptions: specifiedStartDate :: ReportOpts -> IO (Maybe Day)
+ Hledger.Reports.ReportOptions: specifiedStartEndDates :: ReportOpts -> IO (Maybe Day, Maybe Day)
+ Hledger.Utils.Parse: surroundedBy :: Applicative m => m openclose -> m a -> m a
- Hledger.Data.Period: isLastDayOfMonth :: (Num a, Num a1, Eq a, Eq a1) => Integer -> a1 -> a -> Bool
+ Hledger.Data.Period: isLastDayOfMonth :: (Num a2, Num a1, Eq a2, Eq a1) => Integer -> a1 -> a2 -> Bool
- Hledger.Data.Types: Posting :: Maybe Day -> Maybe Day -> Status -> AccountName -> MixedAmount -> Text -> PostingType -> [Tag] -> Maybe Amount -> Maybe Transaction -> Maybe Posting -> Posting
+ Hledger.Data.Types: Posting :: Maybe Day -> Maybe Day -> Status -> AccountName -> MixedAmount -> Text -> PostingType -> [Tag] -> BalanceAssertion -> Maybe Transaction -> Maybe Posting -> Posting
- Hledger.Data.Types: [pbalanceassertion] :: Posting -> Maybe Amount
+ Hledger.Data.Types: [pbalanceassertion] :: Posting -> BalanceAssertion
- Hledger.Read.Common: numberp :: TextParser m (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)
+ Hledger.Read.Common: numberp :: Maybe AmountStyle -> TextParser m (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)
- Hledger.Read.Common: partialbalanceassertionp :: Monad m => JournalParser m (Maybe Amount)
+ Hledger.Read.Common: partialbalanceassertionp :: Monad m => JournalParser m BalanceAssertion
- Hledger.Reports.ReportOptions: ReportOpts :: Period -> Interval -> [Status] -> Bool -> Maybe Int -> Maybe DisplayExp -> Bool -> Bool -> Bool -> Bool -> Maybe FormatStr -> String -> Bool -> Bool -> BalanceType -> AccountListMode -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe NormalBalance -> Bool -> ReportOpts
+ Hledger.Reports.ReportOptions: ReportOpts :: Period -> Interval -> [Status] -> Bool -> Maybe Int -> Maybe DisplayExp -> Bool -> Bool -> Bool -> Bool -> Maybe FormatStr -> String -> Bool -> Bool -> BalanceType -> AccountListMode -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe NormalBalance -> Bool -> Bool -> Bool -> ReportOpts
- Hledger.Reports.ReportOptions: simplifyStatuses :: Ord t => [t] -> [t]
+ Hledger.Reports.ReportOptions: simplifyStatuses :: Ord a => [a] -> [a]
- Hledger.Reports.TransactionsReports: triAmount :: (t4, t3, t2, t1, t5, t) -> t5
+ Hledger.Reports.TransactionsReports: triAmount :: () => (a, b, c, d, e, f) -> e
- Hledger.Reports.TransactionsReports: triBalance :: (t4, t3, t2, t1, t, t5) -> t5
+ Hledger.Reports.TransactionsReports: triBalance :: () => (a, b, c, d, e, f) -> f
- Hledger.Reports.TransactionsReports: triCommodityAmount :: CommoditySymbol -> (t4, t3, t2, t1, MixedAmount, t) -> MixedAmount
+ Hledger.Reports.TransactionsReports: triCommodityAmount :: () => CommoditySymbol -> (a, b, c, d, MixedAmount, f) -> MixedAmount
- Hledger.Reports.TransactionsReports: triCommodityBalance :: CommoditySymbol -> (t4, t3, t2, t1, t, MixedAmount) -> MixedAmount
+ Hledger.Reports.TransactionsReports: triCommodityBalance :: () => CommoditySymbol -> (a, b, c, d, e, MixedAmount) -> MixedAmount
- Hledger.Reports.TransactionsReports: triDate :: (t4, Transaction, t3, t2, t1, t) -> Day
+ Hledger.Reports.TransactionsReports: triDate :: () => (a, Transaction, c, d, e, f) -> Day
- Hledger.Reports.TransactionsReports: triOrigTransaction :: (t5, t4, t3, t2, t1, t) -> t5
+ Hledger.Reports.TransactionsReports: triOrigTransaction :: () => (a, b, c, d, e, f) -> a
- Hledger.Utils: fifth5 :: (t3, t2, t1, t, t4) -> t4
+ Hledger.Utils: fifth5 :: () => (a, b, c, d, e) -> e
- Hledger.Utils: fifth6 :: (t4, t3, t2, t1, t5, t) -> t5
+ Hledger.Utils: fifth6 :: () => (a, b, c, d, e, f) -> e
- Hledger.Utils: first3 :: (t2, t1, t) -> t2
+ Hledger.Utils: first3 :: () => (a, b, c) -> a
- Hledger.Utils: first4 :: (t3, t2, t1, t) -> t3
+ Hledger.Utils: first4 :: () => (a, b, c, d) -> a
- Hledger.Utils: first5 :: (t4, t3, t2, t1, t) -> t4
+ Hledger.Utils: first5 :: () => (a, b, c, d, e) -> a
- Hledger.Utils: first6 :: (t5, t4, t3, t2, t1, t) -> t5
+ Hledger.Utils: first6 :: () => (a, b, c, d, e, f) -> a
- Hledger.Utils: fourth4 :: (t2, t1, t, t3) -> t3
+ Hledger.Utils: fourth4 :: () => (a, b, c, d) -> d
- Hledger.Utils: fourth5 :: (t3, t2, t1, t4, t) -> t4
+ Hledger.Utils: fourth5 :: () => (a, b, c, d, e) -> d
- Hledger.Utils: fourth6 :: (t4, t3, t2, t5, t1, t) -> t5
+ Hledger.Utils: fourth6 :: () => (a, b, c, d, e, f) -> d
- Hledger.Utils: second3 :: (t1, t2, t) -> t2
+ Hledger.Utils: second3 :: () => (a, b, c) -> b
- Hledger.Utils: second4 :: (t2, t3, t1, t) -> t3
+ Hledger.Utils: second4 :: () => (a, b, c, d) -> b
- Hledger.Utils: second5 :: (t3, t4, t2, t1, t) -> t4
+ Hledger.Utils: second5 :: () => (a, b, c, d, e) -> b
- Hledger.Utils: second6 :: (t4, t5, t3, t2, t1, t) -> t5
+ Hledger.Utils: second6 :: () => (a, b, c, d, e, f) -> b
- Hledger.Utils: sixth6 :: (t4, t3, t2, t1, t, t5) -> t5
+ Hledger.Utils: sixth6 :: () => (a, b, c, d, e, f) -> f
- Hledger.Utils: third3 :: (t1, t, t2) -> t2
+ Hledger.Utils: third3 :: () => (a, b, c) -> c
- Hledger.Utils: third4 :: (t2, t1, t3, t) -> t3
+ Hledger.Utils: third4 :: () => (a, b, c, d) -> c
- Hledger.Utils: third5 :: (t3, t2, t4, t1, t) -> t4
+ Hledger.Utils: third5 :: () => (a, b, c, d, e) -> c
- Hledger.Utils: third6 :: (t4, t3, t5, t2, t1, t) -> t5
+ Hledger.Utils: third6 :: () => (a, b, c, d, e, f) -> c
- Hledger.Utils.Tree: branches :: Tree a -> Forest a
+ Hledger.Utils.Tree: branches :: () => Tree a -> Forest a
- Hledger.Utils.Tree: emptyTree :: FastTree a
+ Hledger.Utils.Tree: emptyTree :: () => FastTree a
- Hledger.Utils.Tree: root :: Tree a -> a
+ Hledger.Utils.Tree: root :: () => Tree a -> a
- Hledger.Utils.Tree: subs :: Tree a -> Forest a
+ Hledger.Utils.Tree: subs :: () => Tree a -> Forest a

Files

CHANGES view
@@ -1,5 +1,50 @@-API-ish changes in the hledger-lib package.-See also the hledger and project change logs (for user-visible changes).+API-ish changes in the hledger-lib package. See also hledger.+++# 1.5 (2017/12/31)++* -V/--value uses today's market prices by default, not those of last transaction date. #683, #648)++* csv: allow balance assignment (balance assertion only, no amount) in csv records (Nadrieril)++* journal: allow space as digit group separator character, #330 (Mykola Orliuk)++* journal: balance assertion errors now show line of failed assertion posting, #481 (Sam Jeeves)++* journal: better errors for directives, #402 (Mykola Orliuk)++* journal: better errors for included files, #660 (Mykola Orliuk)++* journal: commodity directives in parent files are inherited by included files, #487 (Mykola Orliuk)++* journal: commodity directives limits precision even after -B, #509 (Mykola Orliuk)++* journal: decimal point/digit group separator chars are now inferred from an applicable commodity directive or default commodity directive. #399, #487 (Mykola Orliuk)++* journal: numbers are parsed more strictly (Mykola Orliuk)++* journal: support Ledger-style automated postings, enabled with --auto flag (Dmitry Astapov)++* journal: support Ledger-style periodic transactions, enabled with --forecast flag (Dmitry Astapov)++* period expressions: fix "nth day of {week,month}", which could generate wrong intervals (Dmitry Astapov)++* period expressions: month names are now case-insensitive (Dmitry Astapov)++* period expressions: stricter checking for invalid expressions (Mykola Orliuk)++* period expressions: support "every 11th Nov" (Dmitry Astapov)++* period expressions: support "every 2nd Thursday of month" (Dmitry Astapov)++* period expressions: support "every Tuesday", short for "every <n>th day of week" (Dmitry Astapov)++* remove upper bounds on all but hledger* and base (experimental)+  It's rare that my deps break their api or that newer versions must+  be avoided, and very common that they release new versions which I+  must tediously and promptly test and release hackage revisions for+  or risk falling out of stackage. Trying it this way for a bit.+  # 1.4 (2017/9/30) 
Hledger/Data.hs view
@@ -22,6 +22,7 @@                module Hledger.Data.StringFormat,                module Hledger.Data.Timeclock,                module Hledger.Data.Transaction,+               module Hledger.Data.AutoTransaction,                module Hledger.Data.Types,                tests_Hledger_Data               )@@ -42,6 +43,7 @@ import Hledger.Data.StringFormat import Hledger.Data.Timeclock import Hledger.Data.Transaction+import Hledger.Data.AutoTransaction import Hledger.Data.Types  tests_Hledger_Data :: Test
Hledger/Data/Account.hs view
@@ -10,6 +10,7 @@ module Hledger.Data.Account where import Data.List+import Data.List.Extra (groupSort, groupOn) import Data.Maybe import Data.Ord import qualified Data.Map as M@@ -63,10 +64,9 @@ accountsFromPostings :: [Posting] -> [Account] accountsFromPostings ps =   let-    acctamts = [(paccount p,pamount p) | p <- ps]-    grouped = groupBy (\a b -> fst a == fst b) $ sort $ acctamts-    counted = [(a, length acctamts) | acctamts@((a,_):_) <- grouped]-    summed = map (\as@((aname,_):_) -> (aname, sumStrict $ map snd as)) grouped -- always non-empty+    grouped = groupSort [(paccount p,pamount p) | p <- ps]+    counted = [(aname, length amts) | (aname, amts) <- grouped]+    summed =  [(aname, sumStrict amts) | (aname, amts) <- grouped]  -- always non-empty     nametree = treeFromPaths $ map (expandAccountName . fst) summed     acctswithnames = nameTreeToAccount "root" nametree     acctswithnumps = mapAccounts setnumps    acctswithnames where setnumps    a = a{anumpostings=fromMaybe 0 $ lookup (aname a) counted}@@ -132,7 +132,7 @@     where       clipped  = [a{aname=clipOrEllipsifyAccountName d $ aname a} | a <- as]       combined = [a{aebalance=sum (map aebalance same)}-                  | same@(a:_) <- groupBy (\a1 a2 -> aname a1 == aname a2) clipped]+                 | same@(a:_) <- groupOn aname clipped] {- test cases, assuming d=1: 
Hledger/Data/AccountName.hs view
@@ -56,9 +56,11 @@ accountNameDrop :: Int -> AccountName -> AccountName accountNameDrop n = accountNameFromComponents . drop n . accountNameComponents --- | ["a:b:c","d:e"] -> ["a","a:b","a:b:c","d","d:e"]+-- | Sorted unique account names implied by these account names,+-- ie these plus all their parent accounts up to the root.+-- Eg: ["a:b:c","d:e"] -> ["a","a:b","a:b:c","d","d:e"] expandAccountNames :: [AccountName] -> [AccountName]-expandAccountNames as = nub $ concatMap expandAccountName as+expandAccountNames as = nub $ sort $ concatMap expandAccountName as  -- | "a:b:c" -> ["a","a:b","a:b:c"] expandAccountName :: AccountName -> [AccountName]
Hledger/Data/Amount.hs view
@@ -58,6 +58,7 @@   -- ** arithmetic   costOfAmount,   divideAmount,+  amountValue,   -- ** rendering   amountstyle,   showAmount,@@ -90,6 +91,7 @@   isZeroMixedAmount,   isReallyZeroMixedAmount,   isReallyZeroMixedAmountCost,+  mixedAmountValue,   -- ** rendering   showMixedAmount,   showMixedAmountOneLine,@@ -113,6 +115,8 @@ import Data.List import Data.Map (findWithDefault) import Data.Maybe+import Data.Time.Calendar (Day)+import Data.Ord (comparing) -- import Data.Text (Text) import qualified Data.Text as T import Test.HUnit@@ -347,6 +351,38 @@     where       s' = findWithDefault s c styles +-- | Find the market value of this amount on the given date, in it's+-- default valuation commodity, based on recorded market prices.+-- If no default valuation commodity can be found, the amount is left+-- unchanged.+amountValue :: Journal -> Day -> Amount -> Amount+amountValue j d a =+  case commodityValue j d (acommodity a) of+    Just v  -> v{aquantity=aquantity v * aquantity a+                ,aprice=aprice a+                }+    Nothing -> a++-- This is here not in Commodity.hs to use the Amount Show instance above for debugging. +-- | Find the market value, if known, of one unit of this commodity (A) on+-- the given valuation date, in the commodity (B) mentioned in the latest+-- applicable market price. The latest applicable market price is the market+-- price directive for commodity A with the latest date that is on or before+-- the valuation date; or if there are multiple such prices with the same date,+-- the last parsed.+commodityValue :: Journal -> Day -> CommoditySymbol -> Maybe Amount+commodityValue j valuationdate c+    | null applicableprices = dbg Nothing+    | otherwise             = dbg $ Just $ mpamount $ last applicableprices+  where+    dbg = dbg8 ("using market price for "++T.unpack c)+    applicableprices =+      [p | p <- sortBy (comparing mpdate) $ jmarketprices j+      , mpcommodity p == c+      , mpdate p <= valuationdate+      ]++ ------------------------------------------------------------------------------- -- MixedAmount @@ -602,6 +638,9 @@ -- | Canonicalise a mixed amount's display styles using the provided commodity style map. canonicaliseMixedAmount :: M.Map CommoditySymbol AmountStyle -> MixedAmount -> MixedAmount canonicaliseMixedAmount styles (Mixed as) = Mixed $ map (canonicaliseAmount styles) as++mixedAmountValue :: Journal -> Day -> MixedAmount -> MixedAmount+mixedAmountValue j d (Mixed as) = Mixed $ map (amountValue j d) as  ------------------------------------------------------------------------------- -- misc
Hledger/Data/AutoTransaction.hs view
@@ -136,7 +136,8 @@ -- -- Note that new transactions require 'txnTieKnot' post-processing. ----- >>> mapM_ (putStr . show) $ runPeriodicTransaction (PeriodicTransaction "monthly from 2017/1 to 2017/4" ["hi" `post` usd 1]) nulldatespan+-- >>> let gen str = mapM_ (putStr . show) $ runPeriodicTransaction (PeriodicTransaction str ["hi" `post` usd 1]) nulldatespan+-- >>> gen "monthly from 2017/1 to 2017/4" -- 2017/01/01 --     hi           $1.00 -- <BLANKLINE>@@ -146,6 +147,92 @@ -- 2017/03/01 --     hi           $1.00 -- <BLANKLINE>+-- >>> gen "monthly from 2017/1 to 2017/5"+-- 2017/01/01+--     hi           $1.00+-- <BLANKLINE>+-- 2017/02/01+--     hi           $1.00+-- <BLANKLINE>+-- 2017/03/01+--     hi           $1.00+-- <BLANKLINE>+-- 2017/04/01+--     hi           $1.00+-- <BLANKLINE>+-- >>> gen "every 2nd day of month from 2017/02 to 2017/04"+-- 2017/01/02+--     hi           $1.00+-- <BLANKLINE>+-- 2017/02/02+--     hi           $1.00+-- <BLANKLINE>+-- 2017/03/02+--     hi           $1.00+-- <BLANKLINE>+-- >>> gen "monthly from 2017/1 to 2017/4"+-- 2017/01/01+--     hi           $1.00+-- <BLANKLINE>+-- 2017/02/01+--     hi           $1.00+-- <BLANKLINE>+-- 2017/03/01+--     hi           $1.00+-- <BLANKLINE>+-- >>> gen "every 30th day of month from 2017/1 to 2017/5"+-- 2016/12/30+--     hi           $1.00+-- <BLANKLINE>+-- 2017/01/30+--     hi           $1.00+-- <BLANKLINE>+-- 2017/02/28+--     hi           $1.00+-- <BLANKLINE>+-- 2017/03/30+--     hi           $1.00+-- <BLANKLINE>+-- 2017/04/30+--     hi           $1.00+-- <BLANKLINE>+-- >>> gen "every 2nd Thursday of month from 2017/1 to 2017/4"+-- 2016/12/08+--     hi           $1.00+-- <BLANKLINE>+-- 2017/01/12+--     hi           $1.00+-- <BLANKLINE>+-- 2017/02/09+--     hi           $1.00+-- <BLANKLINE>+-- 2017/03/09+--     hi           $1.00+-- <BLANKLINE>+-- >>> gen "every nov 29th from 2017 to 2019"+-- 2016/11/29+--     hi           $1.00+-- <BLANKLINE>+-- 2017/11/29+--     hi           $1.00+-- <BLANKLINE>+-- 2018/11/29+--     hi           $1.00+-- <BLANKLINE>+-- >>> gen "2017/1"+-- 2017/01/01+--     hi           $1.00+-- <BLANKLINE>+-- >>> gen ""+-- ... Failed to parse ...+-- >>> gen "weekly from 2017"+-- *** Exception: Unable to generate transactions according to "weekly from 2017" as 2017-01-01 is not a first day of the week+-- >>> gen "monthly from 2017/5/4"+-- *** Exception: Unable to generate transactions according to "monthly from 2017/5/4" as 2017-05-04 is not a first day of the month        +-- >>> gen "every quarter from 2017/1/2"+-- *** Exception: Unable to generate transactions according to "every quarter from 2017/1/2" as 2017-01-02 is not a first day of the quarter        +-- >>> gen "yearly from 2017/1/14"+-- *** Exception: Unable to generate transactions according to "yearly from 2017/1/14" as 2017-01-14 is not a first day of the year         runPeriodicTransaction :: PeriodicTransaction -> (DateSpan -> [Transaction]) runPeriodicTransaction pt = generate where     base = nulltransaction { tpostings = ptpostings pt }@@ -154,5 +241,18 @@     (interval, effectspan) =         case parsePeriodExpr errCurrent periodExpr of             Left e -> error' $ "Failed to parse " ++ show (T.unpack periodExpr) ++ ": " ++ showDateParseError e-            Right x -> x+            Right x -> checkProperStartDate x     generate jspan = [base {tdate=date} | span <- interval `splitSpan` spanIntersect effectspan jspan, let Just date = spanStart span]+    checkProperStartDate (i,s) = +      case (i,spanStart s) of+        (Weeks _,    Just d) -> checkStart d "week"+        (Months _,   Just d) -> checkStart d "month"+        (Quarters _, Just d) -> checkStart d "quarter"+        (Years _,    Just d) -> checkStart d "year"+        _                    -> (i,s) +        where+          checkStart d x =+            let firstDate = fixSmartDate d ("","this",x) +            in   +             if d == firstDate then (i,s)+             else error' $ "Unable to generate transactions according to "++(show periodExpr)++" as "++(show d)++" is not a first day of the "++x
Hledger/Data/Commodity.hs view
@@ -14,7 +14,6 @@ import Data.List import Data.Maybe (fromMaybe) import Data.Monoid--- import Data.Text (Text) import qualified Data.Text as T import Test.HUnit -- import qualified Data.Map as M
Hledger/Data/Dates.hs view
@@ -73,6 +73,7 @@ import Prelude.Compat import Control.Monad import Data.List.Compat+import Data.Default import Data.Maybe import Data.Text (Text) import qualified Data.Text as T@@ -88,6 +89,7 @@ import Data.Time.LocalTime import Safe (headMay, lastMay, readMay) import Text.Megaparsec.Compat+import Text.Megaparsec.Perm import Text.Printf  import Hledger.Data.Types@@ -165,9 +167,15 @@ -- >>> t (Weeks 2) "2008/01/01" "2008/01/15" -- [DateSpan 2007/12/31-2008/01/13,DateSpan 2008/01/14-2008/01/27] -- >>> t (DayOfMonth 2) "2008/01/01" "2008/04/01"--- [DateSpan 2008/01/02-2008/02/01,DateSpan 2008/02/02-2008/03/01,DateSpan 2008/03/02-2008/04/01]+-- [DateSpan 2007/12/02-2008/01/01,DateSpan 2008/01/02-2008/02/01,DateSpan 2008/02/02-2008/03/01,DateSpan 2008/03/02-2008/04/01]+-- >>> t (WeekdayOfMonth 2 4) "2011/01/01" "2011/02/15"+-- [DateSpan 2010/12/09-2011/01/12,DateSpan 2011/01/13-2011/02/09,DateSpan 2011/02/10-2011/03/09] -- >>> t (DayOfWeek 2) "2011/01/01" "2011/01/15"--- [DateSpan 2011/01/04-2011/01/10,DateSpan 2011/01/11-2011/01/17]+-- [DateSpan 2010/12/28-2011/01/03,DateSpan 2011/01/04-2011/01/10,DateSpan 2011/01/11-2011/01/17]+-- >>> t (DayOfYear 11 29) "2011/10/01" "2011/10/15"+-- [DateSpan 2010/11/29-2011/11/28]+-- >>> t (DayOfYear 11 29) "2011/12/01" "2012/12/15"+-- [DateSpan 2011/11/29-2012/11/28,DateSpan 2012/11/29-2013/11/28] -- splitSpan :: Interval -> DateSpan -> [DateSpan] splitSpan _ (DateSpan Nothing Nothing) = [DateSpan Nothing Nothing]@@ -177,8 +185,10 @@ splitSpan (Months n)     s = splitspan startofmonth   (applyN n nextmonth)   s splitSpan (Quarters n)   s = splitspan startofquarter (applyN n nextquarter) s splitSpan (Years n)      s = splitspan startofyear    (applyN n nextyear)    s-splitSpan (DayOfMonth n) s = splitspan (nthdayofmonthcontaining n) (applyN (n-1) nextday . nextmonth) s+splitSpan (DayOfMonth n) s = splitspan (nthdayofmonthcontaining n) (nthdayofmonth n . nextmonth) s+splitSpan (WeekdayOfMonth n wd) s = splitspan (nthweekdayofmonthcontaining n wd) (advancetonthweekday n wd . nextmonth) s splitSpan (DayOfWeek n)  s = splitspan (nthdayofweekcontaining n)  (applyN (n-1) nextday . nextweek)  s+splitSpan (DayOfYear m n) s= splitspan (nthdayofyearcontaining m n) (applyN (n-1) nextday . applyN (m-1) nextmonth . nextyear) s -- splitSpan (WeekOfYear n)    s = splitspan startofweek    (applyN n nextweek)    s -- splitSpan (MonthOfYear n)   s = splitspan startofmonth   (applyN n nextmonth)   s -- splitSpan (QuarterOfYear n) s = splitspan startofquarter (applyN n nextquarter) s@@ -257,7 +267,7 @@ -- | Parse a period expression to an Interval and overall DateSpan using -- the provided reference date, or return a parse error. parsePeriodExpr :: Day -> Text -> Either (ParseError Char MPErr) (Interval, DateSpan)-parsePeriodExpr refdate = parsewith (periodexpr refdate <* eof)+parsePeriodExpr refdate s = parsewith (periodexpr refdate <* eof) (T.toLower s)  maybePeriod :: Day -> Text -> Maybe (Interval,DateSpan) maybePeriod refdate = either (const Nothing) Just . parsePeriodExpr refdate@@ -447,6 +457,7 @@ prevmonth = startofmonth . addGregorianMonthsClip (-1) nextmonth = startofmonth . addGregorianMonthsClip 1 startofmonth day = fromGregorian y m 1 where (y,m,_) = toGregorian day+nthdayofmonth d day = fromGregorian y m d where (y,m,_) = toGregorian day  thisquarter = startofquarter prevquarter = startofquarter . addGregorianMonthsClip (-3)@@ -461,18 +472,106 @@ nextyear = startofyear . addGregorianYearsClip 1 startofyear day = fromGregorian y 1 1 where (y,_,_) = toGregorian day -nthdayofmonthcontaining n d | d1 >= d    = d1-                            | otherwise = d2-    where d1 = addDays (fromIntegral n-1) s-          d2 = addDays (fromIntegral n-1) $ nextmonth s+-- | For given date d find year-long interval that starts on given MM/DD of year+-- and covers it. +--+-- Examples: lets take 2017-11-22. Year-long intervals covering it that+-- starts before Nov 22 will start in 2017. However+-- intervals that start after Nov 23rd should start in 2016:+-- >>> let wed22nd = parsedate "2017-11-22"          +-- >>> nthdayofyearcontaining 11 21 wed22nd+-- 2017-11-21          +-- >>> nthdayofyearcontaining 11 22 wed22nd+-- 2017-11-22          +-- >>> nthdayofyearcontaining 11 23 wed22nd+-- 2016-11-23          +-- >>> nthdayofyearcontaining 12 02 wed22nd+-- 2016-12-02          +-- >>> nthdayofyearcontaining 12 31 wed22nd+-- 2016-12-31          +-- >>> nthdayofyearcontaining 1 1 wed22nd+-- 2017-01-01          +nthdayofyearcontaining m n d | mmddOfSameYear <= d = mmddOfSameYear+                             | otherwise = mmddOfPrevYear+    where mmddOfSameYear = addDays (fromIntegral n-1) $ applyN (m-1) nextmonth s+          mmddOfPrevYear = addDays (fromIntegral n-1) $ applyN (m-1) nextmonth $ prevyear s+          s = startofyear d++-- | For given date d find month-long interval that starts on nth day of month+-- and covers it. +--+-- Examples: lets take 2017-11-22. Month-long intervals covering it that+-- start on 1st-22nd of month will start in Nov. However+-- intervals that start on 23rd-30th of month should start in Oct:+-- >>> let wed22nd = parsedate "2017-11-22"          +-- >>> nthdayofmonthcontaining 1 wed22nd+-- 2017-11-01          +-- >>> nthdayofmonthcontaining 12 wed22nd+-- 2017-11-12          +-- >>> nthdayofmonthcontaining 22 wed22nd+-- 2017-11-22          +-- >>> nthdayofmonthcontaining 23 wed22nd+-- 2017-10-23          +-- >>> nthdayofmonthcontaining 30 wed22nd+-- 2017-10-30          +nthdayofmonthcontaining n d | nthOfSameMonth <= d = nthOfSameMonth+                            | otherwise = nthOfPrevMonth+    where nthOfSameMonth = nthdayofmonth n s+          nthOfPrevMonth = nthdayofmonth n $ prevmonth s           s = startofmonth d -nthdayofweekcontaining n d | d1 >= d    = d1-                           | otherwise = d2-    where d1 = addDays (fromIntegral n-1) s-          d2 = addDays (fromIntegral n-1) $ nextweek s+-- | For given date d find week-long interval that starts on nth day of week+-- and covers it. +--+-- Examples: 2017-11-22 is Wed. Week-long intervals that cover it and+-- start on Mon, Tue or Wed will start in the same week. However+-- intervals that start on Thu or Fri should start in prev week:          +-- >>> let wed22nd = parsedate "2017-11-22"          +-- >>> nthdayofweekcontaining 1 wed22nd+-- 2017-11-20          +-- >>> nthdayofweekcontaining 2 wed22nd+-- 2017-11-21+-- >>> nthdayofweekcontaining 3 wed22nd+-- 2017-11-22          +-- >>> nthdayofweekcontaining 4 wed22nd+-- 2017-11-16          +-- >>> nthdayofweekcontaining 5 wed22nd+-- 2017-11-17          +nthdayofweekcontaining n d | nthOfSameWeek <= d = nthOfSameWeek+                           | otherwise = nthOfPrevWeek+    where nthOfSameWeek = addDays (fromIntegral n-1) s+          nthOfPrevWeek = addDays (fromIntegral n-1) $ prevweek s           s = startofweek d +-- | For given date d find month-long interval that starts on nth weekday of month+-- and covers it. +--+-- Examples: 2017-11-22 is 3rd Wed of Nov. Month-long intervals that cover it and+-- start on 1st-4th Wed will start in Nov. However+-- intervals that start on 4th Thu or Fri or later should start in Oct:          +-- >>> let wed22nd = parsedate "2017-11-22"          +-- >>> nthweekdayofmonthcontaining 1 3 wed22nd+-- 2017-11-01+-- >>> nthweekdayofmonthcontaining 3 2 wed22nd+-- 2017-11-21+-- >>> nthweekdayofmonthcontaining 4 3 wed22nd+-- 2017-11-22+-- >>> nthweekdayofmonthcontaining 4 4 wed22nd+-- 2017-10-26+-- >>> nthweekdayofmonthcontaining 4 5 wed22nd+-- 2017-10-27+nthweekdayofmonthcontaining n wd d | nthWeekdaySameMonth <= d  = nthWeekdaySameMonth+                                   | otherwise = nthWeekdayPrevMonth+    where nthWeekdaySameMonth = advancetonthweekday n wd $ startofmonth d+          nthWeekdayPrevMonth = advancetonthweekday n wd $ prevmonth d+          +-- | Advance to nth weekday wd after given start day s+advancetonthweekday n wd s = addWeeks (n-1) . firstMatch (>=s) . iterate (addWeeks 1) $ firstweekday s+  where          +    addWeeks k = addDays (7 * fromIntegral k)+    firstMatch p = head . dropWhile (not . p)+    firstweekday = addDays (fromIntegral wd-1) . startofweek+ ---------------------------------------------------------------------- -- parsing @@ -529,11 +628,6 @@ -- -- 2008-02-29 -- #endif --- | Parse a time string to a time type using the provided pattern, or--- return the default.-_parsetimewith :: ParseTime t => String -> String -> t -> t-_parsetimewith pat s def = fromMaybe def $ parsetime defaultTimeLocale pat s- {-| Parse a date in any of the formats allowed in ledger's period expressions, and maybe some others:@@ -633,17 +727,11 @@ months         = ["january","february","march","april","may","june",                   "july","august","september","october","november","december"] monthabbrevs   = ["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]--- weekdays       = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]--- weekdayabbrevs = ["mon","tue","wed","thu","fri","sat","sun"]--#if MIN_VERSION_megaparsec(6,0,0)-lc = T.toLower-#else-lc = lowercase-#endif+weekdays       = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]+weekdayabbrevs = ["mon","tue","wed","thu","fri","sat","sun"] -monthIndex t = maybe 0 (+1) $ lc t `elemIndex` months-monIndex t   = maybe 0 (+1) $ lc t `elemIndex` monthabbrevs+monthIndex t = maybe 0 (+1) $ t `elemIndex` months+monIndex t   = maybe 0 (+1) $ t `elemIndex` monthabbrevs  month :: SimpleTextParser SmartDate month = do@@ -657,6 +745,12 @@   let i = monIndex m   return ("",show i,"") +weekday :: SimpleTextParser Int+weekday = do+  wday <- choice . map string' $ weekdays ++ weekdayabbrevs+  let i = head . catMaybes $ [wday `elemIndex` weekdays, wday `elemIndex` weekdayabbrevs]+  return (i+1)+ today,yesterday,tomorrow :: SimpleTextParser SmartDate today     = string "today"     >> return ("","","today") yesterday = string "yesterday" >> return ("","","yesterday")@@ -683,45 +777,63 @@   return ("", T.unpack r, T.unpack p)  -- |--- >>> let p = parsewith (periodexpr (parsedate "2008/11/26")) :: T.Text -> Either (ParseError Char MPErr) (Interval, DateSpan)--- >>> p "from aug to oct"+-- >>> let p = parsePeriodExpr (parsedate "2008/11/26")+-- >>> p "from Aug to Oct" -- Right (NoInterval,DateSpan 2008/08/01-2008/09/30) -- >>> p "aug to oct" -- Right (NoInterval,DateSpan 2008/08/01-2008/09/30)--- >>> p "every 3 days in aug"+-- >>> p "every 3 days in Aug" -- Right (Days 3,DateSpan 2008/08) -- >>> p "daily from aug" -- Right (Days 1,DateSpan 2008/08/01-) -- >>> p "every week to 2009" -- Right (Weeks 1,DateSpan -2008/12/31)+-- >>> p "every 2nd day of month"+-- Right (DayOfMonth 2,DateSpan -)+-- >>> p "every 2nd day"+-- Right (DayOfMonth 2,DateSpan -)+-- >>> p "every 2nd day 2009-"+-- Right (DayOfMonth 2,DateSpan 2009/01/01-)  +-- >>> p "every 29th Nov"+-- Right (DayOfYear 11 29,DateSpan -)+-- >>> p "every 29th nov -2009"+-- Right (DayOfYear 11 29,DateSpan -2008/12/31)+-- >>> p "every nov 29th"+-- Right (DayOfYear 11 29,DateSpan -)+-- >>> p "every Nov 29th 2009-"+-- Right (DayOfYear 11 29,DateSpan 2009/01/01-)+-- >>> p "every 11/29 from 2009"+-- Right (DayOfYear 11 29,DateSpan 2009/01/01-)+-- >>> p "every 2nd Thursday of month to 2009"+-- Right (WeekdayOfMonth 2 4,DateSpan -2008/12/31)+-- >>> p "every 1st monday of month to 2009"+-- Right (WeekdayOfMonth 1 1,DateSpan -2008/12/31)+-- >>> p "every tue"+-- Right (DayOfWeek 2,DateSpan -)+-- >>> p "every 2nd day of week"+-- Right (DayOfWeek 2,DateSpan -)+-- >>> p "every 2nd day of month"+-- Right (DayOfMonth 2,DateSpan -)+-- >>> p "every 2nd day"+-- Right (DayOfMonth 2,DateSpan -)+-- >>> p "every 2nd day 2009-"+-- Right (DayOfMonth 2,DateSpan 2009/01/01-)+-- >>> p "every 2nd day of month 2009-"+-- Right (DayOfMonth 2,DateSpan 2009/01/01-) periodexpr :: Day -> SimpleTextParser (Interval, DateSpan)-periodexpr rdate = choice $ map try [+periodexpr rdate = surroundedBy (many spacenonewline) . choice $ map try [                     intervalanddateperiodexpr rdate,-                    intervalperiodexpr,-                    dateperiodexpr rdate,-                    (return (NoInterval,DateSpan Nothing Nothing))+                    (,) NoInterval <$> periodexprdatespan rdate                    ]  intervalanddateperiodexpr :: Day -> SimpleTextParser (Interval, DateSpan) intervalanddateperiodexpr rdate = do-  many spacenonewline   i <- reportinginterval-  many spacenonewline-  s <- periodexprdatespan rdate+  s <- option def . try $ do+      many spacenonewline+      periodexprdatespan rdate   return (i,s) -intervalperiodexpr :: SimpleTextParser (Interval, DateSpan)-intervalperiodexpr = do-  many spacenonewline-  i <- reportinginterval-  return (i, DateSpan Nothing Nothing)--dateperiodexpr :: Day -> SimpleTextParser (Interval, DateSpan)-dateperiodexpr rdate = do-  many spacenonewline-  s <- periodexprdatespan rdate-  return (NoInterval, s)- -- Parse a reporting interval. reportinginterval :: SimpleTextParser Interval reportinginterval = choice' [@@ -736,31 +848,52 @@                           return $ Months 2,                        do string "every"                           many spacenonewline-                          n <- fmap read $ some digitChar-                          thsuffix+                          n <- nth                           many spacenonewline                           string "day"-                          many spacenonewline-                          string "of"+                          of_ "week"+                          return $ DayOfWeek n,+                       do string "every"                           many spacenonewline-                          string "week"+                          n <- weekday                           return $ DayOfWeek n,                        do string "every"                           many spacenonewline-                          n <- fmap read $ some digitChar-                          thsuffix+                          n <- nth                           many spacenonewline                           string "day"-                          optional $ do-                            many spacenonewline-                            string "of"-                            many spacenonewline-                            string "month"-                          return $ DayOfMonth n+                          optOf_ "month"+                          return $ DayOfMonth n,+                       do string "every"+                          let mnth = choice' [month, mon] >>= \(_,m,_) -> return (read m)+                          d_o_y <- makePermParser $ DayOfYear <$$> try (many spacenonewline *> mnth) <||> try (many spacenonewline *> nth)+                          optOf_ "year"+                          return d_o_y,+                       do string "every"+                          many spacenonewline+                          ("",m,d) <- md+                          optOf_ "year"+                          return $ DayOfYear (read m) (read d),+                       do string "every"+                          many spacenonewline+                          n <- nth+                          many spacenonewline+                          wd <- weekday+                          optOf_ "month"+                          return $ WeekdayOfMonth n wd                     ]     where--      thsuffix = choice' $ map string ["st","nd","rd","th"]+      of_ period = do+        many spacenonewline+        string "of"+        many spacenonewline+        string period+        +      optOf_ period = optional $ try $ of_ period+      +      nth = do n <- some digitChar+               choice' $ map string ["st","nd","rd","th"]+               return $ read n        -- Parse any of several variants of a basic interval, eg "daily", "every day", "every N days".       tryinterval :: String -> String -> (Int -> Interval) -> SimpleTextParser Interval
Hledger/Data/Journal.hs view
@@ -29,8 +29,12 @@   filterTransactionPostings,   filterPostingAmount,   -- * Querying-  journalAccountNames,   journalAccountNamesUsed,+  journalAccountNamesImplied,+  journalAccountNamesDeclared,+  journalAccountNamesDeclaredOrUsed,+  journalAccountNamesDeclaredOrImplied,+  journalAccountNames,   -- journalAmountAndPriceCommodities,   journalAmounts,   overJournalAmounts,@@ -75,6 +79,7 @@ import Data.Functor.Identity (Identity(..)) import qualified Data.HashTable.ST.Cuckoo as HT import Data.List+import Data.List.Extra (groupSort) -- import Data.Map (findWithDefault) import Data.Maybe import Data.Monoid@@ -238,13 +243,32 @@ journalPostings :: Journal -> [Posting] journalPostings = concatMap tpostings . jtxns --- | Unique account names posted to in this journal.+-- | Sorted unique account names posted to by this journal's transactions. journalAccountNamesUsed :: Journal -> [AccountName]-journalAccountNamesUsed = sort . accountNamesFromPostings . journalPostings+journalAccountNamesUsed = accountNamesFromPostings . journalPostings --- | Unique account names in this journal, including parent accounts containing no postings.+-- | Sorted unique account names implied by this journal's transactions - +-- accounts posted to and all their implied parent accounts.+journalAccountNamesImplied :: Journal -> [AccountName]+journalAccountNamesImplied = expandAccountNames . journalAccountNamesUsed++-- | Sorted unique account names declared by account directives in this journal.+journalAccountNamesDeclared :: Journal -> [AccountName]+journalAccountNamesDeclared = nub . sort . jaccounts++-- | Sorted unique account names declared by account directives or posted to+-- by transactions in this journal.+journalAccountNamesDeclaredOrUsed :: Journal -> [AccountName]+journalAccountNamesDeclaredOrUsed j = nub $ sort $ journalAccountNamesDeclared j ++ journalAccountNamesUsed j++-- | Sorted unique account names declared by account directives, or posted to+-- or implied as parents by transactions in this journal.+journalAccountNamesDeclaredOrImplied :: Journal -> [AccountName]+journalAccountNamesDeclaredOrImplied j = nub $ sort $ journalAccountNamesDeclared j ++ journalAccountNamesImplied j++-- | Convenience/compatibility alias for journalAccountNamesDeclaredOrImplied. journalAccountNames :: Journal -> [AccountName]-journalAccountNames = sort . expandAccountNames . journalAccountNamesUsed+journalAccountNames = journalAccountNamesDeclaredOrImplied   journalAccountNameTree :: Journal -> Tree AccountName journalAccountNameTree = accountNameTreeFrom . journalAccountNames@@ -513,7 +537,7 @@ -- | Check a posting's balance assertion and return an error if it -- fails. checkBalanceAssertion :: Posting -> MixedAmount -> Either String ()-checkBalanceAssertion p@Posting{ pbalanceassertion = Just ass} amt+checkBalanceAssertion p@Posting{ pbalanceassertion = Just (ass,_)} amt   | isReallyZeroAmount diff = Right ()   | True    = Left err     where assertedcomm = acommodity ass@@ -535,7 +559,8 @@             (case ptransaction p of                Nothing -> ":" -- shouldn't happen                Just t ->  printf " in %s:\nin transaction:\n%s"-                          (showGenericSourcePos $ tsourcepos t) (chomp $ show t) :: String)+                          (showGenericSourcePos pos) (chomp $ show t) :: String+                            where pos = snd $ fromJust $ pbalanceassertion p)             (showPostingLine p)             (showDate $ postingDate p)             (T.unpack $ paccount p) -- XXX pack@@ -663,7 +688,7 @@   where     inferFromAssignment :: Posting -> CurrentBalancesModifier s Posting     inferFromAssignment p = maybe (return p)-      (fmap (\a -> p { pamount = a, porigin = Just $ originalPosting p }) . setBalance (paccount p))+      (fmap (\a -> p { pamount = a, porigin = Just $ originalPosting p }) . setBalance (paccount p) . fst)       $ pbalanceassertion p  -- | Adds a posting's amonut to the posting's account balance and@@ -730,8 +755,11 @@ -- from the posting amounts (or in some cases, price amounts) in this -- commodity if any, otherwise the default style. journalCommodityStyle :: Journal -> CommoditySymbol -> AmountStyle-journalCommodityStyle j c =-  headDef amountstyle{asprecision=2} $+journalCommodityStyle j = fromMaybe amountstyle{asprecision=2} . journalCommodityStyleLookup j++journalCommodityStyleLookup :: Journal -> CommoditySymbol -> Maybe AmountStyle+journalCommodityStyleLookup j c =+  listToMaybe $   catMaybes [      M.lookup c (jcommodities j) >>= cformat     ,M.lookup c $ jinferredcommodities j@@ -751,8 +779,7 @@ commodityStylesFromAmounts :: [Amount] -> M.Map CommoditySymbol AmountStyle commodityStylesFromAmounts amts = M.fromList commstyles   where-    samecomm = \a1 a2 -> acommodity a1 == acommodity a2-    commamts = [(acommodity $ head as, as) | as <- groupBy samecomm $ sortBy (comparing acommodity) amts]+    commamts = groupSort [(acommodity as, as) | as <- amts]     commstyles = [(c, canonicalStyleFrom $ map astyle as) | (c,as) <- commamts]  -- | Given an ordered list of amount styles, choose a canonical style.@@ -801,7 +828,10 @@       fixtransaction t@Transaction{tpostings=ps} = t{tpostings=map fixposting ps}       fixposting p@Posting{pamount=a} = p{pamount=fixmixedamount a}       fixmixedamount (Mixed as) = Mixed $ map fixamount as-      fixamount = canonicaliseAmount (jinferredcommodities j) . costOfAmount+      fixamount = applyJournalStyle . costOfAmount+      applyJournalStyle a+          | Just s <- journalCommodityStyleLookup j (acommodity a) = a{astyle=s}+          | otherwise = a  -- -- | Get this journal's unique, display-preference-canonicalised commodities, by symbol. -- journalCanonicalCommodities :: Journal -> M.Map String CommoditySymbol
Hledger/Data/Posting.hs view
@@ -132,8 +132,9 @@ isAssignment :: Posting -> Bool isAssignment p = not (hasAmount p) && isJust (pbalanceassertion p) +-- | Sorted unique account names referenced by these postings. accountNamesFromPostings :: [Posting] -> [AccountName]-accountNamesFromPostings = nub . map paccount+accountNamesFromPostings = nub . sort . map paccount  sumPostings :: [Posting] -> MixedAmount sumPostings = sumStrict . map pamount
Hledger/Data/Transaction.hs view
@@ -213,7 +213,7 @@     | postingblock <- postingblocks]   where     postingblocks = [map rstrip $ lines $ concatTopPadded [statusandaccount, "  ", amount, assertion, samelinecomment] | amount <- shownAmounts]-    assertion = maybe "" ((" = " ++) . showAmountWithZeroCommodity) $ pbalanceassertion p+    assertion = maybe "" ((" = " ++) . showAmountWithZeroCommodity . fst) $ pbalanceassertion p     statusandaccount = indent $ fitString (Just $ minwidth) Nothing False True $ pstatusandacct p         where           -- pad to the maximum account name width, plus 2 to leave room for status flags, to keep amounts aligned  @@ -228,6 +228,7 @@     shownAmounts       | elideamount    = [""]       | onelineamounts = [fitString (Just amtwidth) Nothing False False $ showMixedAmountOneLine $ pamount p]+      | null (amounts $ pamount p) = [""]       | otherwise      = map (fitStringMulti (Just amtwidth) Nothing False False . showAmount ) . amounts $ pamount p       where         amtwidth = maximum $ 12 : map (strWidth . showMixedAmount . pamount) ps  -- min. 12 for backwards compatibility@@ -254,7 +255,7 @@ tests_postingAsLines = [    "postingAsLines" ~: do     let p `gives` ls = assertEqual (show p) ls (postingAsLines False False [p] p)-    posting `gives` []+    posting `gives` [""]     posting{       pstatus=Cleared,       paccount="a",
Hledger/Data/Types.hs view
@@ -43,6 +43,8 @@  data DateSpan = DateSpan (Maybe Day) (Maybe Day) deriving (Eq,Ord,Data,Generic,Typeable) +instance Default DateSpan where def = DateSpan Nothing Nothing+ instance NFData DateSpan  -- synonyms for various date-related scalars@@ -89,7 +91,9 @@   | Quarters Int   | Years Int   | DayOfMonth Int+  | WeekdayOfMonth Int Int   | DayOfWeek Int+  | DayOfYear Int Int -- Month, Day   -- WeekOfYear Int   -- MonthOfYear Int   -- QuarterOfYear Int@@ -192,6 +196,8 @@   show Pending   = "!"   show Cleared   = "*" +type BalanceAssertion = Maybe (Amount, GenericSourcePos)+ data Posting = Posting {       pdate             :: Maybe Day,         -- ^ this posting's date, if different from the transaction's       pdate2            :: Maybe Day,         -- ^ this posting's secondary date, if different from the transaction's@@ -201,7 +207,7 @@       pcomment          :: Text,              -- ^ this posting's comment lines, as a single non-indented multi-line string       ptype             :: PostingType,       ptags             :: [Tag],             -- ^ tag names and values, extracted from the comment-      pbalanceassertion :: Maybe Amount,      -- ^ optional: the expected balance in this commodity in the account after this posting+      pbalanceassertion :: BalanceAssertion,  -- ^ optional: the expected balance in this commodity in the account after this posting       ptransaction      :: Maybe Transaction, -- ^ this posting's parent transaction (co-recursive types).                                               -- Tying this knot gets tedious, Maybe makes it easier/optional.       porigin           :: Maybe Posting      -- ^ original posting if this one is result of any transformations (one level only)
Hledger/Read/Common.hs view
@@ -14,6 +14,7 @@  --- * module {-# LANGUAGE CPP, DeriveDataTypeable, RecordWildCards, NamedFieldPuns, NoMonoLocalBinds, ScopedTypeVariables, FlexibleContexts, TupleSections, OverloadedStrings #-}+{-# LANGUAGE LambdaCase #-}  module Hledger.Read.Common where@@ -23,7 +24,7 @@ import Control.Monad.Compat import Control.Monad.Except (ExceptT(..), runExceptT, throwError) --, catchError) import Control.Monad.State.Strict-import Data.Char (isNumber)+import Data.Char import Data.Data import Data.Default import Data.Functor.Identity@@ -31,6 +32,7 @@ import Data.List.NonEmpty (NonEmpty(..)) import Data.List.Split (wordsBy) import Data.Maybe+import qualified Data.Map as M import Data.Monoid import Data.Text (Text) import qualified Data.Text as T@@ -146,6 +148,24 @@ getDefaultCommodityAndStyle :: JournalParser m (Maybe (CommoditySymbol,AmountStyle)) getDefaultCommodityAndStyle = jparsedefaultcommodity `fmap` get +-- | Get amount style associated with default currency.+--+-- Returns 'AmountStyle' used to defined by a latest default commodity directive+-- prior to current position within this file or its parents.+getDefaultAmountStyle :: JournalParser m (Maybe AmountStyle)+getDefaultAmountStyle = fmap snd <$> getDefaultCommodityAndStyle++-- | Lookup currency-specific amount style.+--+-- Returns 'AmountStyle' used in commodity directive within current journal+-- prior to current position or in its parents files.+getAmountStyle :: CommoditySymbol -> JournalParser m (Maybe AmountStyle)+getAmountStyle commodity = do+    specificStyle <-  maybe Nothing cformat . M.lookup commodity . jcommodities <$> get+    defaultStyle <- fmap snd <$> getDefaultCommodityAndStyle+    let effectiveStyle = listToMaybe $ catMaybes [specificStyle, defaultStyle]+    return effectiveStyle+ pushAccount :: AccountName -> JournalParser m () pushAccount acct = modify' (\j -> j{jaccounts = acct : jaccounts j}) @@ -416,8 +436,9 @@   sign <- lift signp   m <- lift multiplierp   c <- lift commoditysymbolp+  suggestedStyle <- getAmountStyle c   sp <- lift $ many spacenonewline-  (q,prec,mdec,mgrps) <- lift numberp+  (q,prec,mdec,mgrps) <- lift $ numberp suggestedStyle   let s = amountstyle{ascommodityside=L, ascommodityspaced=not $ null sp, asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps}   p <- priceamountp   let applysign = if sign=="-" then negate else id@@ -427,9 +448,12 @@ rightsymbolamountp :: Monad m => JournalParser m Amount rightsymbolamountp = do   m <- lift multiplierp-  (q,prec,mdec,mgrps) <- lift numberp+  sign <- lift signp+  rawnum <- lift $ rawnumberp   sp <- lift $ many spacenonewline   c <- lift commoditysymbolp+  suggestedStyle <- getAmountStyle c+  let (q,prec,mdec,mgrps) = fromRawNumber suggestedStyle (sign == "-") rawnum   p <- priceamountp   let s = amountstyle{ascommodityside=R, ascommodityspaced=not $ null sp, asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps}   return $ Amount c q p s m@@ -438,7 +462,8 @@ nosymbolamountp :: Monad m => JournalParser m Amount nosymbolamountp = do   m <- lift multiplierp-  (q,prec,mdec,mgrps) <- lift numberp+  suggestedStyle <- getDefaultAmountStyle+  (q,prec,mdec,mgrps) <- lift $ numberp suggestedStyle   p <- priceamountp   -- apply the most recently seen default commodity and style to this commodityless amount   defcs <- getDefaultCommodityAndStyle@@ -477,14 +502,15 @@             return $ UnitPrice a))          <|> return NoPrice -partialbalanceassertionp :: Monad m => JournalParser m (Maybe Amount)+partialbalanceassertionp :: Monad m => JournalParser m BalanceAssertion partialbalanceassertionp =     try (do           lift (many spacenonewline)+          sourcepos <- genericSourcePos <$> lift getPosition           char '='           lift (many spacenonewline)           a <- amountp -- XXX should restrict to a simple amount-          return $ Just $ a)+          return $ Just (a, sourcepos))          <|> return Nothing  -- balanceassertion :: Monad m => TextParser m (Maybe MixedAmount)@@ -524,56 +550,80 @@ -- seen following the decimal point), the decimal point character used if any, -- and the digit group style if any. ---numberp :: TextParser m (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)-numberp = do-  -- a number is an optional sign followed by a sequence of digits possibly-  -- interspersed with periods, commas, or both-  -- ptrace "numberp"-  sign <- signp-  parts <- some $ choice' [some digitChar, some $ char ',', some $ char '.']-  dbg8 "numberp parsed" (sign,parts) `seq` return ()+numberp :: Maybe AmountStyle -> TextParser m (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)+numberp suggestedStyle = do+    -- a number is an optional sign followed by a sequence of digits possibly+    -- interspersed with periods, commas, or both+    -- ptrace "numberp"+    sign <- signp+    raw <- rawnumberp+    dbg8 "numberp parsed" raw `seq` return ()+    return $ dbg8 "numberp quantity,precision,mdecimalpoint,mgrps" (fromRawNumber suggestedStyle (sign == "-") raw)+    <?> "numberp" -  -- check the number is well-formed and identify the decimal point and digit-  -- group separator characters used, if any-  let (numparts, puncparts) = partition numeric parts-      (ok, mdecimalpoint, mseparator) =-          case (numparts, puncparts) of-            ([],_)     -> (False, Nothing, Nothing)  -- no digits, not ok-            (_,[])     -> (True, Nothing, Nothing)   -- digits with no punctuation, ok-            (_,[[d]])  -> (True, Just d, Nothing)    -- just a single punctuation of length 1, assume it's a decimal point-            (_,[_])    -> (False, Nothing, Nothing)  -- a single punctuation of some other length, not ok-            (_,_:_:_)  ->                                       -- two or more punctuations-              let (s:ss, d) = (init puncparts, last puncparts)  -- the leftmost is a separator and the rightmost may be a decimal point-              in if any ((/=1).length) puncparts               -- adjacent punctuation chars, not ok-                    || any (s/=) ss                            -- separator chars vary, not ok-                    || head parts == s                        -- number begins with a separator char, not ok-                 then (False, Nothing, Nothing)-                 else if s == d-                      then (True, Nothing, Just $ head s)       -- just one kind of punctuation - must be separators-                      else (True, Just $ head d, Just $ head s) -- separator(s) and a decimal point-  unless ok $ fail $ "number seems ill-formed: "++concat parts+fromRawNumber :: Maybe AmountStyle -> Bool -> (Maybe Char, [String], Maybe (Char, String)) -> (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)+fromRawNumber suggestedStyle negated raw = (quantity, precision, mdecimalpoint, mgrps) where+    -- unpack with a hint if useful+    (mseparator, intparts, mdecimalpoint, frac) =+            case raw of+                -- just a single punctuation between two digits groups, assume it's a decimal point+                (Just s, [firstGroup, lastGroup], Nothing)+                    -- if have a decimalHint restrict this assumpion only to a matching separator+                    | maybe True (`asdecimalcheck` s) suggestedStyle -> (Nothing, [firstGroup], Just s, lastGroup) -  -- get the digit group sizes and digit group style if any-  let (intparts',fracparts') = span ((/= mdecimalpoint) . Just . head) parts-      (intparts, fracpart) = (filter numeric intparts', filter numeric fracparts')-      groupsizes = reverse $ case map length intparts of+                (firstSep, digitGroups, Nothing) -> (firstSep, digitGroups, Nothing, [])+                (firstSep, digitGroups, Just (d, frac)) -> (firstSep, digitGroups, Just d, frac)++    -- get the digit group sizes and digit group style if any+    groupsizes = reverse $ case map length intparts of                                (a:b:cs) | a < b -> b:cs                                gs               -> gs-      mgrps = (`DigitGroups` groupsizes) <$> mseparator+    mgrps = (`DigitGroups` groupsizes) <$> mseparator -  -- put the parts back together without digit group separators, get the precision and parse the value-  let int = concat $ "":intparts-      frac = concat $ "":fracpart-      precision = length frac-      int' = if null int then "0" else int-      frac' = if null frac then "0" else frac-      quantity = read $ sign++int'++"."++frac' -- this read should never fail+    -- put the parts back together without digit group separators, get the precision and parse the value+    repr = (if negated then "-" else "") ++ "0" ++ concat intparts ++ (if null frac then "" else "." ++ frac)+    quantity = read repr+    precision = length frac -  return $ dbg8 "numberp quantity,precision,mdecimalpoint,mgrps" (quantity,precision,mdecimalpoint,mgrps)-  <?> "numberp"-  where-    numeric = isNumber . headDef '_'+    asdecimalcheck :: AmountStyle -> Char -> Bool+    asdecimalcheck = \case+        AmountStyle{asdecimalpoint = Just d} -> (d ==)+        AmountStyle{asdigitgroups = Just (DigitGroups g _)} -> (g /=)+        AmountStyle{asprecision = 0} -> const False+        _ -> const True ++rawnumberp :: TextParser m (Maybe Char, [String], Maybe (Char, String))+rawnumberp = do+    let sepChars = ['.', ','] -- all allowed punctuation characters++    (firstSep, groups) <- option (Nothing, []) $ do+        leadingDigits <- some digitChar+        option (Nothing, [leadingDigits]) . try $ do+            firstSep <- oneOf sepChars <|> whitespaceChar+            groups <- some digitChar `sepBy1` char firstSep+            return (Just firstSep, leadingDigits : groups)++    let remSepChars = maybe sepChars (`delete` sepChars) firstSep+        modifier+            | null groups = fmap Just  -- if no digits so far, we require at least some decimals+            | otherwise = optional++    extraGroup <- modifier $ do+        lastSep <- oneOf remSepChars+        digits <- modifier $ some digitChar  -- decimal separator allowed to be without digits if had some before+        return (lastSep, fromMaybe [] digits)++    -- make sure we didn't leading part of mistyped number+    notFollowedBy $ oneOf sepChars <|> (whitespaceChar >> digitChar)++    return $ dbg8 "rawnumberp" (firstSep, groups, extraGroup)+    <?> "rawnumberp"++-- | Parse a unicode char that represents any non-control space char (Zs general category).+whitespaceChar :: TextParser m Char+whitespaceChar = charCategory Space+ -- test_numberp = do --       let s `is` n = assertParseEqual (parseWithState mempty numberp s) n --           assertFails = assertBool . isLeft . parseWithState mempty numberp@@ -609,15 +659,15 @@  emptyorcommentlinep :: JournalParser m () emptyorcommentlinep = do-  lift (many spacenonewline) >> (commentp <|> (lift (many spacenonewline) >> newline >> return ""))+  lift (many spacenonewline) >> (linecommentp <|> (lift (many spacenonewline) >> newline >> return ""))   return ()  -- | Parse a possibly multi-line comment following a semicolon. followingcommentp :: JournalParser m Text followingcommentp =   -- ptrace "followingcommentp"-  do samelinecomment <- lift (many spacenonewline) >> (try semicoloncommentp <|> (newline >> return ""))-     newlinecomments <- many (try (lift (some spacenonewline) >> semicoloncommentp))+  do samelinecomment <- lift (many spacenonewline) >> (try commentp <|> (newline >> return ""))+     newlinecomments <- many (try (lift (some spacenonewline) >> commentp))      return $ T.unlines $ samelinecomment:newlinecomments  -- | Parse a possibly multi-line comment following a semicolon, and@@ -649,10 +699,10 @@   -- to get good error positions.   startpos <- getPosition   commentandwhitespace :: String <- do-    let semicoloncommentp' = (:) <$> char ';' <*> anyChar `manyTill` eolof+    let commentp' = (:) <$> char ';' <*> anyChar `manyTill` eolof     sp1 <- lift (many spacenonewline)-    l1  <- try (lift semicoloncommentp') <|> (newline >> return "")-    ls  <- lift . many $ try ((++) <$> some spacenonewline <*> semicoloncommentp')+    l1  <- try (lift commentp') <|> (newline >> return "")+    ls  <- lift . many $ try ((++) <$> some spacenonewline <*> commentp')     return $ unlines $ (sp1 ++ l1) : ls   let comment = T.pack $ unlines $ map (lstrip . dropWhile (==';') . strip) $ lines commentandwhitespace   -- pdbg 0 $ "commentws:"++show commentandwhitespace@@ -675,14 +725,15 @@    return (comment, tags, mdate, mdate2) +-- A transaction/posting comment must start with a semicolon.+-- This parser ignores leading whitespace. commentp :: JournalParser m Text-commentp = commentStartingWithp commentchars--commentchars :: [Char]-commentchars = "#;*"+commentp = commentStartingWithp ";" -semicoloncommentp :: JournalParser m Text-semicoloncommentp = commentStartingWithp ";"+-- A line (file-level) comment can start with a semicolon, hash,+-- or star (allowing org nodes). This parser ignores leading whitespace.+linecommentp :: JournalParser m Text+linecommentp = commentStartingWithp ";#*"   commentStartingWithp :: [Char] -> JournalParser m Text commentStartingWithp cs = do
Hledger/Read/CsvReader.hs view
@@ -649,10 +649,10 @@     comment     = maybe "" render $ mfieldtemplate "comment"     precomment  = maybe "" render $ mfieldtemplate "precomment"     currency    = maybe (fromMaybe "" mdefaultcurrency) render $ mfieldtemplate "currency"-    amountstr   = (currency++) $ simplifySign $ getAmountStr rules record-    amount      = either amounterror (Mixed . (:[])) $ runParser (evalStateT (amountp <* eof) mempty) "" $ T.pack amountstr+    amountstr   = (currency++) <$> simplifySign <$> getAmountStr rules record+    maybeamount      = either amounterror (Mixed . (:[])) <$> runParser (evalStateT (amountp <* eof) mempty) "" <$> T.pack <$> amountstr     amounterror err = error' $ unlines-      ["error: could not parse \""++amountstr++"\" as an amount"+      ["error: could not parse \""++fromJust amountstr++"\" as an amount"       ,showRecord record       ,"the amount rule is:      "++(fromMaybe "" $ mfieldtemplate "amount")       ,"the currency rule is:    "++(fromMaybe "unspecified" $ mfieldtemplate "currency")@@ -662,10 +662,13 @@        ++"change your amount or currency rules, "        ++"or "++maybe "add a" (const "change your") mskip++" skip rule"       ]-    amount1        = amount-    -- convert balancing amount to cost like hledger print, so eg if +    amount1 = case maybeamount of+                Just a -> a+                Nothing | balance /= Nothing -> nullmixedamt+                Nothing -> error' $ "amount and balance have no value\n"++showRecord record+    -- convert balancing amount to cost like hledger print, so eg if     -- amount1 is "10 GBP @@ 15 USD", amount2 will be "-15 USD".-    amount2        = costOfMixedAmount (-amount)+    amount2        = costOfMixedAmount (-amount1)     s `or` def  = if null s then def else s     defaccount1 = fromMaybe "unknown" $ mdirective "default-account1"     defaccount2 = case isNegativeMixedAmount amount2 of@@ -676,7 +679,7 @@     balance     = maybe Nothing (parsebalance.render) $ mfieldtemplate "balance"     parsebalance str        | all isSpace str  = Nothing-      | otherwise = Just $ either (balanceerror str) id $ runParser (evalStateT (amountp <* eof) mempty) "" $ T.pack $ (currency++) $ simplifySign str+      | otherwise = Just $ (either (balanceerror str) id $ runParser (evalStateT (amountp <* eof) mempty) "" $ T.pack $ (currency++) $ simplifySign str, nullsourcepos)     balanceerror str err = error' $ unlines       ["error: could not parse \""++str++"\" as balance amount"       ,showRecord record@@ -702,7 +705,7 @@         ]       } -getAmountStr :: CsvRules -> CsvRecord -> String+getAmountStr :: CsvRules -> CsvRecord -> Maybe String getAmountStr rules record =  let    mamount    = getEffectiveAssignment rules record "amount"@@ -711,11 +714,11 @@    render     = fmap (strip . renderTemplate rules record)  in   case (render mamount, render mamountin, render mamountout) of-    (Just "", Nothing, Nothing) -> error' $ "amount has no value\n"++showRecord record-    (Just a,  Nothing, Nothing) -> a+    (Just "", Nothing, Nothing) -> Nothing+    (Just a,  Nothing, Nothing) -> Just a     (Nothing, Just "", Just "") -> error' $ "neither amount-in or amount-out has a value\n"++showRecord record-    (Nothing, Just i,  Just "") -> i-    (Nothing, Just "", Just o)  -> negateStr o+    (Nothing, Just i,  Just "") -> Just i+    (Nothing, Just "", Just o)  -> Just $ negateStr o     (Nothing, Just _,  Just _)  -> error' $ "both amount-in and amount-out have a value\n"++showRecord record     _                           -> error' $ "found values for amount and for amount-in/amount-out - please use either amount or amount-in/amount-out\n"++showRecord record 
Hledger/Read/JournalReader.hs view
@@ -81,6 +81,8 @@ import qualified Data.Map.Strict as M import Data.Monoid import Data.Text (Text)+import Data.String+import Data.List import qualified Data.Text as T import Data.Time.Calendar import Data.Time.LocalTime@@ -157,7 +159,7 @@ directivep :: MonadIO m => ErroringJournalParser m () directivep = (do   optional $ char '!'-  choiceInState [+  choice [     includedirectivep    ,aliasdirectivep    ,endaliasesdirectivep@@ -201,7 +203,7 @@       either         (throwError           . ((show parentpos ++ " in included file " ++ show filename ++ ":\n") ++)-          . show)+          . parseErrorPretty)         (return . journalAddFile (filepath, txt))         ej1   case ej of@@ -215,6 +217,7 @@   ,jparsedefaultcommodity = jparsedefaultcommodity j   ,jparseparentaccounts   = jparseparentaccounts j   ,jparsealiases          = jparsealiases j+  ,jcommodities           = jcommodities j   -- ,jparsetransactioncount = jparsetransactioncount j   ,jparsetimeclockentries = jparsetimeclockentries j   }@@ -292,9 +295,19 @@     else parserErrorAt pos $          printf "commodity directive symbol \"%s\" and format directive symbol \"%s\" should be the same" expectedsym acommodity +keywordp :: String -> JournalParser m ()+keywordp = (() <$) . string . fromString++spacesp :: JournalParser m ()+spacesp = () <$ lift (some spacenonewline)++-- | Backtracking parser similar to string, but allows varying amount of space between words+keywordsp :: String -> JournalParser m ()+keywordsp = try . sequence_ . intersperse spacesp . map keywordp . words+ applyaccountdirectivep :: JournalParser m () applyaccountdirectivep = do-  string "apply" >> lift (some spacenonewline) >> string "account"+  keywordsp "apply account" <?> "apply account directive"   lift (some spacenonewline)   parent <- lift accountnamep   newline@@ -302,7 +315,7 @@  endapplyaccountdirectivep :: JournalParser m () endapplyaccountdirectivep = do-  string "end" >> lift (some spacenonewline) >> string "apply" >> lift (some spacenonewline) >> string "account"+  keywordsp "end apply account" <?> "end apply account directive"   popParentAccount  aliasdirectivep :: JournalParser m ()@@ -338,7 +351,7 @@  endaliasesdirectivep :: JournalParser m () endaliasesdirectivep = do-  string "end aliases"+  keywordsp "end aliases" <?> "end aliases directive"   clearAccountAliases  tagdirectivep :: JournalParser m ()@@ -351,7 +364,7 @@  endtagdirectivep :: JournalParser m () endtagdirectivep = do-  (string "end tag" <|> string "pop") <?> "end tag or pop directive"+  (keywordsp "end tag" <|> keywordp "pop") <?> "end tag or pop directive"   lift restofline   return () 
Hledger/Read/TimedotReader.hs view
@@ -141,7 +141,7 @@ -- @ timedotnumericp :: JournalParser m Quantity timedotnumericp = do-  (q, _, _, _) <- lift numberp+  (q, _, _, _) <- lift $ numberp Nothing   msymbol <- optional $ choice $ map (string . fst) timeUnits   lift (many spacenonewline)   let q' = 
Hledger/Reports/BalanceReport.hs view
@@ -17,9 +17,6 @@   BalanceReport,   BalanceReportItem,   balanceReport,-  balanceReportValue,-  mixedAmountValue,-  amountValue,   flatShowsExclusiveBalance,    -- * Tests@@ -32,7 +29,6 @@ import Data.Maybe import Data.Time.Calendar import Test.HUnit-import qualified Data.Text as T  import Hledger.Data import Hledger.Read (mamountp')@@ -151,57 +147,6 @@ --     MultiBalanceReport (_,mbrrows,mbrtotals) = PeriodChangeReport opts q j --     items = [(a,a',n, headDef 0 bs) | ((a,a',n), bs) <- mbrrows] --     total = headDef 0 mbrtotals---- | Convert all the amounts in a single-column balance report to--- their value on the given date in their default valuation--- commodities.-balanceReportValue :: Journal -> Day -> BalanceReport -> BalanceReport-balanceReportValue j d r = r'-  where-    (items,total) = r-    r' =-      dbg8 "known market prices" (jmarketprices j) `seq`-      dbg8 "report end date" d `seq`-      dbg8 "balanceReportValue"-        ([(n, n', i, mixedAmountValue j d a) |(n,n',i,a) <- items], mixedAmountValue j d total)--mixedAmountValue :: Journal -> Day -> MixedAmount -> MixedAmount-mixedAmountValue j d (Mixed as) = Mixed $ map (amountValue j d) as---- | Find the market value of this amount on the given date, in it's--- default valuation commodity, based on recorded market prices.--- If no default valuation commodity can be found, the amount is left--- unchanged.-amountValue :: Journal -> Day -> Amount -> Amount-amountValue j d a =-  case commodityValue j d (acommodity a) of-    Just v  -> v{aquantity=aquantity v * aquantity a-                ,aprice=aprice a-                }-    Nothing -> a---- | Find the market value, if known, of one unit of this commodity (A) on--- the given valuation date, in the commodity (B) mentioned in the latest--- applicable market price. The latest applicable market price is the market--- price directive for commodity A with the latest date that is on or before--- the valuation date; or if there are multiple such prices with the same date,--- the last parsed.-commodityValue :: Journal -> Day -> CommoditySymbol -> Maybe Amount-commodityValue j valuationdate c-    | null applicableprices = dbg Nothing-    | otherwise             = dbg $ Just $ mpamount $ last applicableprices-  where-    dbg = dbg8 ("using market price for "++T.unpack c)-    applicableprices =-      [p | p <- sortBy (comparing mpdate) $ jmarketprices j-      , mpcommodity p == c-      , mpdate p <= valuationdate-      ]-----   tests_balanceReport =
Hledger/Reports/MultiBalanceReports.hs view
@@ -9,7 +9,6 @@   MultiBalanceReport(..),   MultiBalanceReportRow,   multiBalanceReport,-  multiBalanceReportValue,   singleBalanceReport,    -- -- * Tests@@ -234,18 +233,6 @@       dbg1 s = let p = "multiBalanceReport" in Hledger.Utils.dbg1 (p++" "++s)  -- add prefix in this function's debug output       -- dbg1 = const id  -- exclude this function from debug output --- | Convert all the amounts in a multi-column balance report to their--- value on the given date in their default valuation commodities--- (which are determined as of that date, not the report interval dates).-multiBalanceReportValue :: Journal -> Day -> MultiBalanceReport -> MultiBalanceReport-multiBalanceReportValue j d r = r'-  where-    MultiBalanceReport (spans, rows, (coltotals, rowtotaltotal, rowavgtotal)) = r-    r' = MultiBalanceReport-         (spans,-          [(acct, acct', depth, map convert rowamts, convert rowtotal, convert rowavg) | (acct, acct', depth, rowamts, rowtotal, rowavg) <- rows],-          (map convert coltotals, convert rowtotaltotal, convert rowavgtotal))-    convert = mixedAmountValue j d  tests_multiBalanceReport =   let
Hledger/Reports/ReportOptions.hs view
@@ -24,9 +24,12 @@   queryOptsFromOpts,   transactionDateFn,   postingDateFn,+  reportStartEndDates,   reportStartDate,   reportEndDate,-  reportStartEndDates,+  specifiedStartEndDates,+  specifiedStartDate,+  specifiedEndDate,    tests_Hledger_Reports_ReportOptions )@@ -104,6 +107,8 @@       -- eg in the income section of an income statement, this helps --sort-amount know       -- how to sort negative numbers.     ,color_          :: Bool+    ,forecast_       :: Bool+    ,auto_           :: Bool  } deriving (Show, Data, Typeable)  instance Default ReportOpts where def = defreportopts@@ -134,6 +139,8 @@     def     def     def+    def+    def  rawOptsToReportOpts :: RawOpts -> IO ReportOpts rawOptsToReportOpts rawopts = checkReportOpts <$> do@@ -164,6 +171,8 @@     ,sort_amount_ = boolopt "sort-amount" rawopts'     ,pretty_tables_ = boolopt "pretty-tables" rawopts'     ,color_       = color+    ,forecast_    = boolopt "forecast" rawopts'+    ,auto_        = boolopt "auto" rawopts'     }  -- | Do extra validation of raw option values, raising an error if there's a problem.@@ -393,32 +402,41 @@                                                              })  ] --- | The effective report start date is the one specified by options or queries,--- otherwise the earliest transaction or posting date in the journal,+-- | The effective report start/end dates are the dates specified by options or queries,+-- otherwise the earliest/latest transaction or posting date in the journal, -- otherwise (for an empty journal) nothing. -- Needs IO to parse smart dates in options/queries.+reportStartEndDates :: Journal -> ReportOpts -> IO (Maybe (Day,Day))+reportStartEndDates j ropts = do+  (mspecifiedstartdate, mspecifiedenddate) <- specifiedStartEndDates ropts+  return $+    case journalDateSpan False j of  -- don't bother with secondary dates+      DateSpan (Just journalstartdate) (Just journalenddate) ->+        Just (fromMaybe journalstartdate mspecifiedstartdate, fromMaybe journalenddate mspecifiedenddate)+      _ -> Nothing+ reportStartDate :: Journal -> ReportOpts -> IO (Maybe Day) reportStartDate j ropts = (fst <$>) <$> reportStartEndDates j ropts --- | The effective report end date is the one specified by options or queries,--- otherwise the latest transaction or posting date in the journal,--- otherwise (for an empty journal) nothing.--- Needs IO to parse smart dates in options/queries. reportEndDate :: Journal -> ReportOpts -> IO (Maybe Day) reportEndDate j ropts = (snd <$>) <$> reportStartEndDates j ropts -reportStartEndDates :: Journal -> ReportOpts -> IO (Maybe (Day,Day))-reportStartEndDates j ropts = do+-- | The specified report start/end dates are the dates specified by options or queries, if any.+-- Needs IO to parse smart dates in options/queries.+specifiedStartEndDates :: ReportOpts -> IO (Maybe Day, Maybe Day)+specifiedStartEndDates ropts = do   today <- getCurrentDay   let     q = queryFromOpts today ropts-    mrequestedstartdate = queryStartDate False q-    mrequestedenddate = queryEndDate False q-  return $-    case journalDateSpan False j of  -- don't bother with secondary dates-      DateSpan (Just journalstartdate) (Just journalenddate) ->-        Just (fromMaybe journalstartdate mrequestedstartdate, fromMaybe journalenddate mrequestedenddate)-      _ -> Nothing+    mspecifiedstartdate = queryStartDate False q+    mspecifiedenddate   = queryEndDate   False q+  return (mspecifiedstartdate, mspecifiedenddate)++specifiedStartDate :: ReportOpts -> IO (Maybe Day)+specifiedStartDate ropts = fst <$> specifiedStartEndDates ropts++specifiedEndDate :: ReportOpts -> IO (Maybe Day)+specifiedEndDate ropts = snd <$> specifiedStartEndDates ropts   tests_Hledger_Reports_ReportOptions :: Test
Hledger/Utils/Parse.hs view
@@ -38,6 +38,9 @@ choiceInState :: [StateT s (ParsecT MPErr Text m) a] -> StateT s (ParsecT MPErr Text m) a choiceInState = choice . map try +surroundedBy :: Applicative m => m openclose -> m a -> m a+surroundedBy p = between p p+ parsewith :: Parsec e Text a -> Text -> Either (ParseError Char e) a parsewith p = runParser p "" 
− doc/hledger_csv.5
@@ -1,277 +0,0 @@--.TH "hledger_csv" "5" "September 2017" "hledger 1.4" "hledger User Manuals"----.SH NAME-.PP-CSV \- how hledger reads CSV data, and the CSV rules file format-.SH DESCRIPTION-.PP-hledger can read CSV files, converting each CSV record into a journal-entry (transaction), if you provide some conversion hints in a "rules-file".-This file should be named like the CSV file with an additional-\f[C]\&.rules\f[] suffix (eg: \f[C]mybank.csv.rules\f[]); or, you can-specify the file with \f[C]\-\-rules\-file\ PATH\f[].-hledger will create it if necessary, with some default rules which-you\[aq]ll need to adjust.-At minimum, the rules file must specify the \f[C]date\f[] and-\f[C]amount\f[] fields.-For an example, see Cookbook: convert CSV files.-.PP-To learn about \f[I]exporting\f[] CSV, see CSV output.-.SH CSV RULES-.PP-The following seven kinds of rule can appear in the rules file, in any-order.-Blank lines and lines beginning with \f[C]#\f[] or \f[C];\f[] are-ignored.-.SS skip-.PP-\f[C]skip\f[]\f[I]\f[C]N\f[]\f[]-.PP-Skip this number of CSV records at the beginning.-You\[aq]ll need this whenever your CSV data contains header lines.-Eg:-.IP-.nf-\f[C]-#\ ignore\ the\ first\ CSV\ line-skip\ 1-\f[]-.fi-.SS date\-format-.PP-\f[C]date\-format\f[]\f[I]\f[C]DATEFMT\f[]\f[]-.PP-When your CSV date fields are not formatted like \f[C]YYYY/MM/DD\f[] (or-\f[C]YYYY\-MM\-DD\f[] or \f[C]YYYY.MM.DD\f[]), you\[aq]ll need to-specify the format.-DATEFMT is a strptime\-like date parsing pattern, which must parse the-date field values completely.-Examples:-.IP-.nf-\f[C]-#\ for\ dates\ like\ "6/11/2013":-date\-format\ %\-d/%\-m/%Y-\f[]-.fi-.IP-.nf-\f[C]-#\ for\ dates\ like\ "11/06/2013":-date\-format\ %m/%d/%Y-\f[]-.fi-.IP-.nf-\f[C]-#\ for\ dates\ like\ "2013\-Nov\-06":-date\-format\ %Y\-%h\-%d-\f[]-.fi-.IP-.nf-\f[C]-#\ for\ dates\ like\ "11/6/2013\ 11:32\ PM":-date\-format\ %\-m/%\-d/%Y\ %l:%M\ %p-\f[]-.fi-.SS field list-.PP-\f[C]fields\f[]\f[I]\f[C]FIELDNAME1\f[]\f[],-\f[I]\f[C]FIELDNAME2\f[]\f[]...-.PP-This (a) names the CSV fields, in order (names may not contain-whitespace; uninteresting names may be left blank), and (b) assigns them-to journal entry fields if you use any of these standard field names:-\f[C]date\f[], \f[C]date2\f[], \f[C]status\f[], \f[C]code\f[],-\f[C]description\f[], \f[C]comment\f[], \f[C]account1\f[],-\f[C]account2\f[], \f[C]amount\f[], \f[C]amount\-in\f[],-\f[C]amount\-out\f[], \f[C]currency\f[], \f[C]balance\f[].-Eg:-.IP-.nf-\f[C]-#\ use\ the\ 1st,\ 2nd\ and\ 4th\ CSV\ fields\ as\ the\ entry\[aq]s\ date,\ description\ and\ amount,-#\ and\ give\ the\ 7th\ and\ 8th\ fields\ meaningful\ names\ for\ later\ reference:-#-#\ CSV\ field:-#\ \ \ \ \ \ 1\ \ \ \ \ 2\ \ \ \ \ \ \ \ \ \ \ \ 3\ 4\ \ \ \ \ \ \ 5\ 6\ 7\ \ \ \ \ \ \ \ \ \ 8-#\ entry\ field:-fields\ date,\ description,\ ,\ amount,\ ,\ ,\ somefield,\ anotherfield-\f[]-.fi-.SS field assignment-.PP-\f[I]\f[C]ENTRYFIELDNAME\f[]\f[] \f[I]\f[C]FIELDVALUE\f[]\f[]-.PP-This sets a journal entry field (one of the standard names above) to the-given text value, which can include CSV field values interpolated by-name (\f[C]%CSVFIELDNAME\f[]) or 1\-based position (\f[C]%N\f[]).- Eg:-.IP-.nf-\f[C]-#\ set\ the\ amount\ to\ the\ 4th\ CSV\ field\ with\ "USD\ "\ prepended-amount\ USD\ %4-\f[]-.fi-.IP-.nf-\f[C]-#\ combine\ three\ fields\ to\ make\ a\ comment\ (containing\ two\ tags)-comment\ note:\ %somefield\ \-\ %anotherfield,\ date:\ %1-\f[]-.fi-.PP-Field assignments can be used instead of or in addition to a field list.-.SS conditional block-.PP-\f[C]if\f[] \f[I]\f[C]PATTERN\f[]\f[]-.PD 0-.P-.PD-\ \ \ \ \f[I]\f[C]FIELDASSIGNMENTS\f[]\f[]...-.PP-\f[C]if\f[]-.PD 0-.P-.PD-\f[I]\f[C]PATTERN\f[]\f[]-.PD 0-.P-.PD-\f[I]\f[C]PATTERN\f[]\f[]...-.PD 0-.P-.PD-\ \ \ \ \f[I]\f[C]FIELDASSIGNMENTS\f[]\f[]...-.PP-This applies one or more field assignments, only to those CSV records-matched by one of the PATTERNs.-The patterns are case\-insensitive regular expressions which match-anywhere within the whole CSV record (it\[aq]s not yet possible to match-within a specific field).-When there are multiple patterns they can be written on separate lines,-unindented.-The field assignments are on separate lines indented by at least one-space.-Examples:-.IP-.nf-\f[C]-#\ if\ the\ CSV\ record\ contains\ "groceries",\ set\ account2\ to\ "expenses:groceries"-if\ groceries-\ account2\ expenses:groceries-\f[]-.fi-.IP-.nf-\f[C]-#\ if\ the\ CSV\ record\ contains\ any\ of\ these\ patterns,\ set\ account2\ and\ comment\ as\ shown-if-monthly\ service\ fee-atm\ transaction\ fee-banking\ thru\ software-\ account2\ expenses:business:banking-\ comment\ \ XXX\ deductible\ ?\ check\ it-\f[]-.fi-.SS include-.PP-\f[C]include\f[]\f[I]\f[C]RULESFILE\f[]\f[]-.PP-Include another rules file at this point.-\f[C]RULESFILE\f[] is either an absolute file path or a path relative to-the current file\[aq]s directory.-Eg:-.IP-.nf-\f[C]-#\ rules\ reused\ with\ several\ CSV\ files-include\ common.rules-\f[]-.fi-.SS newest\-first-.PP-\f[C]newest\-first\f[]-.PP-Consider adding this rule if all of the following are true: you might be-processing just one day of data, your CSV records are in reverse-chronological order (newest first), and you care about preserving the-order of same\-day transactions.-It usually isn\[aq]t needed, because hledger autodetects the CSV order,-but when all CSV records have the same date it will assume they are-oldest first.-.SH CSV TIPS-.SS CSV ordering-.PP-The generated journal entries will be sorted by date.-The order of same\-day entries will be preserved (except in the special-case where you might need \f[C]newest\-first\f[], see above).-.SS CSV accounts-.PP-Each journal entry will have two postings, to \f[C]account1\f[] and-\f[C]account2\f[] respectively.-It\[aq]s not yet possible to generate entries with more than two-postings.-It\[aq]s conventional and recommended to use \f[C]account1\f[] for the-account whose CSV we are reading.-.SS CSV amounts-.PP-The \f[C]amount\f[] field sets the amount of the \f[C]account1\f[]-posting.-.PP-If the CSV has debit/credit amounts in separate fields, assign to the-\f[C]amount\-in\f[] and \f[C]amount\-out\f[] pseudo fields instead.-(Whichever one has a value will be used, with appropriate sign.-If both contain a value, it may not work so well.)-.PP-If an amount value is parenthesised, it will be de\-parenthesised and-sign\-flipped.-.PP-If an amount value begins with a double minus sign, those will cancel-out and be removed.-.PP-If the CSV has the currency symbol in a separate field, assign that to-the \f[C]currency\f[] pseudo field to have it prepended to the amount.-Or, you can use a field assignment to \f[C]amount\f[] that interpolates-both CSV fields (giving more control, eg to put the currency symbol on-the right).-.SS CSV balance assertions-.PP-If the CSV includes a running balance, you can assign that to the-\f[C]balance\f[] pseudo field; whenever the running balance value is-non\-empty, it will be asserted as the balance after the-\f[C]account1\f[] posting.-.SS Reading multiple CSV files-.PP-You can read multiple CSV files at once using multiple \f[C]\-f\f[]-arguments on the command line, and hledger will look for a-correspondingly\-named rules file for each.-Note if you use the \f[C]\-\-rules\-file\f[] option, this one rules file-will be used for all the CSV files being read.---.SH "REPORTING BUGS"-Report bugs at http://bugs.hledger.org-(or on the #hledger IRC channel or hledger mail list)--.SH AUTHORS-Simon Michael <simon@joyful.com> and contributors--.SH COPYRIGHT--Copyright (C) 2007-2016 Simon Michael.-.br-Released under GNU GPL v3 or later.--.SH SEE ALSO-hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),-hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),-ledger(1)--http://hledger.org
− doc/hledger_csv.5.info
@@ -1,302 +0,0 @@-This is hledger_csv.5.info, produced by makeinfo version 6.0 from stdin.---File: hledger_csv.5.info,  Node: Top,  Next: CSV RULES,  Up: (dir)--hledger_csv(5) hledger 1.4-**************************--hledger can read CSV files, converting each CSV record into a journal-entry (transaction), if you provide some conversion hints in a "rules-file".  This file should be named like the CSV file with an additional-'.rules' suffix (eg: 'mybank.csv.rules'); or, you can specify the file-with '--rules-file PATH'.  hledger will create it if necessary, with-some default rules which you'll need to adjust.  At minimum, the rules-file must specify the 'date' and 'amount' fields.  For an example, see-Cookbook: convert CSV files.--   To learn about _exporting_ CSV, see CSV output.-* Menu:--* CSV RULES::-* CSV TIPS::---File: hledger_csv.5.info,  Node: CSV RULES,  Next: CSV TIPS,  Prev: Top,  Up: Top--1 CSV RULES-***********--The following seven kinds of rule can appear in the rules file, in any-order.  Blank lines and lines beginning with '#' or ';' are ignored.-* Menu:--* skip::-* date-format::-* field list::-* field assignment::-* conditional block::-* include::-* newest-first::---File: hledger_csv.5.info,  Node: skip,  Next: date-format,  Up: CSV RULES--1.1 skip-========--'skip'_'N'_--   Skip this number of CSV records at the beginning.  You'll need this-whenever your CSV data contains header lines.  Eg:--# ignore the first CSV line-skip 1---File: hledger_csv.5.info,  Node: date-format,  Next: field list,  Prev: skip,  Up: CSV RULES--1.2 date-format-===============--'date-format'_'DATEFMT'_--   When your CSV date fields are not formatted like 'YYYY/MM/DD' (or-'YYYY-MM-DD' or 'YYYY.MM.DD'), you'll need to specify the format.-DATEFMT is a strptime-like date parsing pattern, which must parse the-date field values completely.  Examples:--# for dates like "6/11/2013":-date-format %-d/%-m/%Y--# for dates like "11/06/2013":-date-format %m/%d/%Y--# for dates like "2013-Nov-06":-date-format %Y-%h-%d--# for dates like "11/6/2013 11:32 PM":-date-format %-m/%-d/%Y %l:%M %p---File: hledger_csv.5.info,  Node: field list,  Next: field assignment,  Prev: date-format,  Up: CSV RULES--1.3 field list-==============--'fields'_'FIELDNAME1'_, _'FIELDNAME2'_...--   This (a) names the CSV fields, in order (names may not contain-whitespace; uninteresting names may be left blank), and (b) assigns them-to journal entry fields if you use any of these standard field names:-'date', 'date2', 'status', 'code', 'description', 'comment', 'account1',-'account2', 'amount', 'amount-in', 'amount-out', 'currency', 'balance'.-Eg:--# use the 1st, 2nd and 4th CSV fields as the entry's date, description and amount,-# and give the 7th and 8th fields meaningful names for later reference:-#-# CSV field:-#      1     2            3 4       5 6 7          8-# entry field:-fields date, description, , amount, , , somefield, anotherfield---File: hledger_csv.5.info,  Node: field assignment,  Next: conditional block,  Prev: field list,  Up: CSV RULES--1.4 field assignment-====================--_'ENTRYFIELDNAME'_ _'FIELDVALUE'_--   This sets a journal entry field (one of the standard names above) to-the given text value, which can include CSV field values interpolated by-name ('%CSVFIELDNAME') or 1-based position ('%N').  Eg:--# set the amount to the 4th CSV field with "USD " prepended-amount USD %4--# combine three fields to make a comment (containing two tags)-comment note: %somefield - %anotherfield, date: %1--   Field assignments can be used instead of or in addition to a field-list.---File: hledger_csv.5.info,  Node: conditional block,  Next: include,  Prev: field assignment,  Up: CSV RULES--1.5 conditional block-=====================--'if' _'PATTERN'_-    _'FIELDASSIGNMENTS'_...--   'if'-_'PATTERN'_-_'PATTERN'_...-    _'FIELDASSIGNMENTS'_...--   This applies one or more field assignments, only to those CSV records-matched by one of the PATTERNs.  The patterns are case-insensitive-regular expressions which match anywhere within the whole CSV record-(it's not yet possible to match within a specific field).  When there-are multiple patterns they can be written on separate lines, unindented.-The field assignments are on separate lines indented by at least one-space.  Examples:--# if the CSV record contains "groceries", set account2 to "expenses:groceries"-if groceries- account2 expenses:groceries--# if the CSV record contains any of these patterns, set account2 and comment as shown-if-monthly service fee-atm transaction fee-banking thru software- account2 expenses:business:banking- comment  XXX deductible ? check it---File: hledger_csv.5.info,  Node: include,  Next: newest-first,  Prev: conditional block,  Up: CSV RULES--1.6 include-===========--'include'_'RULESFILE'_--   Include another rules file at this point.  'RULESFILE' is either an-absolute file path or a path relative to the current file's directory.-Eg:--# rules reused with several CSV files-include common.rules---File: hledger_csv.5.info,  Node: newest-first,  Prev: include,  Up: CSV RULES--1.7 newest-first-================--'newest-first'--   Consider adding this rule if all of the following are true: you might-be processing just one day of data, your CSV records are in reverse-chronological order (newest first), and you care about preserving the-order of same-day transactions.  It usually isn't needed, because-hledger autodetects the CSV order, but when all CSV records have the-same date it will assume they are oldest first.---File: hledger_csv.5.info,  Node: CSV TIPS,  Prev: CSV RULES,  Up: Top--2 CSV TIPS-**********--* Menu:--* CSV ordering::-* CSV accounts::-* CSV amounts::-* CSV balance assertions::-* Reading multiple CSV files::---File: hledger_csv.5.info,  Node: CSV ordering,  Next: CSV accounts,  Up: CSV TIPS--2.1 CSV ordering-================--The generated journal entries will be sorted by date.  The order of-same-day entries will be preserved (except in the special case where you-might need 'newest-first', see above).---File: hledger_csv.5.info,  Node: CSV accounts,  Next: CSV amounts,  Prev: CSV ordering,  Up: CSV TIPS--2.2 CSV accounts-================--Each journal entry will have two postings, to 'account1' and 'account2'-respectively.  It's not yet possible to generate entries with more than-two postings.  It's conventional and recommended to use 'account1' for-the account whose CSV we are reading.---File: hledger_csv.5.info,  Node: CSV amounts,  Next: CSV balance assertions,  Prev: CSV accounts,  Up: CSV TIPS--2.3 CSV amounts-===============--The 'amount' field sets the amount of the 'account1' posting.--   If the CSV has debit/credit amounts in separate fields, assign to the-'amount-in' and 'amount-out' pseudo fields instead.  (Whichever one has-a value will be used, with appropriate sign.  If both contain a value,-it may not work so well.)--   If an amount value is parenthesised, it will be de-parenthesised and-sign-flipped.--   If an amount value begins with a double minus sign, those will cancel-out and be removed.--   If the CSV has the currency symbol in a separate field, assign that-to the 'currency' pseudo field to have it prepended to the amount.  Or,-you can use a field assignment to 'amount' that interpolates both CSV-fields (giving more control, eg to put the currency symbol on the-right).---File: hledger_csv.5.info,  Node: CSV balance assertions,  Next: Reading multiple CSV files,  Prev: CSV amounts,  Up: CSV TIPS--2.4 CSV balance assertions-==========================--If the CSV includes a running balance, you can assign that to the-'balance' pseudo field; whenever the running balance value is non-empty,-it will be asserted as the balance after the 'account1' posting.---File: hledger_csv.5.info,  Node: Reading multiple CSV files,  Prev: CSV balance assertions,  Up: CSV TIPS--2.5 Reading multiple CSV files-==============================--You can read multiple CSV files at once using multiple '-f' arguments on-the command line, and hledger will look for a correspondingly-named-rules file for each.  Note if you use the '--rules-file' option, this-one rules file will be used for all the CSV files being read.---Tag Table:-Node: Top74-Node: CSV RULES810-Ref: #csv-rules920-Node: skip1182-Ref: #skip1278-Node: date-format1450-Ref: #date-format1579-Node: field list2085-Ref: #field-list2224-Node: field assignment2929-Ref: #field-assignment3086-Node: conditional block3590-Ref: #conditional-block3746-Node: include4642-Ref: #include4774-Node: newest-first5005-Ref: #newest-first5121-Node: CSV TIPS5532-Ref: #csv-tips5628-Node: CSV ordering5746-Ref: #csv-ordering5866-Node: CSV accounts6047-Ref: #csv-accounts6187-Node: CSV amounts6441-Ref: #csv-amounts6589-Node: CSV balance assertions7364-Ref: #csv-balance-assertions7548-Node: Reading multiple CSV files7753-Ref: #reading-multiple-csv-files7925--End Tag Table
− doc/hledger_csv.5.txt
@@ -1,203 +0,0 @@--hledger_csv(5)               hledger User Manuals               hledger_csv(5)----NAME-       CSV - how hledger reads CSV data, and the CSV rules file format--DESCRIPTION-       hledger  can  read CSV files, converting each CSV record into a journal-       entry (transaction), if you provide some conversion hints in  a  "rules-       file".   This file should be named like the CSV file with an additional-       .rules suffix (eg: mybank.csv.rules); or, you can specify the file with-       --rules-file PATH.   hledger  will  create  it  if necessary, with some-       default rules which you'll need to adjust.  At minimum, the rules  file-       must specify the date and amount fields.  For an example, see Cookbook:-       convert CSV files.--       To learn about exporting CSV, see CSV output.--CSV RULES-       The following seven kinds of rule can appear in the rules file, in  any-       order.  Blank lines and lines beginning with # or ; are ignored.--   skip-       skipN--       Skip  this  number  of  CSV records at the beginning.  You'll need this-       whenever your CSV data contains header lines.  Eg:--              # ignore the first CSV line-              skip 1--   date-format-       date-formatDATEFMT--       When your CSV  date  fields  are  not  formatted  like  YYYY/MM/DD  (or-       YYYY-MM-DD  or YYYY.MM.DD), you'll need to specify the format.  DATEFMT-       is a strptime-like date parsing pattern,  which  must  parse  the  date-       field values completely.  Examples:--              # for dates like "6/11/2013":-              date-format %-d/%-m/%Y--              # for dates like "11/06/2013":-              date-format %m/%d/%Y--              # for dates like "2013-Nov-06":-              date-format %Y-%h-%d--              # for dates like "11/6/2013 11:32 PM":-              date-format %-m/%-d/%Y %l:%M %p--   field list-       fieldsFIELDNAME1, FIELDNAME2...--       This  (a)  names the CSV fields, in order (names may not contain white--       space; uninteresting names may be left blank), and (b) assigns them  to-       journal  entry  fields  if  you  use any of these standard field names:-       date, date2, status, code, description,  comment,  account1,  account2,-       amount, amount-in, amount-out, currency, balance.  Eg:--              # use the 1st, 2nd and 4th CSV fields as the entry's date, description and amount,-              # and give the 7th and 8th fields meaningful names for later reference:-              #-              # CSV field:-              #      1     2            3 4       5 6 7          8-              # entry field:-              fields date, description, , amount, , , somefield, anotherfield--   field assignment-       ENTRYFIELDNAME FIELDVALUE--       This  sets  a  journal entry field (one of the standard names above) to-       the given text value, which can include CSV field  values  interpolated-       by name (%CSVFIELDNAME) or 1-based position (%N).-        Eg:--              # set the amount to the 4th CSV field with "USD " prepended-              amount USD %4--              # combine three fields to make a comment (containing two tags)-              comment note: %somefield - %anotherfield, date: %1--       Field  assignments  can  be  used  instead of or in addition to a field-       list.--   conditional block-       if PATTERN-           FIELDASSIGNMENTS...--       if-       PATTERN-       PATTERN...-           FIELDASSIGNMENTS...--       This applies one or more field assignments, only to those  CSV  records-       matched by one of the PATTERNs.  The patterns are case-insensitive reg--       ular expressions which match anywhere within the whole CSV record (it's-       not  yet  possible  to  match within a specific field).  When there are-       multiple patterns they can be written on  separate  lines,  unindented.-       The  field  assignments  are on separate lines indented by at least one-       space.  Examples:--              # if the CSV record contains "groceries", set account2 to "expenses:groceries"-              if groceries-               account2 expenses:groceries--              # if the CSV record contains any of these patterns, set account2 and comment as shown-              if-              monthly service fee-              atm transaction fee-              banking thru software-               account2 expenses:business:banking-               comment  XXX deductible ? check it--   include-       includeRULESFILE--       Include another rules file at this point.  RULESFILE is either an abso--       lute file path or a path relative to the current file's directory.  Eg:--              # rules reused with several CSV files-              include common.rules--   newest-first-       newest-first--       Consider adding this rule if all of the following are true:  you  might-       be  processing  just  one  day of data, your CSV records are in reverse-       chronological order (newest first), and you care about  preserving  the-       order  of  same-day  transactions.   It  usually  isn't needed, because-       hledger autodetects the CSV order, but when all CSV  records  have  the-       same date it will assume they are oldest first.--CSV TIPS-   CSV ordering-       The  generated  journal  entries  will be sorted by date.  The order of-       same-day entries will be preserved (except in the  special  case  where-       you might need newest-first, see above).--   CSV accounts-       Each  journal  entry  will  have two postings, to account1 and account2-       respectively.  It's not yet possible to generate entries with more than-       two  postings.   It's  conventional and recommended to use account1 for-       the account whose CSV we are reading.--   CSV amounts-       The amount field sets the amount of the account1 posting.--       If the CSV has debit/credit amounts in separate fields, assign  to  the-       amount-in  and  amount-out pseudo fields instead.  (Whichever one has a-       value will be used, with appropriate sign.  If both contain a value, it-       may not work so well.)--       If  an  amount  value is parenthesised, it will be de-parenthesised and-       sign-flipped.--       If an amount value begins with a double minus sign, those  will  cancel-       out and be removed.--       If  the CSV has the currency symbol in a separate field, assign that to-       the currency pseudo field to have it prepended to the amount.  Or,  you-       can  use a field assignment to amount that interpolates both CSV fields-       (giving more control, eg to put the currency symbol on the right).--   CSV balance assertions-       If the CSV includes a running balance, you can assign that to the  bal--       ance  pseudo field; whenever the running balance value is non-empty, it-       will be asserted as the balance after the account1 posting.--   Reading multiple CSV files-       You can read multiple CSV files at once using multiple -f arguments  on-       the  command  line,  and  hledger will look for a correspondingly-named-       rules file for each.  Note if you use the --rules-file option, this one-       rules file will be used for all the CSV files being read.----REPORTING BUGS-       Report  bugs at http://bugs.hledger.org (or on the #hledger IRC channel-       or hledger mail list)---AUTHORS-       Simon Michael <simon@joyful.com> and contributors---COPYRIGHT-       Copyright (C) 2007-2016 Simon Michael.-       Released under GNU GPL v3 or later.---SEE ALSO-       hledger(1),     hledger-ui(1),     hledger-web(1),      hledger-api(1),-       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time--       dot(5), ledger(1)--       http://hledger.org----hledger 1.4                     September 2017                  hledger_csv(5)
− doc/hledger_journal.5
@@ -1,1153 +0,0 @@-.\"t--.TH "hledger_journal" "5" "September 2017" "hledger 1.4" "hledger User Manuals"----.SH NAME-.PP-Journal \- hledger\[aq]s default file format, representing a General-Journal-.SH DESCRIPTION-.PP-hledger\[aq]s usual data source is a plain text file containing journal-entries in hledger journal format.-This file represents a standard accounting general journal.-I use file names ending in \f[C]\&.journal\f[], but that\[aq]s not-required.-The journal file contains a number of transaction entries, each-describing a transfer of money (or any commodity) between two or more-named accounts, in a simple format readable by both hledger and humans.-.PP-hledger\[aq]s journal format is a compatible subset, mostly, of-ledger\[aq]s journal format, so hledger can work with compatible ledger-journal files as well.-It\[aq]s safe, and encouraged, to run both hledger and ledger on the-same journal file, eg to validate the results you\[aq]re getting.-.PP-You can use hledger without learning any more about this file; just use-the add or web commands to create and update it.-Many users, though, also edit the journal file directly with a text-editor, perhaps assisted by the helper modes for emacs or vim.-.PP-Here\[aq]s an example:-.IP-.nf-\f[C]-;\ A\ sample\ journal\ file.\ This\ is\ a\ comment.--2008/01/01\ income\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ transaction\[aq]s\ first\ line\ starts\ in\ column\ 0,\ contains\ date\ and\ description-\ \ \ \ assets:bank:checking\ \ $1\ \ \ \ ;\ <\-\ posting\ lines\ start\ with\ whitespace,\ each\ contains\ an\ account\ name-\ \ \ \ income:salary\ \ \ \ \ \ \ \ $\-1\ \ \ \ ;\ \ \ \ followed\ by\ at\ least\ two\ spaces\ and\ an\ amount--2008/06/01\ gift-\ \ \ \ assets:bank:checking\ \ $1\ \ \ \ ;\ <\-\ at\ least\ two\ postings\ in\ a\ transaction-\ \ \ \ income:gifts\ \ \ \ \ \ \ \ \ $\-1\ \ \ \ ;\ <\-\ their\ amounts\ must\ balance\ to\ 0--2008/06/02\ save-\ \ \ \ assets:bank:saving\ \ \ \ $1-\ \ \ \ assets:bank:checking\ \ \ \ \ \ \ \ ;\ <\-\ one\ amount\ may\ be\ omitted;\ here\ $\-1\ is\ inferred--2008/06/03\ eat\ &\ shop\ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ description\ can\ be\ anything-\ \ \ \ expenses:food\ \ \ \ \ \ \ \ \ $1-\ \ \ \ expenses:supplies\ \ \ \ \ $1\ \ \ \ ;\ <\-\ this\ transaction\ debits\ two\ expense\ accounts-\ \ \ \ assets:cash\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ $\-2\ inferred--2008/10/01\ take\ a\ loan-\ \ \ \ assets:bank:checking\ \ $1-\ \ \ \ liabilities:debts\ \ \ \ $\-1--2008/12/31\ *\ pay\ off\ \ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ an\ optional\ *\ or\ !\ after\ the\ date\ means\ "cleared"\ (or\ anything\ you\ want)-\ \ \ \ liabilities:debts\ \ \ \ \ $1-\ \ \ \ assets:bank:checking-\f[]-.fi-.SH FILE FORMAT-.SS Transactions-.PP-Transactions are movements of some quantity of commodities between named-accounts.-Each transaction is represented by a journal entry beginning with a-simple date in column 0.-This can be followed by any of the following, separated by spaces:-.IP \[bu] 2-(optional) a status character (empty, \f[C]!\f[], or \f[C]*\f[])-.IP \[bu] 2-(optional) a transaction code (any short number or text, enclosed in-parentheses)-.IP \[bu] 2-(optional) a transaction description (any remaining text until end of-line or a semicolon)-.IP \[bu] 2-(optional) a transaction comment (any remaining text following a-semicolon until end of line)-.PP-Then comes zero or more (but usually at least 2) indented lines-representing...-.SS Postings-.PP-A posting is an addition of some amount to, or removal of some amount-from, an account.-Each posting line begins with at least one space or tab (2 or 4 spaces-is common), followed by:-.IP \[bu] 2-(optional) a status character (empty, \f[C]!\f[], or \f[C]*\f[]),-followed by a space-.IP \[bu] 2-(required) an account name (any text, optionally containing \f[B]single-spaces\f[], until end of line or a double space)-.IP \[bu] 2-(optional) \f[B]two or more spaces\f[] or tabs followed by an amount.-.PP-Positive amounts are being added to the account, negative amounts are-being removed.-.PP-The amounts within a transaction must always sum up to zero.-As a convenience, one amount may be left blank; it will be inferred so-as to balance the transaction.-.PP-Be sure to note the unusual two\-space delimiter between account name-and amount.-This makes it easy to write account names containing spaces.-But if you accidentally leave only one space (or tab) before the amount,-the amount will be considered part of the account name.-.SS Dates-.SS Simple dates-.PP-Within a journal file, transaction dates use Y/M/D (or Y\-M\-D or Y.M.D)-Leading zeros are optional.-The year may be omitted, in which case it will be inferred from the-context \- the current transaction, the default year set with a default-year directive, or the current date when the command is run.-Some examples: \f[C]2010/01/31\f[], \f[C]1/31\f[],-\f[C]2010\-01\-31\f[], \f[C]2010.1.31\f[].-.SS Secondary dates-.PP-Real\-life transactions sometimes involve more than one date \- eg the-date you write a cheque, and the date it clears in your bank.-When you want to model this, eg for more accurate balances, you can-specify individual posting dates, which I recommend.-Or, you can use the secondary dates (aka auxiliary/effective dates)-feature, supported for compatibility with Ledger.-.PP-A secondary date can be written after the primary date, separated by an-equals sign.-The primary date, on the left, is used by default; the secondary date,-on the right, is used when the \f[C]\-\-date2\f[] flag is specified-(\f[C]\-\-aux\-date\f[] or \f[C]\-\-effective\f[] also work).-.PP-The meaning of secondary dates is up to you, but it\[aq]s best to follow-a consistent rule.-Eg write the bank\[aq]s clearing date as primary, and when needed, the-date the transaction was initiated as secondary.-.PP-Here\[aq]s an example.-Note that a secondary date will use the year of the primary date if-unspecified.-.IP-.nf-\f[C]-2010/2/23=2/19\ movie\ ticket-\ \ expenses:cinema\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $10-\ \ assets:checking-\f[]-.fi-.IP-.nf-\f[C]-$\ hledger\ register\ checking-2010/02/23\ movie\ ticket\ \ \ \ \ \ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10\ \ \ \ \ \ \ \ \ $\-10-\f[]-.fi-.IP-.nf-\f[C]-$\ hledger\ register\ checking\ \-\-date2-2010/02/19\ movie\ ticket\ \ \ \ \ \ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10\ \ \ \ \ \ \ \ \ $\-10-\f[]-.fi-.PP-Secondary dates require some effort; you must use them consistently in-your journal entries and remember whether to use or not use the-\f[C]\-\-date2\f[] flag for your reports.-They are included in hledger for Ledger compatibility, but posting dates-are a more powerful and less confusing alternative.-.SS Posting dates-.PP-You can give individual postings a different date from their parent-transaction, by adding a posting comment containing a tag (see below)-like \f[C]date:DATE\f[].-This is probably the best way to control posting dates precisely.-Eg in this example the expense should appear in May reports, and the-deduction from checking should be reported on 6/1 for easy bank-reconciliation:-.IP-.nf-\f[C]-2015/5/30-\ \ \ \ expenses:food\ \ \ \ \ $10\ \ \ ;\ food\ purchased\ on\ saturday\ 5/30-\ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ ;\ bank\ cleared\ it\ on\ monday,\ date:6/1-\f[]-.fi-.IP-.nf-\f[C]-$\ hledger\ \-f\ t.j\ register\ food-2015/05/30\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ expenses:food\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $10\ \ \ \ \ \ \ \ \ \ \ $10-\f[]-.fi-.IP-.nf-\f[C]-$\ hledger\ \-f\ t.j\ register\ checking-2015/06/01\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10\ \ \ \ \ \ \ \ \ \ $\-10-\f[]-.fi-.PP-DATE should be a simple date; if the year is not specified it will use-the year of the transaction\[aq]s date.-You can set the secondary date similarly, with \f[C]date2:DATE2\f[].-The \f[C]date:\f[] or \f[C]date2:\f[] tags must have a valid simple date-value if they are present, eg a \f[C]date:\f[] tag with no value is not-allowed.-.PP-Ledger\[aq]s earlier, more compact bracketed date syntax is also-supported: \f[C][DATE]\f[], \f[C][DATE=DATE2]\f[] or \f[C][=DATE2]\f[].-hledger will attempt to parse any square\-bracketed sequence of the-\f[C]0123456789/\-.=\f[] characters in this way.-With this syntax, DATE infers its year from the transaction and DATE2-infers its year from DATE.-.SS Status-.PP-Transactions, or individual postings within a transaction, can have a-status mark, which is a single character before the transaction-description or posting account name, separated from it by a space,-indicating one of three statuses:-.PP-.TS-tab(@);-l l.-T{-mark \ -T}@T{-status-T}-_-T{-\ -T}@T{-unmarked-T}-T{-\f[C]!\f[]-T}@T{-pending-T}-T{-\f[C]*\f[]-T}@T{-cleared-T}-.TE-.PP-When reporting, you can filter by status with the-\f[C]\-U/\-\-unmarked\f[], \f[C]\-P/\-\-pending\f[], and-\f[C]\-C/\-\-cleared\f[] flags; or the \f[C]status:\f[],-\f[C]status:!\f[], and \f[C]status:*\f[] queries; or the U, P, C keys in-hledger\-ui.-.PP-Note, in Ledger and in older versions of hledger, the "unmarked" state-is called "uncleared".-As of hledger 1.3 we have renamed it to unmarked for clarity.-.PP-To replicate Ledger and old hledger\[aq]s behaviour of also matching-pending, combine \-U and \-P.-.PP-Status marks are optional, but can be helpful eg for reconciling with-real\-world accounts.-Some editor modes provide highlighting and shortcuts for working with-status.-Eg in Emacs ledger\-mode, you can toggle transaction status with C\-c-C\-e, or posting status with C\-c C\-c.-.PP-What "uncleared", "pending", and "cleared" actually mean is up to you.-Here\[aq]s one suggestion:-.PP-.TS-tab(@);-lw(10.5n) lw(59.5n).-T{-status-T}@T{-meaning-T}-_-T{-uncleared-T}@T{-recorded but not yet reconciled; needs review-T}-T{-pending-T}@T{-tentatively reconciled (if needed, eg during a big reconciliation)-T}-T{-cleared-T}@T{-complete, reconciled as far as possible, and considered correct-T}-.TE-.PP-With this scheme, you would use \f[C]\-PC\f[] to see the current balance-at your bank, \f[C]\-U\f[] to see things which will probably hit your-bank soon (like uncashed checks), and no flags to see the most-up\-to\-date state of your finances.-.SS Description-.PP-A transaction\[aq]s description is the rest of the line following the-date and status mark (or until a comment begins).-Sometimes called the "narration" in traditional bookkeeping, it can be-used for whatever you wish, or left blank.-Transaction descriptions can be queried, unlike comments.-.SS Payee and note-.PP-You can optionally include a \f[C]|\f[] (pipe) character in a-description to subdivide it into a payee/payer name on the left and-additional notes on the right.-This may be worthwhile if you need to do more precise querying and-pivoting by payee.-.SS Account names-.PP-Account names typically have several parts separated by a full colon,-from which hledger derives a hierarchical chart of accounts.-They can be anything you like, but in finance there are traditionally-five top\-level accounts: \f[C]assets\f[], \f[C]liabilities\f[],-\f[C]income\f[], \f[C]expenses\f[], and \f[C]equity\f[].-.PP-Account names may contain single spaces, eg:-\f[C]assets:accounts\ receivable\f[].-Because of this, they must always be followed by \f[B]two or more-spaces\f[] (or newline).-.PP-Account names can be aliased.-.SS Amounts-.PP-After the account name, there is usually an amount.-Important: between account name and amount, there must be \f[B]two or-more spaces\f[].-.PP-Amounts consist of a number and (usually) a currency symbol or commodity-name.-Some examples:-.PP-\f[C]2.00001\f[]-.PD 0-.P-.PD-\f[C]$1\f[]-.PD 0-.P-.PD-\f[C]4000\ AAPL\f[]-.PD 0-.P-.PD-\f[C]3\ "green\ apples"\f[]-.PD 0-.P-.PD-\f[C]\-$1,000,000.00\f[]-.PD 0-.P-.PD-\f[C]INR\ 9,99,99,999.00\f[]-.PD 0-.P-.PD-\f[C]EUR\ \-2.000.000,00\f[]-.PP-As you can see, the amount format is somewhat flexible:-.IP \[bu] 2-amounts are a number (the "quantity") and optionally a currency-symbol/commodity name (the "commodity").-.IP \[bu] 2-the commodity is a symbol, word, or phrase, on the left or right, with-or without a separating space.-If the commodity contains numbers, spaces or non\-word punctuation it-must be enclosed in double quotes.-.IP \[bu] 2-negative amounts with a commodity on the left can have the minus sign-before or after it-.IP \[bu] 2-digit groups (thousands, or any other grouping) can be separated by-commas (in which case period is used for decimal point) or periods (in-which case comma is used for decimal point)-.PP-You can use any of these variations when recording data, but when-hledger displays amounts, it will choose a consistent format for each-commodity.-(Except for price amounts, which are always formatted as written).-The display format is chosen as follows:-.IP \[bu] 2-if there is a commodity directive specifying the format, that is used-.IP \[bu] 2-otherwise the format is inferred from the first posting amount in that-commodity in the journal, and the precision (number of decimal places)-will be the maximum from all posting amounts in that commmodity-.IP \[bu] 2-or if there are no such amounts in the journal, a default format is used-(like \f[C]$1000.00\f[]).-.PP-Price amounts and amounts in D directives usually don\[aq]t affect-amount format inference, but in some situations they can do so-indirectly.-(Eg when D\[aq]s default commodity is applied to a commodity\-less-amount, or when an amountless posting is balanced using a price\[aq]s-commodity, or when \-V is used.) If you find this causing problems, set-the desired format with a commodity directive.-.SS Virtual Postings-.PP-When you parenthesise the account name in a posting, we call that a-\f[I]virtual posting\f[], which means:-.IP \[bu] 2-it is ignored when checking that the transaction is balanced-.IP \[bu] 2-it is excluded from reports when the \f[C]\-\-real/\-R\f[] flag is used,-or the \f[C]real:1\f[] query.-.PP-You could use this, eg, to set an account\[aq]s opening balance without-needing to use the \f[C]equity:opening\ balances\f[] account:-.IP-.nf-\f[C]-1/1\ special\ unbalanced\ posting\ to\ set\ initial\ balance-\ \ (assets:checking)\ \ \ $1000-\f[]-.fi-.PP-When the account name is bracketed, we call it a \f[I]balanced virtual-posting\f[].-This is like an ordinary virtual posting except the balanced virtual-postings in a transaction must balance to 0, like the real postings (but-separately from them).-Balanced virtual postings are also excluded by \f[C]\-\-real/\-R\f[] or-\f[C]real:1\f[].-.IP-.nf-\f[C]-1/1\ buy\ food\ with\ cash,\ and\ update\ some\ budget\-tracking\ subaccounts\ elsewhere-\ \ expenses:food\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $10-\ \ assets:cash\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10-\ \ [assets:checking:available]\ \ \ \ \ $10-\ \ [assets:checking:budget:food]\ \ $\-10-\f[]-.fi-.PP-Virtual postings have some legitimate uses, but those are few.-You can usually find an equivalent journal entry using real postings,-which is more correct and provides better error checking.-.SS Balance Assertions-.PP-hledger supports Ledger\-style balance assertions in journal files.-These look like \f[C]=EXPECTEDBALANCE\f[] following a posting\[aq]s-amount.-Eg in this example we assert the expected dollar balance in accounts a-and b after each posting:-.IP-.nf-\f[C]-2013/1/1-\ \ a\ \ \ $1\ \ =$1-\ \ b\ \ \ \ \ \ \ =$\-1--2013/1/2-\ \ a\ \ \ $1\ \ =$2-\ \ b\ \ $\-1\ \ =$\-2-\f[]-.fi-.PP-After reading a journal file, hledger will check all balance assertions-and report an error if any of them fail.-Balance assertions can protect you from, eg, inadvertently disrupting-reconciled balances while cleaning up old entries.-You can disable them temporarily with the-\f[C]\-\-ignore\-assertions\f[] flag, which can be useful for-troubleshooting or for reading Ledger files.-.SS Assertions and ordering-.PP-hledger sorts an account\[aq]s postings and assertions first by date and-then (for postings on the same day) by parse order.-Note this is different from Ledger, which sorts assertions only by parse-order.-(Also, Ledger assertions do not see the accumulated effect of repeated-postings to the same account within a transaction.)-.PP-So, hledger balance assertions keep working if you reorder-differently\-dated transactions within the journal.-But if you reorder same\-dated transactions or postings, assertions-might break and require updating.-This order dependence does bring an advantage: precise control over the-order of postings and assertions within a day, so you can assert-intra\-day balances.-.SS Assertions and included files-.PP-With included files, things are a little more complicated.-Including preserves the ordering of postings and assertions.-If you have multiple postings to an account on the same day, split-across different files, and you also want to assert the account\[aq]s-balance on the same day, you\[aq]ll have to put the assertion in the-right file.-.SS Assertions and multiple \-f options-.PP-Balance assertions don\[aq]t work well across files specified with-multiple \-f options.-Use include or concatenate the files instead.-.SS Assertions and commodities-.PP-The asserted balance must be a simple single\-commodity amount, and in-fact the assertion checks only this commodity\[aq]s balance within the-(possibly multi\-commodity) account balance.-We could call this a partial balance assertion.-This is compatible with Ledger, and makes it possible to make assertions-about accounts containing multiple commodities.-.PP-To assert each commodity\[aq]s balance in such a multi\-commodity-account, you can add multiple postings (with amount 0 if necessary).-But note that no matter how many assertions you add, you can\[aq]t be-sure the account does not contain some unexpected commodity.-(We\[aq]ll add support for this kind of total balance assertion if-there\[aq]s demand.)-.SS Assertions and subaccounts-.PP-Balance assertions do not count the balance from subaccounts; they check-the posted account\[aq]s exclusive balance.-For example:-.IP-.nf-\f[C]-1/1-\ \ checking:fund\ \ \ 1\ =\ 1\ \ ;\ post\ to\ this\ subaccount,\ its\ balance\ is\ now\ 1-\ \ checking\ \ \ \ \ \ \ \ 1\ =\ 1\ \ ;\ post\ to\ the\ parent\ account,\ its\ exclusive\ balance\ is\ now\ 1-\ \ equity-\f[]-.fi-.PP-The balance report\[aq]s flat mode shows these exclusive balances more-clearly:-.IP-.nf-\f[C]-$\ hledger\ bal\ checking\ \-\-flat-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 1\ \ checking-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 1\ \ checking:fund-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 2-\f[]-.fi-.SS Assertions and virtual postings-.PP-Balance assertions are checked against all postings, both real and-virtual.-They are not affected by the \f[C]\-\-real/\-R\f[] flag or-\f[C]real:\f[] query.-.SS Balance Assignments-.PP-Ledger\-style balance assignments are also supported.-These are like balance assertions, but with no posting amount on the-left side of the equals sign; instead it is calculated automatically so-as to satisfy the assertion.-This can be a convenience during data entry, eg when setting opening-balances:-.IP-.nf-\f[C]-;\ starting\ a\ new\ journal,\ set\ asset\ account\ balances\ -2016/1/1\ opening\ balances-\ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ =\ $409.32-\ \ assets:savings\ \ \ \ \ \ \ \ \ \ \ \ \ =\ $735.24-\ \ assets:cash\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ $42-\ \ equity:opening\ balances-\f[]-.fi-.PP-or when adjusting a balance to reality:-.IP-.nf-\f[C]-;\ no\ cash\ left;\ update\ balance,\ record\ any\ untracked\ spending\ as\ a\ generic\ expense-2016/1/15-\ \ assets:cash\ \ \ \ =\ $0-\ \ expenses:misc-\f[]-.fi-.PP-The calculated amount depends on the account\[aq]s balance in the-commodity at that point (which depends on the previously\-dated postings-of the commodity to that account since the last balance assertion or-assignment).-Note that using balance assignments makes your journal a little less-explicit; to know the exact amount posted, you have to run hledger or do-the calculations yourself, instead of just reading it.-.SS Prices-.SS Transaction prices-.PP-Within a transaction, you can note an amount\[aq]s price in another-commodity.-This can be used to document the cost (in a purchase) or selling price-(in a sale).-For example, transaction prices are useful to record purchases of a-foreign currency.-.PP-Transaction prices are fixed, and do not change over time.-(Ledger users: Ledger uses a different syntax for fixed prices,-\f[C]{=UNITPRICE}\f[], which hledger currently ignores).-.PP-There are several ways to record a transaction price:-.IP "1." 3-Write the price per unit, as \f[C]\@\ UNITPRICE\f[] after the amount:-.RS 4-.IP-.nf-\f[C]-2009/1/1-\ \ assets:euros\ \ \ \ \ €100\ \@\ $1.35\ \ ;\ one\ hundred\ euros\ purchased\ at\ $1.35\ each-\ \ assets:dollars\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ balancing\ amount\ is\ \-$135.00-\f[]-.fi-.RE-.IP "2." 3-Write the total price, as \f[C]\@\@\ TOTALPRICE\f[] after the amount:-.RS 4-.IP-.nf-\f[C]-2009/1/1-\ \ assets:euros\ \ \ \ \ €100\ \@\@\ $135\ \ ;\ one\ hundred\ euros\ purchased\ at\ $135\ for\ the\ lot-\ \ assets:dollars-\f[]-.fi-.RE-.IP "3." 3-Specify amounts for all postings, using exactly two commodities, and let-hledger infer the price that balances the transaction:-.RS 4-.IP-.nf-\f[C]-2009/1/1-\ \ assets:euros\ \ \ \ \ €100\ \ \ \ \ \ \ \ \ \ ;\ one\ hundred\ euros\ purchased-\ \ assets:dollars\ \ $\-135\ \ \ \ \ \ \ \ \ \ ;\ for\ $135-\f[]-.fi-.RE-.PP-Amounts with transaction prices can be displayed in the transaction-price\[aq]s commodity by using the \f[C]\-B/\-\-cost\f[] flag (except-for #551) ("B" is from "cost Basis").-Eg for the above, here is how \-B affects the balance report:-.IP-.nf-\f[C]-$\ hledger\ bal\ \-N\ \-\-flat-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-135\ \ assets:dollars-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ €100\ \ assets:euros-$\ hledger\ bal\ \-N\ \-\-flat\ \-B-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-135\ \ assets:dollars-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $135\ \ assets:euros\ \ \ \ #\ <\-\ the\ euros\[aq]\ cost-\f[]-.fi-.PP-Note \-B is sensitive to the order of postings when a transaction price-is inferred: the inferred price will be in the commodity of the last-amount.-So if example 3\[aq]s postings are reversed, while the transaction is-equivalent, \-B shows something different:-.IP-.nf-\f[C]-2009/1/1-\ \ assets:dollars\ \ $\-135\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ 135\ dollars\ sold-\ \ assets:euros\ \ \ \ \ €100\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ for\ 100\ euros-\f[]-.fi-.IP-.nf-\f[C]-$\ hledger\ bal\ \-N\ \-\-flat\ \-B-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ €\-100\ \ assets:dollars\ \ #\ <\-\ the\ dollars\[aq]\ selling\ price-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ €100\ \ assets:euros-\f[]-.fi-.SS Market prices-.PP-Market prices are not tied to a particular transaction; they represent-historical exchange rates between two commodities.-(Ledger calls them historical prices.) For example, the prices published-by a stock exchange or the foreign exchange market.-hledger can use these prices to show the market value of things at a-given date, see market value.-.PP-To record market prices, use P directives in the main journal or in an-included file.-Their format is:-.IP-.nf-\f[C]-P\ DATE\ COMMODITYBEINGPRICED\ UNITPRICE-\f[]-.fi-.PP-DATE is a simple date as usual.-COMMODITYBEINGPRICED is the symbol of the commodity being priced.-UNITPRICE is an ordinary amount (symbol and quantity) in a second-commodity, specifying the unit price or conversion rate for the first-commodity in terms of the second, on the given date.-.PP-For example, the following directives say that one euro was worth 1.35-US dollars during 2009, and $1.40 from 2010 onward:-.IP-.nf-\f[C]-P\ 2009/1/1\ €\ $1.35-P\ 2010/1/1\ €\ $1.40-\f[]-.fi-.SS Comments-.PP-Lines in the journal beginning with a semicolon (\f[C];\f[]) or hash-(\f[C]#\f[]) or asterisk (\f[C]*\f[]) are comments, and will be ignored.-(Asterisk comments make it easy to treat your journal like an org\-mode-outline in emacs.)-.PP-Also, anything between \f[C]comment\f[] and \f[C]end\ comment\f[]-directives is a (multi\-line) comment.-If there is no \f[C]end\ comment\f[], the comment extends to the end of-the file.-.PP-You can attach comments to a transaction by writing them after the-description and/or indented on the following lines (before the-postings).-Similarly, you can attach comments to an individual posting by writing-them after the amount and/or indented on the following lines.-.PP-Some examples:-.IP-.nf-\f[C]-#\ a\ journal\ comment--;\ also\ a\ journal\ comment--comment-This\ is\ a\ multiline\ comment,-which\ continues\ until\ a\ line-where\ the\ "end\ comment"\ string-appears\ on\ its\ own.-end\ comment--2012/5/14\ something\ \ ;\ a\ transaction\ comment-\ \ \ \ ;\ the\ transaction\ comment,\ continued-\ \ \ \ posting1\ \ 1\ \ ;\ a\ comment\ for\ posting\ 1-\ \ \ \ posting2-\ \ \ \ ;\ a\ comment\ for\ posting\ 2-\ \ \ \ ;\ another\ comment\ line\ for\ posting\ 2-;\ a\ journal\ comment\ (because\ not\ indented)-\f[]-.fi-.SS Tags-.PP-Tags are a way to add extra labels or labelled data to postings and-transactions, which you can then search or pivot on.-.PP-A simple tag is a word (which may contain hyphens) followed by a full-colon, written inside a transaction or posting comment line:-.IP-.nf-\f[C]-2017/1/16\ bought\ groceries\ \ \ \ ;\ sometag:-\f[]-.fi-.PP-Tags can have a value, which is the text after the colon, up to the next-comma or end of line, with leading/trailing whitespace removed:-.IP-.nf-\f[C]-\ \ \ \ expenses:food\ \ \ \ $10\ \ \ ;\ a\-posting\-tag:\ the\ tag\ value-\f[]-.fi-.PP-Note this means hledger\[aq]s tag values can not contain commas or-newlines.-Ending at commas means you can write multiple short tags on one line,-comma separated:-.IP-.nf-\f[C]-\ \ \ \ assets:checking\ \ \ \ \ \ \ ;\ a\ comment\ containing\ tag1:,\ tag2:\ some\ value\ ...-\f[]-.fi-.PP-Here,-.IP \[bu] 2-"\f[C]a\ comment\ containing\f[]" is just comment text, not a tag-.IP \[bu] 2-"\f[C]tag1\f[]" is a tag with no value-.IP \[bu] 2-"\f[C]tag2\f[]" is another tag, whose value is-"\f[C]some\ value\ ...\f[]"-.PP-Tags in a transaction comment affect the transaction and all of its-postings, while tags in a posting comment affect only that posting.-For example, the following transaction has three tags (\f[C]A\f[],-\f[C]TAG2\f[], \f[C]third\-tag\f[]) and the posting has four (those plus-\f[C]posting\-tag\f[]):-.IP-.nf-\f[C]-1/1\ a\ transaction\ \ ;\ A:,\ TAG2:-\ \ \ \ ;\ third\-tag:\ a\ third\ transaction\ tag,\ <\-\ with\ a\ value-\ \ \ \ (a)\ \ $1\ \ ;\ posting\-tag:-\f[]-.fi-.PP-Tags are like Ledger\[aq]s metadata feature, except hledger\[aq]s tag-values are simple strings.-.SS Directives-.SS Account aliases-.PP-You can define aliases which rewrite your account names (after reading-the journal, before generating reports).-hledger\[aq]s account aliases can be useful for:-.IP \[bu] 2-expanding shorthand account names to their full form, allowing easier-data entry and a less verbose journal-.IP \[bu] 2-adapting old journals to your current chart of accounts-.IP \[bu] 2-experimenting with new account organisations, like a new hierarchy or-combining two accounts into one-.IP \[bu] 2-customising reports-.PP-See also Cookbook: rewrite account names.-.SS Basic aliases-.PP-To set an account alias, use the \f[C]alias\f[] directive in your-journal file.-This affects all subsequent journal entries in the current file or its-included files.-The spaces around the = are optional:-.IP-.nf-\f[C]-alias\ OLD\ =\ NEW-\f[]-.fi-.PP-Or, you can use the \f[C]\-\-alias\ \[aq]OLD=NEW\[aq]\f[] option on the-command line.-This affects all entries.-It\[aq]s useful for trying out aliases interactively.-.PP-OLD and NEW are full account names.-hledger will replace any occurrence of the old account name with the new-one.-Subaccounts are also affected.-Eg:-.IP-.nf-\f[C]-alias\ checking\ =\ assets:bank:wells\ fargo:checking-#\ rewrites\ "checking"\ to\ "assets:bank:wells\ fargo:checking",\ or\ "checking:a"\ to\ "assets:bank:wells\ fargo:checking:a"-\f[]-.fi-.SS Regex aliases-.PP-There is also a more powerful variant that uses a regular expression,-indicated by the forward slashes:-.IP-.nf-\f[C]-alias\ /REGEX/\ =\ REPLACEMENT-\f[]-.fi-.PP-or \f[C]\-\-alias\ \[aq]/REGEX/=REPLACEMENT\[aq]\f[].-.PP-REGEX is a case\-insensitive regular expression.-Anywhere it matches inside an account name, the matched part will be-replaced by REPLACEMENT.-If REGEX contains parenthesised match groups, these can be referenced by-the usual numeric backreferences in REPLACEMENT.-Eg:-.IP-.nf-\f[C]-alias\ /^(.+):bank:([^:]+)(.*)/\ =\ \\1:\\2\ \\3-#\ rewrites\ "assets:bank:wells\ fargo:checking"\ to\ \ "assets:wells\ fargo\ checking"-\f[]-.fi-.PP-Also note that REPLACEMENT continues to the end of line (or on command-line, to end of option argument), so it can contain trailing whitespace.-.SS Multiple aliases-.PP-You can define as many aliases as you like using directives or-command\-line options.-Aliases are recursive \- each alias sees the result of applying previous-ones.-(This is different from Ledger, where aliases are non\-recursive by-default).-Aliases are applied in the following order:-.IP "1." 3-alias directives, most recently seen first (recent directives take-precedence over earlier ones; directives not yet seen are ignored)-.IP "2." 3-alias options, in the order they appear on the command line-.SS end aliases-.PP-You can clear (forget) all currently defined aliases with the-\f[C]end\ aliases\f[] directive:-.IP-.nf-\f[C]-end\ aliases-\f[]-.fi-.SS account directive-.PP-The \f[C]account\f[] directive predefines account names, as in Ledger-and Beancount.-This may be useful for your own documentation; hledger doesn\[aq]t make-use of it yet.-.IP-.nf-\f[C]-;\ account\ ACCT-;\ \ \ OPTIONAL\ COMMENTS/TAGS...--account\ assets:bank:checking-\ a\ comment-\ acct\-no:12345--account\ expenses:food--;\ etc.-\f[]-.fi-.SS apply account directive-.PP-You can specify a parent account which will be prepended to all accounts-within a section of the journal.-Use the \f[C]apply\ account\f[] and \f[C]end\ apply\ account\f[]-directives like so:-.IP-.nf-\f[C]-apply\ account\ home--2010/1/1-\ \ \ \ food\ \ \ \ $10-\ \ \ \ cash--end\ apply\ account-\f[]-.fi-.PP-which is equivalent to:-.IP-.nf-\f[C]-2010/01/01-\ \ \ \ home:food\ \ \ \ \ \ \ \ \ \ \ $10-\ \ \ \ home:cash\ \ \ \ \ \ \ \ \ \ $\-10-\f[]-.fi-.PP-If \f[C]end\ apply\ account\f[] is omitted, the effect lasts to the end-of the file.-Included files are also affected, eg:-.IP-.nf-\f[C]-apply\ account\ business-include\ biz.journal-end\ apply\ account-apply\ account\ personal-include\ personal.journal-\f[]-.fi-.PP-Prior to hledger 1.0, legacy \f[C]account\f[] and \f[C]end\f[] spellings-were also supported.-.SS Multi\-line comments-.PP-A line containing just \f[C]comment\f[] starts a multi\-line comment,-and a line containing just \f[C]end\ comment\f[] ends it.-See comments.-.SS commodity directive-.PP-The \f[C]commodity\f[] directive predefines commodities (currently this-is just informational), and also it may define the display format for-amounts in this commodity (overriding the automatically inferred-format).-.PP-It may be written on a single line, like this:-.IP-.nf-\f[C]-;\ commodity\ EXAMPLEAMOUNT--;\ display\ AAAA\ amounts\ with\ the\ symbol\ on\ the\ right,\ space\-separated,-;\ using\ period\ as\ decimal\ point,\ with\ four\ decimal\ places,\ and-;\ separating\ thousands\ with\ comma.-commodity\ 1,000.0000\ AAAA-\f[]-.fi-.PP-or on multiple lines, using the "format" subdirective.-In this case the commodity symbol appears twice and should be the same-in both places:-.IP-.nf-\f[C]-;\ commodity\ SYMBOL-;\ \ \ format\ EXAMPLEAMOUNT--;\ display\ indian\ rupees\ with\ currency\ name\ on\ the\ left,-;\ thousands,\ lakhs\ and\ crores\ comma\-separated,-;\ period\ as\ decimal\ point,\ and\ two\ decimal\ places.-commodity\ INR-\ \ format\ INR\ 9,99,99,999.00-\f[]-.fi-.SS Default commodity-.PP-The D directive sets a default commodity (and display format), to be-used for amounts without a commodity symbol (ie, plain numbers).-(Note this differs from Ledger\[aq]s default commodity directive.) The-commodity and display format will be applied to all subsequent-commodity\-less amounts, or until the next D directive.-.IP-.nf-\f[C]-#\ commodity\-less\ amounts\ should\ be\ treated\ as\ dollars-#\ (and\ displayed\ with\ symbol\ on\ the\ left,\ thousands\ separators\ and\ two\ decimal\ places)-D\ $1,000.00--1/1-\ \ a\ \ \ \ \ 5\ \ \ \ #\ <\-\ commodity\-less\ amount,\ becomes\ $1-\ \ b-\f[]-.fi-.SS Default year-.PP-You can set a default year to be used for subsequent dates which-don\[aq]t specify a year.-This is a line beginning with \f[C]Y\f[] followed by the year.-Eg:-.IP-.nf-\f[C]-Y2009\ \ \ \ \ \ ;\ set\ default\ year\ to\ 2009--12/15\ \ \ \ \ \ ;\ equivalent\ to\ 2009/12/15-\ \ expenses\ \ 1-\ \ assets--Y2010\ \ \ \ \ \ ;\ change\ default\ year\ to\ 2010--2009/1/30\ \ ;\ specifies\ the\ year,\ not\ affected-\ \ expenses\ \ 1-\ \ assets--1/31\ \ \ \ \ \ \ ;\ equivalent\ to\ 2010/1/31-\ \ expenses\ \ 1-\ \ assets-\f[]-.fi-.SS Including other files-.PP-You can pull in the content of additional journal files by writing an-include directive, like this:-.IP-.nf-\f[C]-include\ path/to/file.journal-\f[]-.fi-.PP-If the path does not begin with a slash, it is relative to the current-file.-Glob patterns (\f[C]*\f[]) are not currently supported.-.PP-The \f[C]include\f[] directive can only be used in journal files.-It can include journal, timeclock or timedot files, but not CSV files.-.SH EDITOR SUPPORT-.PP-Add\-on modes exist for various text editors, to make working with-journal files easier.-They add colour, navigation aids and helpful commands.-For hledger users who edit the journal file directly (the majority),-using one of these modes is quite recommended.-.PP-These were written with Ledger in mind, but also work with hledger-files:-.PP-.TS-tab(@);-lw(16.5n) lw(51.5n).-T{-Emacs-T}@T{-http://www.ledger\-cli.org/3.0/doc/ledger\-mode.html-T}-T{-Vim-T}@T{-https://github.com/ledger/ledger/wiki/Getting\-started-T}-T{-Sublime Text-T}@T{-https://github.com/ledger/ledger/wiki/Using\-Sublime\-Text-T}-T{-Textmate-T}@T{-https://github.com/ledger/ledger/wiki/Using\-TextMate\-2-T}-T{-Text Wrangler \ -T}@T{-https://github.com/ledger/ledger/wiki/Editing\-Ledger\-files\-with\-TextWrangler-T}-T{-Visual Studio Code-T}@T{-https://marketplace.visualstudio.com/items?itemName=mark\-hansen.hledger\-vscode-T}-.TE---.SH "REPORTING BUGS"-Report bugs at http://bugs.hledger.org-(or on the #hledger IRC channel or hledger mail list)--.SH AUTHORS-Simon Michael <simon@joyful.com> and contributors--.SH COPYRIGHT--Copyright (C) 2007-2016 Simon Michael.-.br-Released under GNU GPL v3 or later.--.SH SEE ALSO-hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),-hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),-ledger(1)--http://hledger.org
− doc/hledger_journal.5.info
@@ -1,1147 +0,0 @@-This is hledger_journal.5.info, produced by makeinfo version 6.0 from-stdin.---File: hledger_journal.5.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir)--hledger_journal(5) hledger 1.4-******************************--hledger's usual data source is a plain text file containing journal-entries in hledger journal format.  This file represents a standard-accounting general journal.  I use file names ending in '.journal', but-that's not required.  The journal file contains a number of transaction-entries, each describing a transfer of money (or any commodity) between-two or more named accounts, in a simple format readable by both hledger-and humans.--   hledger's journal format is a compatible subset, mostly, of ledger's-journal format, so hledger can work with compatible ledger journal files-as well.  It's safe, and encouraged, to run both hledger and ledger on-the same journal file, eg to validate the results you're getting.--   You can use hledger without learning any more about this file; just-use the add or web commands to create and update it.  Many users,-though, also edit the journal file directly with a text editor, perhaps-assisted by the helper modes for emacs or vim.--   Here's an example:--; A sample journal file. This is a comment.--2008/01/01 income               ; <- transaction's first line starts in column 0, contains date and description-    assets:bank:checking  $1    ; <- posting lines start with whitespace, each contains an account name-    income:salary        $-1    ;    followed by at least two spaces and an amount--2008/06/01 gift-    assets:bank:checking  $1    ; <- at least two postings in a transaction-    income:gifts         $-1    ; <- their amounts must balance to 0--2008/06/02 save-    assets:bank:saving    $1-    assets:bank:checking        ; <- one amount may be omitted; here $-1 is inferred--2008/06/03 eat & shop           ; <- description can be anything-    expenses:food         $1-    expenses:supplies     $1    ; <- this transaction debits two expense accounts-    assets:cash                 ; <- $-2 inferred--2008/10/01 take a loan-    assets:bank:checking  $1-    liabilities:debts    $-1--2008/12/31 * pay off            ; <- an optional * or ! after the date means "cleared" (or anything you want)-    liabilities:debts     $1-    assets:bank:checking--* Menu:--* FILE FORMAT::-* EDITOR SUPPORT::---File: hledger_journal.5.info,  Node: FILE FORMAT,  Next: EDITOR SUPPORT,  Prev: Top,  Up: Top--1 FILE FORMAT-*************--* Menu:--* Transactions::-* Postings::-* Dates::-* Status::-* Description::-* Account names::-* Amounts::-* Virtual Postings::-* Balance Assertions::-* Balance Assignments::-* Prices::-* Comments::-* Tags::-* Directives::---File: hledger_journal.5.info,  Node: Transactions,  Next: Postings,  Up: FILE FORMAT--1.1 Transactions-================--Transactions are movements of some quantity of commodities between named-accounts.  Each transaction is represented by a journal entry beginning-with a simple date in column 0.  This can be followed by any of the-following, separated by spaces:--   * (optional) a status character (empty, '!', or '*')-   * (optional) a transaction code (any short number or text, enclosed-     in parentheses)-   * (optional) a transaction description (any remaining text until end-     of line or a semicolon)-   * (optional) a transaction comment (any remaining text following a-     semicolon until end of line)--   Then comes zero or more (but usually at least 2) indented lines-representing...---File: hledger_journal.5.info,  Node: Postings,  Next: Dates,  Prev: Transactions,  Up: FILE FORMAT--1.2 Postings-============--A posting is an addition of some amount to, or removal of some amount-from, an account.  Each posting line begins with at least one space or-tab (2 or 4 spaces is common), followed by:--   * (optional) a status character (empty, '!', or '*'), followed by a-     space-   * (required) an account name (any text, optionally containing *single-     spaces*, until end of line or a double space)-   * (optional) *two or more spaces* or tabs followed by an amount.--   Positive amounts are being added to the account, negative amounts are-being removed.--   The amounts within a transaction must always sum up to zero.  As a-convenience, one amount may be left blank; it will be inferred so as to-balance the transaction.--   Be sure to note the unusual two-space delimiter between account name-and amount.  This makes it easy to write account names containing-spaces.  But if you accidentally leave only one space (or tab) before-the amount, the amount will be considered part of the account name.---File: hledger_journal.5.info,  Node: Dates,  Next: Status,  Prev: Postings,  Up: FILE FORMAT--1.3 Dates-=========--* Menu:--* Simple dates::-* Secondary dates::-* Posting dates::---File: hledger_journal.5.info,  Node: Simple dates,  Next: Secondary dates,  Up: Dates--1.3.1 Simple dates---------------------Within a journal file, transaction dates use Y/M/D (or Y-M-D or Y.M.D)-Leading zeros are optional.  The year may be omitted, in which case it-will be inferred from the context - the current transaction, the default-year set with a default year directive, or the current date when the-command is run.  Some examples: '2010/01/31', '1/31', '2010-01-31',-'2010.1.31'.---File: hledger_journal.5.info,  Node: Secondary dates,  Next: Posting dates,  Prev: Simple dates,  Up: Dates--1.3.2 Secondary dates------------------------Real-life transactions sometimes involve more than one date - eg the-date you write a cheque, and the date it clears in your bank.  When you-want to model this, eg for more accurate balances, you can specify-individual posting dates, which I recommend.  Or, you can use the-secondary dates (aka auxiliary/effective dates) feature, supported for-compatibility with Ledger.--   A secondary date can be written after the primary date, separated by-an equals sign.  The primary date, on the left, is used by default; the-secondary date, on the right, is used when the '--date2' flag is-specified ('--aux-date' or '--effective' also work).--   The meaning of secondary dates is up to you, but it's best to follow-a consistent rule.  Eg write the bank's clearing date as primary, and-when needed, the date the transaction was initiated as secondary.--   Here's an example.  Note that a secondary date will use the year of-the primary date if unspecified.--2010/2/23=2/19 movie ticket-  expenses:cinema                   $10-  assets:checking--$ hledger register checking-2010/02/23 movie ticket         assets:checking                $-10         $-10--$ hledger register checking --date2-2010/02/19 movie ticket         assets:checking                $-10         $-10--   Secondary dates require some effort; you must use them consistently-in your journal entries and remember whether to use or not use the-'--date2' flag for your reports.  They are included in hledger for-Ledger compatibility, but posting dates are a more powerful and less-confusing alternative.---File: hledger_journal.5.info,  Node: Posting dates,  Prev: Secondary dates,  Up: Dates--1.3.3 Posting dates----------------------You can give individual postings a different date from their parent-transaction, by adding a posting comment containing a tag (see below)-like 'date:DATE'.  This is probably the best way to control posting-dates precisely.  Eg in this example the expense should appear in May-reports, and the deduction from checking should be reported on 6/1 for-easy bank reconciliation:--2015/5/30-    expenses:food     $10   ; food purchased on saturday 5/30-    assets:checking         ; bank cleared it on monday, date:6/1--$ hledger -f t.j register food-2015/05/30                      expenses:food                  $10           $10--$ hledger -f t.j register checking-2015/06/01                      assets:checking               $-10          $-10--   DATE should be a simple date; if the year is not specified it will-use the year of the transaction's date.  You can set the secondary date-similarly, with 'date2:DATE2'.  The 'date:' or 'date2:' tags must have a-valid simple date value if they are present, eg a 'date:' tag with no-value is not allowed.--   Ledger's earlier, more compact bracketed date syntax is also-supported: '[DATE]', '[DATE=DATE2]' or '[=DATE2]'.  hledger will attempt-to parse any square-bracketed sequence of the '0123456789/-.='-characters in this way.  With this syntax, DATE infers its year from the-transaction and DATE2 infers its year from DATE.---File: hledger_journal.5.info,  Node: Status,  Next: Description,  Prev: Dates,  Up: FILE FORMAT--1.4 Status-==========--Transactions, or individual postings within a transaction, can have a-status mark, which is a single character before the transaction-description or posting account name, separated from it by a space,-indicating one of three statuses:--mark  status- -------------------      unmarked-'!'   pending-'*'   cleared--   When reporting, you can filter by status with the '-U/--unmarked',-'-P/--pending', and '-C/--cleared' flags; or the 'status:', 'status:!',-and 'status:*' queries; or the U, P, C keys in hledger-ui.--   Note, in Ledger and in older versions of hledger, the "unmarked"-state is called "uncleared".  As of hledger 1.3 we have renamed it to-unmarked for clarity.--   To replicate Ledger and old hledger's behaviour of also matching-pending, combine -U and -P.--   Status marks are optional, but can be helpful eg for reconciling with-real-world accounts.  Some editor modes provide highlighting and-shortcuts for working with status.  Eg in Emacs ledger-mode, you can-toggle transaction status with C-c C-e, or posting status with C-c C-c.--   What "uncleared", "pending", and "cleared" actually mean is up to-you.  Here's one suggestion:--status      meaning----------------------------------------------------------------------------uncleared   recorded but not yet reconciled; needs review-pending     tentatively reconciled (if needed, eg during a big-            reconciliation)-cleared     complete, reconciled as far as possible, and considered-            correct--   With this scheme, you would use '-PC' to see the current balance at-your bank, '-U' to see things which will probably hit your bank soon-(like uncashed checks), and no flags to see the most up-to-date state of-your finances.---File: hledger_journal.5.info,  Node: Description,  Next: Account names,  Prev: Status,  Up: FILE FORMAT--1.5 Description-===============--A transaction's description is the rest of the line following the date-and status mark (or until a comment begins).  Sometimes called the-"narration" in traditional bookkeeping, it can be used for whatever you-wish, or left blank.  Transaction descriptions can be queried, unlike-comments.-* Menu:--* Payee and note::---File: hledger_journal.5.info,  Node: Payee and note,  Up: Description--1.5.1 Payee and note-----------------------You can optionally include a '|' (pipe) character in a description to-subdivide it into a payee/payer name on the left and additional notes on-the right.  This may be worthwhile if you need to do more precise-querying and pivoting by payee.---File: hledger_journal.5.info,  Node: Account names,  Next: Amounts,  Prev: Description,  Up: FILE FORMAT--1.6 Account names-=================--Account names typically have several parts separated by a full colon,-from which hledger derives a hierarchical chart of accounts.  They can-be anything you like, but in finance there are traditionally five-top-level accounts: 'assets', 'liabilities', 'income', 'expenses', and-'equity'.--   Account names may contain single spaces, eg: 'assets:accounts-receivable'.  Because of this, they must always be followed by *two or-more spaces* (or newline).--   Account names can be aliased.---File: hledger_journal.5.info,  Node: Amounts,  Next: Virtual Postings,  Prev: Account names,  Up: FILE FORMAT--1.7 Amounts-===========--After the account name, there is usually an amount.  Important: between-account name and amount, there must be *two or more spaces*.--   Amounts consist of a number and (usually) a currency symbol or-commodity name.  Some examples:--   '2.00001'-'$1'-'4000 AAPL'-'3 "green apples"'-'-$1,000,000.00'-'INR 9,99,99,999.00'-'EUR -2.000.000,00'--   As you can see, the amount format is somewhat flexible:--   * amounts are a number (the "quantity") and optionally a currency-     symbol/commodity name (the "commodity").-   * the commodity is a symbol, word, or phrase, on the left or right,-     with or without a separating space.  If the commodity contains-     numbers, spaces or non-word punctuation it must be enclosed in-     double quotes.-   * negative amounts with a commodity on the left can have the minus-     sign before or after it-   * digit groups (thousands, or any other grouping) can be separated by-     commas (in which case period is used for decimal point) or periods-     (in which case comma is used for decimal point)--   You can use any of these variations when recording data, but when-hledger displays amounts, it will choose a consistent format for each-commodity.  (Except for price amounts, which are always formatted as-written).  The display format is chosen as follows:--   * if there is a commodity directive specifying the format, that is-     used-   * otherwise the format is inferred from the first posting amount in-     that commodity in the journal, and the precision (number of decimal-     places) will be the maximum from all posting amounts in that-     commmodity-   * or if there are no such amounts in the journal, a default format is-     used (like '$1000.00').--   Price amounts and amounts in D directives usually don't affect amount-format inference, but in some situations they can do so indirectly.  (Eg-when D's default commodity is applied to a commodity-less amount, or-when an amountless posting is balanced using a price's commodity, or-when -V is used.)  If you find this causing problems, set the desired-format with a commodity directive.---File: hledger_journal.5.info,  Node: Virtual Postings,  Next: Balance Assertions,  Prev: Amounts,  Up: FILE FORMAT--1.8 Virtual Postings-====================--When you parenthesise the account name in a posting, we call that a-_virtual posting_, which means:--   * it is ignored when checking that the transaction is balanced-   * it is excluded from reports when the '--real/-R' flag is used, or-     the 'real:1' query.--   You could use this, eg, to set an account's opening balance without-needing to use the 'equity:opening balances' account:--1/1 special unbalanced posting to set initial balance-  (assets:checking)   $1000--   When the account name is bracketed, we call it a _balanced virtual-posting_.  This is like an ordinary virtual posting except the balanced-virtual postings in a transaction must balance to 0, like the real-postings (but separately from them).  Balanced virtual postings are also-excluded by '--real/-R' or 'real:1'.--1/1 buy food with cash, and update some budget-tracking subaccounts elsewhere-  expenses:food                   $10-  assets:cash                    $-10-  [assets:checking:available]     $10-  [assets:checking:budget:food]  $-10--   Virtual postings have some legitimate uses, but those are few.  You-can usually find an equivalent journal entry using real postings, which-is more correct and provides better error checking.---File: hledger_journal.5.info,  Node: Balance Assertions,  Next: Balance Assignments,  Prev: Virtual Postings,  Up: FILE FORMAT--1.9 Balance Assertions-======================--hledger supports Ledger-style balance assertions in journal files.-These look like '=EXPECTEDBALANCE' following a posting's amount.  Eg in-this example we assert the expected dollar balance in accounts a and b-after each posting:--2013/1/1-  a   $1  =$1-  b       =$-1--2013/1/2-  a   $1  =$2-  b  $-1  =$-2--   After reading a journal file, hledger will check all balance-assertions and report an error if any of them fail.  Balance assertions-can protect you from, eg, inadvertently disrupting reconciled balances-while cleaning up old entries.  You can disable them temporarily with-the '--ignore-assertions' flag, which can be useful for troubleshooting-or for reading Ledger files.-* Menu:--* Assertions and ordering::-* Assertions and included files::-* Assertions and multiple -f options::-* Assertions and commodities::-* Assertions and subaccounts::-* Assertions and virtual postings::---File: hledger_journal.5.info,  Node: Assertions and ordering,  Next: Assertions and included files,  Up: Balance Assertions--1.9.1 Assertions and ordering--------------------------------hledger sorts an account's postings and assertions first by date and-then (for postings on the same day) by parse order.  Note this is-different from Ledger, which sorts assertions only by parse order.-(Also, Ledger assertions do not see the accumulated effect of repeated-postings to the same account within a transaction.)--   So, hledger balance assertions keep working if you reorder-differently-dated transactions within the journal.  But if you reorder-same-dated transactions or postings, assertions might break and require-updating.  This order dependence does bring an advantage: precise-control over the order of postings and assertions within a day, so you-can assert intra-day balances.---File: hledger_journal.5.info,  Node: Assertions and included files,  Next: Assertions and multiple -f options,  Prev: Assertions and ordering,  Up: Balance Assertions--1.9.2 Assertions and included files--------------------------------------With included files, things are a little more complicated.  Including-preserves the ordering of postings and assertions.  If you have multiple-postings to an account on the same day, split across different files,-and you also want to assert the account's balance on the same day,-you'll have to put the assertion in the right file.---File: hledger_journal.5.info,  Node: Assertions and multiple -f options,  Next: Assertions and commodities,  Prev: Assertions and included files,  Up: Balance Assertions--1.9.3 Assertions and multiple -f options-------------------------------------------Balance assertions don't work well across files specified with multiple--f options.  Use include or concatenate the files instead.---File: hledger_journal.5.info,  Node: Assertions and commodities,  Next: Assertions and subaccounts,  Prev: Assertions and multiple -f options,  Up: Balance Assertions--1.9.4 Assertions and commodities-----------------------------------The asserted balance must be a simple single-commodity amount, and in-fact the assertion checks only this commodity's balance within the-(possibly multi-commodity) account balance.  We could call this a-partial balance assertion.  This is compatible with Ledger, and makes it-possible to make assertions about accounts containing multiple-commodities.--   To assert each commodity's balance in such a multi-commodity account,-you can add multiple postings (with amount 0 if necessary).  But note-that no matter how many assertions you add, you can't be sure the-account does not contain some unexpected commodity.  (We'll add support-for this kind of total balance assertion if there's demand.)---File: hledger_journal.5.info,  Node: Assertions and subaccounts,  Next: Assertions and virtual postings,  Prev: Assertions and commodities,  Up: Balance Assertions--1.9.5 Assertions and subaccounts-----------------------------------Balance assertions do not count the balance from subaccounts; they check-the posted account's exclusive balance.  For example:--1/1-  checking:fund   1 = 1  ; post to this subaccount, its balance is now 1-  checking        1 = 1  ; post to the parent account, its exclusive balance is now 1-  equity--   The balance report's flat mode shows these exclusive balances more-clearly:--$ hledger bal checking --flat-                   1  checking-                   1  checking:fund----------------------                   2---File: hledger_journal.5.info,  Node: Assertions and virtual postings,  Prev: Assertions and subaccounts,  Up: Balance Assertions--1.9.6 Assertions and virtual postings----------------------------------------Balance assertions are checked against all postings, both real and-virtual.  They are not affected by the '--real/-R' flag or 'real:'-query.---File: hledger_journal.5.info,  Node: Balance Assignments,  Next: Prices,  Prev: Balance Assertions,  Up: FILE FORMAT--1.10 Balance Assignments-========================--Ledger-style balance assignments are also supported.  These are like-balance assertions, but with no posting amount on the left side of the-equals sign; instead it is calculated automatically so as to satisfy the-assertion.  This can be a convenience during data entry, eg when setting-opening balances:--; starting a new journal, set asset account balances-2016/1/1 opening balances-  assets:checking            = $409.32-  assets:savings             = $735.24-  assets:cash                 = $42-  equity:opening balances--   or when adjusting a balance to reality:--; no cash left; update balance, record any untracked spending as a generic expense-2016/1/15-  assets:cash    = $0-  expenses:misc--   The calculated amount depends on the account's balance in the-commodity at that point (which depends on the previously-dated postings-of the commodity to that account since the last balance assertion or-assignment).  Note that using balance assignments makes your journal a-little less explicit; to know the exact amount posted, you have to run-hledger or do the calculations yourself, instead of just reading it.---File: hledger_journal.5.info,  Node: Prices,  Next: Comments,  Prev: Balance Assignments,  Up: FILE FORMAT--1.11 Prices-===========--* Menu:--* Transaction prices::-* Market prices::---File: hledger_journal.5.info,  Node: Transaction prices,  Next: Market prices,  Up: Prices--1.11.1 Transaction prices----------------------------Within a transaction, you can note an amount's price in another-commodity.  This can be used to document the cost (in a purchase) or-selling price (in a sale).  For example, transaction prices are useful-to record purchases of a foreign currency.--   Transaction prices are fixed, and do not change over time.  (Ledger-users: Ledger uses a different syntax for fixed prices, '{=UNITPRICE}',-which hledger currently ignores).--   There are several ways to record a transaction price:--  1. Write the price per unit, as '@ UNITPRICE' after the amount:--     2009/1/1-       assets:euros     €100 @ $1.35  ; one hundred euros purchased at $1.35 each-       assets:dollars                 ; balancing amount is -$135.00--  2. Write the total price, as '@@ TOTALPRICE' after the amount:--     2009/1/1-       assets:euros     €100 @@ $135  ; one hundred euros purchased at $135 for the lot-       assets:dollars--  3. Specify amounts for all postings, using exactly two commodities,-     and let hledger infer the price that balances the transaction:--     2009/1/1-       assets:euros     €100          ; one hundred euros purchased-       assets:dollars  $-135          ; for $135--   Amounts with transaction prices can be displayed in the transaction-price's commodity by using the '-B/--cost' flag (except for #551) ("B"-is from "cost Basis").  Eg for the above, here is how -B affects the-balance report:--$ hledger bal -N --flat-               $-135  assets:dollars-                €100  assets:euros-$ hledger bal -N --flat -B-               $-135  assets:dollars-                $135  assets:euros    # <- the euros' cost--   Note -B is sensitive to the order of postings when a transaction-price is inferred: the inferred price will be in the commodity of the-last amount.  So if example 3's postings are reversed, while the-transaction is equivalent, -B shows something different:--2009/1/1-  assets:dollars  $-135               ; 135 dollars sold-  assets:euros     €100               ; for 100 euros--$ hledger bal -N --flat -B-               €-100  assets:dollars  # <- the dollars' selling price-                €100  assets:euros---File: hledger_journal.5.info,  Node: Market prices,  Prev: Transaction prices,  Up: Prices--1.11.2 Market prices-----------------------Market prices are not tied to a particular transaction; they represent-historical exchange rates between two commodities.  (Ledger calls them-historical prices.)  For example, the prices published by a stock-exchange or the foreign exchange market.  hledger can use these prices-to show the market value of things at a given date, see market value.--   To record market prices, use P directives in the main journal or in-an included file.  Their format is:--P DATE COMMODITYBEINGPRICED UNITPRICE--   DATE is a simple date as usual.  COMMODITYBEINGPRICED is the symbol-of the commodity being priced.  UNITPRICE is an ordinary amount (symbol-and quantity) in a second commodity, specifying the unit price or-conversion rate for the first commodity in terms of the second, on the-given date.--   For example, the following directives say that one euro was worth-1.35 US dollars during 2009, and $1.40 from 2010 onward:--P 2009/1/1 € $1.35-P 2010/1/1 € $1.40---File: hledger_journal.5.info,  Node: Comments,  Next: Tags,  Prev: Prices,  Up: FILE FORMAT--1.12 Comments-=============--Lines in the journal beginning with a semicolon (';') or hash ('#') or-asterisk ('*') are comments, and will be ignored.  (Asterisk comments-make it easy to treat your journal like an org-mode outline in emacs.)--   Also, anything between 'comment' and 'end comment' directives is a-(multi-line) comment.  If there is no 'end comment', the comment extends-to the end of the file.--   You can attach comments to a transaction by writing them after the-description and/or indented on the following lines (before the-postings).  Similarly, you can attach comments to an individual posting-by writing them after the amount and/or indented on the following lines.--   Some examples:--# a journal comment--; also a journal comment--comment-This is a multiline comment,-which continues until a line-where the "end comment" string-appears on its own.-end comment--2012/5/14 something  ; a transaction comment-    ; the transaction comment, continued-    posting1  1  ; a comment for posting 1-    posting2-    ; a comment for posting 2-    ; another comment line for posting 2-; a journal comment (because not indented)---File: hledger_journal.5.info,  Node: Tags,  Next: Directives,  Prev: Comments,  Up: FILE FORMAT--1.13 Tags-=========--Tags are a way to add extra labels or labelled data to postings and-transactions, which you can then search or pivot on.--   A simple tag is a word (which may contain hyphens) followed by a full-colon, written inside a transaction or posting comment line:--2017/1/16 bought groceries    ; sometag:--   Tags can have a value, which is the text after the colon, up to the-next comma or end of line, with leading/trailing whitespace removed:--    expenses:food    $10   ; a-posting-tag: the tag value--   Note this means hledger's tag values can not contain commas or-newlines.  Ending at commas means you can write multiple short tags on-one line, comma separated:--    assets:checking       ; a comment containing tag1:, tag2: some value ...--   Here,--   * "'a comment containing'" is just comment text, not a tag-   * "'tag1'" is a tag with no value-   * "'tag2'" is another tag, whose value is "'some value ...'"--   Tags in a transaction comment affect the transaction and all of its-postings, while tags in a posting comment affect only that posting.  For-example, the following transaction has three tags ('A', 'TAG2',-'third-tag') and the posting has four (those plus 'posting-tag'):--1/1 a transaction  ; A:, TAG2:-    ; third-tag: a third transaction tag, <- with a value-    (a)  $1  ; posting-tag:--   Tags are like Ledger's metadata feature, except hledger's tag values-are simple strings.---File: hledger_journal.5.info,  Node: Directives,  Prev: Tags,  Up: FILE FORMAT--1.14 Directives-===============--* Menu:--* Account aliases::-* account directive::-* apply account directive::-* Multi-line comments::-* commodity directive::-* Default commodity::-* Default year::-* Including other files::---File: hledger_journal.5.info,  Node: Account aliases,  Next: account directive,  Up: Directives--1.14.1 Account aliases-------------------------You can define aliases which rewrite your account names (after reading-the journal, before generating reports).  hledger's account aliases can-be useful for:--   * expanding shorthand account names to their full form, allowing-     easier data entry and a less verbose journal-   * adapting old journals to your current chart of accounts-   * experimenting with new account organisations, like a new hierarchy-     or combining two accounts into one-   * customising reports--   See also Cookbook: rewrite account names.-* Menu:--* Basic aliases::-* Regex aliases::-* Multiple aliases::-* end aliases::---File: hledger_journal.5.info,  Node: Basic aliases,  Next: Regex aliases,  Up: Account aliases--1.14.1.1 Basic aliases-......................--To set an account alias, use the 'alias' directive in your journal file.-This affects all subsequent journal entries in the current file or its-included files.  The spaces around the = are optional:--alias OLD = NEW--   Or, you can use the '--alias 'OLD=NEW'' option on the command line.-This affects all entries.  It's useful for trying out aliases-interactively.--   OLD and NEW are full account names.  hledger will replace any-occurrence of the old account name with the new one.  Subaccounts are-also affected.  Eg:--alias checking = assets:bank:wells fargo:checking-# rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"---File: hledger_journal.5.info,  Node: Regex aliases,  Next: Multiple aliases,  Prev: Basic aliases,  Up: Account aliases--1.14.1.2 Regex aliases-......................--There is also a more powerful variant that uses a regular expression,-indicated by the forward slashes:--alias /REGEX/ = REPLACEMENT--   or '--alias '/REGEX/=REPLACEMENT''.--   REGEX is a case-insensitive regular expression.  Anywhere it matches-inside an account name, the matched part will be replaced by-REPLACEMENT. If REGEX contains parenthesised match groups, these can be-referenced by the usual numeric backreferences in REPLACEMENT. Eg:--alias /^(.+):bank:([^:]+)(.*)/ = \1:\2 \3-# rewrites "assets:bank:wells fargo:checking" to  "assets:wells fargo checking"--   Also note that REPLACEMENT continues to the end of line (or on-command line, to end of option argument), so it can contain trailing-whitespace.---File: hledger_journal.5.info,  Node: Multiple aliases,  Next: end aliases,  Prev: Regex aliases,  Up: Account aliases--1.14.1.3 Multiple aliases-.........................--You can define as many aliases as you like using directives or-command-line options.  Aliases are recursive - each alias sees the-result of applying previous ones.  (This is different from Ledger, where-aliases are non-recursive by default).  Aliases are applied in the-following order:--  1. alias directives, most recently seen first (recent directives take-     precedence over earlier ones; directives not yet seen are ignored)-  2. alias options, in the order they appear on the command line---File: hledger_journal.5.info,  Node: end aliases,  Prev: Multiple aliases,  Up: Account aliases--1.14.1.4 end aliases-....................--You can clear (forget) all currently defined aliases with the 'end-aliases' directive:--end aliases---File: hledger_journal.5.info,  Node: account directive,  Next: apply account directive,  Prev: Account aliases,  Up: Directives--1.14.2 account directive---------------------------The 'account' directive predefines account names, as in Ledger and-Beancount.  This may be useful for your own documentation; hledger-doesn't make use of it yet.--; account ACCT-;   OPTIONAL COMMENTS/TAGS...--account assets:bank:checking- a comment- acct-no:12345--account expenses:food--; etc.---File: hledger_journal.5.info,  Node: apply account directive,  Next: Multi-line comments,  Prev: account directive,  Up: Directives--1.14.3 apply account directive---------------------------------You can specify a parent account which will be prepended to all accounts-within a section of the journal.  Use the 'apply account' and 'end apply-account' directives like so:--apply account home--2010/1/1-    food    $10-    cash--end apply account--   which is equivalent to:--2010/01/01-    home:food           $10-    home:cash          $-10--   If 'end apply account' is omitted, the effect lasts to the end of the-file.  Included files are also affected, eg:--apply account business-include biz.journal-end apply account-apply account personal-include personal.journal--   Prior to hledger 1.0, legacy 'account' and 'end' spellings were also-supported.---File: hledger_journal.5.info,  Node: Multi-line comments,  Next: commodity directive,  Prev: apply account directive,  Up: Directives--1.14.4 Multi-line comments-----------------------------A line containing just 'comment' starts a multi-line comment, and a line-containing just 'end comment' ends it.  See comments.---File: hledger_journal.5.info,  Node: commodity directive,  Next: Default commodity,  Prev: Multi-line comments,  Up: Directives--1.14.5 commodity directive-----------------------------The 'commodity' directive predefines commodities (currently this is just-informational), and also it may define the display format for amounts in-this commodity (overriding the automatically inferred format).--   It may be written on a single line, like this:--; commodity EXAMPLEAMOUNT--; display AAAA amounts with the symbol on the right, space-separated,-; using period as decimal point, with four decimal places, and-; separating thousands with comma.-commodity 1,000.0000 AAAA--   or on multiple lines, using the "format" subdirective.  In this case-the commodity symbol appears twice and should be the same in both-places:--; commodity SYMBOL-;   format EXAMPLEAMOUNT--; display indian rupees with currency name on the left,-; thousands, lakhs and crores comma-separated,-; period as decimal point, and two decimal places.-commodity INR-  format INR 9,99,99,999.00---File: hledger_journal.5.info,  Node: Default commodity,  Next: Default year,  Prev: commodity directive,  Up: Directives--1.14.6 Default commodity---------------------------The D directive sets a default commodity (and display format), to be-used for amounts without a commodity symbol (ie, plain numbers).  (Note-this differs from Ledger's default commodity directive.)  The commodity-and display format will be applied to all subsequent commodity-less-amounts, or until the next D directive.--# commodity-less amounts should be treated as dollars-# (and displayed with symbol on the left, thousands separators and two decimal places)-D $1,000.00--1/1-  a     5    # <- commodity-less amount, becomes $1-  b---File: hledger_journal.5.info,  Node: Default year,  Next: Including other files,  Prev: Default commodity,  Up: Directives--1.14.7 Default year----------------------You can set a default year to be used for subsequent dates which don't-specify a year.  This is a line beginning with 'Y' followed by the year.-Eg:--Y2009      ; set default year to 2009--12/15      ; equivalent to 2009/12/15-  expenses  1-  assets--Y2010      ; change default year to 2010--2009/1/30  ; specifies the year, not affected-  expenses  1-  assets--1/31       ; equivalent to 2010/1/31-  expenses  1-  assets---File: hledger_journal.5.info,  Node: Including other files,  Prev: Default year,  Up: Directives--1.14.8 Including other files-------------------------------You can pull in the content of additional journal files by writing an-include directive, like this:--include path/to/file.journal--   If the path does not begin with a slash, it is relative to the-current file.  Glob patterns ('*') are not currently supported.--   The 'include' directive can only be used in journal files.  It can-include journal, timeclock or timedot files, but not CSV files.---File: hledger_journal.5.info,  Node: EDITOR SUPPORT,  Prev: FILE FORMAT,  Up: Top--2 EDITOR SUPPORT-****************--Add-on modes exist for various text editors, to make working with-journal files easier.  They add colour, navigation aids and helpful-commands.  For hledger users who edit the journal file directly (the-majority), using one of these modes is quite recommended.--   These were written with Ledger in mind, but also work with hledger-files:--Emacs             http://www.ledger-cli.org/3.0/doc/ledger-mode.html-Vim               https://github.com/ledger/ledger/wiki/Getting-started-Sublime Text      https://github.com/ledger/ledger/wiki/Using-Sublime-Text-Textmate          https://github.com/ledger/ledger/wiki/Using-TextMate-2-Text Wrangler     https://github.com/ledger/ledger/wiki/Editing-Ledger-files-with-TextWrangler-Visual Studio     https://marketplace.visualstudio.com/items?itemName=mark-hansen.hledger-vscode-Code---Tag Table:-Node: Top78-Node: FILE FORMAT2374-Ref: #file-format2500-Node: Transactions2723-Ref: #transactions2846-Node: Postings3530-Ref: #postings3659-Node: Dates4654-Ref: #dates4771-Node: Simple dates4836-Ref: #simple-dates4964-Node: Secondary dates5330-Ref: #secondary-dates5486-Node: Posting dates7049-Ref: #posting-dates7180-Node: Status8554-Ref: #status8676-Node: Description10390-Ref: #description10530-Node: Payee and note10849-Ref: #payee-and-note10965-Node: Account names11207-Ref: #account-names11352-Node: Amounts11839-Ref: #amounts11977-Node: Virtual Postings14078-Ref: #virtual-postings14239-Node: Balance Assertions15459-Ref: #balance-assertions15636-Node: Assertions and ordering16532-Ref: #assertions-and-ordering16720-Node: Assertions and included files17420-Ref: #assertions-and-included-files17663-Node: Assertions and multiple -f options17996-Ref: #assertions-and-multiple--f-options18252-Node: Assertions and commodities18384-Ref: #assertions-and-commodities18621-Node: Assertions and subaccounts19317-Ref: #assertions-and-subaccounts19551-Node: Assertions and virtual postings20072-Ref: #assertions-and-virtual-postings20281-Node: Balance Assignments20423-Ref: #balance-assignments20594-Node: Prices21713-Ref: #prices21848-Node: Transaction prices21899-Ref: #transaction-prices22046-Node: Market prices24202-Ref: #market-prices24339-Node: Comments25299-Ref: #comments25423-Node: Tags26536-Ref: #tags26656-Node: Directives28058-Ref: #directives28173-Node: Account aliases28366-Ref: #account-aliases28512-Node: Basic aliases29116-Ref: #basic-aliases29261-Node: Regex aliases29951-Ref: #regex-aliases30121-Node: Multiple aliases30839-Ref: #multiple-aliases31013-Node: end aliases31511-Ref: #end-aliases31653-Node: account directive31754-Ref: #account-directive31936-Node: apply account directive32232-Ref: #apply-account-directive32430-Node: Multi-line comments33089-Ref: #multi-line-comments33281-Node: commodity directive33409-Ref: #commodity-directive33595-Node: Default commodity34467-Ref: #default-commodity34642-Node: Default year35179-Ref: #default-year35346-Node: Including other files35769-Ref: #including-other-files35928-Node: EDITOR SUPPORT36325-Ref: #editor-support36445--End Tag Table
− doc/hledger_journal.5.txt
@@ -1,848 +0,0 @@--hledger_journal(5)           hledger User Manuals           hledger_journal(5)----NAME-       Journal - hledger's default file format, representing a General Journal--DESCRIPTION-       hledger's usual data source is a plain  text  file  containing  journal-       entries  in  hledger  journal  format.  This file represents a standard-       accounting general journal.  I use file names ending in  .journal,  but-       that's not required.  The journal file contains a number of transaction-       entries, each describing a transfer of money (or any commodity) between-       two or more named accounts, in a simple format readable by both hledger-       and humans.--       hledger's journal format is a compatible subset,  mostly,  of  ledger's-       journal  format,  so  hledger  can  work with compatible ledger journal-       files as well.  It's safe, and encouraged,  to  run  both  hledger  and-       ledger on the same journal file, eg to validate the results you're get--       ting.--       You can use hledger without learning any more about this file; just use-       the  add  or web commands to create and update it.  Many users, though,-       also edit the  journal  file  directly  with  a  text  editor,  perhaps-       assisted by the helper modes for emacs or vim.--       Here's an example:--              ; A sample journal file. This is a comment.--              2008/01/01 income               ; <- transaction's first line starts in column 0, contains date and description-                  assets:bank:checking  $1    ; <- posting lines start with whitespace, each contains an account name-                  income:salary        $-1    ;    followed by at least two spaces and an amount--              2008/06/01 gift-                  assets:bank:checking  $1    ; <- at least two postings in a transaction-                  income:gifts         $-1    ; <- their amounts must balance to 0--              2008/06/02 save-                  assets:bank:saving    $1-                  assets:bank:checking        ; <- one amount may be omitted; here $-1 is inferred--              2008/06/03 eat & shop           ; <- description can be anything-                  expenses:food         $1-                  expenses:supplies     $1    ; <- this transaction debits two expense accounts-                  assets:cash                 ; <- $-2 inferred--              2008/10/01 take a loan-                  assets:bank:checking  $1-                  liabilities:debts    $-1--              2008/12/31 * pay off            ; <- an optional * or ! after the date means "cleared" (or anything you want)-                  liabilities:debts     $1-                  assets:bank:checking--FILE FORMAT-   Transactions-       Transactions  are  movements  of  some  quantity of commodities between-       named accounts.  Each transaction is represented  by  a  journal  entry-       beginning  with a simple date in column 0.  This can be followed by any-       of the following, separated by spaces:--       o (optional) a status character (empty, !, or *)--       o (optional) a transaction code (any short number or text, enclosed  in-         parentheses)--       o (optional) a transaction description (any remaining text until end of-         line or a semicolon)--       o (optional) a transaction comment  (any  remaining  text  following  a-         semicolon until end of line)--       Then  comes zero or more (but usually at least 2) indented lines repre--       senting...--   Postings-       A posting is an addition of some amount to, or removal of  some  amount-       from,  an account.  Each posting line begins with at least one space or-       tab (2 or 4 spaces is common), followed by:--       o (optional) a status character (empty, !, or *), followed by a space--       o (required) an account name (any text,  optionally  containing  single-         spaces, until end of line or a double space)--       o (optional) two or more spaces or tabs followed by an amount.--       Positive  amounts  are being added to the account, negative amounts are-       being removed.--       The amounts within a transaction must always sum up to zero.  As a con--       venience,  one  amount  may be left blank; it will be inferred so as to-       balance the transaction.--       Be sure to note the unusual two-space delimiter  between  account  name-       and  amount.  This makes it easy to write account names containing spa--       ces.  But if you accidentally leave only one space (or tab) before  the-       amount, the amount will be considered part of the account name.--   Dates-   Simple dates-       Within  a journal file, transaction dates use Y/M/D (or Y-M-D or Y.M.D)-       Leading zeros are optional.  The year may be omitted, in which case  it-       will  be  inferred  from  the  context  -  the current transaction, the-       default year set with a default year directive,  or  the  current  date-       when  the command is run.  Some examples: 2010/01/31, 1/31, 2010-01-31,-       2010.1.31.--   Secondary dates-       Real-life transactions sometimes involve more than one date  -  eg  the-       date you write a cheque, and the date it clears in your bank.  When you-       want to model this, eg for more  accurate  balances,  you  can  specify-       individual  posting dates, which I recommend.  Or, you can use the sec--       ondary dates (aka auxiliary/effective  dates)  feature,  supported  for-       compatibility with Ledger.--       A secondary date can be written after the primary date, separated by an-       equals sign.  The primary date, on the left, is used  by  default;  the-       secondary  date,  on the right, is used when the --date2 flag is speci--       fied (--aux-date or --effective also work).--       The meaning of secondary dates is up to you, but it's best to follow  a-       consistent  rule.   Eg  write  the bank's clearing date as primary, and-       when needed, the date the transaction was initiated as secondary.--       Here's an example.  Note that a secondary date will use the year of the-       primary date if unspecified.--              2010/2/23=2/19 movie ticket-                expenses:cinema                   $10-                assets:checking--              $ hledger register checking-              2010/02/23 movie ticket         assets:checking                $-10         $-10--              $ hledger register checking --date2-              2010/02/19 movie ticket         assets:checking                $-10         $-10--       Secondary  dates require some effort; you must use them consistently in-       your journal entries and remember whether to use or not use the --date2-       flag for your reports.  They are included in hledger for Ledger compat--       ibility, but posting dates are  a  more  powerful  and  less  confusing-       alternative.--   Posting dates-       You  can  give  individual  postings a different date from their parent-       transaction, by adding a posting comment containing a tag  (see  below)-       like date:DATE.  This is probably the best way to control posting dates-       precisely.  Eg in  this  example  the  expense  should  appear  in  May-       reports,  and the deduction from checking should be reported on 6/1 for-       easy bank reconciliation:--              2015/5/30-                  expenses:food     $10   ; food purchased on saturday 5/30-                  assets:checking         ; bank cleared it on monday, date:6/1--              $ hledger -f t.j register food-              2015/05/30                      expenses:food                  $10           $10--              $ hledger -f t.j register checking-              2015/06/01                      assets:checking               $-10          $-10--       DATE should be a simple date; if the year is not specified it will  use-       the  year  of  the  transaction's date.  You can set the secondary date-       similarly, with date2:DATE2.  The date: or  date2:  tags  must  have  a-       valid  simple  date  value  if they are present, eg a date: tag with no-       value is not allowed.--       Ledger's earlier, more compact bracketed date syntax is also supported:-       [DATE],  [DATE=DATE2]  or  [=DATE2].  hledger will attempt to parse any-       square-bracketed sequence of the 0123456789/-.= characters in this way.-       With  this  syntax, DATE infers its year from the transaction and DATE2-       infers its year from DATE.--   Status-       Transactions, or individual postings within a transaction, can  have  a-       status  mark,  which  is  a  single  character  before  the transaction-       description or posting account name, separated  from  it  by  a  space,-       indicating one of three statuses:---       mark     status-       -------------------                unmarked-       !        pending-       *        cleared--       When  reporting,  you  can  filter  by  status  with the -U/--unmarked,-       -P/--pending, and -C/--cleared flags; or  the  status:,  status:!,  and-       status:* queries; or the U, P, C keys in hledger-ui.--       Note,  in Ledger and in older versions of hledger, the "unmarked" state-       is called "uncleared".  As  of  hledger  1.3  we  have  renamed  it  to-       unmarked for clarity.--       To  replicate Ledger and old hledger's behaviour of also matching pend--       ing, combine -U and -P.--       Status marks are optional, but can be helpful eg for  reconciling  with-       real-world accounts.  Some editor modes provide highlighting and short--       cuts for working with status.  Eg in Emacs ledger-mode, you can  toggle-       transaction status with C-c C-e, or posting status with C-c C-c.--       What  "uncleared", "pending", and "cleared" actually mean is up to you.-       Here's one suggestion:---       status       meaning-       ---------------------------------------------------------------------------       uncleared    recorded but not yet reconciled; needs review-       pending      tentatively reconciled (if needed, eg during a  big  recon--                    ciliation)-       cleared      complete,  reconciled  as  far  as possible, and considered-                    correct--       With this scheme, you would use -PC to see the current balance at  your-       bank,  -U  to  see  things which will probably hit your bank soon (like-       uncashed checks), and no flags to see the most up-to-date state of your-       finances.--   Description-       A  transaction's description is the rest of the line following the date-       and status mark (or until a  comment  begins).   Sometimes  called  the-       "narration" in traditional bookkeeping, it can be used for whatever you-       wish, or left blank.  Transaction descriptions can be  queried,  unlike-       comments.--   Payee and note-       You  can  optionally  include  a | (pipe) character in a description to-       subdivide it into a payee/payer name on the left and  additional  notes-       on  the  right.   This may be worthwhile if you need to do more precise-       querying and pivoting by payee.--   Account names-       Account names typically have several parts separated by a  full  colon,-       from  which hledger derives a hierarchical chart of accounts.  They can-       be anything you like, but  in  finance  there  are  traditionally  five-       top-level  accounts: assets, liabilities, income, expenses, and equity.--       Account names may contain single  spaces,  eg:  assets:accounts receiv--       able.   Because  of  this,  they must always be followed by two or more-       spaces (or newline).--       Account names can be aliased.--   Amounts-       After the account name, there is usually an amount.  Important: between-       account name and amount, there must be two or more spaces.--       Amounts  consist of a number and (usually) a currency symbol or commod--       ity name.  Some examples:--       2.00001-       $1-       4000 AAPL-       3 "green apples"-       -$1,000,000.00-       INR 9,99,99,999.00-       EUR -2.000.000,00--       As you can see, the amount format is somewhat flexible:--       o amounts are a number (the "quantity") and optionally a currency  sym--         bol/commodity name (the "commodity").--       o the  commodity  is  a  symbol, word, or phrase, on the left or right,-         with or without a separating space.  If the commodity  contains  num--         bers,  spaces  or  non-word punctuation it must be enclosed in double-         quotes.--       o negative amounts with a commodity on the left can have the minus sign-         before or after it--       o digit  groups  (thousands, or any other grouping) can be separated by-         commas (in which case period is used for decimal  point)  or  periods-         (in which case comma is used for decimal point)--       You  can  use  any  of  these  variations when recording data, but when-       hledger displays amounts, it will choose a consistent format  for  each-       commodity.   (Except  for  price amounts, which are always formatted as-       written).  The display format is chosen as follows:--       o if there is a commodity directive specifying the format, that is used--       o otherwise  the  format  is  inferred from the first posting amount in-         that commodity in the journal, and the precision (number  of  decimal-         places) will be the maximum from all posting amounts in that commmod--         ity--       o or if there are no such amounts in the journal, a default  format  is-         used (like $1000.00).--       Price  amounts  and amounts in D directives usually don't affect amount-       format inference, but in some situations they  can  do  so  indirectly.-       (Eg  when  D's default commodity is applied to a commodity-less amount,-       or when an amountless posting is balanced using a price's commodity, or-       when  -V  is  used.) If you find this causing problems, set the desired-       format with a commodity directive.--   Virtual Postings-       When you parenthesise the account name in a posting,  we  call  that  a-       virtual posting, which means:--       o it is ignored when checking that the transaction is balanced--       o it  is  excluded from reports when the --real/-R flag is used, or the-         real:1 query.--       You could use this, eg, to set an  account's  opening  balance  without-       needing to use the equity:opening balances account:--              1/1 special unbalanced posting to set initial balance-                (assets:checking)   $1000--       When the account name is bracketed, we call it a balanced virtual post--       ing.  This is like an ordinary virtual posting except the balanced vir--       tual  postings  in a transaction must balance to 0, like the real post--       ings (but separately from them).  Balanced virtual  postings  are  also-       excluded by --real/-R or real:1.--              1/1 buy food with cash, and update some budget-tracking subaccounts elsewhere-                expenses:food                   $10-                assets:cash                    $-10-                [assets:checking:available]     $10-                [assets:checking:budget:food]  $-10--       Virtual postings have some legitimate uses, but those are few.  You can-       usually find an equivalent journal entry using real postings, which  is-       more correct and provides better error checking.--   Balance Assertions-       hledger  supports  Ledger-style  balance  assertions  in journal files.-       These look like =EXPECTEDBALANCE following a posting's amount.   Eg  in-       this  example we assert the expected dollar balance in accounts a and b-       after each posting:--              2013/1/1-                a   $1  =$1-                b       =$-1--              2013/1/2-                a   $1  =$2-                b  $-1  =$-2--       After reading a journal file, hledger will check all balance assertions-       and  report  an error if any of them fail.  Balance assertions can pro--       tect you from, eg, inadvertently disrupting reconciled  balances  while-       cleaning  up  old  entries.   You can disable them temporarily with the-       --ignore-assertions flag, which can be useful  for  troubleshooting  or-       for reading Ledger files.--   Assertions and ordering-       hledger  sorts  an  account's postings and assertions first by date and-       then (for postings on the same day) by parse order.  Note this is  dif--       ferent from Ledger, which sorts assertions only by parse order.  (Also,-       Ledger assertions do not see the accumulated effect of  repeated  post--       ings to the same account within a transaction.)--       So,  hledger  balance  assertions  keep  working if you reorder differ--       ently-dated transactions  within  the  journal.   But  if  you  reorder-       same-dated transactions or postings, assertions might break and require-       updating.  This order dependence does bring an advantage: precise  con--       trol over the order of postings and assertions within a day, so you can-       assert intra-day balances.--   Assertions and included files-       With included files, things are a little more  complicated.   Including-       preserves  the ordering of postings and assertions.  If you have multi--       ple postings to an account on the  same  day,  split  across  different-       files,  and  you  also want to assert the account's balance on the same-       day, you'll have to put the assertion in the right file.--   Assertions and multiple -f options-       Balance assertions don't work well across files specified with multiple-       -f options.  Use include or concatenate the files instead.--   Assertions and commodities-       The  asserted  balance must be a simple single-commodity amount, and in-       fact the assertion checks only  this  commodity's  balance  within  the-       (possibly  multi-commodity) account balance.  We could call this a par--       tial balance assertion.  This is compatible with Ledger, and  makes  it-       possible to make assertions about accounts containing multiple commodi--       ties.--       To assert each commodity's balance in such a  multi-commodity  account,-       you  can  add multiple postings (with amount 0 if necessary).  But note-       that no matter how many assertions you  add,  you  can't  be  sure  the-       account does not contain some unexpected commodity.  (We'll add support-       for this kind of total balance assertion if there's demand.)--   Assertions and subaccounts-       Balance assertions do not count  the  balance  from  subaccounts;  they-       check the posted account's exclusive balance.  For example:--              1/1-                checking:fund   1 = 1  ; post to this subaccount, its balance is now 1-                checking        1 = 1  ; post to the parent account, its exclusive balance is now 1-                equity--       The  balance  report's  flat  mode  shows these exclusive balances more-       clearly:--              $ hledger bal checking --flat-                                 1  checking-                                 1  checking:fund-              ---------------------                                 2--   Assertions and virtual postings-       Balance assertions are checked against all postings, both real and vir--       tual.  They are not affected by the --real/-R flag or real: query.--   Balance Assignments-       Ledger-style  balance  assignments  are also supported.  These are like-       balance assertions, but with no posting amount on the left side of  the-       equals  sign;  instead  it is calculated automatically so as to satisfy-       the assertion.  This can be a convenience during data  entry,  eg  when-       setting opening balances:--              ; starting a new journal, set asset account balances-              2016/1/1 opening balances-                assets:checking            = $409.32-                assets:savings             = $735.24-                assets:cash                 = $42-                equity:opening balances--       or when adjusting a balance to reality:--              ; no cash left; update balance, record any untracked spending as a generic expense-              2016/1/15-                assets:cash    = $0-                expenses:misc--       The calculated amount depends on the account's balance in the commodity-       at that point (which depends on the previously-dated  postings  of  the-       commodity  to  that account since the last balance assertion or assign--       ment).  Note that using balance assignments makes your journal a little-       less explicit; to know the exact amount posted, you have to run hledger-       or do the calculations yourself, instead of just reading it.--   Prices-   Transaction prices-       Within a transaction, you can note an amount's price in another commod--       ity.   This can be used to document the cost (in a purchase) or selling-       price (in a sale).  For  example,  transaction  prices  are  useful  to-       record purchases of a foreign currency.--       Transaction  prices  are  fixed,  and do not change over time.  (Ledger-       users: Ledger uses a different syntax for fixed  prices,  {=UNITPRICE},-       which hledger currently ignores).--       There are several ways to record a transaction price:--       1. Write the price per unit, as @ UNITPRICE after the amount:--                  2009/1/1-                    assets:euros     100 @ $1.35  ; one hundred euros purchased at $1.35 each-                    assets:dollars                 ; balancing amount is -$135.00--       2. Write the total price, as @@ TOTALPRICE after the amount:--                  2009/1/1-                    assets:euros     100 @@ $135  ; one hundred euros purchased at $135 for the lot-                    assets:dollars--       3. Specify amounts for all postings, using exactly two commodities, and-          let hledger infer the price that balances the transaction:--                  2009/1/1-                    assets:euros     100          ; one hundred euros purchased-                    assets:dollars  $-135          ; for $135--       Amounts with transaction prices can be  displayed  in  the  transaction-       price's commodity by using the -B/--cost flag (except for #551) ("B" is-       from "cost Basis").  Eg for the above, here is how -B affects the  bal--       ance report:--              $ hledger bal -N --flat-                             $-135  assets:dollars-                              100  assets:euros-              $ hledger bal -N --flat -B-                             $-135  assets:dollars-                              $135  assets:euros    # <- the euros' cost--       Note  -B is sensitive to the order of postings when a transaction price-       is inferred: the inferred price will be in the commodity  of  the  last-       amount.  So if example 3's postings are reversed, while the transaction-       is equivalent, -B shows something different:--              2009/1/1-                assets:dollars  $-135               ; 135 dollars sold-                assets:euros     100               ; for 100 euros--              $ hledger bal -N --flat -B-                             -100  assets:dollars  # <- the dollars' selling price-                              100  assets:euros--   Market prices-       Market prices are not tied to a particular transaction; they  represent-       historical  exchange rates between two commodities.  (Ledger calls them-       historical prices.) For  example,  the  prices  published  by  a  stock-       exchange  or the foreign exchange market.  hledger can use these prices-       to show the market value of things at a given date, see market value.--       To record market prices, use P directives in the main journal or in  an-       included file.  Their format is:--              P DATE COMMODITYBEINGPRICED UNITPRICE--       DATE  is a simple date as usual.  COMMODITYBEINGPRICED is the symbol of-       the commodity being priced.  UNITPRICE is an  ordinary  amount  (symbol-       and  quantity) in a second commodity, specifying the unit price or con--       version rate for the first commodity in terms of  the  second,  on  the-       given date.--       For  example, the following directives say that one euro was worth 1.35-       US dollars during 2009, and $1.40 from 2010 onward:--              P 2009/1/1  $1.35-              P 2010/1/1  $1.40--   Comments-       Lines in the journal beginning with a semicolon  (;)  or  hash  (#)  or-       asterisk  (*)  are  comments,  and will be ignored.  (Asterisk comments-       make it easy to treat your journal like an org-mode outline in  emacs.)--       Also,   anything  between  comment  and  end comment  directives  is  a-       (multi-line) comment.  If there is no end comment, the comment  extends-       to the end of the file.--       You  can  attach  comments  to  a transaction by writing them after the-       description and/or indented on the following lines  (before  the  post--       ings).   Similarly, you can attach comments to an individual posting by-       writing them after the amount and/or indented on the following lines.--       Some examples:--              # a journal comment--              ; also a journal comment--              comment-              This is a multiline comment,-              which continues until a line-              where the "end comment" string-              appears on its own.-              end comment--              2012/5/14 something  ; a transaction comment-                  ; the transaction comment, continued-                  posting1  1  ; a comment for posting 1-                  posting2-                  ; a comment for posting 2-                  ; another comment line for posting 2-              ; a journal comment (because not indented)--   Tags-       Tags are a way to add extra labels or labelled  data  to  postings  and-       transactions, which you can then search or pivot on.--       A  simple  tag is a word (which may contain hyphens) followed by a full-       colon, written inside a transaction or posting comment line:--              2017/1/16 bought groceries    ; sometag:--       Tags can have a value, which is the text after the  colon,  up  to  the-       next comma or end of line, with leading/trailing whitespace removed:--                  expenses:food    $10   ; a-posting-tag: the tag value--       Note  this  means  hledger's  tag values can not contain commas or new--       lines.  Ending at commas means you can write multiple short tags on one-       line, comma separated:--                  assets:checking       ; a comment containing tag1:, tag2: some value ...--       Here,--       o "a comment containing" is just comment text, not a tag--       o "tag1" is a tag with no value--       o "tag2" is another tag, whose value is "some value ..."--       Tags  in  a  transaction  comment affect the transaction and all of its-       postings, while tags in a posting comment  affect  only  that  posting.-       For  example,  the  following  transaction  has  three  tags  (A, TAG2,-       third-tag) and the posting has four (those plus posting-tag):--              1/1 a transaction  ; A:, TAG2:-                  ; third-tag: a third transaction tag, <- with a value-                  (a)  $1  ; posting-tag:--       Tags are like Ledger's metadata feature, except  hledger's  tag  values-       are simple strings.--   Directives-   Account aliases-       You  can define aliases which rewrite your account names (after reading-       the journal, before generating reports).  hledger's account aliases can-       be useful for:--       o expanding shorthand account names to their full form, allowing easier-         data entry and a less verbose journal--       o adapting old journals to your current chart of accounts--       o experimenting with new account organisations, like a new hierarchy or-         combining two accounts into one--       o customising reports--       See also Cookbook: rewrite account names.--   Basic aliases-       To  set an account alias, use the alias directive in your journal file.-       This affects all subsequent journal entries in the current file or  its-       included files.  The spaces around the = are optional:--              alias OLD = NEW--       Or, you can use the --alias 'OLD=NEW' option on the command line.  This-       affects all entries.  It's useful for trying out aliases interactively.--       OLD  and  NEW  are full account names.  hledger will replace any occur--       rence of the old account name with the new one.  Subaccounts  are  also-       affected.  Eg:--              alias checking = assets:bank:wells fargo:checking-              # rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"--   Regex aliases-       There  is  also a more powerful variant that uses a regular expression,-       indicated by the forward slashes:--              alias /REGEX/ = REPLACEMENT--       or --alias '/REGEX/=REPLACEMENT'.--       REGEX is a case-insensitive regular expression.   Anywhere  it  matches-       inside  an  account name, the matched part will be replaced by REPLACE--       MENT.  If REGEX contains parenthesised match groups, these can be  ref--       erenced by the usual numeric backreferences in REPLACEMENT.  Eg:--              alias /^(.+):bank:([^:]+)(.*)/ = \1:\2 \3-              # rewrites "assets:bank:wells fargo:checking" to  "assets:wells fargo checking"--       Also  note that REPLACEMENT continues to the end of line (or on command-       line, to end of option argument), so it  can  contain  trailing  white--       space.--   Multiple aliases-       You  can  define  as  many aliases as you like using directives or com--       mand-line options.  Aliases are recursive - each alias sees the  result-       of  applying  previous  ones.   (This  is  different from Ledger, where-       aliases are non-recursive by default).  Aliases are applied in the fol--       lowing order:--       1. alias  directives,  most recently seen first (recent directives take-          precedence over earlier ones; directives not yet seen are ignored)--       2. alias options, in the order they appear on the command line--   end aliases-       You  can  clear  (forget)  all  currently  defined  aliases  with   the-       end aliases directive:--              end aliases--   account directive-       The  account directive predefines account names, as in Ledger and Bean--       count.  This may be useful for your own documentation; hledger  doesn't-       make use of it yet.--              ; account ACCT-              ;   OPTIONAL COMMENTS/TAGS...--              account assets:bank:checking-               a comment-               acct-no:12345--              account expenses:food--              ; etc.--   apply account directive-       You  can  specify  a  parent  account  which  will  be prepended to all-       accounts within a section of the journal.  Use  the  apply account  and-       end apply account directives like so:--              apply account home--              2010/1/1-                  food    $10-                  cash--              end apply account--       which is equivalent to:--              2010/01/01-                  home:food           $10-                  home:cash          $-10--       If  end apply account  is  omitted,  the effect lasts to the end of the-       file.  Included files are also affected, eg:--              apply account business-              include biz.journal-              end apply account-              apply account personal-              include personal.journal--       Prior to hledger 1.0, legacy account and end spellings were  also  sup--       ported.--   Multi-line comments-       A  line containing just comment starts a multi-line comment, and a line-       containing just end comment ends it.  See comments.--   commodity directive-       The commodity directive predefines commodities (currently this is  just-       informational),  and  also it may define the display format for amounts-       in this commodity (overriding the automatically inferred format).--       It may be written on a single line, like this:--              ; commodity EXAMPLEAMOUNT--              ; display AAAA amounts with the symbol on the right, space-separated,-              ; using period as decimal point, with four decimal places, and-              ; separating thousands with comma.-              commodity 1,000.0000 AAAA--       or on multiple lines, using the "format" subdirective.   In  this  case-       the  commodity  symbol  appears  twice  and  should be the same in both-       places:--              ; commodity SYMBOL-              ;   format EXAMPLEAMOUNT--              ; display indian rupees with currency name on the left,-              ; thousands, lakhs and crores comma-separated,-              ; period as decimal point, and two decimal places.-              commodity INR-                format INR 9,99,99,999.00--   Default commodity-       The D directive sets a default commodity (and display  format),  to  be-       used for amounts without a commodity symbol (ie, plain numbers).  (Note-       this differs from Ledger's default commodity directive.) The  commodity-       and  display  format  will  be applied to all subsequent commodity-less-       amounts, or until the next D directive.--              # commodity-less amounts should be treated as dollars-              # (and displayed with symbol on the left, thousands separators and two decimal places)-              D $1,000.00--              1/1-                a     5    # <- commodity-less amount, becomes $1-                b--   Default year-       You can set a default year to be used for subsequent dates which  don't-       specify  a year.  This is a line beginning with Y followed by the year.-       Eg:--              Y2009      ; set default year to 2009--              12/15      ; equivalent to 2009/12/15-                expenses  1-                assets--              Y2010      ; change default year to 2010--              2009/1/30  ; specifies the year, not affected-                expenses  1-                assets--              1/31       ; equivalent to 2010/1/31-                expenses  1-                assets--   Including other files-       You can pull in the content of additional journal files by  writing  an-       include directive, like this:--              include path/to/file.journal--       If  the path does not begin with a slash, it is relative to the current-       file.  Glob patterns (*) are not currently supported.--       The include directive can only  be  used  in  journal  files.   It  can-       include journal, timeclock or timedot files, but not CSV files.--EDITOR SUPPORT-       Add-on modes exist for various text editors, to make working with jour--       nal files easier.  They add colour, navigation aids  and  helpful  com--       mands.   For  hledger  users  who  edit  the journal file directly (the-       majority), using one of these modes is quite recommended.--       These were written with Ledger in mind,  but  also  work  with  hledger-       files:---       Emacs              http://www.ledger-cli.org/3.0/doc/ledger-mode.html-       Vim                https://github.com/ledger/ledger/wiki/Get--                          ting-started-       Sublime Text       https://github.com/ledger/ledger/wiki/Using-Sub--                          lime-Text-       Textmate           https://github.com/ledger/ledger/wiki/Using-Text--                          Mate-2-       Text Wrangler      https://github.com/ledger/ledger/wiki/Edit--                          ing-Ledger-files-with-TextWrangler---       Visual    Studio   https://marketplace.visualstudio.com/items?item--       Code               Name=mark-hansen.hledger-vscode----REPORTING BUGS-       Report  bugs at http://bugs.hledger.org (or on the #hledger IRC channel-       or hledger mail list)---AUTHORS-       Simon Michael <simon@joyful.com> and contributors---COPYRIGHT-       Copyright (C) 2007-2016 Simon Michael.-       Released under GNU GPL v3 or later.---SEE ALSO-       hledger(1),     hledger-ui(1),     hledger-web(1),      hledger-api(1),-       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time--       dot(5), ledger(1)--       http://hledger.org----hledger 1.4                     September 2017              hledger_journal(5)
− doc/hledger_timeclock.5
@@ -1,100 +0,0 @@--.TH "hledger_timeclock" "5" "September 2017" "hledger 1.4" "hledger User Manuals"----.SH NAME-.PP-Timeclock \- the time logging format of timeclock.el, as read by hledger-.SH DESCRIPTION-.PP-hledger can read timeclock files.-As with Ledger, these are (a subset of) timeclock.el\[aq]s format,-containing clock\-in and clock\-out entries as in the example below.-The date is a simple date.-The time format is HH:MM[:SS][+\-ZZZZ].-Seconds and timezone are optional.-The timezone, if present, must be four digits and is ignored (currently-the time is always interpreted as a local time).-.IP-.nf-\f[C]-i\ 2015/03/30\ 09:00:00\ some:account\ name\ \ optional\ description\ after\ two\ spaces-o\ 2015/03/30\ 09:20:00-i\ 2015/03/31\ 22:21:45\ another\ account-o\ 2015/04/01\ 02:00:34-\f[]-.fi-.PP-hledger treats each clock\-in/clock\-out pair as a transaction posting-some number of hours to an account.-Or if the session spans more than one day, it is split into several-transactions, one for each day.-For the above time log, \f[C]hledger\ print\f[] generates these journal-entries:-.IP-.nf-\f[C]-$\ hledger\ \-f\ t.timeclock\ print-2015/03/30\ *\ optional\ description\ after\ two\ spaces-\ \ \ \ (some:account\ name)\ \ \ \ \ \ \ \ \ 0.33h--2015/03/31\ *\ 22:21\-23:59-\ \ \ \ (another\ account)\ \ \ \ \ \ \ \ \ 1.64h--2015/04/01\ *\ 00:00\-02:00-\ \ \ \ (another\ account)\ \ \ \ \ \ \ \ \ 2.01h-\f[]-.fi-.PP-Here is a sample.timeclock to download and some queries to try:-.IP-.nf-\f[C]-$\ hledger\ \-f\ sample.timeclock\ balance\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ current\ time\ balances-$\ hledger\ \-f\ sample.timeclock\ register\ \-p\ 2009/3\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ sessions\ in\ march\ 2009-$\ hledger\ \-f\ sample.timeclock\ register\ \-p\ weekly\ \-\-depth\ 1\ \-\-empty\ \ #\ time\ summary\ by\ week-\f[]-.fi-.PP-To generate time logs, ie to clock in and clock out, you could:-.IP \[bu] 2-use emacs and the built\-in timeclock.el, or the extended-timeclock\-x.el and perhaps the extras in ledgerutils.el-.IP \[bu] 2-at the command line, use these bash aliases:-.RS 2-.IP-.nf-\f[C]-alias\ ti="echo\ i\ `date\ \[aq]+%Y\-%m\-%d\ %H:%M:%S\[aq]`\ \\$*\ >>$TIMELOG"-alias\ to="echo\ o\ `date\ \[aq]+%Y\-%m\-%d\ %H:%M:%S\[aq]`\ >>$TIMELOG"-\f[]-.fi-.RE-.IP \[bu] 2-or use the old \f[C]ti\f[] and \f[C]to\f[] scripts in the ledger 2.x-repository.-These rely on a "timeclock" executable which I think is just the ledger-2 executable renamed.---.SH "REPORTING BUGS"-Report bugs at http://bugs.hledger.org-(or on the #hledger IRC channel or hledger mail list)--.SH AUTHORS-Simon Michael <simon@joyful.com> and contributors--.SH COPYRIGHT--Copyright (C) 2007-2016 Simon Michael.-.br-Released under GNU GPL v3 or later.--.SH SEE ALSO-hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),-hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),-ledger(1)--http://hledger.org
− doc/hledger_timeclock.5.info
@@ -1,62 +0,0 @@-This is hledger_timeclock.5.info, produced by makeinfo version 6.0 from-stdin.---File: hledger_timeclock.5.info,  Node: Top,  Up: (dir)--hledger_timeclock(5) hledger 1.4-********************************--hledger can read timeclock files.  As with Ledger, these are (a subset-of) timeclock.el's format, containing clock-in and clock-out entries as-in the example below.  The date is a simple date.  The time format is-HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional.  The timezone, if-present, must be four digits and is ignored (currently the time is-always interpreted as a local time).--i 2015/03/30 09:00:00 some:account name  optional description after two spaces-o 2015/03/30 09:20:00-i 2015/03/31 22:21:45 another account-o 2015/04/01 02:00:34--   hledger treats each clock-in/clock-out pair as a transaction posting-some number of hours to an account.  Or if the session spans more than-one day, it is split into several transactions, one for each day.  For-the above time log, 'hledger print' generates these journal entries:--$ hledger -f t.timeclock print-2015/03/30 * optional description after two spaces-    (some:account name)         0.33h--2015/03/31 * 22:21-23:59-    (another account)         1.64h--2015/04/01 * 00:00-02:00-    (another account)         2.01h--   Here is a sample.timeclock to download and some queries to try:--$ hledger -f sample.timeclock balance                               # current time balances-$ hledger -f sample.timeclock register -p 2009/3                    # sessions in march 2009-$ hledger -f sample.timeclock register -p weekly --depth 1 --empty  # time summary by week--   To generate time logs, ie to clock in and clock out, you could:--   * use emacs and the built-in timeclock.el, or the extended-     timeclock-x.el and perhaps the extras in ledgerutils.el--   * at the command line, use these bash aliases:--     alias ti="echo i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG"-     alias to="echo o `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"--   * or use the old 'ti' and 'to' scripts in the ledger 2.x repository.-     These rely on a "timeclock" executable which I think is just the-     ledger 2 executable renamed.----Tag Table:-Node: Top80--End Tag Table
− doc/hledger_timeclock.5.txt
@@ -1,82 +0,0 @@--hledger_timeclock(5)         hledger User Manuals         hledger_timeclock(5)----NAME-       Timeclock - the time logging format of timeclock.el, as read by hledger--DESCRIPTION-       hledger can read timeclock files.  As with Ledger, these are (a  subset-       of) timeclock.el's format, containing clock-in and clock-out entries as-       in the example below.  The date is a simple date.  The time  format  is-       HH:MM[:SS][+-ZZZZ].   Seconds and timezone are optional.  The timezone,-       if present, must be four digits and is ignored (currently the  time  is-       always interpreted as a local time).--              i 2015/03/30 09:00:00 some:account name  optional description after two spaces-              o 2015/03/30 09:20:00-              i 2015/03/31 22:21:45 another account-              o 2015/04/01 02:00:34--       hledger  treats  each  clock-in/clock-out pair as a transaction posting-       some number of hours to an account.  Or if the session spans more  than-       one  day, it is split into several transactions, one for each day.  For-       the above time log, hledger print generates these journal entries:--              $ hledger -f t.timeclock print-              2015/03/30 * optional description after two spaces-                  (some:account name)         0.33h--              2015/03/31 * 22:21-23:59-                  (another account)         1.64h--              2015/04/01 * 00:00-02:00-                  (another account)         2.01h--       Here is a sample.timeclock to download and some queries to try:--              $ hledger -f sample.timeclock balance                               # current time balances-              $ hledger -f sample.timeclock register -p 2009/3                    # sessions in march 2009-              $ hledger -f sample.timeclock register -p weekly --depth 1 --empty  # time summary by week--       To generate time logs, ie to clock in and clock out, you could:--       o use emacs and  the  built-in  timeclock.el,  or  the  extended  time--         clock-x.el and perhaps the extras in ledgerutils.el--       o at the command line, use these bash aliases:--                alias ti="echo i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG"-                alias to="echo o `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"--       o or use the old ti and to scripts in the ledger 2.x repository.  These-         rely on a "timeclock" executable which I think is just the  ledger  2-         executable renamed.----REPORTING BUGS-       Report  bugs at http://bugs.hledger.org (or on the #hledger IRC channel-       or hledger mail list)---AUTHORS-       Simon Michael <simon@joyful.com> and contributors---COPYRIGHT-       Copyright (C) 2007-2016 Simon Michael.-       Released under GNU GPL v3 or later.---SEE ALSO-       hledger(1),     hledger-ui(1),     hledger-web(1),      hledger-api(1),-       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time--       dot(5), ledger(1)--       http://hledger.org----hledger 1.4                     September 2017            hledger_timeclock(5)
− doc/hledger_timedot.5
@@ -1,154 +0,0 @@--.TH "hledger_timedot" "5" "September 2017" "hledger 1.4" "hledger User Manuals"----.SH NAME-.PP-Timedot \- hledger\[aq]s human\-friendly time logging format-.SH DESCRIPTION-.PP-Timedot is a plain text format for logging dated, categorised quantities-(of time, usually), supported by hledger.-It is convenient for approximate and retroactive time logging, eg when-the real\-time clock\-in/out required with a timeclock file is too-precise or too interruptive.-It can be formatted like a bar chart, making clear at a glance where-time was spent.-.PP-Though called "timedot", this format is read by hledger as commodityless-quantities, so it could be used to represent dated quantities other than-time.-In the docs below we\[aq]ll assume it\[aq]s time.-.SH FILE FORMAT-.PP-A timedot file contains a series of day entries.-A day entry begins with a date, and is followed by category/quantity-pairs, one per line.-Dates are hledger\-style simple dates (see hledger_journal(5)).-Categories are hledger\-style account names, optionally indented.-As in a hledger journal, there must be at least two spaces between the-category (account name) and the quantity.-.PP-Quantities can be written as:-.IP \[bu] 2-a sequence of dots (.) representing quarter hours.-Spaces may optionally be used for grouping and readability.-Eg: ....-\&..-.IP \[bu] 2-an integral or decimal number, representing hours.-Eg: 1.5-.IP \[bu] 2-an integral or decimal number immediately followed by a unit symbol-\f[C]s\f[], \f[C]m\f[], \f[C]h\f[], \f[C]d\f[], \f[C]w\f[], \f[C]mo\f[],-or \f[C]y\f[], representing seconds, minutes, hours, days weeks, months-or years respectively.-Eg: 90m.-The following equivalencies are assumed, currently: 1m = 60s, 1h = 60m,-1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.-.PP-Blank lines and lines beginning with #, ; or * are ignored.-An example:-.IP-.nf-\f[C]-#\ on\ this\ day,\ 6h\ was\ spent\ on\ client\ work,\ 1.5h\ on\ haskell\ FOSS\ work,\ etc.-2016/2/1-inc:client1\ \ \ ....\ ....\ ....\ ....\ ....\ ....-fos:haskell\ \ \ ....\ ..\ -biz:research\ \ .--2016/2/2-inc:client1\ \ \ ....\ ....-biz:research\ \ .-\f[]-.fi-.PP-Or with numbers:-.IP-.nf-\f[C]-2016/2/3-inc:client1\ \ \ 4-fos:hledger\ \ \ 3-biz:research\ \ 1-\f[]-.fi-.PP-Reporting:-.IP-.nf-\f[C]-$\ hledger\ \-f\ t.timedot\ print\ date:2016/2/2-2016/02/02\ *-\ \ \ \ (inc:client1)\ \ \ \ \ \ \ \ \ \ 2.00--2016/02/02\ *-\ \ \ \ (biz:research)\ \ \ \ \ \ \ \ \ \ 0.25-\f[]-.fi-.IP-.nf-\f[C]-$\ hledger\ \-f\ t.timedot\ bal\ \-\-daily\ \-\-tree-Balance\ changes\ in\ 2016/02/01\-2016/02/03:--\ \ \ \ \ \ \ \ \ \ \ \ ||\ \ 2016/02/01d\ \ 2016/02/02d\ \ 2016/02/03d\ -============++========================================-\ biz\ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 1.00\ -\ \ \ research\ ||\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 1.00\ -\ fos\ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 1.50\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ 3.00\ -\ \ \ haskell\ \ ||\ \ \ \ \ \ \ \ \ 1.50\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ \ \ \ 0\ -\ \ \ hledger\ \ ||\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ 3.00\ -\ inc\ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 6.00\ \ \ \ \ \ \ \ \ 2.00\ \ \ \ \ \ \ \ \ 4.00\ -\ \ \ client1\ \ ||\ \ \ \ \ \ \ \ \ 6.00\ \ \ \ \ \ \ \ \ 2.00\ \ \ \ \ \ \ \ \ 4.00\ -\-\-\-\-\-\-\-\-\-\-\-\-++\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--\ \ \ \ \ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 7.75\ \ \ \ \ \ \ \ \ 2.25\ \ \ \ \ \ \ \ \ 8.00\ -\f[]-.fi-.PP-I prefer to use period for separating account components.-We can make this work with an account alias:-.IP-.nf-\f[C]-2016/2/4-fos.hledger.timedot\ \ 4-fos.ledger\ \ \ \ \ \ \ \ \ \ \ ..-\f[]-.fi-.IP-.nf-\f[C]-$\ hledger\ \-f\ t.timedot\ \-\-alias\ /\\\\./=:\ bal\ date:2016/2/4-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 4.50\ \ fos-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 4.00\ \ \ \ hledger:timedot-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 0.50\ \ \ \ ledger-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 4.50-\f[]-.fi-.PP-Here is a sample.timedot.---.SH "REPORTING BUGS"-Report bugs at http://bugs.hledger.org-(or on the #hledger IRC channel or hledger mail list)--.SH AUTHORS-Simon Michael <simon@joyful.com> and contributors--.SH COPYRIGHT--Copyright (C) 2007-2016 Simon Michael.-.br-Released under GNU GPL v3 or later.--.SH SEE ALSO-hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),-hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),-ledger(1)--http://hledger.org
− doc/hledger_timedot.5.info
@@ -1,116 +0,0 @@-This is hledger_timedot.5.info, produced by makeinfo version 6.0 from-stdin.---File: hledger_timedot.5.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir)--hledger_timedot(5) hledger 1.4-******************************--Timedot is a plain text format for logging dated, categorised quantities-(of time, usually), supported by hledger.  It is convenient for-approximate and retroactive time logging, eg when the real-time-clock-in/out required with a timeclock file is too precise or too-interruptive.  It can be formatted like a bar chart, making clear at a-glance where time was spent.--   Though called "timedot", this format is read by hledger as-commodityless quantities, so it could be used to represent dated-quantities other than time.  In the docs below we'll assume it's time.-* Menu:--* FILE FORMAT::---File: hledger_timedot.5.info,  Node: FILE FORMAT,  Prev: Top,  Up: Top--1 FILE FORMAT-*************--A timedot file contains a series of day entries.  A day entry begins-with a date, and is followed by category/quantity pairs, one per line.-Dates are hledger-style simple dates (see hledger_journal(5)).-Categories are hledger-style account names, optionally indented.  As in-a hledger journal, there must be at least two spaces between the-category (account name) and the quantity.--   Quantities can be written as:--   * a sequence of dots (.)  representing quarter hours.  Spaces may-     optionally be used for grouping and readability.  Eg: ....  ..--   * an integral or decimal number, representing hours.  Eg: 1.5--   * an integral or decimal number immediately followed by a unit symbol-     's', 'm', 'h', 'd', 'w', 'mo', or 'y', representing seconds,-     minutes, hours, days weeks, months or years respectively.  Eg: 90m.-     The following equivalencies are assumed, currently: 1m = 60s, 1h =-     60m, 1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.--   Blank lines and lines beginning with #, ; or * are ignored.  An-example:--# on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.-2016/2/1-inc:client1   .... .... .... .... .... ....-fos:haskell   .... ..-biz:research  .--2016/2/2-inc:client1   .... ....-biz:research  .--   Or with numbers:--2016/2/3-inc:client1   4-fos:hledger   3-biz:research  1--   Reporting:--$ hledger -f t.timedot print date:2016/2/2-2016/02/02 *-    (inc:client1)          2.00--2016/02/02 *-    (biz:research)          0.25--$ hledger -f t.timedot bal --daily --tree-Balance changes in 2016/02/01-2016/02/03:--            ||  2016/02/01d  2016/02/02d  2016/02/03d-============++========================================- biz        ||         0.25         0.25         1.00-   research ||         0.25         0.25         1.00- fos        ||         1.50            0         3.00-   haskell  ||         1.50            0            0-   hledger  ||            0            0         3.00- inc        ||         6.00         2.00         4.00-   client1  ||         6.00         2.00         4.00-------------++-----------------------------------------            ||         7.75         2.25         8.00--   I prefer to use period for separating account components.  We can-make this work with an account alias:--2016/2/4-fos.hledger.timedot  4-fos.ledger           ..--$ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4-                4.50  fos-                4.00    hledger:timedot-                0.50    ledger----------------------                4.50--   Here is a sample.timedot.---Tag Table:-Node: Top78-Node: FILE FORMAT809-Ref: #file-format912--End Tag Table
− doc/hledger_timedot.5.txt
@@ -1,127 +0,0 @@--hledger_timedot(5)           hledger User Manuals           hledger_timedot(5)----NAME-       Timedot - hledger's human-friendly time logging format--DESCRIPTION-       Timedot  is  a plain text format for logging dated, categorised quanti--       ties (of time, usually), supported by hledger.  It  is  convenient  for-       approximate  and  retroactive  time  logging,  eg  when  the  real-time-       clock-in/out required with a timeclock  file  is  too  precise  or  too-       interruptive.   It can be formatted like a bar chart, making clear at a-       glance where time was spent.--       Though called "timedot", this format is read by hledger  as  commodity--       less  quantities,  so  it  could  be used to represent dated quantities-       other than time.  In the docs below we'll assume it's time.--FILE FORMAT-       A timedot file contains a series of day entries.  A  day  entry  begins-       with  a date, and is followed by category/quantity pairs, one per line.-       Dates are hledger-style simple dates (see  hledger_journal(5)).   Cate--       gories  are  hledger-style account names, optionally indented.  As in a-       hledger journal, there must be at least two spaces between the category-       (account name) and the quantity.--       Quantities can be written as:--       o a  sequence  of  dots  (.)  representing  quarter  hours.  Spaces may-         optionally be used for grouping and readability.  Eg: ....  ..--       o an integral or decimal number, representing hours.  Eg: 1.5--       o an integral or decimal number immediately followed by a  unit  symbol-         s,  m,  h, d, w, mo, or y, representing seconds, minutes, hours, days-         weeks, months or years respectively.  Eg: 90m.  The following equiva--         lencies  are  assumed,  currently: 1m = 60s, 1h = 60m, 1d = 24h, 1w =-         7d, 1mo = 30d, 1y=365d.--       Blank lines and lines beginning with #, ; or * are ignored.   An  exam--       ple:--              # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.-              2016/2/1-              inc:client1   .... .... .... .... .... ....-              fos:haskell   .... ..-              biz:research  .--              2016/2/2-              inc:client1   .... ....-              biz:research  .--       Or with numbers:--              2016/2/3-              inc:client1   4-              fos:hledger   3-              biz:research  1--       Reporting:--              $ hledger -f t.timedot print date:2016/2/2-              2016/02/02 *-                  (inc:client1)          2.00--              2016/02/02 *-                  (biz:research)          0.25--              $ hledger -f t.timedot bal --daily --tree-              Balance changes in 2016/02/01-2016/02/03:--                          ||  2016/02/01d  2016/02/02d  2016/02/03d-              ============++========================================-               biz        ||         0.25         0.25         1.00-                 research ||         0.25         0.25         1.00-               fos        ||         1.50            0         3.00-                 haskell  ||         1.50            0            0-                 hledger  ||            0            0         3.00-               inc        ||         6.00         2.00         4.00-                 client1  ||         6.00         2.00         4.00-              ------------++-----------------------------------------                          ||         7.75         2.25         8.00--       I  prefer to use period for separating account components.  We can make-       this work with an account alias:--              2016/2/4-              fos.hledger.timedot  4-              fos.ledger           ..--              $ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4-                              4.50  fos-                              4.00    hledger:timedot-                              0.50    ledger-              ---------------------                              4.50--       Here is a sample.timedot.----REPORTING BUGS-       Report bugs at http://bugs.hledger.org (or on the #hledger IRC  channel-       or hledger mail list)---AUTHORS-       Simon Michael <simon@joyful.com> and contributors---COPYRIGHT-       Copyright (C) 2007-2016 Simon Michael.-       Released under GNU GPL v3 or later.---SEE ALSO-       hledger(1),      hledger-ui(1),     hledger-web(1),     hledger-api(1),-       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time--       dot(5), ledger(1)--       http://hledger.org----hledger 1.4                     September 2017              hledger_timedot(5)
hledger-lib.cabal view
@@ -1,9 +1,11 @@--- This file has been generated from package.yaml by hpack version 0.17.1.+-- This file has been generated from package.yaml by hpack version 0.20.0. -- -- see: https://github.com/sol/hpack+--+-- hash: c0497f13da483640b446c596007d9e15f8235a01f8b2ae8ffa96f89dbf59ffb7  name:           hledger-lib-version:        1.4+version:        1.5 synopsis:       Core data types, parsers and functionality for the hledger accounting tools description:    This is a reusable library containing hledger's core functionality.                 .@@ -30,18 +32,18 @@     README  data-files:-    doc/hledger_csv.5-    doc/hledger_csv.5.info-    doc/hledger_csv.5.txt-    doc/hledger_journal.5-    doc/hledger_journal.5.info-    doc/hledger_journal.5.txt-    doc/hledger_timeclock.5-    doc/hledger_timeclock.5.info-    doc/hledger_timeclock.5.txt-    doc/hledger_timedot.5-    doc/hledger_timedot.5.info-    doc/hledger_timedot.5.txt+    hledger_csv.5+    hledger_csv.info+    hledger_csv.txt+    hledger_journal.5+    hledger_journal.info+    hledger_journal.txt+    hledger_timeclock.5+    hledger_timeclock.info+    hledger_timeclock.txt+    hledger_timedot.5+    hledger_timedot.info+    hledger_timedot.txt  source-repository head   type: git@@ -52,37 +54,38 @@       ./.   ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-name-shadowing -fno-warn-missing-signatures -fno-warn-type-defaults -fno-warn-orphans   build-depends:-      base >=4.8 && <5-    , base-compat >=0.8.1-    , ansi-terminal >= 0.6.2.3 && < 0.8+      Decimal+    , HUnit+    , ansi-terminal >=0.6.2.3     , array+    , base >=4.8 && <5+    , base-compat >=0.8.1     , blaze-markup >=0.5.1     , bytestring-    , cmdargs >=0.10 && <0.11+    , cmdargs >=0.10     , containers     , csv     , data-default >=0.5-    , Decimal     , deepseq     , directory+    , extra     , filepath-    , hashtables >= 1.2-    , megaparsec >=5.0 && < 6.2+    , hashtables >=1.2+    , megaparsec >=5.0     , mtl     , mtl-compat     , old-time-    , parsec >= 3+    , parsec >=3     , pretty-show >=1.6.4     , regex-tdfa     , safe >=0.2     , semigroups-    , split >=0.1 && <0.3-    , text >=1.2 && <1.3+    , split >=0.1+    , text >=1.2     , time >=1.5-    , transformers >=0.2 && <0.6+    , transformers >=0.2     , uglymemo-    , utf8-string >=0.3.5 && <1.1-    , HUnit+    , utf8-string >=0.3.5   exposed-modules:       Hledger       Hledger.Data@@ -140,39 +143,40 @@       tests   ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-name-shadowing -fno-warn-missing-signatures -fno-warn-type-defaults -fno-warn-orphans   build-depends:-      base >=4.8 && <5-    , base-compat >=0.8.1-    , ansi-terminal >= 0.6.2.3 && < 0.8+      Decimal+    , Glob >=0.7+    , HUnit+    , ansi-terminal >=0.6.2.3     , array+    , base >=4.8 && <5+    , base-compat >=0.8.1     , blaze-markup >=0.5.1     , bytestring-    , cmdargs >=0.10 && <0.11+    , cmdargs >=0.10     , containers     , csv     , data-default >=0.5-    , Decimal     , deepseq     , directory+    , doctest >=0.8+    , extra     , filepath-    , hashtables >= 1.2-    , megaparsec >=5.0 && < 6.2+    , hashtables >=1.2+    , megaparsec >=5.0     , mtl     , mtl-compat     , old-time-    , parsec >= 3+    , parsec >=3     , pretty-show >=1.6.4     , regex-tdfa     , safe >=0.2     , semigroups-    , split >=0.1 && <0.3-    , text >=1.2 && <1.3+    , split >=0.1+    , text >=1.2     , time >=1.5-    , transformers >=0.2 && <0.6+    , transformers >=0.2     , uglymemo-    , utf8-string >=0.3.5 && <1.1-    , HUnit-    , doctest >=0.8-    , Glob >=0.7+    , utf8-string >=0.3.5   other-modules:       Hledger       Hledger.Data@@ -218,6 +222,7 @@       Hledger.Utils.Tree       Hledger.Utils.UTF8IOCompat       Text.Megaparsec.Compat+      Paths_hledger_lib   default-language: Haskell2010  test-suite hunittests@@ -228,40 +233,41 @@       tests   ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-name-shadowing -fno-warn-missing-signatures -fno-warn-type-defaults -fno-warn-orphans   build-depends:-      base >=4.8 && <5-    , base-compat >=0.8.1-    , ansi-terminal >= 0.6.2.3 && < 0.8+      Decimal+    , HUnit+    , ansi-terminal >=0.6.2.3     , array+    , base >=4.8 && <5+    , base-compat >=0.8.1     , blaze-markup >=0.5.1     , bytestring-    , cmdargs >=0.10 && <0.11+    , cmdargs >=0.10     , containers     , csv     , data-default >=0.5-    , Decimal     , deepseq     , directory+    , extra     , filepath-    , hashtables >= 1.2-    , megaparsec >=5.0 && < 6.2+    , hashtables >=1.2+    , hledger-lib+    , megaparsec >=5.0     , mtl     , mtl-compat     , old-time-    , parsec >= 3+    , parsec >=3     , pretty-show >=1.6.4     , regex-tdfa     , safe >=0.2     , semigroups-    , split >=0.1 && <0.3-    , text >=1.2 && <1.3-    , time >=1.5-    , transformers >=0.2 && <0.6-    , uglymemo-    , utf8-string >=0.3.5 && <1.1-    , HUnit-    , hledger-lib+    , split >=0.1     , test-framework     , test-framework-hunit+    , text >=1.2+    , time >=1.5+    , transformers >=0.2+    , uglymemo+    , utf8-string >=0.3.5   other-modules:       Hledger       Hledger.Data@@ -307,4 +313,5 @@       Hledger.Utils.Tree       Hledger.Utils.UTF8IOCompat       Text.Megaparsec.Compat+      Paths_hledger_lib   default-language: Haskell2010
+ hledger_csv.5 view
@@ -0,0 +1,334 @@++.TH "hledger_csv" "5" "December 2017" "hledger 1.5" "hledger User Manuals"++++.SH NAME+.PP+CSV \- how hledger reads CSV data, and the CSV rules file format+.SH DESCRIPTION+.PP+hledger can read CSV (comma\-separated value) files as if they were+journal files, automatically converting each CSV record into a+transaction.+(To learn about \f[I]writing\f[] CSV, see CSV output.)+.PP+Converting CSV to transactions requires some special conversion rules.+These do several things:+.IP \[bu] 2+they describe the layout and format of the CSV data+.IP \[bu] 2+they can customize the generated journal entries using a simple+templating language+.IP \[bu] 2+they can add refinements based on patterns in the CSV data, eg+categorizing transactions with more detailed account names.+.PP+When reading a CSV file named \f[C]FILE.csv\f[], hledger looks for a+conversion rules file named \f[C]FILE.csv.rules\f[] in the same+directory.+You can override this with the \f[C]\-\-rules\-file\f[] option.+If the rules file does not exist, hledger will auto\-create one with+some example rules, which you'll need to adjust.+.PP+At minimum, the rules file must identify the \f[C]date\f[] and+\f[C]amount\f[] fields.+It may also be necessary to specify the date format, and the number of+header lines to skip.+Eg:+.IP+.nf+\f[C]+fields\ date,\ _,\ _,\ amount+date\-format\ \ %d/%m/%Y+skip\ 1+\f[]+.fi+.PP+A more complete example:+.IP+.nf+\f[C]+#\ hledger\ CSV\ rules\ for\ amazon.com\ order\ history++#\ sample:+#\ "Date","Type","To/From","Name","Status","Amount","Fees","Transaction\ ID"+#\ "Jul\ 29,\ 2012","Payment","To","Adapteva,\ Inc.","Completed","$25.00","$0.00","17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL"++#\ skip\ one\ header\ line+skip\ 1++#\ name\ the\ csv\ fields\ (and\ assign\ the\ transaction\[aq]s\ date,\ amount\ and\ code)+fields\ date,\ _,\ toorfrom,\ name,\ amzstatus,\ amount,\ fees,\ code++#\ how\ to\ parse\ the\ date+date\-format\ %b\ %\-d,\ %Y++#\ combine\ two\ fields\ to\ make\ the\ description+description\ %toorfrom\ %name++#\ save\ these\ fields\ as\ tags+comment\ \ \ \ \ status:%amzstatus,\ fees:%fees++#\ set\ the\ base\ account\ for\ all\ transactions+account1\ \ \ \ assets:amazon++#\ flip\ the\ sign\ on\ the\ amount+amount\ \ \ \ \ \ \-%amount+\f[]+.fi+.PP+For more examples, see Convert CSV files.+.SH CSV RULES+.PP+The following seven kinds of rule can appear in the rules file, in any+order.+Blank lines and lines beginning with \f[C]#\f[] or \f[C];\f[] are+ignored.+.SS skip+.PP+\f[C]skip\f[]\f[I]\f[CI]N\f[I]\f[]+.PP+Skip this number of CSV records at the beginning.+You'll need this whenever your CSV data contains header lines.+Eg:+.IP+.nf+\f[C]+#\ ignore\ the\ first\ CSV\ line+skip\ 1+\f[]+.fi+.SS date\-format+.PP+\f[C]date\-format\f[]\f[I]\f[CI]DATEFMT\f[I]\f[]+.PP+When your CSV date fields are not formatted like \f[C]YYYY/MM/DD\f[] (or+\f[C]YYYY\-MM\-DD\f[] or \f[C]YYYY.MM.DD\f[]), you'll need to specify+the format.+DATEFMT is a strptime\-like date parsing pattern, which must parse the+date field values completely.+Examples:+.IP+.nf+\f[C]+#\ for\ dates\ like\ "6/11/2013":+date\-format\ %\-d/%\-m/%Y+\f[]+.fi+.IP+.nf+\f[C]+#\ for\ dates\ like\ "11/06/2013":+date\-format\ %m/%d/%Y+\f[]+.fi+.IP+.nf+\f[C]+#\ for\ dates\ like\ "2013\-Nov\-06":+date\-format\ %Y\-%h\-%d+\f[]+.fi+.IP+.nf+\f[C]+#\ for\ dates\ like\ "11/6/2013\ 11:32\ PM":+date\-format\ %\-m/%\-d/%Y\ %l:%M\ %p+\f[]+.fi+.SS field list+.PP+\f[C]fields\f[]\f[I]\f[CI]FIELDNAME1\f[I]\f[],+\f[I]\f[CI]FIELDNAME2\f[I]\f[]\&...+.PP+This (a) names the CSV fields, in order (names may not contain+whitespace; uninteresting names may be left blank), and (b) assigns them+to journal entry fields if you use any of these standard field names:+\f[C]date\f[], \f[C]date2\f[], \f[C]status\f[], \f[C]code\f[],+\f[C]description\f[], \f[C]comment\f[], \f[C]account1\f[],+\f[C]account2\f[], \f[C]amount\f[], \f[C]amount\-in\f[],+\f[C]amount\-out\f[], \f[C]currency\f[], \f[C]balance\f[].+Eg:+.IP+.nf+\f[C]+#\ use\ the\ 1st,\ 2nd\ and\ 4th\ CSV\ fields\ as\ the\ entry\[aq]s\ date,\ description\ and\ amount,+#\ and\ give\ the\ 7th\ and\ 8th\ fields\ meaningful\ names\ for\ later\ reference:+#+#\ CSV\ field:+#\ \ \ \ \ \ 1\ \ \ \ \ 2\ \ \ \ \ \ \ \ \ \ \ \ 3\ 4\ \ \ \ \ \ \ 5\ 6\ 7\ \ \ \ \ \ \ \ \ \ 8+#\ entry\ field:+fields\ date,\ description,\ ,\ amount,\ ,\ ,\ somefield,\ anotherfield+\f[]+.fi+.SS field assignment+.PP+\f[I]\f[CI]ENTRYFIELDNAME\f[I]\f[] \f[I]\f[CI]FIELDVALUE\f[I]\f[]+.PP+This sets a journal entry field (one of the standard names above) to the+given text value, which can include CSV field values interpolated by+name (\f[C]%CSVFIELDNAME\f[]) or 1\-based position (\f[C]%N\f[]).+ Eg:+.IP+.nf+\f[C]+#\ set\ the\ amount\ to\ the\ 4th\ CSV\ field\ with\ "USD\ "\ prepended+amount\ USD\ %4+\f[]+.fi+.IP+.nf+\f[C]+#\ combine\ three\ fields\ to\ make\ a\ comment\ (containing\ two\ tags)+comment\ note:\ %somefield\ \-\ %anotherfield,\ date:\ %1+\f[]+.fi+.PP+Field assignments can be used instead of or in addition to a field list.+.SS conditional block+.PP+\f[C]if\f[] \f[I]\f[CI]PATTERN\f[I]\f[]+.PD 0+.P+.PD+\ \ \ \ \f[I]\f[CI]FIELDASSIGNMENTS\f[I]\f[]\&...+.PP+\f[C]if\f[]+.PD 0+.P+.PD+\f[I]\f[CI]PATTERN\f[I]\f[]+.PD 0+.P+.PD+\f[I]\f[CI]PATTERN\f[I]\f[]\&...+.PD 0+.P+.PD+\ \ \ \ \f[I]\f[CI]FIELDASSIGNMENTS\f[I]\f[]\&...+.PP+This applies one or more field assignments, only to those CSV records+matched by one of the PATTERNs.+The patterns are case\-insensitive regular expressions which match+anywhere within the whole CSV record (it's not yet possible to match+within a specific field).+When there are multiple patterns they can be written on separate lines,+unindented.+The field assignments are on separate lines indented by at least one+space.+Examples:+.IP+.nf+\f[C]+#\ if\ the\ CSV\ record\ contains\ "groceries",\ set\ account2\ to\ "expenses:groceries"+if\ groceries+\ account2\ expenses:groceries+\f[]+.fi+.IP+.nf+\f[C]+#\ if\ the\ CSV\ record\ contains\ any\ of\ these\ patterns,\ set\ account2\ and\ comment\ as\ shown+if+monthly\ service\ fee+atm\ transaction\ fee+banking\ thru\ software+\ account2\ expenses:business:banking+\ comment\ \ XXX\ deductible\ ?\ check\ it+\f[]+.fi+.SS include+.PP+\f[C]include\f[]\f[I]\f[CI]RULESFILE\f[I]\f[]+.PP+Include another rules file at this point.+\f[C]RULESFILE\f[] is either an absolute file path or a path relative to+the current file's directory.+Eg:+.IP+.nf+\f[C]+#\ rules\ reused\ with\ several\ CSV\ files+include\ common.rules+\f[]+.fi+.SS newest\-first+.PP+\f[C]newest\-first\f[]+.PP+Consider adding this rule if all of the following are true: you might be+processing just one day of data, your CSV records are in reverse+chronological order (newest first), and you care about preserving the+order of same\-day transactions.+It usually isn't needed, because hledger autodetects the CSV order, but+when all CSV records have the same date it will assume they are oldest+first.+.SH CSV TIPS+.SS CSV ordering+.PP+The generated journal entries will be sorted by date.+The order of same\-day entries will be preserved (except in the special+case where you might need \f[C]newest\-first\f[], see above).+.SS CSV accounts+.PP+Each journal entry will have two postings, to \f[C]account1\f[] and+\f[C]account2\f[] respectively.+It's not yet possible to generate entries with more than two postings.+It's conventional and recommended to use \f[C]account1\f[] for the+account whose CSV we are reading.+.SS CSV amounts+.PP+The \f[C]amount\f[] field sets the amount of the \f[C]account1\f[]+posting.+.PP+If the CSV has debit/credit amounts in separate fields, assign to the+\f[C]amount\-in\f[] and \f[C]amount\-out\f[] pseudo fields instead.+(Whichever one has a value will be used, with appropriate sign.+If both contain a value, it may not work so well.)+.PP+If an amount value is parenthesised, it will be de\-parenthesised and+sign\-flipped.+.PP+If an amount value begins with a double minus sign, those will cancel+out and be removed.+.PP+If the CSV has the currency symbol in a separate field, assign that to+the \f[C]currency\f[] pseudo field to have it prepended to the amount.+Or, you can use a field assignment to \f[C]amount\f[] that interpolates+both CSV fields (giving more control, eg to put the currency symbol on+the right).+.SS CSV balance assertions+.PP+If the CSV includes a running balance, you can assign that to the+\f[C]balance\f[] pseudo field; whenever the running balance value is+non\-empty, it will be asserted as the balance after the+\f[C]account1\f[] posting.+.SS Reading multiple CSV files+.PP+You can read multiple CSV files at once using multiple \f[C]\-f\f[]+arguments on the command line, and hledger will look for a+correspondingly\-named rules file for each.+Note if you use the \f[C]\-\-rules\-file\f[] option, this one rules file+will be used for all the CSV files being read.+++.SH "REPORTING BUGS"+Report bugs at http://bugs.hledger.org+(or on the #hledger IRC channel or hledger mail list)++.SH AUTHORS+Simon Michael <simon@joyful.com> and contributors++.SH COPYRIGHT++Copyright (C) 2007-2016 Simon Michael.+.br+Released under GNU GPL v3 or later.++.SH SEE ALSO+hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),+hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),+ledger(1)++http://hledger.org
+ hledger_csv.info view
@@ -0,0 +1,349 @@+This is hledger_csv.info, produced by makeinfo version 6.5 from stdin.+++File: hledger_csv.info,  Node: Top,  Next: CSV RULES,  Up: (dir)++hledger_csv(5) hledger 1.5+**************************++hledger can read CSV (comma-separated value) files as if they were+journal files, automatically converting each CSV record into a+transaction.  (To learn about _writing_ CSV, see CSV output.)++   Converting CSV to transactions requires some special conversion+rules.  These do several things:++   * they describe the layout and format of the CSV data+   * they can customize the generated journal entries using a simple+     templating language+   * they can add refinements based on patterns in the CSV data, eg+     categorizing transactions with more detailed account names.++   When reading a CSV file named 'FILE.csv', hledger looks for a+conversion rules file named 'FILE.csv.rules' in the same directory.  You+can override this with the '--rules-file' option.  If the rules file+does not exist, hledger will auto-create one with some example rules,+which you'll need to adjust.++   At minimum, the rules file must identify the 'date' and 'amount'+fields.  It may also be necessary to specify the date format, and the+number of header lines to skip.  Eg:++fields date, _, _, amount+date-format  %d/%m/%Y+skip 1++   A more complete example:++# hledger CSV rules for amazon.com order history++# sample:+# "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"+# "Jul 29, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$0.00","17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL"++# skip one header line+skip 1++# name the csv fields (and assign the transaction's date, amount and code)+fields date, _, toorfrom, name, amzstatus, amount, fees, code++# how to parse the date+date-format %b %-d, %Y++# combine two fields to make the description+description %toorfrom %name++# save these fields as tags+comment     status:%amzstatus, fees:%fees++# set the base account for all transactions+account1    assets:amazon++# flip the sign on the amount+amount      -%amount++   For more examples, see Convert CSV files.+* Menu:++* CSV RULES::+* CSV TIPS::+++File: hledger_csv.info,  Node: CSV RULES,  Next: CSV TIPS,  Prev: Top,  Up: Top++1 CSV RULES+***********++The following seven kinds of rule can appear in the rules file, in any+order.  Blank lines and lines beginning with '#' or ';' are ignored.+* Menu:++* skip::+* date-format::+* field list::+* field assignment::+* conditional block::+* include::+* newest-first::+++File: hledger_csv.info,  Node: skip,  Next: date-format,  Up: CSV RULES++1.1 skip+========++'skip'_'N'_++   Skip this number of CSV records at the beginning.  You'll need this+whenever your CSV data contains header lines.  Eg:++# ignore the first CSV line+skip 1+++File: hledger_csv.info,  Node: date-format,  Next: field list,  Prev: skip,  Up: CSV RULES++1.2 date-format+===============++'date-format'_'DATEFMT'_++   When your CSV date fields are not formatted like 'YYYY/MM/DD' (or+'YYYY-MM-DD' or 'YYYY.MM.DD'), you'll need to specify the format.+DATEFMT is a strptime-like date parsing pattern, which must parse the+date field values completely.  Examples:++# for dates like "6/11/2013":+date-format %-d/%-m/%Y++# for dates like "11/06/2013":+date-format %m/%d/%Y++# for dates like "2013-Nov-06":+date-format %Y-%h-%d++# for dates like "11/6/2013 11:32 PM":+date-format %-m/%-d/%Y %l:%M %p+++File: hledger_csv.info,  Node: field list,  Next: field assignment,  Prev: date-format,  Up: CSV RULES++1.3 field list+==============++'fields'_'FIELDNAME1'_, _'FIELDNAME2'_...++   This (a) names the CSV fields, in order (names may not contain+whitespace; uninteresting names may be left blank), and (b) assigns them+to journal entry fields if you use any of these standard field names:+'date', 'date2', 'status', 'code', 'description', 'comment', 'account1',+'account2', 'amount', 'amount-in', 'amount-out', 'currency', 'balance'.+Eg:++# use the 1st, 2nd and 4th CSV fields as the entry's date, description and amount,+# and give the 7th and 8th fields meaningful names for later reference:+#+# CSV field:+#      1     2            3 4       5 6 7          8+# entry field:+fields date, description, , amount, , , somefield, anotherfield+++File: hledger_csv.info,  Node: field assignment,  Next: conditional block,  Prev: field list,  Up: CSV RULES++1.4 field assignment+====================++_'ENTRYFIELDNAME'_ _'FIELDVALUE'_++   This sets a journal entry field (one of the standard names above) to+the given text value, which can include CSV field values interpolated by+name ('%CSVFIELDNAME') or 1-based position ('%N').  Eg:++# set the amount to the 4th CSV field with "USD " prepended+amount USD %4++# combine three fields to make a comment (containing two tags)+comment note: %somefield - %anotherfield, date: %1++   Field assignments can be used instead of or in addition to a field+list.+++File: hledger_csv.info,  Node: conditional block,  Next: include,  Prev: field assignment,  Up: CSV RULES++1.5 conditional block+=====================++'if' _'PATTERN'_+    _'FIELDASSIGNMENTS'_...++   'if'+_'PATTERN'_+_'PATTERN'_...+    _'FIELDASSIGNMENTS'_...++   This applies one or more field assignments, only to those CSV records+matched by one of the PATTERNs.  The patterns are case-insensitive+regular expressions which match anywhere within the whole CSV record+(it's not yet possible to match within a specific field).  When there+are multiple patterns they can be written on separate lines, unindented.+The field assignments are on separate lines indented by at least one+space.  Examples:++# if the CSV record contains "groceries", set account2 to "expenses:groceries"+if groceries+ account2 expenses:groceries++# if the CSV record contains any of these patterns, set account2 and comment as shown+if+monthly service fee+atm transaction fee+banking thru software+ account2 expenses:business:banking+ comment  XXX deductible ? check it+++File: hledger_csv.info,  Node: include,  Next: newest-first,  Prev: conditional block,  Up: CSV RULES++1.6 include+===========++'include'_'RULESFILE'_++   Include another rules file at this point.  'RULESFILE' is either an+absolute file path or a path relative to the current file's directory.+Eg:++# rules reused with several CSV files+include common.rules+++File: hledger_csv.info,  Node: newest-first,  Prev: include,  Up: CSV RULES++1.7 newest-first+================++'newest-first'++   Consider adding this rule if all of the following are true: you might+be processing just one day of data, your CSV records are in reverse+chronological order (newest first), and you care about preserving the+order of same-day transactions.  It usually isn't needed, because+hledger autodetects the CSV order, but when all CSV records have the+same date it will assume they are oldest first.+++File: hledger_csv.info,  Node: CSV TIPS,  Prev: CSV RULES,  Up: Top++2 CSV TIPS+**********++* Menu:++* CSV ordering::+* CSV accounts::+* CSV amounts::+* CSV balance assertions::+* Reading multiple CSV files::+++File: hledger_csv.info,  Node: CSV ordering,  Next: CSV accounts,  Up: CSV TIPS++2.1 CSV ordering+================++The generated journal entries will be sorted by date.  The order of+same-day entries will be preserved (except in the special case where you+might need 'newest-first', see above).+++File: hledger_csv.info,  Node: CSV accounts,  Next: CSV amounts,  Prev: CSV ordering,  Up: CSV TIPS++2.2 CSV accounts+================++Each journal entry will have two postings, to 'account1' and 'account2'+respectively.  It's not yet possible to generate entries with more than+two postings.  It's conventional and recommended to use 'account1' for+the account whose CSV we are reading.+++File: hledger_csv.info,  Node: CSV amounts,  Next: CSV balance assertions,  Prev: CSV accounts,  Up: CSV TIPS++2.3 CSV amounts+===============++The 'amount' field sets the amount of the 'account1' posting.++   If the CSV has debit/credit amounts in separate fields, assign to the+'amount-in' and 'amount-out' pseudo fields instead.  (Whichever one has+a value will be used, with appropriate sign.  If both contain a value,+it may not work so well.)++   If an amount value is parenthesised, it will be de-parenthesised and+sign-flipped.++   If an amount value begins with a double minus sign, those will cancel+out and be removed.++   If the CSV has the currency symbol in a separate field, assign that+to the 'currency' pseudo field to have it prepended to the amount.  Or,+you can use a field assignment to 'amount' that interpolates both CSV+fields (giving more control, eg to put the currency symbol on the+right).+++File: hledger_csv.info,  Node: CSV balance assertions,  Next: Reading multiple CSV files,  Prev: CSV amounts,  Up: CSV TIPS++2.4 CSV balance assertions+==========================++If the CSV includes a running balance, you can assign that to the+'balance' pseudo field; whenever the running balance value is non-empty,+it will be asserted as the balance after the 'account1' posting.+++File: hledger_csv.info,  Node: Reading multiple CSV files,  Prev: CSV balance assertions,  Up: CSV TIPS++2.5 Reading multiple CSV files+==============================++You can read multiple CSV files at once using multiple '-f' arguments on+the command line, and hledger will look for a correspondingly-named+rules file for each.  Note if you use the '--rules-file' option, this+one rules file will be used for all the CSV files being read.+++Tag Table:+Node: Top72+Node: CSV RULES2161+Ref: #csv-rules2269+Node: skip2531+Ref: #skip2625+Node: date-format2797+Ref: #date-format2924+Node: field list3430+Ref: #field-list3567+Node: field assignment4272+Ref: #field-assignment4427+Node: conditional block4931+Ref: #conditional-block5085+Node: include5981+Ref: #include6111+Node: newest-first6342+Ref: #newest-first6456+Node: CSV TIPS6867+Ref: #csv-tips6961+Node: CSV ordering7079+Ref: #csv-ordering7197+Node: CSV accounts7378+Ref: #csv-accounts7516+Node: CSV amounts7770+Ref: #csv-amounts7916+Node: CSV balance assertions8691+Ref: #csv-balance-assertions8873+Node: Reading multiple CSV files9078+Ref: #reading-multiple-csv-files9248++End Tag Table
+ hledger_csv.txt view
@@ -0,0 +1,252 @@++hledger_csv(5)               hledger User Manuals               hledger_csv(5)++++NAME+       CSV - how hledger reads CSV data, and the CSV rules file format++DESCRIPTION+       hledger  can  read  CSV  (comma-separated  value) files as if they were+       journal files, automatically converting each CSV record into a transac-+       tion.  (To learn about writing CSV, see CSV output.)++       Converting  CSV to transactions requires some special conversion rules.+       These do several things:++       o they describe the layout and format of the CSV data++       o they can customize the generated journal entries using a simple  tem-+         plating language++       o they  can add refinements based on patterns in the CSV data, eg cate-+         gorizing transactions with more detailed account names.++       When reading a CSV file named FILE.csv, hledger looks for a  conversion+       rules  file  named FILE.csv.rules in the same directory.  You can over-+       ride this with the --rules-file option.  If the  rules  file  does  not+       exist,  hledger  will  auto-create  one  with some example rules, which+       you'll need to adjust.++       At minimum, the rules file must identify the date  and  amount  fields.+       It  may also be necessary to specify the date format, and the number of+       header lines to skip.  Eg:++              fields date, _, _, amount+              date-format  %d/%m/%Y+              skip 1++       A more complete example:++              # hledger CSV rules for amazon.com order history++              # sample:+              # "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"+              # "Jul 29, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$0.00","17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL"++              # skip one header line+              skip 1++              # name the csv fields (and assign the transaction's date, amount and code)+              fields date, _, toorfrom, name, amzstatus, amount, fees, code++              # how to parse the date+              date-format %b %-d, %Y++              # combine two fields to make the description+              description %toorfrom %name++              # save these fields as tags+              comment     status:%amzstatus, fees:%fees++              # set the base account for all transactions+              account1    assets:amazon++              # flip the sign on the amount+              amount      -%amount++       For more examples, see Convert CSV files.++CSV RULES+       The following seven kinds of rule can appear in the rules file, in  any+       order.  Blank lines and lines beginning with # or ; are ignored.++   skip+       skipN++       Skip  this  number  of  CSV records at the beginning.  You'll need this+       whenever your CSV data contains header lines.  Eg:++              # ignore the first CSV line+              skip 1++   date-format+       date-formatDATEFMT++       When your CSV  date  fields  are  not  formatted  like  YYYY/MM/DD  (or+       YYYY-MM-DD  or YYYY.MM.DD), you'll need to specify the format.  DATEFMT+       is a strptime-like date parsing pattern,  which  must  parse  the  date+       field values completely.  Examples:++              # for dates like "6/11/2013":+              date-format %-d/%-m/%Y++              # for dates like "11/06/2013":+              date-format %m/%d/%Y++              # for dates like "2013-Nov-06":+              date-format %Y-%h-%d++              # for dates like "11/6/2013 11:32 PM":+              date-format %-m/%-d/%Y %l:%M %p++   field list+       fieldsFIELDNAME1, FIELDNAME2...++       This  (a)  names the CSV fields, in order (names may not contain white-+       space; uninteresting names may be left blank), and (b) assigns them  to+       journal  entry  fields  if  you  use any of these standard field names:+       date, date2, status, code, description,  comment,  account1,  account2,+       amount, amount-in, amount-out, currency, balance.  Eg:++              # use the 1st, 2nd and 4th CSV fields as the entry's date, description and amount,+              # and give the 7th and 8th fields meaningful names for later reference:+              #+              # CSV field:+              #      1     2            3 4       5 6 7          8+              # entry field:+              fields date, description, , amount, , , somefield, anotherfield++   field assignment+       ENTRYFIELDNAME FIELDVALUE++       This  sets  a  journal entry field (one of the standard names above) to+       the given text value, which can include CSV field  values  interpolated+       by name (%CSVFIELDNAME) or 1-based position (%N).+        Eg:++              # set the amount to the 4th CSV field with "USD " prepended+              amount USD %4++              # combine three fields to make a comment (containing two tags)+              comment note: %somefield - %anotherfield, date: %1++       Field  assignments  can  be  used  instead of or in addition to a field+       list.++   conditional block+       if PATTERN+           FIELDASSIGNMENTS...++       if+       PATTERN+       PATTERN...+           FIELDASSIGNMENTS...++       This applies one or more field assignments, only to those  CSV  records+       matched by one of the PATTERNs.  The patterns are case-insensitive reg-+       ular expressions which match anywhere within the whole CSV record (it's+       not  yet  possible  to  match within a specific field).  When there are+       multiple patterns they can be written on  separate  lines,  unindented.+       The  field  assignments  are on separate lines indented by at least one+       space.  Examples:++              # if the CSV record contains "groceries", set account2 to "expenses:groceries"+              if groceries+               account2 expenses:groceries++              # if the CSV record contains any of these patterns, set account2 and comment as shown+              if+              monthly service fee+              atm transaction fee+              banking thru software+               account2 expenses:business:banking+               comment  XXX deductible ? check it++   include+       includeRULESFILE++       Include another rules file at this point.  RULESFILE is either an abso-+       lute file path or a path relative to the current file's directory.  Eg:++              # rules reused with several CSV files+              include common.rules++   newest-first+       newest-first++       Consider adding this rule if all of the following are true:  you  might+       be  processing  just  one  day of data, your CSV records are in reverse+       chronological order (newest first), and you care about  preserving  the+       order  of  same-day  transactions.   It  usually  isn't needed, because+       hledger autodetects the CSV order, but when all CSV  records  have  the+       same date it will assume they are oldest first.++CSV TIPS+   CSV ordering+       The  generated  journal  entries  will be sorted by date.  The order of+       same-day entries will be preserved (except in the  special  case  where+       you might need newest-first, see above).++   CSV accounts+       Each  journal  entry  will  have two postings, to account1 and account2+       respectively.  It's not yet possible to generate entries with more than+       two  postings.   It's  conventional and recommended to use account1 for+       the account whose CSV we are reading.++   CSV amounts+       The amount field sets the amount of the account1 posting.++       If the CSV has debit/credit amounts in separate fields, assign  to  the+       amount-in  and  amount-out pseudo fields instead.  (Whichever one has a+       value will be used, with appropriate sign.  If both contain a value, it+       may not work so well.)++       If  an  amount  value is parenthesised, it will be de-parenthesised and+       sign-flipped.++       If an amount value begins with a double minus sign, those  will  cancel+       out and be removed.++       If  the CSV has the currency symbol in a separate field, assign that to+       the currency pseudo field to have it prepended to the amount.  Or,  you+       can  use a field assignment to amount that interpolates both CSV fields+       (giving more control, eg to put the currency symbol on the right).++   CSV balance assertions+       If the CSV includes a running balance, you can assign that to the  bal-+       ance  pseudo field; whenever the running balance value is non-empty, it+       will be asserted as the balance after the account1 posting.++   Reading multiple CSV files+       You can read multiple CSV files at once using multiple -f arguments  on+       the  command  line,  and  hledger will look for a correspondingly-named+       rules file for each.  Note if you use the --rules-file option, this one+       rules file will be used for all the CSV files being read.++++REPORTING BUGS+       Report  bugs at http://bugs.hledger.org (or on the #hledger IRC channel+       or hledger mail list)+++AUTHORS+       Simon Michael <simon@joyful.com> and contributors+++COPYRIGHT+       Copyright (C) 2007-2016 Simon Michael.+       Released under GNU GPL v3 or later.+++SEE ALSO+       hledger(1),     hledger-ui(1),     hledger-web(1),      hledger-api(1),+       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time-+       dot(5), ledger(1)++       http://hledger.org++++hledger 1.5                      December 2017                  hledger_csv(5)
+ hledger_journal.5 view
@@ -0,0 +1,1249 @@+.\"t++.TH "hledger_journal" "5" "December 2017" "hledger 1.5" "hledger User Manuals"++++.SH NAME+.PP+Journal \- hledger's default file format, representing a General Journal+.SH DESCRIPTION+.PP+hledger's usual data source is a plain text file containing journal+entries in hledger journal format.+This file represents a standard accounting general journal.+I use file names ending in \f[C]\&.journal\f[], but that's not required.+The journal file contains a number of transaction entries, each+describing a transfer of money (or any commodity) between two or more+named accounts, in a simple format readable by both hledger and humans.+.PP+hledger's journal format is a compatible subset, mostly, of ledger's+journal format, so hledger can work with compatible ledger journal files+as well.+It's safe, and encouraged, to run both hledger and ledger on the same+journal file, eg to validate the results you're getting.+.PP+You can use hledger without learning any more about this file; just use+the add or web commands to create and update it.+Many users, though, also edit the journal file directly with a text+editor, perhaps assisted by the helper modes for emacs or vim.+.PP+Here's an example:+.IP+.nf+\f[C]+;\ A\ sample\ journal\ file.\ This\ is\ a\ comment.++2008/01/01\ income\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ transaction\[aq]s\ first\ line\ starts\ in\ column\ 0,\ contains\ date\ and\ description+\ \ \ \ assets:bank:checking\ \ $1\ \ \ \ ;\ <\-\ posting\ lines\ start\ with\ whitespace,\ each\ contains\ an\ account\ name+\ \ \ \ income:salary\ \ \ \ \ \ \ \ $\-1\ \ \ \ ;\ \ \ \ followed\ by\ at\ least\ two\ spaces\ and\ an\ amount++2008/06/01\ gift+\ \ \ \ assets:bank:checking\ \ $1\ \ \ \ ;\ <\-\ at\ least\ two\ postings\ in\ a\ transaction+\ \ \ \ income:gifts\ \ \ \ \ \ \ \ \ $\-1\ \ \ \ ;\ <\-\ their\ amounts\ must\ balance\ to\ 0++2008/06/02\ save+\ \ \ \ assets:bank:saving\ \ \ \ $1+\ \ \ \ assets:bank:checking\ \ \ \ \ \ \ \ ;\ <\-\ one\ amount\ may\ be\ omitted;\ here\ $\-1\ is\ inferred++2008/06/03\ eat\ &\ shop\ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ description\ can\ be\ anything+\ \ \ \ expenses:food\ \ \ \ \ \ \ \ \ $1+\ \ \ \ expenses:supplies\ \ \ \ \ $1\ \ \ \ ;\ <\-\ this\ transaction\ debits\ two\ expense\ accounts+\ \ \ \ assets:cash\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ $\-2\ inferred++2008/10/01\ take\ a\ loan+\ \ \ \ assets:bank:checking\ \ $1+\ \ \ \ liabilities:debts\ \ \ \ $\-1++2008/12/31\ *\ pay\ off\ \ \ \ \ \ \ \ \ \ \ \ ;\ <\-\ an\ optional\ *\ or\ !\ after\ the\ date\ means\ "cleared"\ (or\ anything\ you\ want)+\ \ \ \ liabilities:debts\ \ \ \ \ $1+\ \ \ \ assets:bank:checking+\f[]+.fi+.SH FILE FORMAT+.SS Transactions+.PP+Transactions are movements of some quantity of commodities between named+accounts.+Each transaction is represented by a journal entry beginning with a+simple date in column 0.+This can be followed by any of the following, separated by spaces:+.IP \[bu] 2+(optional) a status character (empty, \f[C]!\f[], or \f[C]*\f[])+.IP \[bu] 2+(optional) a transaction code (any short number or text, enclosed in+parentheses)+.IP \[bu] 2+(optional) a transaction description (any remaining text until end of+line or a semicolon)+.IP \[bu] 2+(optional) a transaction comment (any remaining text following a+semicolon until end of line)+.PP+Then comes zero or more (but usually at least 2) indented lines+representing\&...+.SS Postings+.PP+A posting is an addition of some amount to, or removal of some amount+from, an account.+Each posting line begins with at least one space or tab (2 or 4 spaces+is common), followed by:+.IP \[bu] 2+(optional) a status character (empty, \f[C]!\f[], or \f[C]*\f[]),+followed by a space+.IP \[bu] 2+(required) an account name (any text, optionally containing \f[B]single+spaces\f[], until end of line or a double space)+.IP \[bu] 2+(optional) \f[B]two or more spaces\f[] or tabs followed by an amount.+.PP+Positive amounts are being added to the account, negative amounts are+being removed.+.PP+The amounts within a transaction must always sum up to zero.+As a convenience, one amount may be left blank; it will be inferred so+as to balance the transaction.+.PP+Be sure to note the unusual two\-space delimiter between account name+and amount.+This makes it easy to write account names containing spaces.+But if you accidentally leave only one space (or tab) before the amount,+the amount will be considered part of the account name.+.SS Dates+.SS Simple dates+.PP+Within a journal file, transaction dates use Y/M/D (or Y\-M\-D or Y.M.D)+Leading zeros are optional.+The year may be omitted, in which case it will be inferred from the+context \- the current transaction, the default year set with a default+year directive, or the current date when the command is run.+Some examples: \f[C]2010/01/31\f[], \f[C]1/31\f[],+\f[C]2010\-01\-31\f[], \f[C]2010.1.31\f[].+.SS Secondary dates+.PP+Real\-life transactions sometimes involve more than one date \- eg the+date you write a cheque, and the date it clears in your bank.+When you want to model this, eg for more accurate balances, you can+specify individual posting dates, which I recommend.+Or, you can use the secondary dates (aka auxiliary/effective dates)+feature, supported for compatibility with Ledger.+.PP+A secondary date can be written after the primary date, separated by an+equals sign.+The primary date, on the left, is used by default; the secondary date,+on the right, is used when the \f[C]\-\-date2\f[] flag is specified+(\f[C]\-\-aux\-date\f[] or \f[C]\-\-effective\f[] also work).+.PP+The meaning of secondary dates is up to you, but it's best to follow a+consistent rule.+Eg write the bank's clearing date as primary, and when needed, the date+the transaction was initiated as secondary.+.PP+Here's an example.+Note that a secondary date will use the year of the primary date if+unspecified.+.IP+.nf+\f[C]+2010/2/23=2/19\ movie\ ticket+\ \ expenses:cinema\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $10+\ \ assets:checking+\f[]+.fi+.IP+.nf+\f[C]+$\ hledger\ register\ checking+2010/02/23\ movie\ ticket\ \ \ \ \ \ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10\ \ \ \ \ \ \ \ \ $\-10+\f[]+.fi+.IP+.nf+\f[C]+$\ hledger\ register\ checking\ \-\-date2+2010/02/19\ movie\ ticket\ \ \ \ \ \ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10\ \ \ \ \ \ \ \ \ $\-10+\f[]+.fi+.PP+Secondary dates require some effort; you must use them consistently in+your journal entries and remember whether to use or not use the+\f[C]\-\-date2\f[] flag for your reports.+They are included in hledger for Ledger compatibility, but posting dates+are a more powerful and less confusing alternative.+.SS Posting dates+.PP+You can give individual postings a different date from their parent+transaction, by adding a posting comment containing a tag (see below)+like \f[C]date:DATE\f[].+This is probably the best way to control posting dates precisely.+Eg in this example the expense should appear in May reports, and the+deduction from checking should be reported on 6/1 for easy bank+reconciliation:+.IP+.nf+\f[C]+2015/5/30+\ \ \ \ expenses:food\ \ \ \ \ $10\ \ \ ;\ food\ purchased\ on\ saturday\ 5/30+\ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ ;\ bank\ cleared\ it\ on\ monday,\ date:6/1+\f[]+.fi+.IP+.nf+\f[C]+$\ hledger\ \-f\ t.j\ register\ food+2015/05/30\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ expenses:food\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $10\ \ \ \ \ \ \ \ \ \ \ $10+\f[]+.fi+.IP+.nf+\f[C]+$\ hledger\ \-f\ t.j\ register\ checking+2015/06/01\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10\ \ \ \ \ \ \ \ \ \ $\-10+\f[]+.fi+.PP+DATE should be a simple date; if the year is not specified it will use+the year of the transaction's date.+You can set the secondary date similarly, with \f[C]date2:DATE2\f[].+The \f[C]date:\f[] or \f[C]date2:\f[] tags must have a valid simple date+value if they are present, eg a \f[C]date:\f[] tag with no value is not+allowed.+.PP+Ledger's earlier, more compact bracketed date syntax is also supported:+\f[C][DATE]\f[], \f[C][DATE=DATE2]\f[] or \f[C][=DATE2]\f[].+hledger will attempt to parse any square\-bracketed sequence of the+\f[C]0123456789/\-.=\f[] characters in this way.+With this syntax, DATE infers its year from the transaction and DATE2+infers its year from DATE.+.SS Status+.PP+Transactions, or individual postings within a transaction, can have a+status mark, which is a single character before the transaction+description or posting account name, separated from it by a space,+indicating one of three statuses:+.PP+.TS+tab(@);+l l.+T{+mark \ +T}@T{+status+T}+_+T{+\ +T}@T{+unmarked+T}+T{+\f[C]!\f[]+T}@T{+pending+T}+T{+\f[C]*\f[]+T}@T{+cleared+T}+.TE+.PP+When reporting, you can filter by status with the+\f[C]\-U/\-\-unmarked\f[], \f[C]\-P/\-\-pending\f[], and+\f[C]\-C/\-\-cleared\f[] flags; or the \f[C]status:\f[],+\f[C]status:!\f[], and \f[C]status:*\f[] queries; or the U, P, C keys in+hledger\-ui.+.PP+Note, in Ledger and in older versions of hledger, the \[lq]unmarked\[rq]+state is called \[lq]uncleared\[rq].+As of hledger 1.3 we have renamed it to unmarked for clarity.+.PP+To replicate Ledger and old hledger's behaviour of also matching+pending, combine \-U and \-P.+.PP+Status marks are optional, but can be helpful eg for reconciling with+real\-world accounts.+Some editor modes provide highlighting and shortcuts for working with+status.+Eg in Emacs ledger\-mode, you can toggle transaction status with C\-c+C\-e, or posting status with C\-c C\-c.+.PP+What \[lq]uncleared\[rq], \[lq]pending\[rq], and \[lq]cleared\[rq]+actually mean is up to you.+Here's one suggestion:+.PP+.TS+tab(@);+lw(9.9n) lw(60.1n).+T{+status+T}@T{+meaning+T}+_+T{+uncleared+T}@T{+recorded but not yet reconciled; needs review+T}+T{+pending+T}@T{+tentatively reconciled (if needed, eg during a big reconciliation)+T}+T{+cleared+T}@T{+complete, reconciled as far as possible, and considered correct+T}+.TE+.PP+With this scheme, you would use \f[C]\-PC\f[] to see the current balance+at your bank, \f[C]\-U\f[] to see things which will probably hit your+bank soon (like uncashed checks), and no flags to see the most+up\-to\-date state of your finances.+.SS Description+.PP+A transaction's description is the rest of the line following the date+and status mark (or until a comment begins).+Sometimes called the \[lq]narration\[rq] in traditional bookkeeping, it+can be used for whatever you wish, or left blank.+Transaction descriptions can be queried, unlike comments.+.SS Payee and note+.PP+You can optionally include a \f[C]|\f[] (pipe) character in a+description to subdivide it into a payee/payer name on the left and+additional notes on the right.+This may be worthwhile if you need to do more precise querying and+pivoting by payee.+.SS Account names+.PP+Account names typically have several parts separated by a full colon,+from which hledger derives a hierarchical chart of accounts.+They can be anything you like, but in finance there are traditionally+five top\-level accounts: \f[C]assets\f[], \f[C]liabilities\f[],+\f[C]income\f[], \f[C]expenses\f[], and \f[C]equity\f[].+.PP+Account names may contain single spaces, eg:+\f[C]assets:accounts\ receivable\f[].+Because of this, they must always be followed by \f[B]two or more+spaces\f[] (or newline).+.PP+Account names can be aliased.+.SS Amounts+.PP+After the account name, there is usually an amount.+Important: between account name and amount, there must be \f[B]two or+more spaces\f[].+.PP+Amounts consist of a number and (usually) a currency symbol or commodity+name.+Some examples:+.PP+\f[C]2.00001\f[]+.PD 0+.P+.PD+\f[C]$1\f[]+.PD 0+.P+.PD+\f[C]4000\ AAPL\f[]+.PD 0+.P+.PD+\f[C]3\ "green\ apples"\f[]+.PD 0+.P+.PD+\f[C]\-$1,000,000.00\f[]+.PD 0+.P+.PD+\f[C]INR\ 9,99,99,999.00\f[]+.PD 0+.P+.PD+\f[C]EUR\ \-2.000.000,00\f[]+.PD 0+.P+.PD+\f[C]1\ 999\ 999.9455\f[]+.PP+As you can see, the amount format is somewhat flexible:+.IP \[bu] 2+amounts are a number (the \[lq]quantity\[rq]) and optionally a currency+symbol/commodity name (the \[lq]commodity\[rq]).+.IP \[bu] 2+the commodity is a symbol, word, or phrase, on the left or right, with+or without a separating space.+If the commodity contains numbers, spaces or non\-word punctuation it+must be enclosed in double quotes.+.IP \[bu] 2+negative amounts with a commodity on the left can have the minus sign+before or after it+.IP \[bu] 2+digit groups (thousands, or any other grouping) can be separated by+space or comma or period and should be used as separator between all+groups+.IP \[bu] 2+decimal part can be separated by comma or period and should be different+from digit groups separator+.PP+You can use any of these variations when recording data.+However, there is some ambiguous way of representing numbers like+\f[C]$1.000\f[] and \f[C]$1,000\f[] both may mean either one thousand or+one dollar.+By default hledger will assume that this is sole delimiter is used only+for decimals.+On the other hand commodity format declared prior to that line will help+to resolve that ambiguity differently:+.IP+.nf+\f[C]+commodity\ $1,000.00++2017/12/25\ New\ life\ of\ Scrooge+\ \ \ \ expenses:gifts\ \ $1,000+\ \ \ \ assets+\f[]+.fi+.PP+Though journal may contain mixed styles to represent amount, when+hledger displays amounts, it will choose a consistent format for each+commodity.+(Except for price amounts, which are always formatted as written).+The display format is chosen as follows:+.IP \[bu] 2+if there is a commodity directive specifying the format, that is used+.IP \[bu] 2+otherwise the format is inferred from the first posting amount in that+commodity in the journal, and the precision (number of decimal places)+will be the maximum from all posting amounts in that commmodity+.IP \[bu] 2+or if there are no such amounts in the journal, a default format is used+(like \f[C]$1000.00\f[]).+.PP+Price amounts and amounts in D directives usually don't affect amount+format inference, but in some situations they can do so indirectly.+(Eg when D's default commodity is applied to a commodity\-less amount,+or when an amountless posting is balanced using a price's commodity, or+when \-V is used.) If you find this causing problems, set the desired+format with a commodity directive.+.SS Virtual Postings+.PP+When you parenthesise the account name in a posting, we call that a+\f[I]virtual posting\f[], which means:+.IP \[bu] 2+it is ignored when checking that the transaction is balanced+.IP \[bu] 2+it is excluded from reports when the \f[C]\-\-real/\-R\f[] flag is used,+or the \f[C]real:1\f[] query.+.PP+You could use this, eg, to set an account's opening balance without+needing to use the \f[C]equity:opening\ balances\f[] account:+.IP+.nf+\f[C]+1/1\ special\ unbalanced\ posting\ to\ set\ initial\ balance+\ \ (assets:checking)\ \ \ $1000+\f[]+.fi+.PP+When the account name is bracketed, we call it a \f[I]balanced virtual+posting\f[].+This is like an ordinary virtual posting except the balanced virtual+postings in a transaction must balance to 0, like the real postings (but+separately from them).+Balanced virtual postings are also excluded by \f[C]\-\-real/\-R\f[] or+\f[C]real:1\f[].+.IP+.nf+\f[C]+1/1\ buy\ food\ with\ cash,\ and\ update\ some\ budget\-tracking\ subaccounts\ elsewhere+\ \ expenses:food\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $10+\ \ assets:cash\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-10+\ \ [assets:checking:available]\ \ \ \ \ $10+\ \ [assets:checking:budget:food]\ \ $\-10+\f[]+.fi+.PP+Virtual postings have some legitimate uses, but those are few.+You can usually find an equivalent journal entry using real postings,+which is more correct and provides better error checking.+.SS Balance Assertions+.PP+hledger supports Ledger\-style balance assertions in journal files.+These look like \f[C]=EXPECTEDBALANCE\f[] following a posting's amount.+Eg in this example we assert the expected dollar balance in accounts a+and b after each posting:+.IP+.nf+\f[C]+2013/1/1+\ \ a\ \ \ $1\ \ =$1+\ \ b\ \ \ \ \ \ \ =$\-1++2013/1/2+\ \ a\ \ \ $1\ \ =$2+\ \ b\ \ $\-1\ \ =$\-2+\f[]+.fi+.PP+After reading a journal file, hledger will check all balance assertions+and report an error if any of them fail.+Balance assertions can protect you from, eg, inadvertently disrupting+reconciled balances while cleaning up old entries.+You can disable them temporarily with the+\f[C]\-\-ignore\-assertions\f[] flag, which can be useful for+troubleshooting or for reading Ledger files.+.SS Assertions and ordering+.PP+hledger sorts an account's postings and assertions first by date and+then (for postings on the same day) by parse order.+Note this is different from Ledger, which sorts assertions only by parse+order.+(Also, Ledger assertions do not see the accumulated effect of repeated+postings to the same account within a transaction.)+.PP+So, hledger balance assertions keep working if you reorder+differently\-dated transactions within the journal.+But if you reorder same\-dated transactions or postings, assertions+might break and require updating.+This order dependence does bring an advantage: precise control over the+order of postings and assertions within a day, so you can assert+intra\-day balances.+.SS Assertions and included files+.PP+With included files, things are a little more complicated.+Including preserves the ordering of postings and assertions.+If you have multiple postings to an account on the same day, split+across different files, and you also want to assert the account's+balance on the same day, you'll have to put the assertion in the right+file.+.SS Assertions and multiple \-f options+.PP+Balance assertions don't work well across files specified with multiple+\-f options.+Use include or concatenate the files instead.+.SS Assertions and commodities+.PP+The asserted balance must be a simple single\-commodity amount, and in+fact the assertion checks only this commodity's balance within the+(possibly multi\-commodity) account balance.+We could call this a partial balance assertion.+This is compatible with Ledger, and makes it possible to make assertions+about accounts containing multiple commodities.+.PP+To assert each commodity's balance in such a multi\-commodity account,+you can add multiple postings (with amount 0 if necessary).+But note that no matter how many assertions you add, you can't be sure+the account does not contain some unexpected commodity.+(We'll add support for this kind of total balance assertion if there's+demand.)+.SS Assertions and subaccounts+.PP+Balance assertions do not count the balance from subaccounts; they check+the posted account's exclusive balance.+For example:+.IP+.nf+\f[C]+1/1+\ \ checking:fund\ \ \ 1\ =\ 1\ \ ;\ post\ to\ this\ subaccount,\ its\ balance\ is\ now\ 1+\ \ checking\ \ \ \ \ \ \ \ 1\ =\ 1\ \ ;\ post\ to\ the\ parent\ account,\ its\ exclusive\ balance\ is\ now\ 1+\ \ equity+\f[]+.fi+.PP+The balance report's flat mode shows these exclusive balances more+clearly:+.IP+.nf+\f[C]+$\ hledger\ bal\ checking\ \-\-flat+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 1\ \ checking+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 1\ \ checking:fund+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 2+\f[]+.fi+.SS Assertions and virtual postings+.PP+Balance assertions are checked against all postings, both real and+virtual.+They are not affected by the \f[C]\-\-real/\-R\f[] flag or+\f[C]real:\f[] query.+.SS Balance Assignments+.PP+Ledger\-style balance assignments are also supported.+These are like balance assertions, but with no posting amount on the+left side of the equals sign; instead it is calculated automatically so+as to satisfy the assertion.+This can be a convenience during data entry, eg when setting opening+balances:+.IP+.nf+\f[C]+;\ starting\ a\ new\ journal,\ set\ asset\ account\ balances\ +2016/1/1\ opening\ balances+\ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ =\ $409.32+\ \ assets:savings\ \ \ \ \ \ \ \ \ \ \ \ \ =\ $735.24+\ \ assets:cash\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ $42+\ \ equity:opening\ balances+\f[]+.fi+.PP+or when adjusting a balance to reality:+.IP+.nf+\f[C]+;\ no\ cash\ left;\ update\ balance,\ record\ any\ untracked\ spending\ as\ a\ generic\ expense+2016/1/15+\ \ assets:cash\ \ \ \ =\ $0+\ \ expenses:misc+\f[]+.fi+.PP+The calculated amount depends on the account's balance in the commodity+at that point (which depends on the previously\-dated postings of the+commodity to that account since the last balance assertion or+assignment).+Note that using balance assignments makes your journal a little less+explicit; to know the exact amount posted, you have to run hledger or do+the calculations yourself, instead of just reading it.+.SS Prices+.SS Transaction prices+.PP+Within a transaction, you can note an amount's price in another+commodity.+This can be used to document the cost (in a purchase) or selling price+(in a sale).+For example, transaction prices are useful to record purchases of a+foreign currency.+.PP+Transaction prices are fixed, and do not change over time.+(Ledger users: Ledger uses a different syntax for fixed prices,+\f[C]{=UNITPRICE}\f[], which hledger currently ignores).+.PP+There are several ways to record a transaction price:+.IP "1." 3+Write the price per unit, as \f[C]\@\ UNITPRICE\f[] after the amount:+.RS 4+.IP+.nf+\f[C]+2009/1/1+\ \ assets:euros\ \ \ \ \ €100\ \@\ $1.35\ \ ;\ one\ hundred\ euros\ purchased\ at\ $1.35\ each+\ \ assets:dollars\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ balancing\ amount\ is\ \-$135.00+\f[]+.fi+.RE+.IP "2." 3+Write the total price, as \f[C]\@\@\ TOTALPRICE\f[] after the amount:+.RS 4+.IP+.nf+\f[C]+2009/1/1+\ \ assets:euros\ \ \ \ \ €100\ \@\@\ $135\ \ ;\ one\ hundred\ euros\ purchased\ at\ $135\ for\ the\ lot+\ \ assets:dollars+\f[]+.fi+.RE+.IP "3." 3+Specify amounts for all postings, using exactly two commodities, and let+hledger infer the price that balances the transaction:+.RS 4+.IP+.nf+\f[C]+2009/1/1+\ \ assets:euros\ \ \ \ \ €100\ \ \ \ \ \ \ \ \ \ ;\ one\ hundred\ euros\ purchased+\ \ assets:dollars\ \ $\-135\ \ \ \ \ \ \ \ \ \ ;\ for\ $135+\f[]+.fi+.RE+.PP+Amounts with transaction prices can be displayed in the transaction+price's commodity by using the \f[C]\-B/\-\-cost\f[] flag (except for+#551) (\[lq]B\[rq] is from \[lq]cost Basis\[rq]).+Eg for the above, here is how \-B affects the balance report:+.IP+.nf+\f[C]+$\ hledger\ bal\ \-N\ \-\-flat+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-135\ \ assets:dollars+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ €100\ \ assets:euros+$\ hledger\ bal\ \-N\ \-\-flat\ \-B+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-135\ \ assets:dollars+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $135\ \ assets:euros\ \ \ \ #\ <\-\ the\ euros\[aq]\ cost+\f[]+.fi+.PP+Note \-B is sensitive to the order of postings when a transaction price+is inferred: the inferred price will be in the commodity of the last+amount.+So if example 3's postings are reversed, while the transaction is+equivalent, \-B shows something different:+.IP+.nf+\f[C]+2009/1/1+\ \ assets:dollars\ \ $\-135\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ 135\ dollars\ sold+\ \ assets:euros\ \ \ \ \ €100\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ for\ 100\ euros+\f[]+.fi+.IP+.nf+\f[C]+$\ hledger\ bal\ \-N\ \-\-flat\ \-B+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ €\-100\ \ assets:dollars\ \ #\ <\-\ the\ dollars\[aq]\ selling\ price+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ €100\ \ assets:euros+\f[]+.fi+.SS Market prices+.PP+Market prices are not tied to a particular transaction; they represent+historical exchange rates between two commodities.+(Ledger calls them historical prices.) For example, the prices published+by a stock exchange or the foreign exchange market.+hledger can use these prices to show the market value of things at a+given date, see market value.+.PP+To record market prices, use P directives in the main journal or in an+included file.+Their format is:+.IP+.nf+\f[C]+P\ DATE\ COMMODITYBEINGPRICED\ UNITPRICE+\f[]+.fi+.PP+DATE is a simple date as usual.+COMMODITYBEINGPRICED is the symbol of the commodity being priced.+UNITPRICE is an ordinary amount (symbol and quantity) in a second+commodity, specifying the unit price or conversion rate for the first+commodity in terms of the second, on the given date.+.PP+For example, the following directives say that one euro was worth 1.35+US dollars during 2009, and $1.40 from 2010 onward:+.IP+.nf+\f[C]+P\ 2009/1/1\ €\ $1.35+P\ 2010/1/1\ €\ $1.40+\f[]+.fi+.SS Comments+.PP+Lines in the journal beginning with a semicolon (\f[C];\f[]) or hash+(\f[C]#\f[]) or star (\f[C]*\f[]) are comments, and will be ignored.+(Star comments cause org\-mode nodes to be ignored, allowing emacs users+to fold and navigate their journals with org\-mode or orgstruct\-mode.)+.PP+Also, anything between \f[C]comment\f[] and \f[C]end\ comment\f[]+directives is a (multi\-line) comment.+If there is no \f[C]end\ comment\f[], the comment extends to the end of+the file.+.PP+You can attach comments to a transaction by writing them after the+description and/or indented on the following lines (before the+postings).+Similarly, you can attach comments to an individual posting by writing+them after the amount and/or indented on the following lines.+Transaction and posting comments must begin with a semicolon+(\f[C];\f[]).+.PP+Some examples:+.IP+.nf+\f[C]+#\ a\ file\ comment++;\ also\ a\ file\ comment++comment+This\ is\ a\ multiline\ file\ comment,+which\ continues\ until\ a\ line+where\ the\ "end\ comment"\ string+appears\ on\ its\ own\ (or\ end\ of\ file).+end\ comment++2012/5/14\ something\ \ ;\ a\ transaction\ comment+\ \ \ \ ;\ the\ transaction\ comment,\ continued+\ \ \ \ posting1\ \ 1\ \ ;\ a\ comment\ for\ posting\ 1+\ \ \ \ posting2+\ \ \ \ ;\ a\ comment\ for\ posting\ 2+\ \ \ \ ;\ another\ comment\ line\ for\ posting\ 2+;\ a\ file\ comment\ (because\ not\ indented)+\f[]+.fi+.SS Tags+.PP+Tags are a way to add extra labels or labelled data to postings and+transactions, which you can then search or pivot on.+.PP+A simple tag is a word (which may contain hyphens) followed by a full+colon, written inside a transaction or posting comment line:+.IP+.nf+\f[C]+2017/1/16\ bought\ groceries\ \ \ \ ;\ sometag:+\f[]+.fi+.PP+Tags can have a value, which is the text after the colon, up to the next+comma or end of line, with leading/trailing whitespace removed:+.IP+.nf+\f[C]+\ \ \ \ expenses:food\ \ \ \ $10\ \ \ ;\ a\-posting\-tag:\ the\ tag\ value+\f[]+.fi+.PP+Note this means hledger's tag values can not contain commas or newlines.+Ending at commas means you can write multiple short tags on one line,+comma separated:+.IP+.nf+\f[C]+\ \ \ \ assets:checking\ \ \ \ \ \ \ ;\ a\ comment\ containing\ tag1:,\ tag2:\ some\ value\ ...+\f[]+.fi+.PP+Here,+.IP \[bu] 2+\[lq]\f[C]a\ comment\ containing\f[]\[rq] is just comment text, not a+tag+.IP \[bu] 2+\[lq]\f[C]tag1\f[]\[rq] is a tag with no value+.IP \[bu] 2+\[lq]\f[C]tag2\f[]\[rq] is another tag, whose value is+\[lq]\f[C]some\ value\ ...\f[]\[rq]+.PP+Tags in a transaction comment affect the transaction and all of its+postings, while tags in a posting comment affect only that posting.+For example, the following transaction has three tags (\f[C]A\f[],+\f[C]TAG2\f[], \f[C]third\-tag\f[]) and the posting has four (those plus+\f[C]posting\-tag\f[]):+.IP+.nf+\f[C]+1/1\ a\ transaction\ \ ;\ A:,\ TAG2:+\ \ \ \ ;\ third\-tag:\ a\ third\ transaction\ tag,\ <\-\ with\ a\ value+\ \ \ \ (a)\ \ $1\ \ ;\ posting\-tag:+\f[]+.fi+.PP+Tags are like Ledger's metadata feature, except hledger's tag values are+simple strings.+.SS Directives+.SS Account aliases+.PP+You can define aliases which rewrite your account names (after reading+the journal, before generating reports).+hledger's account aliases can be useful for:+.IP \[bu] 2+expanding shorthand account names to their full form, allowing easier+data entry and a less verbose journal+.IP \[bu] 2+adapting old journals to your current chart of accounts+.IP \[bu] 2+experimenting with new account organisations, like a new hierarchy or+combining two accounts into one+.IP \[bu] 2+customising reports+.PP+See also Cookbook: rewrite account names.+.SS Basic aliases+.PP+To set an account alias, use the \f[C]alias\f[] directive in your+journal file.+This affects all subsequent journal entries in the current file or its+included files.+The spaces around the = are optional:+.IP+.nf+\f[C]+alias\ OLD\ =\ NEW+\f[]+.fi+.PP+Or, you can use the \f[C]\-\-alias\ \[aq]OLD=NEW\[aq]\f[] option on the+command line.+This affects all entries.+It's useful for trying out aliases interactively.+.PP+OLD and NEW are full account names.+hledger will replace any occurrence of the old account name with the new+one.+Subaccounts are also affected.+Eg:+.IP+.nf+\f[C]+alias\ checking\ =\ assets:bank:wells\ fargo:checking+#\ rewrites\ "checking"\ to\ "assets:bank:wells\ fargo:checking",\ or\ "checking:a"\ to\ "assets:bank:wells\ fargo:checking:a"+\f[]+.fi+.SS Regex aliases+.PP+There is also a more powerful variant that uses a regular expression,+indicated by the forward slashes:+.IP+.nf+\f[C]+alias\ /REGEX/\ =\ REPLACEMENT+\f[]+.fi+.PP+or \f[C]\-\-alias\ \[aq]/REGEX/=REPLACEMENT\[aq]\f[].+.PP+REGEX is a case\-insensitive regular expression.+Anywhere it matches inside an account name, the matched part will be+replaced by REPLACEMENT.+If REGEX contains parenthesised match groups, these can be referenced by+the usual numeric backreferences in REPLACEMENT.+Eg:+.IP+.nf+\f[C]+alias\ /^(.+):bank:([^:]+)(.*)/\ =\ \\1:\\2\ \\3+#\ rewrites\ "assets:bank:wells\ fargo:checking"\ to\ \ "assets:wells\ fargo\ checking"+\f[]+.fi+.PP+Also note that REPLACEMENT continues to the end of line (or on command+line, to end of option argument), so it can contain trailing whitespace.+.SS Multiple aliases+.PP+You can define as many aliases as you like using directives or+command\-line options.+Aliases are recursive \- each alias sees the result of applying previous+ones.+(This is different from Ledger, where aliases are non\-recursive by+default).+Aliases are applied in the following order:+.IP "1." 3+alias directives, most recently seen first (recent directives take+precedence over earlier ones; directives not yet seen are ignored)+.IP "2." 3+alias options, in the order they appear on the command line+.SS end aliases+.PP+You can clear (forget) all currently defined aliases with the+\f[C]end\ aliases\f[] directive:+.IP+.nf+\f[C]+end\ aliases+\f[]+.fi+.SS account directive+.PP+The \f[C]account\f[] directive predefines account names, as in Ledger+and Beancount.+This may be useful for your own documentation; hledger doesn't make use+of it yet.+.IP+.nf+\f[C]+;\ account\ ACCT+;\ \ \ OPTIONAL\ COMMENTS/TAGS...++account\ assets:bank:checking+\ a\ comment+\ acct\-no:12345++account\ expenses:food++;\ etc.+\f[]+.fi+.SS apply account directive+.PP+You can specify a parent account which will be prepended to all accounts+within a section of the journal.+Use the \f[C]apply\ account\f[] and \f[C]end\ apply\ account\f[]+directives like so:+.IP+.nf+\f[C]+apply\ account\ home++2010/1/1+\ \ \ \ food\ \ \ \ $10+\ \ \ \ cash++end\ apply\ account+\f[]+.fi+.PP+which is equivalent to:+.IP+.nf+\f[C]+2010/01/01+\ \ \ \ home:food\ \ \ \ \ \ \ \ \ \ \ $10+\ \ \ \ home:cash\ \ \ \ \ \ \ \ \ \ $\-10+\f[]+.fi+.PP+If \f[C]end\ apply\ account\f[] is omitted, the effect lasts to the end+of the file.+Included files are also affected, eg:+.IP+.nf+\f[C]+apply\ account\ business+include\ biz.journal+end\ apply\ account+apply\ account\ personal+include\ personal.journal+\f[]+.fi+.PP+Prior to hledger 1.0, legacy \f[C]account\f[] and \f[C]end\f[] spellings+were also supported.+.SS Multi\-line comments+.PP+A line containing just \f[C]comment\f[] starts a multi\-line comment,+and a line containing just \f[C]end\ comment\f[] ends it.+See comments.+.SS commodity directive+.PP+The \f[C]commodity\f[] directive predefines commodities (currently this+is just informational), and also it may define the display format for+amounts in this commodity (overriding the automatically inferred+format).+.PP+It may be written on a single line, like this:+.IP+.nf+\f[C]+;\ commodity\ EXAMPLEAMOUNT++;\ display\ AAAA\ amounts\ with\ the\ symbol\ on\ the\ right,\ space\-separated,+;\ using\ period\ as\ decimal\ point,\ with\ four\ decimal\ places,\ and+;\ separating\ thousands\ with\ comma.+commodity\ 1,000.0000\ AAAA+\f[]+.fi+.PP+or on multiple lines, using the \[lq]format\[rq] subdirective.+In this case the commodity symbol appears twice and should be the same+in both places:+.IP+.nf+\f[C]+;\ commodity\ SYMBOL+;\ \ \ format\ EXAMPLEAMOUNT++;\ display\ indian\ rupees\ with\ currency\ name\ on\ the\ left,+;\ thousands,\ lakhs\ and\ crores\ comma\-separated,+;\ period\ as\ decimal\ point,\ and\ two\ decimal\ places.+commodity\ INR+\ \ format\ INR\ 9,99,99,999.00+\f[]+.fi+.SS Default commodity+.PP+The D directive sets a default commodity (and display format), to be+used for amounts without a commodity symbol (ie, plain numbers).+(Note this differs from Ledger's default commodity directive.) The+commodity and display format will be applied to all subsequent+commodity\-less amounts, or until the next D directive.+.IP+.nf+\f[C]+#\ commodity\-less\ amounts\ should\ be\ treated\ as\ dollars+#\ (and\ displayed\ with\ symbol\ on\ the\ left,\ thousands\ separators\ and\ two\ decimal\ places)+D\ $1,000.00++1/1+\ \ a\ \ \ \ \ 5\ \ \ \ ;\ <\-\ commodity\-less\ amount,\ becomes\ $1+\ \ b+\f[]+.fi+.SS Default year+.PP+You can set a default year to be used for subsequent dates which don't+specify a year.+This is a line beginning with \f[C]Y\f[] followed by the year.+Eg:+.IP+.nf+\f[C]+Y2009\ \ \ \ \ \ ;\ set\ default\ year\ to\ 2009++12/15\ \ \ \ \ \ ;\ equivalent\ to\ 2009/12/15+\ \ expenses\ \ 1+\ \ assets++Y2010\ \ \ \ \ \ ;\ change\ default\ year\ to\ 2010++2009/1/30\ \ ;\ specifies\ the\ year,\ not\ affected+\ \ expenses\ \ 1+\ \ assets++1/31\ \ \ \ \ \ \ ;\ equivalent\ to\ 2010/1/31+\ \ expenses\ \ 1+\ \ assets+\f[]+.fi+.SS Including other files+.PP+You can pull in the content of additional journal files by writing an+include directive, like this:+.IP+.nf+\f[C]+include\ path/to/file.journal+\f[]+.fi+.PP+If the path does not begin with a slash, it is relative to the current+file.+Glob patterns (\f[C]*\f[]) are not currently supported.+.PP+The \f[C]include\f[] directive can only be used in journal files.+It can include journal, timeclock or timedot files, but not CSV files.+.SH Periodic transactions+.PP+A periodic transaction starts with a tilde `~' in place of a date+followed by a period expression:+.IP+.nf+\f[C]+~\ weekly+\ \ assets:bank:checking\ \ \ $400\ ;\ paycheck+\ \ income:acme\ inc+\f[]+.fi+.PP+Periodic transactions are used for forecasting and budgeting only, they+have no effect unless the \f[C]\-\-forecast\f[] or \f[C]\-\-budget\f[]+flag is used.+With \f[C]\-\-forecast\f[], each periodic transaction rule generates+recurring forecast transactions at the specified interval, beginning the+day after the last recorded journal transaction and ending 6 months from+today, or at the specified report end date.+With \f[C]balance\ \-\-budget\f[], each periodic transaction declares+recurring budget goals for one or more accounts.+.PD 0+.P+.PD+For more details, see: balance > Budgeting, Budgeting and Forecasting.+.SH Automated posting rules+.PP+Automated posting rule starts with an equal sign `=' in place of a date,+followed by a query:+.IP+.nf+\f[C]+=\ expenses:gifts+\ \ \ \ budget:gifts\ \ *\-1+\ \ \ \ assets:budget\ \ *1+\f[]+.fi+.PP+When \f[C]\-\-auto\f[] option is specified on the command line,+automated posting rule will add its postings to all transactions that+match the query.+.PP+If amount in the automated posting rule includes commodity name, new+posting will be made in the given commodity, otherwise commodity of the+matched transaction will be used.+.PP+When amount in the automated posting rule begins with the '*', amount+will be treated as a multiplier that is applied to the amount of the+first posting in the matched transaction.+.PP+In example above, every transaction in \f[C]expenses:gifts\f[] account+will have two additional postings added to it: amount of the original+gift will be debited from \f[C]budget:gifts\f[] and credited into+\f[C]assets:budget\f[]:+.IP+.nf+\f[C]+;\ Original\ transaction+2017\-12\-14+\ \ expenses:gifts\ \ $20+\ \ assets++;\ With\ automated\ postings\ applied+2017/12/14+\ \ \ \ expenses:gifts\ \ \ \ \ \ \ \ \ \ \ \ \ $20+\ \ \ \ assets+\ \ \ \ budget:gifts\ \ \ \ \ \ \ \ \ \ \ \ \ \ $\-20+\ \ \ \ assets:budget\ \ \ \ \ \ \ \ \ \ \ \ \ \ $20+\f[]+.fi+.SH EDITOR SUPPORT+.PP+Add\-on modes exist for various text editors, to make working with+journal files easier.+They add colour, navigation aids and helpful commands.+For hledger users who edit the journal file directly (the majority),+using one of these modes is quite recommended.+.PP+These were written with Ledger in mind, but also work with hledger+files:+.PP+.TS+tab(@);+lw(16.5n) lw(53.5n).+T{+Emacs+T}@T{+http://www.ledger\-cli.org/3.0/doc/ledger\-mode.html+T}+T{+Vim+T}@T{+https://github.com/ledger/ledger/wiki/Getting\-started+T}+T{+Sublime Text+T}@T{+https://github.com/ledger/ledger/wiki/Using\-Sublime\-Text+T}+T{+Textmate+T}@T{+https://github.com/ledger/ledger/wiki/Using\-TextMate\-2+T}+T{+Text Wrangler \ +T}@T{+https://github.com/ledger/ledger/wiki/Editing\-Ledger\-files\-with\-TextWrangler+T}+T{+Visual Studio Code+T}@T{+https://marketplace.visualstudio.com/items?itemName=mark\-hansen.hledger\-vscode+T}+.TE+++.SH "REPORTING BUGS"+Report bugs at http://bugs.hledger.org+(or on the #hledger IRC channel or hledger mail list)++.SH AUTHORS+Simon Michael <simon@joyful.com> and contributors++.SH COPYRIGHT++Copyright (C) 2007-2016 Simon Michael.+.br+Released under GNU GPL v3 or later.++.SH SEE ALSO+hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),+hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),+ledger(1)++http://hledger.org
+ hledger_journal.info view
@@ -0,0 +1,1235 @@+This is hledger_journal.info, produced by makeinfo version 6.5 from+stdin.+++File: hledger_journal.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir)++hledger_journal(5) hledger 1.5+******************************++hledger's usual data source is a plain text file containing journal+entries in hledger journal format.  This file represents a standard+accounting general journal.  I use file names ending in '.journal', but+that's not required.  The journal file contains a number of transaction+entries, each describing a transfer of money (or any commodity) between+two or more named accounts, in a simple format readable by both hledger+and humans.++   hledger's journal format is a compatible subset, mostly, of ledger's+journal format, so hledger can work with compatible ledger journal files+as well.  It's safe, and encouraged, to run both hledger and ledger on+the same journal file, eg to validate the results you're getting.++   You can use hledger without learning any more about this file; just+use the add or web commands to create and update it.  Many users,+though, also edit the journal file directly with a text editor, perhaps+assisted by the helper modes for emacs or vim.++   Here's an example:++; A sample journal file. This is a comment.++2008/01/01 income               ; <- transaction's first line starts in column 0, contains date and description+    assets:bank:checking  $1    ; <- posting lines start with whitespace, each contains an account name+    income:salary        $-1    ;    followed by at least two spaces and an amount++2008/06/01 gift+    assets:bank:checking  $1    ; <- at least two postings in a transaction+    income:gifts         $-1    ; <- their amounts must balance to 0++2008/06/02 save+    assets:bank:saving    $1+    assets:bank:checking        ; <- one amount may be omitted; here $-1 is inferred++2008/06/03 eat & shop           ; <- description can be anything+    expenses:food         $1+    expenses:supplies     $1    ; <- this transaction debits two expense accounts+    assets:cash                 ; <- $-2 inferred++2008/10/01 take a loan+    assets:bank:checking  $1+    liabilities:debts    $-1++2008/12/31 * pay off            ; <- an optional * or ! after the date means "cleared" (or anything you want)+    liabilities:debts     $1+    assets:bank:checking++* Menu:++* FILE FORMAT::+* Periodic transactions::+* Automated posting rules::+* EDITOR SUPPORT::+++File: hledger_journal.info,  Node: FILE FORMAT,  Next: Periodic transactions,  Prev: Top,  Up: Top++1 FILE FORMAT+*************++* Menu:++* Transactions::+* Postings::+* Dates::+* Status::+* Description::+* Account names::+* Amounts::+* Virtual Postings::+* Balance Assertions::+* Balance Assignments::+* Prices::+* Comments::+* Tags::+* Directives::+++File: hledger_journal.info,  Node: Transactions,  Next: Postings,  Up: FILE FORMAT++1.1 Transactions+================++Transactions are movements of some quantity of commodities between named+accounts.  Each transaction is represented by a journal entry beginning+with a simple date in column 0.  This can be followed by any of the+following, separated by spaces:++   * (optional) a status character (empty, '!', or '*')+   * (optional) a transaction code (any short number or text, enclosed+     in parentheses)+   * (optional) a transaction description (any remaining text until end+     of line or a semicolon)+   * (optional) a transaction comment (any remaining text following a+     semicolon until end of line)++   Then comes zero or more (but usually at least 2) indented lines+representing...+++File: hledger_journal.info,  Node: Postings,  Next: Dates,  Prev: Transactions,  Up: FILE FORMAT++1.2 Postings+============++A posting is an addition of some amount to, or removal of some amount+from, an account.  Each posting line begins with at least one space or+tab (2 or 4 spaces is common), followed by:++   * (optional) a status character (empty, '!', or '*'), followed by a+     space+   * (required) an account name (any text, optionally containing *single+     spaces*, until end of line or a double space)+   * (optional) *two or more spaces* or tabs followed by an amount.++   Positive amounts are being added to the account, negative amounts are+being removed.++   The amounts within a transaction must always sum up to zero.  As a+convenience, one amount may be left blank; it will be inferred so as to+balance the transaction.++   Be sure to note the unusual two-space delimiter between account name+and amount.  This makes it easy to write account names containing+spaces.  But if you accidentally leave only one space (or tab) before+the amount, the amount will be considered part of the account name.+++File: hledger_journal.info,  Node: Dates,  Next: Status,  Prev: Postings,  Up: FILE FORMAT++1.3 Dates+=========++* Menu:++* Simple dates::+* Secondary dates::+* Posting dates::+++File: hledger_journal.info,  Node: Simple dates,  Next: Secondary dates,  Up: Dates++1.3.1 Simple dates+------------------++Within a journal file, transaction dates use Y/M/D (or Y-M-D or Y.M.D)+Leading zeros are optional.  The year may be omitted, in which case it+will be inferred from the context - the current transaction, the default+year set with a default year directive, or the current date when the+command is run.  Some examples: '2010/01/31', '1/31', '2010-01-31',+'2010.1.31'.+++File: hledger_journal.info,  Node: Secondary dates,  Next: Posting dates,  Prev: Simple dates,  Up: Dates++1.3.2 Secondary dates+---------------------++Real-life transactions sometimes involve more than one date - eg the+date you write a cheque, and the date it clears in your bank.  When you+want to model this, eg for more accurate balances, you can specify+individual posting dates, which I recommend.  Or, you can use the+secondary dates (aka auxiliary/effective dates) feature, supported for+compatibility with Ledger.++   A secondary date can be written after the primary date, separated by+an equals sign.  The primary date, on the left, is used by default; the+secondary date, on the right, is used when the '--date2' flag is+specified ('--aux-date' or '--effective' also work).++   The meaning of secondary dates is up to you, but it's best to follow+a consistent rule.  Eg write the bank's clearing date as primary, and+when needed, the date the transaction was initiated as secondary.++   Here's an example.  Note that a secondary date will use the year of+the primary date if unspecified.++2010/2/23=2/19 movie ticket+  expenses:cinema                   $10+  assets:checking++$ hledger register checking+2010/02/23 movie ticket         assets:checking                $-10         $-10++$ hledger register checking --date2+2010/02/19 movie ticket         assets:checking                $-10         $-10++   Secondary dates require some effort; you must use them consistently+in your journal entries and remember whether to use or not use the+'--date2' flag for your reports.  They are included in hledger for+Ledger compatibility, but posting dates are a more powerful and less+confusing alternative.+++File: hledger_journal.info,  Node: Posting dates,  Prev: Secondary dates,  Up: Dates++1.3.3 Posting dates+-------------------++You can give individual postings a different date from their parent+transaction, by adding a posting comment containing a tag (see below)+like 'date:DATE'.  This is probably the best way to control posting+dates precisely.  Eg in this example the expense should appear in May+reports, and the deduction from checking should be reported on 6/1 for+easy bank reconciliation:++2015/5/30+    expenses:food     $10   ; food purchased on saturday 5/30+    assets:checking         ; bank cleared it on monday, date:6/1++$ hledger -f t.j register food+2015/05/30                      expenses:food                  $10           $10++$ hledger -f t.j register checking+2015/06/01                      assets:checking               $-10          $-10++   DATE should be a simple date; if the year is not specified it will+use the year of the transaction's date.  You can set the secondary date+similarly, with 'date2:DATE2'.  The 'date:' or 'date2:' tags must have a+valid simple date value if they are present, eg a 'date:' tag with no+value is not allowed.++   Ledger's earlier, more compact bracketed date syntax is also+supported: '[DATE]', '[DATE=DATE2]' or '[=DATE2]'.  hledger will attempt+to parse any square-bracketed sequence of the '0123456789/-.='+characters in this way.  With this syntax, DATE infers its year from the+transaction and DATE2 infers its year from DATE.+++File: hledger_journal.info,  Node: Status,  Next: Description,  Prev: Dates,  Up: FILE FORMAT++1.4 Status+==========++Transactions, or individual postings within a transaction, can have a+status mark, which is a single character before the transaction+description or posting account name, separated from it by a space,+indicating one of three statuses:++mark  status+ +-----------------+      unmarked+'!'   pending+'*'   cleared++   When reporting, you can filter by status with the '-U/--unmarked',+'-P/--pending', and '-C/--cleared' flags; or the 'status:', 'status:!',+and 'status:*' queries; or the U, P, C keys in hledger-ui.++   Note, in Ledger and in older versions of hledger, the "unmarked"+state is called "uncleared".  As of hledger 1.3 we have renamed it to+unmarked for clarity.++   To replicate Ledger and old hledger's behaviour of also matching+pending, combine -U and -P.++   Status marks are optional, but can be helpful eg for reconciling with+real-world accounts.  Some editor modes provide highlighting and+shortcuts for working with status.  Eg in Emacs ledger-mode, you can+toggle transaction status with C-c C-e, or posting status with C-c C-c.++   What "uncleared", "pending", and "cleared" actually mean is up to+you.  Here's one suggestion:++status     meaning+--------------------------------------------------------------------------+uncleared  recorded but not yet reconciled; needs review+pending    tentatively reconciled (if needed, eg during a big+           reconciliation)+cleared    complete, reconciled as far as possible, and considered+           correct++   With this scheme, you would use '-PC' to see the current balance at+your bank, '-U' to see things which will probably hit your bank soon+(like uncashed checks), and no flags to see the most up-to-date state of+your finances.+++File: hledger_journal.info,  Node: Description,  Next: Account names,  Prev: Status,  Up: FILE FORMAT++1.5 Description+===============++A transaction's description is the rest of the line following the date+and status mark (or until a comment begins).  Sometimes called the+"narration" in traditional bookkeeping, it can be used for whatever you+wish, or left blank.  Transaction descriptions can be queried, unlike+comments.+* Menu:++* Payee and note::+++File: hledger_journal.info,  Node: Payee and note,  Up: Description++1.5.1 Payee and note+--------------------++You can optionally include a '|' (pipe) character in a description to+subdivide it into a payee/payer name on the left and additional notes on+the right.  This may be worthwhile if you need to do more precise+querying and pivoting by payee.+++File: hledger_journal.info,  Node: Account names,  Next: Amounts,  Prev: Description,  Up: FILE FORMAT++1.6 Account names+=================++Account names typically have several parts separated by a full colon,+from which hledger derives a hierarchical chart of accounts.  They can+be anything you like, but in finance there are traditionally five+top-level accounts: 'assets', 'liabilities', 'income', 'expenses', and+'equity'.++   Account names may contain single spaces, eg: 'assets:accounts+receivable'.  Because of this, they must always be followed by *two or+more spaces* (or newline).++   Account names can be aliased.+++File: hledger_journal.info,  Node: Amounts,  Next: Virtual Postings,  Prev: Account names,  Up: FILE FORMAT++1.7 Amounts+===========++After the account name, there is usually an amount.  Important: between+account name and amount, there must be *two or more spaces*.++   Amounts consist of a number and (usually) a currency symbol or+commodity name.  Some examples:++   '2.00001'+'$1'+'4000 AAPL'+'3 "green apples"'+'-$1,000,000.00'+'INR 9,99,99,999.00'+'EUR -2.000.000,00'+'1 999 999.9455'++   As you can see, the amount format is somewhat flexible:++   * amounts are a number (the "quantity") and optionally a currency+     symbol/commodity name (the "commodity").+   * the commodity is a symbol, word, or phrase, on the left or right,+     with or without a separating space.  If the commodity contains+     numbers, spaces or non-word punctuation it must be enclosed in+     double quotes.+   * negative amounts with a commodity on the left can have the minus+     sign before or after it+   * digit groups (thousands, or any other grouping) can be separated by+     space or comma or period and should be used as separator between+     all groups+   * decimal part can be separated by comma or period and should be+     different from digit groups separator++   You can use any of these variations when recording data.  However,+there is some ambiguous way of representing numbers like '$1.000' and+'$1,000' both may mean either one thousand or one dollar.  By default+hledger will assume that this is sole delimiter is used only for+decimals.  On the other hand commodity format declared prior to that+line will help to resolve that ambiguity differently:++commodity $1,000.00++2017/12/25 New life of Scrooge+    expenses:gifts  $1,000+    assets++   Though journal may contain mixed styles to represent amount, when+hledger displays amounts, it will choose a consistent format for each+commodity.  (Except for price amounts, which are always formatted as+written).  The display format is chosen as follows:++   * if there is a commodity directive specifying the format, that is+     used+   * otherwise the format is inferred from the first posting amount in+     that commodity in the journal, and the precision (number of decimal+     places) will be the maximum from all posting amounts in that+     commmodity+   * or if there are no such amounts in the journal, a default format is+     used (like '$1000.00').++   Price amounts and amounts in D directives usually don't affect amount+format inference, but in some situations they can do so indirectly.  (Eg+when D's default commodity is applied to a commodity-less amount, or+when an amountless posting is balanced using a price's commodity, or+when -V is used.)  If you find this causing problems, set the desired+format with a commodity directive.+++File: hledger_journal.info,  Node: Virtual Postings,  Next: Balance Assertions,  Prev: Amounts,  Up: FILE FORMAT++1.8 Virtual Postings+====================++When you parenthesise the account name in a posting, we call that a+_virtual posting_, which means:++   * it is ignored when checking that the transaction is balanced+   * it is excluded from reports when the '--real/-R' flag is used, or+     the 'real:1' query.++   You could use this, eg, to set an account's opening balance without+needing to use the 'equity:opening balances' account:++1/1 special unbalanced posting to set initial balance+  (assets:checking)   $1000++   When the account name is bracketed, we call it a _balanced virtual+posting_.  This is like an ordinary virtual posting except the balanced+virtual postings in a transaction must balance to 0, like the real+postings (but separately from them).  Balanced virtual postings are also+excluded by '--real/-R' or 'real:1'.++1/1 buy food with cash, and update some budget-tracking subaccounts elsewhere+  expenses:food                   $10+  assets:cash                    $-10+  [assets:checking:available]     $10+  [assets:checking:budget:food]  $-10++   Virtual postings have some legitimate uses, but those are few.  You+can usually find an equivalent journal entry using real postings, which+is more correct and provides better error checking.+++File: hledger_journal.info,  Node: Balance Assertions,  Next: Balance Assignments,  Prev: Virtual Postings,  Up: FILE FORMAT++1.9 Balance Assertions+======================++hledger supports Ledger-style balance assertions in journal files.+These look like '=EXPECTEDBALANCE' following a posting's amount.  Eg in+this example we assert the expected dollar balance in accounts a and b+after each posting:++2013/1/1+  a   $1  =$1+  b       =$-1++2013/1/2+  a   $1  =$2+  b  $-1  =$-2++   After reading a journal file, hledger will check all balance+assertions and report an error if any of them fail.  Balance assertions+can protect you from, eg, inadvertently disrupting reconciled balances+while cleaning up old entries.  You can disable them temporarily with+the '--ignore-assertions' flag, which can be useful for troubleshooting+or for reading Ledger files.+* Menu:++* Assertions and ordering::+* Assertions and included files::+* Assertions and multiple -f options::+* Assertions and commodities::+* Assertions and subaccounts::+* Assertions and virtual postings::+++File: hledger_journal.info,  Node: Assertions and ordering,  Next: Assertions and included files,  Up: Balance Assertions++1.9.1 Assertions and ordering+-----------------------------++hledger sorts an account's postings and assertions first by date and+then (for postings on the same day) by parse order.  Note this is+different from Ledger, which sorts assertions only by parse order.+(Also, Ledger assertions do not see the accumulated effect of repeated+postings to the same account within a transaction.)++   So, hledger balance assertions keep working if you reorder+differently-dated transactions within the journal.  But if you reorder+same-dated transactions or postings, assertions might break and require+updating.  This order dependence does bring an advantage: precise+control over the order of postings and assertions within a day, so you+can assert intra-day balances.+++File: hledger_journal.info,  Node: Assertions and included files,  Next: Assertions and multiple -f options,  Prev: Assertions and ordering,  Up: Balance Assertions++1.9.2 Assertions and included files+-----------------------------------++With included files, things are a little more complicated.  Including+preserves the ordering of postings and assertions.  If you have multiple+postings to an account on the same day, split across different files,+and you also want to assert the account's balance on the same day,+you'll have to put the assertion in the right file.+++File: hledger_journal.info,  Node: Assertions and multiple -f options,  Next: Assertions and commodities,  Prev: Assertions and included files,  Up: Balance Assertions++1.9.3 Assertions and multiple -f options+----------------------------------------++Balance assertions don't work well across files specified with multiple+-f options.  Use include or concatenate the files instead.+++File: hledger_journal.info,  Node: Assertions and commodities,  Next: Assertions and subaccounts,  Prev: Assertions and multiple -f options,  Up: Balance Assertions++1.9.4 Assertions and commodities+--------------------------------++The asserted balance must be a simple single-commodity amount, and in+fact the assertion checks only this commodity's balance within the+(possibly multi-commodity) account balance.  We could call this a+partial balance assertion.  This is compatible with Ledger, and makes it+possible to make assertions about accounts containing multiple+commodities.++   To assert each commodity's balance in such a multi-commodity account,+you can add multiple postings (with amount 0 if necessary).  But note+that no matter how many assertions you add, you can't be sure the+account does not contain some unexpected commodity.  (We'll add support+for this kind of total balance assertion if there's demand.)+++File: hledger_journal.info,  Node: Assertions and subaccounts,  Next: Assertions and virtual postings,  Prev: Assertions and commodities,  Up: Balance Assertions++1.9.5 Assertions and subaccounts+--------------------------------++Balance assertions do not count the balance from subaccounts; they check+the posted account's exclusive balance.  For example:++1/1+  checking:fund   1 = 1  ; post to this subaccount, its balance is now 1+  checking        1 = 1  ; post to the parent account, its exclusive balance is now 1+  equity++   The balance report's flat mode shows these exclusive balances more+clearly:++$ hledger bal checking --flat+                   1  checking+                   1  checking:fund+--------------------+                   2+++File: hledger_journal.info,  Node: Assertions and virtual postings,  Prev: Assertions and subaccounts,  Up: Balance Assertions++1.9.6 Assertions and virtual postings+-------------------------------------++Balance assertions are checked against all postings, both real and+virtual.  They are not affected by the '--real/-R' flag or 'real:'+query.+++File: hledger_journal.info,  Node: Balance Assignments,  Next: Prices,  Prev: Balance Assertions,  Up: FILE FORMAT++1.10 Balance Assignments+========================++Ledger-style balance assignments are also supported.  These are like+balance assertions, but with no posting amount on the left side of the+equals sign; instead it is calculated automatically so as to satisfy the+assertion.  This can be a convenience during data entry, eg when setting+opening balances:++; starting a new journal, set asset account balances +2016/1/1 opening balances+  assets:checking            = $409.32+  assets:savings             = $735.24+  assets:cash                 = $42+  equity:opening balances++   or when adjusting a balance to reality:++; no cash left; update balance, record any untracked spending as a generic expense+2016/1/15+  assets:cash    = $0+  expenses:misc++   The calculated amount depends on the account's balance in the+commodity at that point (which depends on the previously-dated postings+of the commodity to that account since the last balance assertion or+assignment).  Note that using balance assignments makes your journal a+little less explicit; to know the exact amount posted, you have to run+hledger or do the calculations yourself, instead of just reading it.+++File: hledger_journal.info,  Node: Prices,  Next: Comments,  Prev: Balance Assignments,  Up: FILE FORMAT++1.11 Prices+===========++* Menu:++* Transaction prices::+* Market prices::+++File: hledger_journal.info,  Node: Transaction prices,  Next: Market prices,  Up: Prices++1.11.1 Transaction prices+-------------------------++Within a transaction, you can note an amount's price in another+commodity.  This can be used to document the cost (in a purchase) or+selling price (in a sale).  For example, transaction prices are useful+to record purchases of a foreign currency.++   Transaction prices are fixed, and do not change over time.  (Ledger+users: Ledger uses a different syntax for fixed prices, '{=UNITPRICE}',+which hledger currently ignores).++   There are several ways to record a transaction price:++  1. Write the price per unit, as '@ UNITPRICE' after the amount:++     2009/1/1+       assets:euros     €100 @ $1.35  ; one hundred euros purchased at $1.35 each+       assets:dollars                 ; balancing amount is -$135.00++  2. Write the total price, as '@@ TOTALPRICE' after the amount:++     2009/1/1+       assets:euros     €100 @@ $135  ; one hundred euros purchased at $135 for the lot+       assets:dollars++  3. Specify amounts for all postings, using exactly two commodities,+     and let hledger infer the price that balances the transaction:++     2009/1/1+       assets:euros     €100          ; one hundred euros purchased+       assets:dollars  $-135          ; for $135++   Amounts with transaction prices can be displayed in the transaction+price's commodity by using the '-B/--cost' flag (except for #551) ("B"+is from "cost Basis").  Eg for the above, here is how -B affects the+balance report:++$ hledger bal -N --flat+               $-135  assets:dollars+                €100  assets:euros+$ hledger bal -N --flat -B+               $-135  assets:dollars+                $135  assets:euros    # <- the euros' cost++   Note -B is sensitive to the order of postings when a transaction+price is inferred: the inferred price will be in the commodity of the+last amount.  So if example 3's postings are reversed, while the+transaction is equivalent, -B shows something different:++2009/1/1+  assets:dollars  $-135               ; 135 dollars sold+  assets:euros     €100               ; for 100 euros++$ hledger bal -N --flat -B+               €-100  assets:dollars  # <- the dollars' selling price+                €100  assets:euros+++File: hledger_journal.info,  Node: Market prices,  Prev: Transaction prices,  Up: Prices++1.11.2 Market prices+--------------------++Market prices are not tied to a particular transaction; they represent+historical exchange rates between two commodities.  (Ledger calls them+historical prices.)  For example, the prices published by a stock+exchange or the foreign exchange market.  hledger can use these prices+to show the market value of things at a given date, see market value.++   To record market prices, use P directives in the main journal or in+an included file.  Their format is:++P DATE COMMODITYBEINGPRICED UNITPRICE++   DATE is a simple date as usual.  COMMODITYBEINGPRICED is the symbol+of the commodity being priced.  UNITPRICE is an ordinary amount (symbol+and quantity) in a second commodity, specifying the unit price or+conversion rate for the first commodity in terms of the second, on the+given date.++   For example, the following directives say that one euro was worth+1.35 US dollars during 2009, and $1.40 from 2010 onward:++P 2009/1/1 € $1.35+P 2010/1/1 € $1.40+++File: hledger_journal.info,  Node: Comments,  Next: Tags,  Prev: Prices,  Up: FILE FORMAT++1.12 Comments+=============++Lines in the journal beginning with a semicolon (';') or hash ('#') or+star ('*') are comments, and will be ignored.  (Star comments cause+org-mode nodes to be ignored, allowing emacs users to fold and navigate+their journals with org-mode or orgstruct-mode.)++   Also, anything between 'comment' and 'end comment' directives is a+(multi-line) comment.  If there is no 'end comment', the comment extends+to the end of the file.++   You can attach comments to a transaction by writing them after the+description and/or indented on the following lines (before the+postings).  Similarly, you can attach comments to an individual posting+by writing them after the amount and/or indented on the following lines.+Transaction and posting comments must begin with a semicolon (';').++   Some examples:++# a file comment++; also a file comment++comment+This is a multiline file comment,+which continues until a line+where the "end comment" string+appears on its own (or end of file).+end comment++2012/5/14 something  ; a transaction comment+    ; the transaction comment, continued+    posting1  1  ; a comment for posting 1+    posting2+    ; a comment for posting 2+    ; another comment line for posting 2+; a file comment (because not indented)+++File: hledger_journal.info,  Node: Tags,  Next: Directives,  Prev: Comments,  Up: FILE FORMAT++1.13 Tags+=========++Tags are a way to add extra labels or labelled data to postings and+transactions, which you can then search or pivot on.++   A simple tag is a word (which may contain hyphens) followed by a full+colon, written inside a transaction or posting comment line:++2017/1/16 bought groceries    ; sometag:++   Tags can have a value, which is the text after the colon, up to the+next comma or end of line, with leading/trailing whitespace removed:++    expenses:food    $10   ; a-posting-tag: the tag value++   Note this means hledger's tag values can not contain commas or+newlines.  Ending at commas means you can write multiple short tags on+one line, comma separated:++    assets:checking       ; a comment containing tag1:, tag2: some value ...++   Here,++   * "'a comment containing'" is just comment text, not a tag+   * "'tag1'" is a tag with no value+   * "'tag2'" is another tag, whose value is "'some value ...'"++   Tags in a transaction comment affect the transaction and all of its+postings, while tags in a posting comment affect only that posting.  For+example, the following transaction has three tags ('A', 'TAG2',+'third-tag') and the posting has four (those plus 'posting-tag'):++1/1 a transaction  ; A:, TAG2:+    ; third-tag: a third transaction tag, <- with a value+    (a)  $1  ; posting-tag:++   Tags are like Ledger's metadata feature, except hledger's tag values+are simple strings.+++File: hledger_journal.info,  Node: Directives,  Prev: Tags,  Up: FILE FORMAT++1.14 Directives+===============++* Menu:++* Account aliases::+* account directive::+* apply account directive::+* Multi-line comments::+* commodity directive::+* Default commodity::+* Default year::+* Including other files::+++File: hledger_journal.info,  Node: Account aliases,  Next: account directive,  Up: Directives++1.14.1 Account aliases+----------------------++You can define aliases which rewrite your account names (after reading+the journal, before generating reports).  hledger's account aliases can+be useful for:++   * expanding shorthand account names to their full form, allowing+     easier data entry and a less verbose journal+   * adapting old journals to your current chart of accounts+   * experimenting with new account organisations, like a new hierarchy+     or combining two accounts into one+   * customising reports++   See also Cookbook: rewrite account names.+* Menu:++* Basic aliases::+* Regex aliases::+* Multiple aliases::+* end aliases::+++File: hledger_journal.info,  Node: Basic aliases,  Next: Regex aliases,  Up: Account aliases++1.14.1.1 Basic aliases+......................++To set an account alias, use the 'alias' directive in your journal file.+This affects all subsequent journal entries in the current file or its+included files.  The spaces around the = are optional:++alias OLD = NEW++   Or, you can use the '--alias 'OLD=NEW'' option on the command line.+This affects all entries.  It's useful for trying out aliases+interactively.++   OLD and NEW are full account names.  hledger will replace any+occurrence of the old account name with the new one.  Subaccounts are+also affected.  Eg:++alias checking = assets:bank:wells fargo:checking+# rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"+++File: hledger_journal.info,  Node: Regex aliases,  Next: Multiple aliases,  Prev: Basic aliases,  Up: Account aliases++1.14.1.2 Regex aliases+......................++There is also a more powerful variant that uses a regular expression,+indicated by the forward slashes:++alias /REGEX/ = REPLACEMENT++   or '--alias '/REGEX/=REPLACEMENT''.++   REGEX is a case-insensitive regular expression.  Anywhere it matches+inside an account name, the matched part will be replaced by+REPLACEMENT. If REGEX contains parenthesised match groups, these can be+referenced by the usual numeric backreferences in REPLACEMENT. Eg:++alias /^(.+):bank:([^:]+)(.*)/ = \1:\2 \3+# rewrites "assets:bank:wells fargo:checking" to  "assets:wells fargo checking"++   Also note that REPLACEMENT continues to the end of line (or on+command line, to end of option argument), so it can contain trailing+whitespace.+++File: hledger_journal.info,  Node: Multiple aliases,  Next: end aliases,  Prev: Regex aliases,  Up: Account aliases++1.14.1.3 Multiple aliases+.........................++You can define as many aliases as you like using directives or+command-line options.  Aliases are recursive - each alias sees the+result of applying previous ones.  (This is different from Ledger, where+aliases are non-recursive by default).  Aliases are applied in the+following order:++  1. alias directives, most recently seen first (recent directives take+     precedence over earlier ones; directives not yet seen are ignored)+  2. alias options, in the order they appear on the command line+++File: hledger_journal.info,  Node: end aliases,  Prev: Multiple aliases,  Up: Account aliases++1.14.1.4 end aliases+....................++You can clear (forget) all currently defined aliases with the 'end+aliases' directive:++end aliases+++File: hledger_journal.info,  Node: account directive,  Next: apply account directive,  Prev: Account aliases,  Up: Directives++1.14.2 account directive+------------------------++The 'account' directive predefines account names, as in Ledger and+Beancount.  This may be useful for your own documentation; hledger+doesn't make use of it yet.++; account ACCT+;   OPTIONAL COMMENTS/TAGS...++account assets:bank:checking+ a comment+ acct-no:12345++account expenses:food++; etc.+++File: hledger_journal.info,  Node: apply account directive,  Next: Multi-line comments,  Prev: account directive,  Up: Directives++1.14.3 apply account directive+------------------------------++You can specify a parent account which will be prepended to all accounts+within a section of the journal.  Use the 'apply account' and 'end apply+account' directives like so:++apply account home++2010/1/1+    food    $10+    cash++end apply account++   which is equivalent to:++2010/01/01+    home:food           $10+    home:cash          $-10++   If 'end apply account' is omitted, the effect lasts to the end of the+file.  Included files are also affected, eg:++apply account business+include biz.journal+end apply account+apply account personal+include personal.journal++   Prior to hledger 1.0, legacy 'account' and 'end' spellings were also+supported.+++File: hledger_journal.info,  Node: Multi-line comments,  Next: commodity directive,  Prev: apply account directive,  Up: Directives++1.14.4 Multi-line comments+--------------------------++A line containing just 'comment' starts a multi-line comment, and a line+containing just 'end comment' ends it.  See comments.+++File: hledger_journal.info,  Node: commodity directive,  Next: Default commodity,  Prev: Multi-line comments,  Up: Directives++1.14.5 commodity directive+--------------------------++The 'commodity' directive predefines commodities (currently this is just+informational), and also it may define the display format for amounts in+this commodity (overriding the automatically inferred format).++   It may be written on a single line, like this:++; commodity EXAMPLEAMOUNT++; display AAAA amounts with the symbol on the right, space-separated,+; using period as decimal point, with four decimal places, and+; separating thousands with comma.+commodity 1,000.0000 AAAA++   or on multiple lines, using the "format" subdirective.  In this case+the commodity symbol appears twice and should be the same in both+places:++; commodity SYMBOL+;   format EXAMPLEAMOUNT++; display indian rupees with currency name on the left,+; thousands, lakhs and crores comma-separated,+; period as decimal point, and two decimal places.+commodity INR+  format INR 9,99,99,999.00+++File: hledger_journal.info,  Node: Default commodity,  Next: Default year,  Prev: commodity directive,  Up: Directives++1.14.6 Default commodity+------------------------++The D directive sets a default commodity (and display format), to be+used for amounts without a commodity symbol (ie, plain numbers).  (Note+this differs from Ledger's default commodity directive.)  The commodity+and display format will be applied to all subsequent commodity-less+amounts, or until the next D directive.++# commodity-less amounts should be treated as dollars+# (and displayed with symbol on the left, thousands separators and two decimal places)+D $1,000.00++1/1+  a     5    ; <- commodity-less amount, becomes $1+  b+++File: hledger_journal.info,  Node: Default year,  Next: Including other files,  Prev: Default commodity,  Up: Directives++1.14.7 Default year+-------------------++You can set a default year to be used for subsequent dates which don't+specify a year.  This is a line beginning with 'Y' followed by the year.+Eg:++Y2009      ; set default year to 2009++12/15      ; equivalent to 2009/12/15+  expenses  1+  assets++Y2010      ; change default year to 2010++2009/1/30  ; specifies the year, not affected+  expenses  1+  assets++1/31       ; equivalent to 2010/1/31+  expenses  1+  assets+++File: hledger_journal.info,  Node: Including other files,  Prev: Default year,  Up: Directives++1.14.8 Including other files+----------------------------++You can pull in the content of additional journal files by writing an+include directive, like this:++include path/to/file.journal++   If the path does not begin with a slash, it is relative to the+current file.  Glob patterns ('*') are not currently supported.++   The 'include' directive can only be used in journal files.  It can+include journal, timeclock or timedot files, but not CSV files.+++File: hledger_journal.info,  Node: Periodic transactions,  Next: Automated posting rules,  Prev: FILE FORMAT,  Up: Top++2 Periodic transactions+***********************++A periodic transaction starts with a tilde '~' in place of a date+followed by a period expression:++~ weekly+  assets:bank:checking   $400 ; paycheck+  income:acme inc++   Periodic transactions are used for forecasting and budgeting only,+they have no effect unless the '--forecast' or '--budget' flag is used.+With '--forecast', each periodic transaction rule generates recurring+forecast transactions at the specified interval, beginning the day after+the last recorded journal transaction and ending 6 months from today, or+at the specified report end date.  With 'balance --budget', each+periodic transaction declares recurring budget goals for one or more+accounts.+For more details, see: balance > Budgeting, Budgeting and Forecasting.+++File: hledger_journal.info,  Node: Automated posting rules,  Next: EDITOR SUPPORT,  Prev: Periodic transactions,  Up: Top++3 Automated posting rules+*************************++Automated posting rule starts with an equal sign '=' in place of a date,+followed by a query:++= expenses:gifts+    budget:gifts  *-1+    assets:budget  *1++   When '--auto' option is specified on the command line, automated+posting rule will add its postings to all transactions that match the+query.++   If amount in the automated posting rule includes commodity name, new+posting will be made in the given commodity, otherwise commodity of the+matched transaction will be used.++   When amount in the automated posting rule begins with the '*', amount+will be treated as a multiplier that is applied to the amount of the+first posting in the matched transaction.++   In example above, every transaction in 'expenses:gifts' account will+have two additional postings added to it: amount of the original gift+will be debited from 'budget:gifts' and credited into 'assets:budget':++; Original transaction+2017-12-14+  expenses:gifts  $20+  assets++; With automated postings applied+2017/12/14+    expenses:gifts             $20+    assets+    budget:gifts              $-20+    assets:budget              $20+++File: hledger_journal.info,  Node: EDITOR SUPPORT,  Prev: Automated posting rules,  Up: Top++4 EDITOR SUPPORT+****************++Add-on modes exist for various text editors, to make working with+journal files easier.  They add colour, navigation aids and helpful+commands.  For hledger users who edit the journal file directly (the+majority), using one of these modes is quite recommended.++   These were written with Ledger in mind, but also work with hledger+files:++Emacs             http://www.ledger-cli.org/3.0/doc/ledger-mode.html+Vim               https://github.com/ledger/ledger/wiki/Getting-started+Sublime Text      https://github.com/ledger/ledger/wiki/Using-Sublime-Text+Textmate          https://github.com/ledger/ledger/wiki/Using-TextMate-2+Text Wrangler     https://github.com/ledger/ledger/wiki/Editing-Ledger-files-with-TextWrangler+Visual Studio     https://marketplace.visualstudio.com/items?itemName=mark-hansen.hledger-vscode+Code+++Tag Table:+Node: Top76+Node: FILE FORMAT2424+Ref: #file-format2555+Node: Transactions2778+Ref: #transactions2899+Node: Postings3583+Ref: #postings3710+Node: Dates4705+Ref: #dates4820+Node: Simple dates4885+Ref: #simple-dates5011+Node: Secondary dates5377+Ref: #secondary-dates5531+Node: Posting dates7094+Ref: #posting-dates7223+Node: Status8597+Ref: #status8717+Node: Description10425+Ref: #description10563+Node: Payee and note10882+Ref: #payee-and-note10996+Node: Account names11238+Ref: #account-names11381+Node: Amounts11868+Ref: #amounts12004+Node: Virtual Postings14684+Ref: #virtual-postings14843+Node: Balance Assertions16063+Ref: #balance-assertions16238+Node: Assertions and ordering17134+Ref: #assertions-and-ordering17320+Node: Assertions and included files18020+Ref: #assertions-and-included-files18261+Node: Assertions and multiple -f options18594+Ref: #assertions-and-multiple--f-options18848+Node: Assertions and commodities18980+Ref: #assertions-and-commodities19215+Node: Assertions and subaccounts19911+Ref: #assertions-and-subaccounts20143+Node: Assertions and virtual postings20664+Ref: #assertions-and-virtual-postings20871+Node: Balance Assignments21013+Ref: #balance-assignments21182+Node: Prices22302+Ref: #prices22435+Node: Transaction prices22486+Ref: #transaction-prices22631+Node: Market prices24787+Ref: #market-prices24922+Node: Comments25882+Ref: #comments26004+Node: Tags27246+Ref: #tags27364+Node: Directives28766+Ref: #directives28879+Node: Account aliases29072+Ref: #account-aliases29216+Node: Basic aliases29820+Ref: #basic-aliases29963+Node: Regex aliases30653+Ref: #regex-aliases30821+Node: Multiple aliases31539+Ref: #multiple-aliases31711+Node: end aliases32209+Ref: #end-aliases32349+Node: account directive32450+Ref: #account-directive32630+Node: apply account directive32926+Ref: #apply-account-directive33122+Node: Multi-line comments33781+Ref: #multi-line-comments33971+Node: commodity directive34099+Ref: #commodity-directive34283+Node: Default commodity35155+Ref: #default-commodity35328+Node: Default year35865+Ref: #default-year36030+Node: Including other files36453+Ref: #including-other-files36610+Node: Periodic transactions37007+Ref: #periodic-transactions37178+Node: Automated posting rules37921+Ref: #automated-posting-rules38099+Node: EDITOR SUPPORT39208+Ref: #editor-support39338++End Tag Table
+ hledger_journal.txt view
@@ -0,0 +1,918 @@++hledger_journal(5)           hledger User Manuals           hledger_journal(5)++++NAME+       Journal - hledger's default file format, representing a General Journal++DESCRIPTION+       hledger's usual data source is a plain  text  file  containing  journal+       entries  in  hledger  journal  format.  This file represents a standard+       accounting general journal.  I use file names ending in  .journal,  but+       that's not required.  The journal file contains a number of transaction+       entries, each describing a transfer of money (or any commodity) between+       two or more named accounts, in a simple format readable by both hledger+       and humans.++       hledger's journal format is a compatible subset,  mostly,  of  ledger's+       journal  format,  so  hledger  can  work with compatible ledger journal+       files as well.  It's safe, and encouraged,  to  run  both  hledger  and+       ledger on the same journal file, eg to validate the results you're get-+       ting.++       You can use hledger without learning any more about this file; just use+       the  add  or web commands to create and update it.  Many users, though,+       also edit the  journal  file  directly  with  a  text  editor,  perhaps+       assisted by the helper modes for emacs or vim.++       Here's an example:++              ; A sample journal file. This is a comment.++              2008/01/01 income               ; <- transaction's first line starts in column 0, contains date and description+                  assets:bank:checking  $1    ; <- posting lines start with whitespace, each contains an account name+                  income:salary        $-1    ;    followed by at least two spaces and an amount++              2008/06/01 gift+                  assets:bank:checking  $1    ; <- at least two postings in a transaction+                  income:gifts         $-1    ; <- their amounts must balance to 0++              2008/06/02 save+                  assets:bank:saving    $1+                  assets:bank:checking        ; <- one amount may be omitted; here $-1 is inferred++              2008/06/03 eat & shop           ; <- description can be anything+                  expenses:food         $1+                  expenses:supplies     $1    ; <- this transaction debits two expense accounts+                  assets:cash                 ; <- $-2 inferred++              2008/10/01 take a loan+                  assets:bank:checking  $1+                  liabilities:debts    $-1++              2008/12/31 * pay off            ; <- an optional * or ! after the date means "cleared" (or anything you want)+                  liabilities:debts     $1+                  assets:bank:checking++FILE FORMAT+   Transactions+       Transactions  are  movements  of  some  quantity of commodities between+       named accounts.  Each transaction is represented  by  a  journal  entry+       beginning  with a simple date in column 0.  This can be followed by any+       of the following, separated by spaces:++       o (optional) a status character (empty, !, or *)++       o (optional) a transaction code (any short number or text, enclosed  in+         parentheses)++       o (optional) a transaction description (any remaining text until end of+         line or a semicolon)++       o (optional) a transaction comment  (any  remaining  text  following  a+         semicolon until end of line)++       Then  comes zero or more (but usually at least 2) indented lines repre-+       senting...++   Postings+       A posting is an addition of some amount to, or removal of  some  amount+       from,  an account.  Each posting line begins with at least one space or+       tab (2 or 4 spaces is common), followed by:++       o (optional) a status character (empty, !, or *), followed by a space++       o (required) an account name (any text,  optionally  containing  single+         spaces, until end of line or a double space)++       o (optional) two or more spaces or tabs followed by an amount.++       Positive  amounts  are being added to the account, negative amounts are+       being removed.++       The amounts within a transaction must always sum up to zero.  As a con-+       venience,  one  amount  may be left blank; it will be inferred so as to+       balance the transaction.++       Be sure to note the unusual two-space delimiter  between  account  name+       and  amount.  This makes it easy to write account names containing spa-+       ces.  But if you accidentally leave only one space (or tab) before  the+       amount, the amount will be considered part of the account name.++   Dates+   Simple dates+       Within  a journal file, transaction dates use Y/M/D (or Y-M-D or Y.M.D)+       Leading zeros are optional.  The year may be omitted, in which case  it+       will  be  inferred  from  the  context  -  the current transaction, the+       default year set with a default year directive,  or  the  current  date+       when  the command is run.  Some examples: 2010/01/31, 1/31, 2010-01-31,+       2010.1.31.++   Secondary dates+       Real-life transactions sometimes involve more than one date  -  eg  the+       date you write a cheque, and the date it clears in your bank.  When you+       want to model this, eg for more  accurate  balances,  you  can  specify+       individual  posting dates, which I recommend.  Or, you can use the sec-+       ondary dates (aka auxiliary/effective  dates)  feature,  supported  for+       compatibility with Ledger.++       A secondary date can be written after the primary date, separated by an+       equals sign.  The primary date, on the left, is used  by  default;  the+       secondary  date,  on the right, is used when the --date2 flag is speci-+       fied (--aux-date or --effective also work).++       The meaning of secondary dates is up to you, but it's best to follow  a+       consistent  rule.   Eg  write  the bank's clearing date as primary, and+       when needed, the date the transaction was initiated as secondary.++       Here's an example.  Note that a secondary date will use the year of the+       primary date if unspecified.++              2010/2/23=2/19 movie ticket+                expenses:cinema                   $10+                assets:checking++              $ hledger register checking+              2010/02/23 movie ticket         assets:checking                $-10         $-10++              $ hledger register checking --date2+              2010/02/19 movie ticket         assets:checking                $-10         $-10++       Secondary  dates require some effort; you must use them consistently in+       your journal entries and remember whether to use or not use the --date2+       flag for your reports.  They are included in hledger for Ledger compat-+       ibility, but posting dates are  a  more  powerful  and  less  confusing+       alternative.++   Posting dates+       You  can  give  individual  postings a different date from their parent+       transaction, by adding a posting comment containing a tag  (see  below)+       like date:DATE.  This is probably the best way to control posting dates+       precisely.  Eg in  this  example  the  expense  should  appear  in  May+       reports,  and the deduction from checking should be reported on 6/1 for+       easy bank reconciliation:++              2015/5/30+                  expenses:food     $10   ; food purchased on saturday 5/30+                  assets:checking         ; bank cleared it on monday, date:6/1++              $ hledger -f t.j register food+              2015/05/30                      expenses:food                  $10           $10++              $ hledger -f t.j register checking+              2015/06/01                      assets:checking               $-10          $-10++       DATE should be a simple date; if the year is not specified it will  use+       the  year  of  the  transaction's date.  You can set the secondary date+       similarly, with date2:DATE2.  The date: or  date2:  tags  must  have  a+       valid  simple  date  value  if they are present, eg a date: tag with no+       value is not allowed.++       Ledger's earlier, more compact bracketed date syntax is also supported:+       [DATE],  [DATE=DATE2]  or  [=DATE2].  hledger will attempt to parse any+       square-bracketed sequence of the 0123456789/-.= characters in this way.+       With  this  syntax, DATE infers its year from the transaction and DATE2+       infers its year from DATE.++   Status+       Transactions, or individual postings within a transaction, can  have  a+       status  mark,  which  is  a  single  character  before  the transaction+       description or posting account name, separated  from  it  by  a  space,+       indicating one of three statuses:+++       mark     status+       ------------------+                unmarked+       !        pending+       *        cleared++       When  reporting,  you  can  filter  by  status  with the -U/--unmarked,+       -P/--pending, and -C/--cleared flags; or  the  status:,  status:!,  and+       status:* queries; or the U, P, C keys in hledger-ui.++       Note,  in Ledger and in older versions of hledger, the "unmarked" state+       is called "uncleared".  As  of  hledger  1.3  we  have  renamed  it  to+       unmarked for clarity.++       To  replicate Ledger and old hledger's behaviour of also matching pend-+       ing, combine -U and -P.++       Status marks are optional, but can be helpful eg for  reconciling  with+       real-world accounts.  Some editor modes provide highlighting and short-+       cuts for working with status.  Eg in Emacs ledger-mode, you can  toggle+       transaction status with C-c C-e, or posting status with C-c C-c.++       What  "uncleared", "pending", and "cleared" actually mean is up to you.+       Here's one suggestion:+++       status       meaning+       --------------------------------------------------------------------------+       uncleared    recorded but not yet reconciled; needs review+       pending      tentatively reconciled (if needed, eg during a big reconcil-+                    iation)+       cleared      complete, reconciled as far as possible, and considered cor-+                    rect++       With this scheme, you would use -PC to see the current balance at  your+       bank,  -U  to  see  things which will probably hit your bank soon (like+       uncashed checks), and no flags to see the most up-to-date state of your+       finances.++   Description+       A  transaction's description is the rest of the line following the date+       and status mark (or until a  comment  begins).   Sometimes  called  the+       "narration" in traditional bookkeeping, it can be used for whatever you+       wish, or left blank.  Transaction descriptions can be  queried,  unlike+       comments.++   Payee and note+       You  can  optionally  include  a | (pipe) character in a description to+       subdivide it into a payee/payer name on the left and  additional  notes+       on  the  right.   This may be worthwhile if you need to do more precise+       querying and pivoting by payee.++   Account names+       Account names typically have several parts separated by a  full  colon,+       from  which hledger derives a hierarchical chart of accounts.  They can+       be anything you like, but  in  finance  there  are  traditionally  five+       top-level  accounts: assets, liabilities, income, expenses, and equity.++       Account names may contain single  spaces,  eg:  assets:accounts receiv-+       able.   Because  of  this,  they must always be followed by two or more+       spaces (or newline).++       Account names can be aliased.++   Amounts+       After the account name, there is usually an amount.  Important: between+       account name and amount, there must be two or more spaces.++       Amounts  consist of a number and (usually) a currency symbol or commod-+       ity name.  Some examples:++       2.00001+       $1+       4000 AAPL+       3 "green apples"+       -$1,000,000.00+       INR 9,99,99,999.00+       EUR -2.000.000,00+       1 999 999.9455++       As you can see, the amount format is somewhat flexible:++       o amounts are a number (the "quantity") and optionally a currency  sym-+         bol/commodity name (the "commodity").++       o the  commodity  is  a  symbol, word, or phrase, on the left or right,+         with or without a separating space.  If the commodity  contains  num-+         bers,  spaces  or  non-word punctuation it must be enclosed in double+         quotes.++       o negative amounts with a commodity on the left can have the minus sign+         before or after it++       o digit  groups  (thousands, or any other grouping) can be separated by+         space or comma or period and should be used as separator between  all+         groups++       o decimal  part  can be separated by comma or period and should be dif-+         ferent from digit groups separator++       You can use any of these  variations  when  recording  data.   However,+       there  is  some  ambiguous  way of representing numbers like $1.000 and+       $1,000 both may mean either one thousand or  one  dollar.   By  default+       hledger  will assume that this is sole delimiter is used only for deci-+       mals.  On the other hand commodity format declared prior to  that  line+       will help to resolve that ambiguity differently:++              commodity $1,000.00++              2017/12/25 New life of Scrooge+                  expenses:gifts  $1,000+                  assets++       Though  journal  may  contain  mixed  styles  to represent amount, when+       hledger displays amounts, it will choose a consistent format  for  each+       commodity.   (Except  for  price amounts, which are always formatted as+       written).  The display format is chosen as follows:++       o if there is a commodity directive specifying the format, that is used++       o otherwise  the  format  is  inferred from the first posting amount in+         that commodity in the journal, and the precision (number  of  decimal+         places) will be the maximum from all posting amounts in that commmod-+         ity++       o or if there are no such amounts in the journal, a default  format  is+         used (like $1000.00).++       Price  amounts  and amounts in D directives usually don't affect amount+       format inference, but in some situations they  can  do  so  indirectly.+       (Eg  when  D's default commodity is applied to a commodity-less amount,+       or when an amountless posting is balanced using a price's commodity, or+       when  -V  is  used.) If you find this causing problems, set the desired+       format with a commodity directive.++   Virtual Postings+       When you parenthesise the account name in a posting,  we  call  that  a+       virtual posting, which means:++       o it is ignored when checking that the transaction is balanced++       o it  is  excluded from reports when the --real/-R flag is used, or the+         real:1 query.++       You could use this, eg, to set an  account's  opening  balance  without+       needing to use the equity:opening balances account:++              1/1 special unbalanced posting to set initial balance+                (assets:checking)   $1000++       When the account name is bracketed, we call it a balanced virtual post-+       ing.  This is like an ordinary virtual posting except the balanced vir-+       tual  postings  in a transaction must balance to 0, like the real post-+       ings (but separately from them).  Balanced virtual  postings  are  also+       excluded by --real/-R or real:1.++              1/1 buy food with cash, and update some budget-tracking subaccounts elsewhere+                expenses:food                   $10+                assets:cash                    $-10+                [assets:checking:available]     $10+                [assets:checking:budget:food]  $-10++       Virtual postings have some legitimate uses, but those are few.  You can+       usually find an equivalent journal entry using real postings, which  is+       more correct and provides better error checking.++   Balance Assertions+       hledger  supports  Ledger-style  balance  assertions  in journal files.+       These look like =EXPECTEDBALANCE following a posting's amount.   Eg  in+       this  example we assert the expected dollar balance in accounts a and b+       after each posting:++              2013/1/1+                a   $1  =$1+                b       =$-1++              2013/1/2+                a   $1  =$2+                b  $-1  =$-2++       After reading a journal file, hledger will check all balance assertions+       and  report  an error if any of them fail.  Balance assertions can pro-+       tect you from, eg, inadvertently disrupting reconciled  balances  while+       cleaning  up  old  entries.   You can disable them temporarily with the+       --ignore-assertions flag, which can be useful  for  troubleshooting  or+       for reading Ledger files.++   Assertions and ordering+       hledger  sorts  an  account's postings and assertions first by date and+       then (for postings on the same day) by parse order.  Note this is  dif-+       ferent from Ledger, which sorts assertions only by parse order.  (Also,+       Ledger assertions do not see the accumulated effect of  repeated  post-+       ings to the same account within a transaction.)++       So,  hledger  balance  assertions  keep  working if you reorder differ-+       ently-dated transactions  within  the  journal.   But  if  you  reorder+       same-dated transactions or postings, assertions might break and require+       updating.  This order dependence does bring an advantage: precise  con-+       trol over the order of postings and assertions within a day, so you can+       assert intra-day balances.++   Assertions and included files+       With included files, things are a little more  complicated.   Including+       preserves  the ordering of postings and assertions.  If you have multi-+       ple postings to an account on the  same  day,  split  across  different+       files,  and  you  also want to assert the account's balance on the same+       day, you'll have to put the assertion in the right file.++   Assertions and multiple -f options+       Balance assertions don't work well across files specified with multiple+       -f options.  Use include or concatenate the files instead.++   Assertions and commodities+       The  asserted  balance must be a simple single-commodity amount, and in+       fact the assertion checks only  this  commodity's  balance  within  the+       (possibly  multi-commodity) account balance.  We could call this a par-+       tial balance assertion.  This is compatible with Ledger, and  makes  it+       possible to make assertions about accounts containing multiple commodi-+       ties.++       To assert each commodity's balance in such a  multi-commodity  account,+       you  can  add multiple postings (with amount 0 if necessary).  But note+       that no matter how many assertions you  add,  you  can't  be  sure  the+       account does not contain some unexpected commodity.  (We'll add support+       for this kind of total balance assertion if there's demand.)++   Assertions and subaccounts+       Balance assertions do not count  the  balance  from  subaccounts;  they+       check the posted account's exclusive balance.  For example:++              1/1+                checking:fund   1 = 1  ; post to this subaccount, its balance is now 1+                checking        1 = 1  ; post to the parent account, its exclusive balance is now 1+                equity++       The  balance  report's  flat  mode  shows these exclusive balances more+       clearly:++              $ hledger bal checking --flat+                                 1  checking+                                 1  checking:fund+              --------------------+                                 2++   Assertions and virtual postings+       Balance assertions are checked against all postings, both real and vir-+       tual.  They are not affected by the --real/-R flag or real: query.++   Balance Assignments+       Ledger-style  balance  assignments  are also supported.  These are like+       balance assertions, but with no posting amount on the left side of  the+       equals  sign;  instead  it is calculated automatically so as to satisfy+       the assertion.  This can be a convenience during data  entry,  eg  when+       setting opening balances:++              ; starting a new journal, set asset account balances+              2016/1/1 opening balances+                assets:checking            = $409.32+                assets:savings             = $735.24+                assets:cash                 = $42+                equity:opening balances++       or when adjusting a balance to reality:++              ; no cash left; update balance, record any untracked spending as a generic expense+              2016/1/15+                assets:cash    = $0+                expenses:misc++       The calculated amount depends on the account's balance in the commodity+       at that point (which depends on the previously-dated  postings  of  the+       commodity  to  that account since the last balance assertion or assign-+       ment).  Note that using balance assignments makes your journal a little+       less explicit; to know the exact amount posted, you have to run hledger+       or do the calculations yourself, instead of just reading it.++   Prices+   Transaction prices+       Within a transaction, you can note an amount's price in another commod-+       ity.   This can be used to document the cost (in a purchase) or selling+       price (in a sale).  For  example,  transaction  prices  are  useful  to+       record purchases of a foreign currency.++       Transaction  prices  are  fixed,  and do not change over time.  (Ledger+       users: Ledger uses a different syntax for fixed  prices,  {=UNITPRICE},+       which hledger currently ignores).++       There are several ways to record a transaction price:++       1. Write the price per unit, as @ UNITPRICE after the amount:++                  2009/1/1+                    assets:euros     100 @ $1.35  ; one hundred euros purchased at $1.35 each+                    assets:dollars                 ; balancing amount is -$135.00++       2. Write the total price, as @@ TOTALPRICE after the amount:++                  2009/1/1+                    assets:euros     100 @@ $135  ; one hundred euros purchased at $135 for the lot+                    assets:dollars++       3. Specify amounts for all postings, using exactly two commodities, and+          let hledger infer the price that balances the transaction:++                  2009/1/1+                    assets:euros     100          ; one hundred euros purchased+                    assets:dollars  $-135          ; for $135++       Amounts with transaction prices can be  displayed  in  the  transaction+       price's commodity by using the -B/--cost flag (except for #551) ("B" is+       from "cost Basis").  Eg for the above, here is how -B affects the  bal-+       ance report:++              $ hledger bal -N --flat+                             $-135  assets:dollars+                              100  assets:euros+              $ hledger bal -N --flat -B+                             $-135  assets:dollars+                              $135  assets:euros    # <- the euros' cost++       Note  -B is sensitive to the order of postings when a transaction price+       is inferred: the inferred price will be in the commodity  of  the  last+       amount.  So if example 3's postings are reversed, while the transaction+       is equivalent, -B shows something different:++              2009/1/1+                assets:dollars  $-135               ; 135 dollars sold+                assets:euros     100               ; for 100 euros++              $ hledger bal -N --flat -B+                             -100  assets:dollars  # <- the dollars' selling price+                              100  assets:euros++   Market prices+       Market prices are not tied to a particular transaction; they  represent+       historical  exchange rates between two commodities.  (Ledger calls them+       historical prices.) For  example,  the  prices  published  by  a  stock+       exchange  or the foreign exchange market.  hledger can use these prices+       to show the market value of things at a given date, see market value.++       To record market prices, use P directives in the main journal or in  an+       included file.  Their format is:++              P DATE COMMODITYBEINGPRICED UNITPRICE++       DATE  is a simple date as usual.  COMMODITYBEINGPRICED is the symbol of+       the commodity being priced.  UNITPRICE is an  ordinary  amount  (symbol+       and  quantity) in a second commodity, specifying the unit price or con-+       version rate for the first commodity in terms of  the  second,  on  the+       given date.++       For  example, the following directives say that one euro was worth 1.35+       US dollars during 2009, and $1.40 from 2010 onward:++              P 2009/1/1  $1.35+              P 2010/1/1  $1.40++   Comments+       Lines in the journal beginning with a semicolon (;) or hash (#) or star+       (*)  are  comments, and will be ignored.  (Star comments cause org-mode+       nodes to be ignored, allowing emacs users to fold  and  navigate  their+       journals with org-mode or orgstruct-mode.)++       Also,   anything  between  comment  and  end comment  directives  is  a+       (multi-line) comment.  If there is no end comment, the comment  extends+       to the end of the file.++       You  can  attach  comments  to  a transaction by writing them after the+       description and/or indented on the following lines  (before  the  post-+       ings).   Similarly, you can attach comments to an individual posting by+       writing them after the amount and/or indented on the  following  lines.+       Transaction and posting comments must begin with a semicolon (;).++       Some examples:++              # a file comment++              ; also a file comment++              comment+              This is a multiline file comment,+              which continues until a line+              where the "end comment" string+              appears on its own (or end of file).+              end comment++              2012/5/14 something  ; a transaction comment+                  ; the transaction comment, continued+                  posting1  1  ; a comment for posting 1+                  posting2+                  ; a comment for posting 2+                  ; another comment line for posting 2+              ; a file comment (because not indented)++   Tags+       Tags  are  a  way  to add extra labels or labelled data to postings and+       transactions, which you can then search or pivot on.++       A simple tag is a word (which may contain hyphens) followed by  a  full+       colon, written inside a transaction or posting comment line:++              2017/1/16 bought groceries    ; sometag:++       Tags  can  have  a  value, which is the text after the colon, up to the+       next comma or end of line, with leading/trailing whitespace removed:++                  expenses:food    $10   ; a-posting-tag: the tag value++       Note this means hledger's tag values can not  contain  commas  or  new-+       lines.  Ending at commas means you can write multiple short tags on one+       line, comma separated:++                  assets:checking       ; a comment containing tag1:, tag2: some value ...++       Here,++       o "a comment containing" is just comment text, not a tag++       o "tag1" is a tag with no value++       o "tag2" is another tag, whose value is "some value ..."++       Tags in a transaction comment affect the transaction  and  all  of  its+       postings,  while  tags  in  a posting comment affect only that posting.+       For example,  the  following  transaction  has  three  tags  (A,  TAG2,+       third-tag) and the posting has four (those plus posting-tag):++              1/1 a transaction  ; A:, TAG2:+                  ; third-tag: a third transaction tag, <- with a value+                  (a)  $1  ; posting-tag:++       Tags  are  like  Ledger's metadata feature, except hledger's tag values+       are simple strings.++   Directives+   Account aliases+       You can define aliases which rewrite your account names (after  reading+       the journal, before generating reports).  hledger's account aliases can+       be useful for:++       o expanding shorthand account names to their full form, allowing easier+         data entry and a less verbose journal++       o adapting old journals to your current chart of accounts++       o experimenting with new account organisations, like a new hierarchy or+         combining two accounts into one++       o customising reports++       See also Cookbook: rewrite account names.++   Basic aliases+       To set an account alias, use the alias directive in your journal  file.+       This  affects all subsequent journal entries in the current file or its+       included files.  The spaces around the = are optional:++              alias OLD = NEW++       Or, you can use the --alias 'OLD=NEW' option on the command line.  This+       affects all entries.  It's useful for trying out aliases interactively.++       OLD and NEW are full account names.  hledger will  replace  any  occur-+       rence  of  the old account name with the new one.  Subaccounts are also+       affected.  Eg:++              alias checking = assets:bank:wells fargo:checking+              # rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a"++   Regex aliases+       There is also a more powerful variant that uses a  regular  expression,+       indicated by the forward slashes:++              alias /REGEX/ = REPLACEMENT++       or --alias '/REGEX/=REPLACEMENT'.++       REGEX  is  a  case-insensitive regular expression.  Anywhere it matches+       inside an account name, the matched part will be replaced  by  REPLACE-+       MENT.   If REGEX contains parenthesised match groups, these can be ref-+       erenced by the usual numeric backreferences in REPLACEMENT.  Eg:++              alias /^(.+):bank:([^:]+)(.*)/ = \1:\2 \3+              # rewrites "assets:bank:wells fargo:checking" to  "assets:wells fargo checking"++       Also note that REPLACEMENT continues to the end of line (or on  command+       line,  to  end  of  option argument), so it can contain trailing white-+       space.++   Multiple aliases+       You can define as many aliases as you like  using  directives  or  com-+       mand-line  options.  Aliases are recursive - each alias sees the result+       of applying previous ones.   (This  is  different  from  Ledger,  where+       aliases are non-recursive by default).  Aliases are applied in the fol-+       lowing order:++       1. alias directives, most recently seen first (recent  directives  take+          precedence over earlier ones; directives not yet seen are ignored)++       2. alias options, in the order they appear on the command line++   end aliases+       You   can  clear  (forget)  all  currently  defined  aliases  with  the+       end aliases directive:++              end aliases++   account directive+       The account directive predefines account names, as in Ledger and  Bean-+       count.   This may be useful for your own documentation; hledger doesn't+       make use of it yet.++              ; account ACCT+              ;   OPTIONAL COMMENTS/TAGS...++              account assets:bank:checking+               a comment+               acct-no:12345++              account expenses:food++              ; etc.++   apply account directive+       You can specify a  parent  account  which  will  be  prepended  to  all+       accounts  within  a  section of the journal.  Use the apply account and+       end apply account directives like so:++              apply account home++              2010/1/1+                  food    $10+                  cash++              end apply account++       which is equivalent to:++              2010/01/01+                  home:food           $10+                  home:cash          $-10++       If end apply account is omitted, the effect lasts to  the  end  of  the+       file.  Included files are also affected, eg:++              apply account business+              include biz.journal+              end apply account+              apply account personal+              include personal.journal++       Prior  to  hledger 1.0, legacy account and end spellings were also sup-+       ported.++   Multi-line comments+       A line containing just comment starts a multi-line comment, and a  line+       containing just end comment ends it.  See comments.++   commodity directive+       The  commodity directive predefines commodities (currently this is just+       informational), and also it may define the display format  for  amounts+       in this commodity (overriding the automatically inferred format).++       It may be written on a single line, like this:++              ; commodity EXAMPLEAMOUNT++              ; display AAAA amounts with the symbol on the right, space-separated,+              ; using period as decimal point, with four decimal places, and+              ; separating thousands with comma.+              commodity 1,000.0000 AAAA++       or  on  multiple  lines, using the "format" subdirective.  In this case+       the commodity symbol appears twice and  should  be  the  same  in  both+       places:++              ; commodity SYMBOL+              ;   format EXAMPLEAMOUNT++              ; display indian rupees with currency name on the left,+              ; thousands, lakhs and crores comma-separated,+              ; period as decimal point, and two decimal places.+              commodity INR+                format INR 9,99,99,999.00++   Default commodity+       The  D  directive  sets a default commodity (and display format), to be+       used for amounts without a commodity symbol (ie, plain numbers).  (Note+       this  differs from Ledger's default commodity directive.) The commodity+       and display format will be applied  to  all  subsequent  commodity-less+       amounts, or until the next D directive.++              # commodity-less amounts should be treated as dollars+              # (and displayed with symbol on the left, thousands separators and two decimal places)+              D $1,000.00++              1/1+                a     5    ; <- commodity-less amount, becomes $1+                b++   Default year+       You  can set a default year to be used for subsequent dates which don't+       specify a year.  This is a line beginning with Y followed by the  year.+       Eg:++              Y2009      ; set default year to 2009++              12/15      ; equivalent to 2009/12/15+                expenses  1+                assets++              Y2010      ; change default year to 2010++              2009/1/30  ; specifies the year, not affected+                expenses  1+                assets++              1/31       ; equivalent to 2010/1/31+                expenses  1+                assets++   Including other files+       You  can  pull in the content of additional journal files by writing an+       include directive, like this:++              include path/to/file.journal++       If the path does not begin with a slash, it is relative to the  current+       file.  Glob patterns (*) are not currently supported.++       The  include  directive  can  only  be  used  in journal files.  It can+       include journal, timeclock or timedot files, but not CSV files.++Periodic transactions+       A periodic transaction starts with a tilde `~' in place of a date  fol-+       lowed by a period expression:++              ~ weekly+                assets:bank:checking   $400 ; paycheck+                income:acme inc++       Periodic transactions are used for forecasting and budgeting only, they+       have no effect unless the --forecast or --budget flag  is  used.   With+       --forecast, each periodic transaction rule generates recurring forecast+       transactions at the specified interval, beginning  the  day  after  the+       last recorded journal transaction and ending 6 months from today, or at+       the specified report end date.  With  balance --budget,  each  periodic+       transaction declares recurring budget goals for one or more accounts.+       For  more details, see: balance > Budgeting, Budgeting and Forecasting.++Automated posting rules+       Automated posting rule starts with an equal sign  `='  in  place  of  a+       date, followed by a query:++              = expenses:gifts+                  budget:gifts  *-1+                  assets:budget  *1++       When  --auto option is specified on the command line, automated posting+       rule will add its postings to all transactions that match the query.++       If amount in the automated posting rule includes  commodity  name,  new+       posting will be made in the given commodity, otherwise commodity of the+       matched transaction will be used.++       When amount in the automated posting rule begins with the  '*',  amount+       will  be  treated  as a multiplier that is applied to the amount of the+       first posting in the matched transaction.++       In example above, every transaction in expenses:gifts account will have+       two  additional  postings added to it: amount of the original gift will+       be debited from budget:gifts and credited into assets:budget:++              ; Original transaction+              2017-12-14+                expenses:gifts  $20+                assets++              ; With automated postings applied+              2017/12/14+                  expenses:gifts             $20+                  assets+                  budget:gifts              $-20+                  assets:budget              $20++EDITOR SUPPORT+       Add-on modes exist for various text editors, to make working with jour-+       nal  files  easier.   They add colour, navigation aids and helpful com-+       mands.  For hledger users who  edit  the  journal  file  directly  (the+       majority), using one of these modes is quite recommended.++       These  were  written  with  Ledger  in mind, but also work with hledger+       files:+++       Emacs              http://www.ledger-cli.org/3.0/doc/ledger-mode.html+       Vim                https://github.com/ledger/ledger/wiki/Getting-started+++       Sublime Text       https://github.com/ledger/ledger/wiki/Using-Sub-+                          lime-Text+       Textmate           https://github.com/ledger/ledger/wiki/Using-Text-+                          Mate-2+       Text Wrangler      https://github.com/ledger/ledger/wiki/Edit-+                          ing-Ledger-files-with-TextWrangler+       Visual    Studio   https://marketplace.visualstudio.com/items?item-+       Code               Name=mark-hansen.hledger-vscode++++REPORTING BUGS+       Report bugs at http://bugs.hledger.org (or on the #hledger IRC  channel+       or hledger mail list)+++AUTHORS+       Simon Michael <simon@joyful.com> and contributors+++COPYRIGHT+       Copyright (C) 2007-2016 Simon Michael.+       Released under GNU GPL v3 or later.+++SEE ALSO+       hledger(1),      hledger-ui(1),     hledger-web(1),     hledger-api(1),+       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time-+       dot(5), ledger(1)++       http://hledger.org++++hledger 1.5                      December 2017              hledger_journal(5)
+ hledger_timeclock.5 view
@@ -0,0 +1,92 @@++.TH "hledger_timeclock" "5" "December 2017" "hledger 1.5" "hledger User Manuals"++++.SH NAME+.PP+Timeclock \- the time logging format of timeclock.el, as read by hledger+.SH DESCRIPTION+.PP+hledger can read timeclock files.+As with Ledger, these are (a subset of) timeclock.el's format,+containing clock\-in and clock\-out entries as in the example below.+The date is a simple date.+The time format is HH:MM[:SS][+\-ZZZZ].+Seconds and timezone are optional.+The timezone, if present, must be four digits and is ignored (currently+the time is always interpreted as a local time).+.IP+.nf+\f[C]+i\ 2015/03/30\ 09:00:00\ some:account\ name\ \ optional\ description\ after\ two\ spaces+o\ 2015/03/30\ 09:20:00+i\ 2015/03/31\ 22:21:45\ another\ account+o\ 2015/04/01\ 02:00:34+\f[]+.fi+.PP+hledger treats each clock\-in/clock\-out pair as a transaction posting+some number of hours to an account.+Or if the session spans more than one day, it is split into several+transactions, one for each day.+For the above time log, \f[C]hledger\ print\f[] generates these journal+entries:+.IP+.nf+\f[C]+$\ hledger\ \-f\ t.timeclock\ print+2015/03/30\ *\ optional\ description\ after\ two\ spaces+\ \ \ \ (some:account\ name)\ \ \ \ \ \ \ \ \ 0.33h++2015/03/31\ *\ 22:21\-23:59+\ \ \ \ (another\ account)\ \ \ \ \ \ \ \ \ 1.64h++2015/04/01\ *\ 00:00\-02:00+\ \ \ \ (another\ account)\ \ \ \ \ \ \ \ \ 2.01h+\f[]+.fi+.PP+Here is a sample.timeclock to download and some queries to try:+.IP+.nf+\f[C]+$\ hledger\ \-f\ sample.timeclock\ balance\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ current\ time\ balances+$\ hledger\ \-f\ sample.timeclock\ register\ \-p\ 2009/3\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ sessions\ in\ march\ 2009+$\ hledger\ \-f\ sample.timeclock\ register\ \-p\ weekly\ \-\-depth\ 1\ \-\-empty\ \ #\ time\ summary\ by\ week+\f[]+.fi+.PP+To generate time logs, ie to clock in and clock out, you could:+.IP \[bu] 2+use emacs and the built\-in timeclock.el, or the extended+timeclock\-x.el and perhaps the extras in ledgerutils.el+.IP \[bu] 2+at the command line, use these bash aliases:+\f[C]shell\ \ \ alias\ ti="echo\ i\ `date\ \[aq]+%Y\-%m\-%d\ %H:%M:%S\[aq]`\ \\$*\ >>$TIMELOG"\ \ \ alias\ to="echo\ o\ `date\ \[aq]+%Y\-%m\-%d\ %H:%M:%S\[aq]`\ >>$TIMELOG"\f[]+.IP \[bu] 2+or use the old \f[C]ti\f[] and \f[C]to\f[] scripts in the ledger 2.x+repository.+These rely on a \[lq]timeclock\[rq] executable which I think is just the+ledger 2 executable renamed.+++.SH "REPORTING BUGS"+Report bugs at http://bugs.hledger.org+(or on the #hledger IRC channel or hledger mail list)++.SH AUTHORS+Simon Michael <simon@joyful.com> and contributors++.SH COPYRIGHT++Copyright (C) 2007-2016 Simon Michael.+.br+Released under GNU GPL v3 or later.++.SH SEE ALSO+hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),+hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),+ledger(1)++http://hledger.org
+ hledger_timeclock.info view
@@ -0,0 +1,60 @@+This is hledger_timeclock.info, produced by makeinfo version 6.5 from+stdin.+++File: hledger_timeclock.info,  Node: Top,  Up: (dir)++hledger_timeclock(5) hledger 1.5+********************************++hledger can read timeclock files.  As with Ledger, these are (a subset+of) timeclock.el's format, containing clock-in and clock-out entries as+in the example below.  The date is a simple date.  The time format is+HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional.  The timezone, if+present, must be four digits and is ignored (currently the time is+always interpreted as a local time).++i 2015/03/30 09:00:00 some:account name  optional description after two spaces+o 2015/03/30 09:20:00+i 2015/03/31 22:21:45 another account+o 2015/04/01 02:00:34++   hledger treats each clock-in/clock-out pair as a transaction posting+some number of hours to an account.  Or if the session spans more than+one day, it is split into several transactions, one for each day.  For+the above time log, 'hledger print' generates these journal entries:++$ hledger -f t.timeclock print+2015/03/30 * optional description after two spaces+    (some:account name)         0.33h++2015/03/31 * 22:21-23:59+    (another account)         1.64h++2015/04/01 * 00:00-02:00+    (another account)         2.01h++   Here is a sample.timeclock to download and some queries to try:++$ hledger -f sample.timeclock balance                               # current time balances+$ hledger -f sample.timeclock register -p 2009/3                    # sessions in march 2009+$ hledger -f sample.timeclock register -p weekly --depth 1 --empty  # time summary by week++   To generate time logs, ie to clock in and clock out, you could:++   * use emacs and the built-in timeclock.el, or the extended+     timeclock-x.el and perhaps the extras in ledgerutils.el++   * at the command line, use these bash aliases: 'shell alias ti="echo+     i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o+     `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"'+   * or use the old 'ti' and 'to' scripts in the ledger 2.x repository.+     These rely on a "timeclock" executable which I think is just the+     ledger 2 executable renamed.++++Tag Table:+Node: Top78++End Tag Table
+ hledger_timeclock.txt view
@@ -0,0 +1,80 @@++hledger_timeclock(5)         hledger User Manuals         hledger_timeclock(5)++++NAME+       Timeclock - the time logging format of timeclock.el, as read by hledger++DESCRIPTION+       hledger can read timeclock files.  As with Ledger, these are (a  subset+       of) timeclock.el's format, containing clock-in and clock-out entries as+       in the example below.  The date is a simple date.  The time  format  is+       HH:MM[:SS][+-ZZZZ].   Seconds and timezone are optional.  The timezone,+       if present, must be four digits and is ignored (currently the  time  is+       always interpreted as a local time).++              i 2015/03/30 09:00:00 some:account name  optional description after two spaces+              o 2015/03/30 09:20:00+              i 2015/03/31 22:21:45 another account+              o 2015/04/01 02:00:34++       hledger  treats  each  clock-in/clock-out pair as a transaction posting+       some number of hours to an account.  Or if the session spans more  than+       one  day, it is split into several transactions, one for each day.  For+       the above time log, hledger print generates these journal entries:++              $ hledger -f t.timeclock print+              2015/03/30 * optional description after two spaces+                  (some:account name)         0.33h++              2015/03/31 * 22:21-23:59+                  (another account)         1.64h++              2015/04/01 * 00:00-02:00+                  (another account)         2.01h++       Here is a sample.timeclock to download and some queries to try:++              $ hledger -f sample.timeclock balance                               # current time balances+              $ hledger -f sample.timeclock register -p 2009/3                    # sessions in march 2009+              $ hledger -f sample.timeclock register -p weekly --depth 1 --empty  # time summary by week++       To generate time logs, ie to clock in and clock out, you could:++       o use emacs and  the  built-in  timeclock.el,  or  the  extended  time-+         clock-x.el and perhaps the extras in ledgerutils.el++       o at     the     command     line,     use    these    bash    aliases:+         shell   alias ti="echo i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG"   alias to="echo o `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"++       o or use the old ti and to scripts in the ledger 2.x repository.  These+         rely on a "timeclock" executable which I think is just the  ledger  2+         executable renamed.++++REPORTING BUGS+       Report  bugs at http://bugs.hledger.org (or on the #hledger IRC channel+       or hledger mail list)+++AUTHORS+       Simon Michael <simon@joyful.com> and contributors+++COPYRIGHT+       Copyright (C) 2007-2016 Simon Michael.+       Released under GNU GPL v3 or later.+++SEE ALSO+       hledger(1),     hledger-ui(1),     hledger-web(1),      hledger-api(1),+       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time-+       dot(5), ledger(1)++       http://hledger.org++++hledger 1.5                      December 2017            hledger_timeclock(5)
+ hledger_timedot.5 view
@@ -0,0 +1,154 @@++.TH "hledger_timedot" "5" "December 2017" "hledger 1.5" "hledger User Manuals"++++.SH NAME+.PP+Timedot \- hledger's human\-friendly time logging format+.SH DESCRIPTION+.PP+Timedot is a plain text format for logging dated, categorised quantities+(of time, usually), supported by hledger.+It is convenient for approximate and retroactive time logging, eg when+the real\-time clock\-in/out required with a timeclock file is too+precise or too interruptive.+It can be formatted like a bar chart, making clear at a glance where+time was spent.+.PP+Though called \[lq]timedot\[rq], this format is read by hledger as+commodityless quantities, so it could be used to represent dated+quantities other than time.+In the docs below we'll assume it's time.+.SH FILE FORMAT+.PP+A timedot file contains a series of day entries.+A day entry begins with a date, and is followed by category/quantity+pairs, one per line.+Dates are hledger\-style simple dates (see hledger_journal(5)).+Categories are hledger\-style account names, optionally indented.+As in a hledger journal, there must be at least two spaces between the+category (account name) and the quantity.+.PP+Quantities can be written as:+.IP \[bu] 2+a sequence of dots (.) representing quarter hours.+Spaces may optionally be used for grouping and readability.+Eg: \&....+\&..+.IP \[bu] 2+an integral or decimal number, representing hours.+Eg: 1.5+.IP \[bu] 2+an integral or decimal number immediately followed by a unit symbol+\f[C]s\f[], \f[C]m\f[], \f[C]h\f[], \f[C]d\f[], \f[C]w\f[], \f[C]mo\f[],+or \f[C]y\f[], representing seconds, minutes, hours, days weeks, months+or years respectively.+Eg: 90m.+The following equivalencies are assumed, currently: 1m = 60s, 1h = 60m,+1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.+.PP+Blank lines and lines beginning with #, ; or * are ignored.+An example:+.IP+.nf+\f[C]+#\ on\ this\ day,\ 6h\ was\ spent\ on\ client\ work,\ 1.5h\ on\ haskell\ FOSS\ work,\ etc.+2016/2/1+inc:client1\ \ \ ....\ ....\ ....\ ....\ ....\ ....+fos:haskell\ \ \ ....\ ..\ +biz:research\ \ .++2016/2/2+inc:client1\ \ \ ....\ ....+biz:research\ \ .+\f[]+.fi+.PP+Or with numbers:+.IP+.nf+\f[C]+2016/2/3+inc:client1\ \ \ 4+fos:hledger\ \ \ 3+biz:research\ \ 1+\f[]+.fi+.PP+Reporting:+.IP+.nf+\f[C]+$\ hledger\ \-f\ t.timedot\ print\ date:2016/2/2+2016/02/02\ *+\ \ \ \ (inc:client1)\ \ \ \ \ \ \ \ \ \ 2.00++2016/02/02\ *+\ \ \ \ (biz:research)\ \ \ \ \ \ \ \ \ \ 0.25+\f[]+.fi+.IP+.nf+\f[C]+$\ hledger\ \-f\ t.timedot\ bal\ \-\-daily\ \-\-tree+Balance\ changes\ in\ 2016/02/01\-2016/02/03:++\ \ \ \ \ \ \ \ \ \ \ \ ||\ \ 2016/02/01d\ \ 2016/02/02d\ \ 2016/02/03d\ +============++========================================+\ biz\ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 1.00\ +\ \ \ research\ ||\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 0.25\ \ \ \ \ \ \ \ \ 1.00\ +\ fos\ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 1.50\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ 3.00\ +\ \ \ haskell\ \ ||\ \ \ \ \ \ \ \ \ 1.50\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ \ \ \ 0\ +\ \ \ hledger\ \ ||\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ 3.00\ +\ inc\ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 6.00\ \ \ \ \ \ \ \ \ 2.00\ \ \ \ \ \ \ \ \ 4.00\ +\ \ \ client1\ \ ||\ \ \ \ \ \ \ \ \ 6.00\ \ \ \ \ \ \ \ \ 2.00\ \ \ \ \ \ \ \ \ 4.00\ +\-\-\-\-\-\-\-\-\-\-\-\-++\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\ \ \ \ \ \ \ \ \ \ \ \ ||\ \ \ \ \ \ \ \ \ 7.75\ \ \ \ \ \ \ \ \ 2.25\ \ \ \ \ \ \ \ \ 8.00\ +\f[]+.fi+.PP+I prefer to use period for separating account components.+We can make this work with an account alias:+.IP+.nf+\f[C]+2016/2/4+fos.hledger.timedot\ \ 4+fos.ledger\ \ \ \ \ \ \ \ \ \ \ ..+\f[]+.fi+.IP+.nf+\f[C]+$\ hledger\ \-f\ t.timedot\ \-\-alias\ /\\\\./=:\ bal\ date:2016/2/4+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 4.50\ \ fos+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 4.00\ \ \ \ hledger:timedot+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 0.50\ \ \ \ ledger+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 4.50+\f[]+.fi+.PP+Here is a sample.timedot.+++.SH "REPORTING BUGS"+Report bugs at http://bugs.hledger.org+(or on the #hledger IRC channel or hledger mail list)++.SH AUTHORS+Simon Michael <simon@joyful.com> and contributors++.SH COPYRIGHT++Copyright (C) 2007-2016 Simon Michael.+.br+Released under GNU GPL v3 or later.++.SH SEE ALSO+hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),+hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5),+ledger(1)++http://hledger.org
+ hledger_timedot.info view
@@ -0,0 +1,116 @@+This is hledger_timedot.info, produced by makeinfo version 6.5 from+stdin.+++File: hledger_timedot.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir)++hledger_timedot(5) hledger 1.5+******************************++Timedot is a plain text format for logging dated, categorised quantities+(of time, usually), supported by hledger.  It is convenient for+approximate and retroactive time logging, eg when the real-time+clock-in/out required with a timeclock file is too precise or too+interruptive.  It can be formatted like a bar chart, making clear at a+glance where time was spent.++   Though called "timedot", this format is read by hledger as+commodityless quantities, so it could be used to represent dated+quantities other than time.  In the docs below we'll assume it's time.+* Menu:++* FILE FORMAT::+++File: hledger_timedot.info,  Node: FILE FORMAT,  Prev: Top,  Up: Top++1 FILE FORMAT+*************++A timedot file contains a series of day entries.  A day entry begins+with a date, and is followed by category/quantity pairs, one per line.+Dates are hledger-style simple dates (see hledger_journal(5)).+Categories are hledger-style account names, optionally indented.  As in+a hledger journal, there must be at least two spaces between the+category (account name) and the quantity.++   Quantities can be written as:++   * a sequence of dots (.)  representing quarter hours.  Spaces may+     optionally be used for grouping and readability.  Eg: ....  ..++   * an integral or decimal number, representing hours.  Eg: 1.5++   * an integral or decimal number immediately followed by a unit symbol+     's', 'm', 'h', 'd', 'w', 'mo', or 'y', representing seconds,+     minutes, hours, days weeks, months or years respectively.  Eg: 90m.+     The following equivalencies are assumed, currently: 1m = 60s, 1h =+     60m, 1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d.++   Blank lines and lines beginning with #, ; or * are ignored.  An+example:++# on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.+2016/2/1+inc:client1   .... .... .... .... .... ....+fos:haskell   .... .. +biz:research  .++2016/2/2+inc:client1   .... ....+biz:research  .++   Or with numbers:++2016/2/3+inc:client1   4+fos:hledger   3+biz:research  1++   Reporting:++$ hledger -f t.timedot print date:2016/2/2+2016/02/02 *+    (inc:client1)          2.00++2016/02/02 *+    (biz:research)          0.25++$ hledger -f t.timedot bal --daily --tree+Balance changes in 2016/02/01-2016/02/03:++            ||  2016/02/01d  2016/02/02d  2016/02/03d +============++========================================+ biz        ||         0.25         0.25         1.00 +   research ||         0.25         0.25         1.00 + fos        ||         1.50            0         3.00 +   haskell  ||         1.50            0            0 +   hledger  ||            0            0         3.00 + inc        ||         6.00         2.00         4.00 +   client1  ||         6.00         2.00         4.00 +------------++----------------------------------------+            ||         7.75         2.25         8.00 ++   I prefer to use period for separating account components.  We can+make this work with an account alias:++2016/2/4+fos.hledger.timedot  4+fos.ledger           ..++$ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4+                4.50  fos+                4.00    hledger:timedot+                0.50    ledger+--------------------+                4.50++   Here is a sample.timedot.+++Tag Table:+Node: Top76+Node: FILE FORMAT805+Ref: #file-format906++End Tag Table
+ hledger_timedot.txt view
@@ -0,0 +1,127 @@++hledger_timedot(5)           hledger User Manuals           hledger_timedot(5)++++NAME+       Timedot - hledger's human-friendly time logging format++DESCRIPTION+       Timedot  is  a plain text format for logging dated, categorised quanti-+       ties (of time, usually), supported by hledger.  It  is  convenient  for+       approximate  and  retroactive  time  logging,  eg  when  the  real-time+       clock-in/out required with a timeclock  file  is  too  precise  or  too+       interruptive.   It can be formatted like a bar chart, making clear at a+       glance where time was spent.++       Though called "timedot", this format is read by hledger  as  commodity-+       less  quantities,  so  it  could  be used to represent dated quantities+       other than time.  In the docs below we'll assume it's time.++FILE FORMAT+       A timedot file contains a series of day entries.  A  day  entry  begins+       with  a date, and is followed by category/quantity pairs, one per line.+       Dates are hledger-style simple dates (see  hledger_journal(5)).   Cate-+       gories  are  hledger-style account names, optionally indented.  As in a+       hledger journal, there must be at least two spaces between the category+       (account name) and the quantity.++       Quantities can be written as:++       o a  sequence  of  dots  (.)  representing  quarter  hours.  Spaces may+         optionally be used for grouping and readability.  Eg: ....  ..++       o an integral or decimal number, representing hours.  Eg: 1.5++       o an integral or decimal number immediately followed by a  unit  symbol+         s,  m,  h, d, w, mo, or y, representing seconds, minutes, hours, days+         weeks, months or years respectively.  Eg: 90m.  The following equiva-+         lencies  are  assumed,  currently: 1m = 60s, 1h = 60m, 1d = 24h, 1w =+         7d, 1mo = 30d, 1y=365d.++       Blank lines and lines beginning with #, ; or * are ignored.   An  exam-+       ple:++              # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc.+              2016/2/1+              inc:client1   .... .... .... .... .... ....+              fos:haskell   .... ..+              biz:research  .++              2016/2/2+              inc:client1   .... ....+              biz:research  .++       Or with numbers:++              2016/2/3+              inc:client1   4+              fos:hledger   3+              biz:research  1++       Reporting:++              $ hledger -f t.timedot print date:2016/2/2+              2016/02/02 *+                  (inc:client1)          2.00++              2016/02/02 *+                  (biz:research)          0.25++              $ hledger -f t.timedot bal --daily --tree+              Balance changes in 2016/02/01-2016/02/03:++                          ||  2016/02/01d  2016/02/02d  2016/02/03d+              ============++========================================+               biz        ||         0.25         0.25         1.00+                 research ||         0.25         0.25         1.00+               fos        ||         1.50            0         3.00+                 haskell  ||         1.50            0            0+                 hledger  ||            0            0         3.00+               inc        ||         6.00         2.00         4.00+                 client1  ||         6.00         2.00         4.00+              ------------++----------------------------------------+                          ||         7.75         2.25         8.00++       I  prefer to use period for separating account components.  We can make+       this work with an account alias:++              2016/2/4+              fos.hledger.timedot  4+              fos.ledger           ..++              $ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4+                              4.50  fos+                              4.00    hledger:timedot+                              0.50    ledger+              --------------------+                              4.50++       Here is a sample.timedot.++++REPORTING BUGS+       Report bugs at http://bugs.hledger.org (or on the #hledger IRC  channel+       or hledger mail list)+++AUTHORS+       Simon Michael <simon@joyful.com> and contributors+++COPYRIGHT+       Copyright (C) 2007-2016 Simon Michael.+       Released under GNU GPL v3 or later.+++SEE ALSO+       hledger(1),      hledger-ui(1),     hledger-web(1),     hledger-api(1),+       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time-+       dot(5), ledger(1)++       http://hledger.org++++hledger 1.5                      December 2017              hledger_timedot(5)